~ubuntu-branches/ubuntu/utopic/texlive-bin/utopic

« back to all changes in this revision

Viewing changes to texk/dvipdfmx/dvipdfmx-20120420/src/spc_util.c

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2012-05-07 10:47:49 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20120507104749-p00ot5sajjbkp1hp
Tags: 2011.20120507-1
* new upstream checkout: uptex 1.10
* drop patches for config file inclusion in (x)dvipdfmx, included upstream
* add man page for etex
* include pmpost patches and build it
* adapt/unfuzzify patches for current sources
* disable mtx building, we have prepmx package in Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  $Header: /home/cvsroot/dvipdfmx/src/spc_util.c,v 1.17 2011/03/06 03:14:15 chofchof Exp $
 
2
    
 
3
    This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
 
4
 
 
5
    Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
 
6
    the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
 
7
    
 
8
    Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
 
9
 
 
10
    This program is free software; you can redistribute it and/or modify
 
11
    it under the terms of the GNU General Public License as published by
 
12
    the Free Software Foundation; either version 2 of the License, or
 
13
    (at your option) any later version.
 
14
    
 
15
    This program is distributed in the hope that it will be useful,
 
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
    GNU General Public License for more details.
 
19
    
 
20
    You should have received a copy of the GNU General Public License
 
21
    along with this program; if not, write to the Free Software
 
22
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
23
*/
 
24
 
 
25
#if HAVE_CONFIG_H
 
26
#include "config.h"
 
27
#endif
 
28
 
 
29
#include "system.h"
 
30
#include "mem.h"
 
31
#include "error.h"
 
32
#include "dpxutil.h"
 
33
 
 
34
#include "pdfdev.h"
 
35
#include "pdfparse.h"
 
36
#include "pdfcolor.h"
 
37
#include "pdfdraw.h"
 
38
 
 
39
#include "specials.h"
 
40
 
 
41
#include "spc_util.h"
 
42
 
 
43
 
 
44
#ifndef ISBLANK
 
45
#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
 
46
#endif
 
47
static void
 
48
skip_blank (const char **pp, const char *endptr)
 
49
{
 
50
  const char  *p = *pp;
 
51
  for ( ; p < endptr && ISBLANK(*p); p++);
 
52
  *pp = p;
 
53
}
 
54
 
 
55
 
 
56
/* From pdfcolor.c */
 
57
static int pdf_color_namedcolor (pdf_color *color, const char *colorname);
 
58
 
 
59
static int
 
60
spc_util_read_numbers (double *values, int num_values,
 
61
                       struct spc_env *spe, struct spc_arg *args)
 
62
{
 
63
  int   count;
 
64
  char *q;
 
65
 
 
66
  skip_blank(&args->curptr, args->endptr);
 
67
  for (count = 0;
 
68
       count < num_values &&
 
69
       args->curptr < args->endptr; ) {
 
70
    q = parse_float_decimal(&args->curptr, args->endptr);
 
71
    if (!q)
 
72
      break;
 
73
    else {
 
74
      values[count] = atof(q);
 
75
      RELEASE(q);
 
76
      skip_blank(&args->curptr, args->endptr);
 
77
      count++;
 
78
    }
 
79
  }
 
80
 
 
81
  return  count;
 
82
}
 
83
 
 
84
static void
 
85
rgb_color_from_hsv (pdf_color *color, double h, double s, double v)
 
86
{
 
87
  double  r, g, b;
 
88
  ASSERT( color );
 
89
  r = g = b = v;
 
90
  if (s != 0.0) {
 
91
    double h6, f, v1, v2, v3;
 
92
    int    i;
 
93
    h6 = h * 6; /* 360 / 60 */
 
94
    i  = (int) h6;
 
95
    f  = h6 - i;
 
96
    v1 = v * (1 - s);
 
97
    v2 = v * (1 - s * f);
 
98
    v3 = v * (1 - s * (1 - f));
 
99
    switch (i) {
 
100
    case  0: r = v ; g = v3; b = v1; break;
 
101
    case  1: r = v2; g = v ; b = v1; break;
 
102
    case  2: r = v1; g = v ; b = v3; break;
 
103
    case  3: r = v1; g = v2; b = v ; break;
 
104
    case  4: r = v3; g = v1; b = v ; break;
 
105
    case  5: r = v ; g = v1; b = v2; break;
 
106
    case  6: r = v ; g = v1; b = v2; break;
 
107
    }
 
108
  }
 
109
  pdf_color_rgbcolor(color, r, g, b);
 
110
}
 
111
 
 
112
static int
 
113
spc_read_color_color (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap)
 
114
{
 
115
  char    *q;
 
116
  double   cv[4];
 
117
  int      nc;
 
118
  int      error = 0;
 
119
 
 
120
  q = parse_c_ident(&ap->curptr, ap->endptr);
 
121
  if (!q) {
 
122
    spc_warn(spe, "No valid color specified?");
 
123
    return  -1;
 
124
  }
 
125
  skip_blank(&ap->curptr, ap->endptr);
 
126
 
 
127
  if (!strcmp(q, "rgb")) { /* Handle rgb color */
 
128
    nc = spc_util_read_numbers(cv, 3, spe, ap);
 
129
    if (nc != 3) {
 
130
      spc_warn(spe, "Invalid value for RGB color specification.");
 
131
      error = -1;
 
132
    } else {
 
133
      pdf_color_rgbcolor(colorspec, cv[0], cv[1], cv[2]);
 
134
    }
 
135
  } else if (!strcmp(q, "cmyk")) { /* Handle cmyk color */
 
136
    nc = spc_util_read_numbers(cv, 4, spe, ap);
 
137
    if (nc != 4) {
 
138
      spc_warn(spe, "Invalid value for CMYK color specification.");
 
139
      error = -1;
 
140
    } else {
 
141
      pdf_color_cmykcolor(colorspec, cv[0], cv[1], cv[2], cv[3]);
 
142
    }
 
143
  } else if (!strcmp(q, "gray")) { /* Handle gray */
 
144
    nc = spc_util_read_numbers(cv, 1, spe, ap);
 
145
    if (nc != 1) {
 
146
      spc_warn(spe, "Invalid value for gray color specification.");
 
147
      error = -1;
 
148
    } else {
 
149
      pdf_color_graycolor(colorspec, cv[0]);
 
150
    }
 
151
  } else if (!strcmp(q, "hsb")) {
 
152
    nc = spc_util_read_numbers(cv, 3, spe, ap);
 
153
    if (nc != 3) {
 
154
      spc_warn(spe, "Invalid value for HSB color specification.");
 
155
      error = -1;
 
156
    } else {
 
157
      rgb_color_from_hsv(colorspec, cv[0], cv[1], cv[2]);
 
158
      spc_warn(spe, "HSB color converted to RGB: hsb: <%g, %g, %g> ==> rgb: <%g, %g, %g>",
 
159
               cv[0], cv[1], cv[2],
 
160
               colorspec->values[0], colorspec->values[1], colorspec->values[2]);
 
161
    }
 
162
  } else { /* Must be a "named" color */
 
163
    error = pdf_color_namedcolor(colorspec, q);
 
164
    if (error)
 
165
      spc_warn(spe, "Unrecognized color name: %s", q);
 
166
  }
 
167
  RELEASE(q);
 
168
 
 
169
  return  error;
 
170
}
 
171
 
 
172
/* Argumaent for this is PDF_Number or PDF_Array.
 
173
 * But we ignore that since we don't want to add
 
174
 * dependency to pdfxxx and @foo can not be
 
175
 * allowed for color specification. "pdf" here
 
176
 * means pdf: special syntax.
 
177
 */
 
178
static int
 
179
spc_read_color_pdf (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap)
 
180
{
 
181
  double  cv[4]; /* at most four */
 
182
  int     nc, isarry = 0;
 
183
  int     error = 0;
 
184
  char   *q;
 
185
 
 
186
  skip_blank(&ap->curptr, ap->endptr);
 
187
 
 
188
  if (ap->curptr[0] == '[') {
 
189
    ap->curptr++; skip_blank(&ap->curptr, ap->endptr);
 
190
    isarry = 1;
 
191
  }
 
192
 
 
193
  nc = spc_util_read_numbers(cv, 4, spe, ap);
 
194
  switch (nc) {
 
195
  case  1:
 
196
    pdf_color_graycolor(colorspec, cv[0]);
 
197
    break;
 
198
  case  3:
 
199
    pdf_color_rgbcolor (colorspec, cv[0], cv[1], cv[2]);
 
200
    break;
 
201
  case  4:
 
202
    pdf_color_cmykcolor(colorspec, cv[0], cv[1], cv[2], cv[3]);
 
203
    break;
 
204
  default:
 
205
    /* Try to read the color names defined in dvipsname.def */
 
206
    q = parse_c_ident(&ap->curptr, ap->endptr);
 
207
    if (q) {
 
208
      error = pdf_color_namedcolor(colorspec, q);
 
209
      if (error)
 
210
        spc_warn(spe, "Unrecognized color name: %s, keep the current color", q);
 
211
      RELEASE(q);
 
212
    } else {
 
213
      error = -1;
 
214
    }
 
215
    break;
 
216
  }
 
217
 
 
218
  if (isarry) {
 
219
    skip_blank(&ap->curptr, ap->endptr);
 
220
    if (ap->curptr >= ap->endptr || ap->curptr[0] != ']') {
 
221
      spc_warn(spe, "Unbalanced '[' and ']' in color specification.");
 
222
      error = -1;
 
223
    } else {
 
224
      ap->curptr++;
 
225
    }
 
226
  }
 
227
 
 
228
  return  error;
 
229
}
 
230
 
 
231
 
 
232
/* This is for reading *single* color specification. */
 
233
int
 
234
spc_util_read_colorspec (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap)
 
235
{
 
236
  ASSERT(colorspec && spe && ap);
 
237
 
 
238
  skip_blank(&ap->curptr, ap->endptr);
 
239
  if (ap->curptr >= ap->endptr) {
 
240
    return -1;
 
241
  }
 
242
  return spc_read_color_color(spe, colorspec, ap);
 
243
}
 
244
 
 
245
int
 
246
spc_util_read_pdfcolor (struct spc_env *spe, pdf_color *colorspec, struct spc_arg *ap, pdf_color *defaultcolor)
 
247
{
 
248
  int error = 0;
 
249
 
 
250
  ASSERT(colorspec && spe && ap);
 
251
 
 
252
  skip_blank(&ap->curptr, ap->endptr);
 
253
  if (ap->curptr >= ap->endptr) {
 
254
    return -1;
 
255
  }
 
256
  error = spc_read_color_pdf(spe, colorspec, ap);
 
257
  if (error < 0 && defaultcolor) {
 
258
    pdf_color_copycolor(colorspec, defaultcolor);
 
259
    error = 0;
 
260
  }
 
261
  return error;
 
262
}
 
263
 
 
264
/* This need to allow 'true' prefix for unit and
 
265
 * length value must be divided by current magnification.
 
266
 */
 
267
int
 
268
spc_util_read_length (struct spc_env *spe, double *vp /* ret. */, struct spc_arg *ap)
 
269
{
 
270
  char   *q;
 
271
  double  v, u = 1.0;
 
272
  const char *ukeys[] = {
 
273
#define K_UNIT__PT  0
 
274
#define K_UNIT__IN  1
 
275
#define K_UNIT__CM  2
 
276
#define K_UNIT__MM  3
 
277
#define K_UNIT__BP  4
 
278
    "pt", "in", "cm", "mm", "bp", NULL
 
279
  };
 
280
  int     k, error = 0;
 
281
 
 
282
  q = parse_float_decimal(&ap->curptr, ap->endptr);
 
283
  if (!q)
 
284
    return  -1;
 
285
 
 
286
  v = atof(q);
 
287
  RELEASE(q);
 
288
 
 
289
  q = parse_c_ident(&ap->curptr, ap->endptr);
 
290
  if (q) {
 
291
    if (strlen(q) > strlen("true") &&
 
292
        !memcmp(q, "true", strlen("true"))) {
 
293
      u /= spe->mag != 0.0 ? spe->mag : 1.0; /* inverse magnify */
 
294
      q += strlen("true");
 
295
    }
 
296
    for (k = 0; ukeys[k] && strcmp(ukeys[k], q); k++);
 
297
    switch (k) {
 
298
    case K_UNIT__PT: u *= 72.0 / 72.27; break;
 
299
    case K_UNIT__IN: u *= 72.0; break;
 
300
    case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
 
301
    case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
 
302
    case K_UNIT__BP: u *= 1.0 ; break;
 
303
    default:
 
304
      spc_warn(spe, "Unknown unit of measure: %s", q);
 
305
      error = -1;
 
306
      break;
 
307
    }
 
308
    RELEASE(q);
 
309
  }
 
310
 
 
311
  *vp = v * u;
 
312
  return  error;
 
313
}
 
314
 
 
315
 
 
316
/*
 
317
 * Compute a transformation matrix
 
318
 * transformations are applied in the following
 
319
 * order: scaling, rotate, displacement.
 
320
 */
 
321
static void
 
322
make_transmatrix (pdf_tmatrix *M,
 
323
                  double xoffset, double yoffset,
 
324
                  double xscale,  double yscale,
 
325
                  double rotate)
 
326
{
 
327
  double c, s;
 
328
 
 
329
  c = cos(rotate);
 
330
  s = sin(rotate);
 
331
 
 
332
  M->a =  xscale * c; M->b = xscale * s;
 
333
  M->c = -yscale * s; M->d = yscale * c;
 
334
  M->e = xoffset;     M->f = yoffset;
 
335
}
 
336
 
 
337
static int
 
338
spc_read_dimtrns_dvips (struct spc_env *spe, transform_info *t, struct spc_arg *ap)
 
339
{
 
340
  static const char *_dtkeys[] = {
 
341
#define  K_TRN__HOFFSET  0
 
342
#define  K_TRN__VOFFSET  1
 
343
    "hoffset", "voffset",
 
344
#define  K_DIM__HSIZE    2
 
345
#define  K_DIM__VSIZE    3
 
346
    "hsize", "vsize",
 
347
#define  K_TRN__HSCALE   4
 
348
#define  K_TRN__VSCALE   5
 
349
    "hscale", "vscale",
 
350
#define  K_TRN__ANGLE    6
 
351
    "angle",
 
352
#define  K__CLIP         7
 
353
    "clip",
 
354
#define  K_DIM__LLX      8
 
355
#define  K_DIM__LLY      9
 
356
#define  K_DIM__URX     10
 
357
#define  K_DIM__URY     11
 
358
    "llx", "lly", "urx", "ury",
 
359
#define  K_DIM__RWI     12
 
360
#define  K_DIM__RHI     13
 
361
    "rwi", "rhi",
 
362
    NULL
 
363
  };
 
364
  double xoffset, yoffset, xscale, yscale, rotate;
 
365
  int    error  = 0;
 
366
 
 
367
  xoffset = yoffset = rotate = 0.0; xscale = yscale = 1.0;
 
368
 
 
369
  skip_blank(&ap->curptr, ap->endptr);
 
370
  while (!error && ap->curptr < ap->endptr) {
 
371
    char  *kp, *vp;
 
372
    int    k;
 
373
 
 
374
    kp = parse_c_ident(&ap->curptr, ap->endptr);
 
375
    if (!kp)
 
376
      break;
 
377
 
 
378
    for (k = 0; _dtkeys[k] && strcmp(kp, _dtkeys[k]); k++);
 
379
    if (!_dtkeys[k]) {
 
380
      spc_warn(spe, "Unrecognized dimension/transformation key: %s", kp);
 
381
      error = -1;
 
382
      RELEASE(kp);
 
383
      break;
 
384
    }
 
385
 
 
386
    skip_blank(&ap->curptr, ap->endptr);
 
387
    if (k == K__CLIP) {
 
388
      t->flags |= INFO_DO_CLIP;
 
389
      RELEASE(kp);
 
390
      continue; /* not key-value */
 
391
    }
 
392
 
 
393
    if (ap->curptr < ap->endptr && ap->curptr[0] == '=') {
 
394
      ap->curptr++;
 
395
      skip_blank(&ap->curptr, ap->endptr);
 
396
    }
 
397
 
 
398
    vp = NULL;
 
399
    if (ap->curptr[0] == '\'' || ap->curptr[0] == '\"') {
 
400
      char  qchr = ap->curptr[0];
 
401
      ap->curptr++;
 
402
      skip_blank(&ap->curptr, ap->endptr);
 
403
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
404
      skip_blank(&ap->curptr, ap->endptr);
 
405
      if (vp && qchr != ap->curptr[0]) {
 
406
        spc_warn(spe, "Syntax error in dimension/transformation specification.");
 
407
        error = -1;
 
408
        RELEASE(vp); vp = NULL;
 
409
      }
 
410
      ap->curptr++;
 
411
    } else {
 
412
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
413
    }
 
414
    if (!error && !vp) {
 
415
      spc_warn(spe, "Missing value for dimension/transformation: %s", kp);
 
416
      error = -1;
 
417
    }
 
418
    RELEASE(kp);
 
419
    if (!vp || error) {
 
420
      break;
 
421
    }
 
422
 
 
423
    switch (k) {
 
424
    case  K_TRN__HOFFSET:
 
425
      xoffset = atof(vp);
 
426
      break;
 
427
    case  K_TRN__VOFFSET:
 
428
      yoffset = atof(vp);
 
429
      break;
 
430
    case  K_DIM__HSIZE:
 
431
      t->width   = atof(vp);
 
432
      t->flags  |= INFO_HAS_WIDTH;
 
433
      break;
 
434
    case  K_DIM__VSIZE:
 
435
      t->height  = atof(vp);
 
436
      t->flags  |= INFO_HAS_HEIGHT;
 
437
      break;
 
438
    case  K_TRN__HSCALE:
 
439
      xscale  = atof(vp) / 100.0;
 
440
      break;
 
441
    case  K_TRN__VSCALE:
 
442
      yscale  = atof(vp) / 100.0;
 
443
      break;
 
444
    case  K_TRN__ANGLE:
 
445
      rotate  = M_PI * atof(vp) / 180.0;
 
446
      break;
 
447
    case  K_DIM__LLX:
 
448
      t->bbox.llx = atof(vp);
 
449
      t->flags   |= INFO_HAS_USER_BBOX;
 
450
      break;
 
451
    case  K_DIM__LLY:
 
452
      t->bbox.lly = atof(vp);
 
453
      t->flags   |= INFO_HAS_USER_BBOX;
 
454
      break;
 
455
    case  K_DIM__URX:
 
456
      t->bbox.urx = atof(vp);
 
457
      t->flags   |= INFO_HAS_USER_BBOX;
 
458
      break;
 
459
    case  K_DIM__URY:
 
460
      t->bbox.ury = atof(vp);
 
461
      t->flags   |= INFO_HAS_USER_BBOX;
 
462
      break;
 
463
    case  K_DIM__RWI:
 
464
      t->width  = atof(vp) / 10.0;
 
465
      t->flags |= INFO_HAS_WIDTH;
 
466
      break;
 
467
    case  K_DIM__RHI:
 
468
      t->height = atof(vp) / 10.0;
 
469
      t->flags |= INFO_HAS_HEIGHT;
 
470
      break;
 
471
    }
 
472
    skip_blank(&ap->curptr, ap->endptr);
 
473
    RELEASE(vp);
 
474
  }
 
475
  make_transmatrix(&(t->matrix), xoffset, yoffset, xscale, yscale, rotate);
 
476
 
 
477
  return  error;
 
478
}
 
479
 
 
480
 
 
481
static int
 
482
spc_read_dimtrns_pdfm (struct spc_env *spe, transform_info *p, struct spc_arg *ap, long *page_no)
 
483
{
 
484
  int     has_scale, has_xscale, has_yscale, has_rotate, has_matrix;
 
485
  const char *_dtkeys[] = {
 
486
#define  K_DIM__WIDTH  0
 
487
#define  K_DIM__HEIGHT 1
 
488
#define  K_DIM__DEPTH  2
 
489
    "width", "height", "depth",
 
490
#define  K_TRN__SCALE  3
 
491
#define  K_TRN__XSCALE 4
 
492
#define  K_TRN__YSCALE 5
 
493
#define  K_TRN__ROTATE 6
 
494
    "scale", "xscale", "yscale", "rotate", /* See "Dvipdfmx User's Manual", p.5 */
 
495
#define  K_TRN__BBOX   7
 
496
    "bbox",
 
497
#define  K_TRN__MATRIX 8
 
498
    "matrix",
 
499
#undef  K__CLIP
 
500
#define  K__CLIP       9
 
501
    "clip",
 
502
#define  K__PAGE       10
 
503
    "page",
 
504
#define  K__HIDE       11
 
505
    "hide",
 
506
     NULL
 
507
  };
 
508
  double xscale, yscale, rotate;
 
509
  int    error = 0;
 
510
 
 
511
  has_xscale = has_yscale = has_scale = has_rotate = has_matrix = 0;
 
512
  xscale = yscale = 1.0; rotate = 0.0;
 
513
  p->flags |= INFO_DO_CLIP;   /* default: do clipping */
 
514
  p->flags &= ~INFO_DO_HIDE;   /* default: do clipping */
 
515
 
 
516
  skip_blank(&ap->curptr, ap->endptr);
 
517
 
 
518
  while (!error && ap->curptr < ap->endptr) {
 
519
    char  *kp, *vp;
 
520
    int    k;
 
521
 
 
522
    kp = parse_c_ident(&ap->curptr, ap->endptr);
 
523
    if (!kp)
 
524
      break;
 
525
 
 
526
    skip_blank(&ap->curptr, ap->endptr);
 
527
    for (k = 0; _dtkeys[k] && strcmp(_dtkeys[k], kp); k++);
 
528
    switch (k) {
 
529
    case  K_DIM__WIDTH:
 
530
      error = spc_util_read_length(spe, &p->width , ap);
 
531
      p->flags |= INFO_HAS_WIDTH;
 
532
      break;
 
533
    case  K_DIM__HEIGHT:
 
534
      error = spc_util_read_length(spe, &p->height, ap);
 
535
      p->flags |= INFO_HAS_HEIGHT;
 
536
      break;
 
537
    case  K_DIM__DEPTH:
 
538
      error = spc_util_read_length(spe, &p->depth , ap);
 
539
      p->flags |= INFO_HAS_HEIGHT;
 
540
      break;
 
541
    case  K_TRN__SCALE:
 
542
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
543
      if (!vp)
 
544
        error = -1;
 
545
      else {
 
546
        xscale = yscale = atof(vp);
 
547
        has_scale = 1;
 
548
        RELEASE(vp);
 
549
      }
 
550
      break;
 
551
    case  K_TRN__XSCALE:
 
552
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
553
      if (!vp)
 
554
        error = -1;
 
555
      else {
 
556
        xscale  = atof(vp);
 
557
        has_xscale = 1;
 
558
        RELEASE(vp);
 
559
      }
 
560
      break;
 
561
    case  K_TRN__YSCALE:
 
562
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
563
      if (!vp)
 
564
        error = -1;
 
565
      else {
 
566
        yscale  = atof(vp);
 
567
        has_yscale = 1;
 
568
        RELEASE(vp);
 
569
      }
 
570
      break;
 
571
    case  K_TRN__ROTATE:
 
572
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
573
      if (!vp)
 
574
        error = -1;
 
575
      else {
 
576
        rotate = M_PI * atof(vp) / 180.0;
 
577
        has_rotate = 1;
 
578
        RELEASE(vp);
 
579
      }
 
580
      break;
 
581
    case  K_TRN__BBOX:
 
582
      {
 
583
        double  v[4];
 
584
        if (spc_util_read_numbers(v, 4, spe, ap) != 4)
 
585
          error = -1;
 
586
        else {
 
587
          p->bbox.llx = v[0];
 
588
          p->bbox.lly = v[1];
 
589
          p->bbox.urx = v[2];
 
590
          p->bbox.ury = v[3];
 
591
          p->flags   |= INFO_HAS_USER_BBOX;
 
592
        }
 
593
      }
 
594
      break;
 
595
    case  K_TRN__MATRIX:
 
596
      {
 
597
        double  v[6];
 
598
        if (spc_util_read_numbers(v, 6, spe, ap) != 6)
 
599
          error = -1;
 
600
        else {
 
601
          pdf_setmatrix(&(p->matrix), v[0], v[1], v[2], v[3], v[4], v[5]);
 
602
          has_matrix = 1;
 
603
        }
 
604
      }
 
605
      break;
 
606
    case  K__CLIP:
 
607
      vp = parse_float_decimal(&ap->curptr, ap->endptr);
 
608
      if (!vp)
 
609
        error = -1;
 
610
      else {
 
611
        if (atof(vp))
 
612
          p->flags |= INFO_DO_CLIP;
 
613
        else
 
614
          p->flags &= ~INFO_DO_CLIP;
 
615
        RELEASE(vp);
 
616
      }
 
617
      break;
 
618
    case  K__PAGE:
 
619
      {
 
620
        double page;
 
621
        if (page_no && spc_util_read_numbers(&page, 1, spe, ap) == 1)
 
622
          *page_no = (long) page;
 
623
        else
 
624
          error = -1;
 
625
      }
 
626
      break;
 
627
    case  K__HIDE:
 
628
      p->flags |= INFO_DO_HIDE;
 
629
      break;
 
630
    default:
 
631
      error = -1;
 
632
      break;
 
633
    }
 
634
    if (error)
 
635
      spc_warn(spe, "Unrecognized key or invalid value for dimension/transformation: %s", kp);
 
636
    else
 
637
      skip_blank(&ap->curptr, ap->endptr);
 
638
    RELEASE(kp);
 
639
  }
 
640
 
 
641
  if (!error) {
 
642
    /* Check consistency */
 
643
    if (has_xscale && (p->flags & INFO_HAS_WIDTH)) {
 
644
      spc_warn(spe, "Can't supply both width and xscale. Ignore xscale.");
 
645
      xscale = 1.0;
 
646
    } else if (has_yscale &&
 
647
               (p->flags & INFO_HAS_HEIGHT)) {
 
648
      spc_warn(spe, "Can't supply both height/depth and yscale. Ignore yscale.");
 
649
      yscale = 1.0;
 
650
    } else if (has_scale &&
 
651
               (has_xscale || has_yscale)) {
 
652
      spc_warn(spe, "Can't supply overall scale along with axis scales.");
 
653
      error = -1;
 
654
    } else if (has_matrix &&
 
655
               (has_scale || has_xscale || has_yscale || has_rotate)) {
 
656
      spc_warn(spe, "Can't supply transform matrix along with scales or rotate. Ignore scales and rotate.");
 
657
    }
 
658
  }
 
659
 
 
660
  if (!has_matrix) {
 
661
    make_transmatrix(&(p->matrix), 0.0, 0.0, xscale, yscale, rotate);
 
662
  }
 
663
 
 
664
  if (!(p->flags & INFO_HAS_USER_BBOX)) {
 
665
    p->flags &= ~INFO_DO_CLIP;    /* no clipping needed */
 
666
  }
 
667
 
 
668
  return  error;
 
669
}
 
670
 
 
671
int
 
672
spc_util_read_dimtrns (struct spc_env *spe, transform_info *ti, struct spc_arg *args, long *page_no, int syntax)
 
673
{
 
674
  ASSERT(ti && spe && args);
 
675
 
 
676
  if (syntax) {
 
677
    ASSERT(!page_no);
 
678
    return  spc_read_dimtrns_dvips(spe, ti, args);
 
679
  } else {
 
680
    return  spc_read_dimtrns_pdfm (spe, ti, args, page_no);
 
681
  }
 
682
 
 
683
  return  -1;
 
684
}
 
685
 
 
686
 
 
687
/* Color names */
 
688
#ifdef  rgb
 
689
#undef  rgb
 
690
#endif
 
691
#ifdef  cmyk
 
692
#undef  cmyk
 
693
#endif
 
694
#define gray(g)       {1, {g}}
 
695
#define rgb8(r,g,b)   {3, {((r)/255.0), ((g)/255.0), ((b)/255.0), 0.0}}
 
696
#define cmyk(c,m,y,k) {4, {(c), (m), (y), (k)}}
 
697
 
 
698
static struct colordef_
 
699
{
 
700
  const char  *key;
 
701
  pdf_color    color;
 
702
} colordefs[] = {
 
703
  {"GreenYellow",    cmyk(0.15, 0.00, 0.69, 0.00)},
 
704
  {"Yellow",         cmyk(0.00, 0.00, 1.00, 0.00)},
 
705
  {"Goldenrod",      cmyk(0.00, 0.10, 0.84, 0.00)},
 
706
  {"Dandelion",      cmyk(0.00, 0.29, 0.84, 0.00)},
 
707
  {"Apricot",        cmyk(0.00, 0.32, 0.52, 0.00)},
 
708
  {"Peach",          cmyk(0.00, 0.50, 0.70, 0.00)},
 
709
  {"Melon",          cmyk(0.00, 0.46, 0.50, 0.00)},
 
710
  {"YellowOrange",   cmyk(0.00, 0.42, 1.00, 0.00)},
 
711
  {"Orange",         cmyk(0.00, 0.61, 0.87, 0.00)},
 
712
  {"BurntOrange",    cmyk(0.00, 0.51, 1.00, 0.00)},
 
713
  {"Bittersweet",    cmyk(0.00, 0.75, 1.00, 0.24)},
 
714
  {"RedOrange",      cmyk(0.00, 0.77, 0.87, 0.00)},
 
715
  {"Mahogany",       cmyk(0.00, 0.85, 0.87, 0.35)},
 
716
  {"Maroon",         cmyk(0.00, 0.87, 0.68, 0.32)},
 
717
  {"BrickRed",       cmyk(0.00, 0.89, 0.94, 0.28)},
 
718
  {"Red",            cmyk(0.00, 1.00, 1.00, 0.00)},
 
719
  {"OrangeRed",      cmyk(0.00, 1.00, 0.50, 0.00)},
 
720
  {"RubineRed",      cmyk(0.00, 1.00, 0.13, 0.00)},
 
721
  {"WildStrawberry", cmyk(0.00, 0.96, 0.39, 0.00)},
 
722
  {"Salmon",         cmyk(0.00, 0.53, 0.38, 0.00)},
 
723
  {"CarnationPink",  cmyk(0.00, 0.63, 0.00, 0.00)},
 
724
  {"Magenta",        cmyk(0.00, 1.00, 0.00, 0.00)},
 
725
  {"VioletRed",      cmyk(0.00, 0.81, 0.00, 0.00)},
 
726
  {"Rhodamine",      cmyk(0.00, 0.82, 0.00, 0.00)},
 
727
  {"Mulberry",       cmyk(0.34, 0.90, 0.00, 0.02)},
 
728
  {"RedViolet",      cmyk(0.07, 0.90, 0.00, 0.34)},
 
729
  {"Fuchsia",        cmyk(0.47, 0.91, 0.00, 0.08)},
 
730
  {"Lavender",       cmyk(0.00, 0.48, 0.00, 0.00)},
 
731
  {"Thistle",        cmyk(0.12, 0.59, 0.00, 0.00)},
 
732
  {"Orchid",         cmyk(0.32, 0.64, 0.00, 0.00)},
 
733
  {"DarkOrchid",     cmyk(0.40, 0.80, 0.20, 0.00)},
 
734
  {"Purple",         cmyk(0.45, 0.86, 0.00, 0.00)},
 
735
  {"Plum",           cmyk(0.50, 1.00, 0.00, 0.00)},
 
736
  {"Violet",         cmyk(0.79, 0.88, 0.00, 0.00)},
 
737
  {"RoyalPurple",    cmyk(0.75, 0.90, 0.00, 0.00)},
 
738
  {"BlueViolet",     cmyk(0.86, 0.91, 0.00, 0.04)},
 
739
  {"Periwinkle",     cmyk(0.57, 0.55, 0.00, 0.00)},
 
740
  {"CadetBlue",      cmyk(0.62, 0.57, 0.23, 0.00)},
 
741
  {"CornflowerBlue", cmyk(0.65, 0.13, 0.00, 0.00)},
 
742
  {"MidnightBlue",   cmyk(0.98, 0.13, 0.00, 0.43)},
 
743
  {"NavyBlue",       cmyk(0.94, 0.54, 0.00, 0.00)},
 
744
  {"RoyalBlue",      cmyk(1.00, 0.50, 0.00, 0.00)},
 
745
  {"Blue",           cmyk(1.00, 1.00, 0.00, 0.00)},
 
746
  {"Cerulean",       cmyk(0.94, 0.11, 0.00, 0.00)},
 
747
  {"Cyan",           cmyk(1.00, 0.00, 0.00, 0.00)},
 
748
  {"ProcessBlue",    cmyk(0.96, 0.00, 0.00, 0.00)},
 
749
  {"SkyBlue",        cmyk(0.62, 0.00, 0.12, 0.00)},
 
750
  {"Turquoise",      cmyk(0.85, 0.00, 0.20, 0.00)},
 
751
  {"TealBlue",       cmyk(0.86, 0.00, 0.34, 0.02)},
 
752
  {"Aquamarine",     cmyk(0.82, 0.00, 0.30, 0.00)},
 
753
  {"BlueGreen",      cmyk(0.85, 0.00, 0.33, 0.00)},
 
754
  {"Emerald",        cmyk(1.00, 0.00, 0.50, 0.00)},
 
755
  {"JungleGreen",    cmyk(0.99, 0.00, 0.52, 0.00)},
 
756
  {"SeaGreen",       cmyk(0.69, 0.00, 0.50, 0.00)},
 
757
  {"Green",          cmyk(1.00, 0.00, 1.00, 0.00)},
 
758
  {"ForestGreen",    cmyk(0.91, 0.00, 0.88, 0.12)},
 
759
  {"PineGreen",      cmyk(0.92, 0.00, 0.59, 0.25)},
 
760
  {"LimeGreen",      cmyk(0.50, 0.00, 1.00, 0.00)},
 
761
  {"YellowGreen",    cmyk(0.44, 0.00, 0.74, 0.00)},
 
762
  {"SpringGreen",    cmyk(0.26, 0.00, 0.76, 0.00)},
 
763
  {"OliveGreen",     cmyk(0.64, 0.00, 0.95, 0.40)},
 
764
  {"RawSienna",      cmyk(0.00, 0.72, 1.00, 0.45)},
 
765
  {"Sepia",          cmyk(0.00, 0.83, 1.00, 0.70)},
 
766
  {"Brown",          cmyk(0.00, 0.81, 1.00, 0.60)},
 
767
  {"Tan",            cmyk(0.14, 0.42, 0.56, 0.00)},
 
768
  /* Adobe Reader 7 and 8 had problem when gray and cmyk black colors
 
769
   * are mixed. No problem with Previewer.app.
 
770
   * It happens when \usepackage[dvipdfm]{graphicx} and then called
 
771
   * \usepackage{color} without dvipdfm option. */
 
772
  {"Gray",           gray(0.5)},
 
773
  {"Black",          gray(0.0)},
 
774
  {"White",          gray(1.0)},
 
775
  {NULL}
 
776
};
 
777
 
 
778
 
 
779
static int
 
780
pdf_color_namedcolor (pdf_color *color, const char *name)
 
781
{
 
782
  int   i;
 
783
  for (i = 0; colordefs[i].key; i++) {
 
784
    if (!strcmp(colordefs[i].key, name)) {
 
785
      pdf_color_copycolor(color, &colordefs[i].color);
 
786
      return  0;
 
787
    }
 
788
  }
 
789
  return  -1;
 
790
}
 
791