upgraded to xpdf-3.01pl1
[swftools.git] / pdf2swf / xpdf / GfxState.h
1 //========================================================================
2 //
3 // GfxState.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #ifndef GFXSTATE_H
10 #define GFXSTATE_H
11
12 #include <aconf.h>
13
14 #ifdef USE_GCC_PRAGMAS
15 #pragma interface
16 #endif
17
18 #include "gtypes.h"
19 #include "Object.h"
20 #include "Function.h"
21
22 class Array;
23 class GfxFont;
24 class PDFRectangle;
25 class GfxShading;
26
27 //------------------------------------------------------------------------
28 // GfxBlendMode
29 //------------------------------------------------------------------------
30
31 enum GfxBlendMode {
32   gfxBlendNormal,
33   gfxBlendMultiply,
34   gfxBlendScreen,
35   gfxBlendOverlay,
36   gfxBlendDarken,
37   gfxBlendLighten,
38   gfxBlendColorDodge,
39   gfxBlendColorBurn,
40   gfxBlendHardLight,
41   gfxBlendSoftLight,
42   gfxBlendDifference,
43   gfxBlendExclusion,
44   gfxBlendHue,
45   gfxBlendSaturation,
46   gfxBlendColor,
47   gfxBlendLuminosity
48 };
49
50 //------------------------------------------------------------------------
51 // GfxColorComp
52 //------------------------------------------------------------------------
53
54 // 16.16 fixed point color component
55 typedef int GfxColorComp;
56
57 #define gfxColorComp1 0x10000
58
59 static inline GfxColorComp dblToCol(double x) {
60   return (GfxColorComp)(x * gfxColorComp1);
61 }
62
63 static inline double colToDbl(GfxColorComp x) {
64   return (double)x / (double)gfxColorComp1;
65 }
66
67 static inline GfxColorComp byteToCol(Guchar x) {
68   // (x / 255) << 16  =  (0.0000000100000001... * x) << 16
69   //                  =  ((x << 8) + (x) + (x >> 8) + ...) << 16
70   //                  =  (x << 8) + (x) + (x >> 7)
71   //                                      [for rounding]
72   return (GfxColorComp)((x << 8) + x + (x >> 7));
73 }
74
75 static inline Guchar colToByte(GfxColorComp x) {
76   // 255 * x + 0.5  =  256 * x - x + 0x8000
77   return (Guchar)(((x << 8) - x + 0x8000) >> 16);
78 }
79
80 //------------------------------------------------------------------------
81 // GfxColor
82 //------------------------------------------------------------------------
83
84 #define gfxColorMaxComps funcMaxOutputs
85
86 struct GfxColor {
87   GfxColorComp c[gfxColorMaxComps];
88 };
89
90 //------------------------------------------------------------------------
91 // GfxGray
92 //------------------------------------------------------------------------
93
94 typedef GfxColorComp GfxGray;
95
96 //------------------------------------------------------------------------
97 // GfxRGB
98 //------------------------------------------------------------------------
99
100 struct GfxRGB {
101   GfxColorComp r, g, b;
102 };
103
104 //------------------------------------------------------------------------
105 // GfxCMYK
106 //------------------------------------------------------------------------
107
108 struct GfxCMYK {
109   GfxColorComp c, m, y, k;
110 };
111
112 //------------------------------------------------------------------------
113 // GfxColorSpace
114 //------------------------------------------------------------------------
115
116 // NB: The nGfxColorSpaceModes constant and the gfxColorSpaceModeNames
117 // array defined in GfxState.cc must match this enum.
118 enum GfxColorSpaceMode {
119   csDeviceGray,
120   csCalGray,
121   csDeviceRGB,
122   csCalRGB,
123   csDeviceCMYK,
124   csLab,
125   csICCBased,
126   csIndexed,
127   csSeparation,
128   csDeviceN,
129   csPattern
130 };
131
132 class GfxColorSpace {
133 public:
134
135   GfxColorSpace();
136   virtual ~GfxColorSpace();
137   virtual GfxColorSpace *copy() = 0;
138   virtual GfxColorSpaceMode getMode() = 0;
139
140   // Construct a color space.  Returns NULL if unsuccessful.
141   static GfxColorSpace *parse(Object *csObj);
142
143   // Convert to gray, RGB, or CMYK.
144   virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
145   virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
146   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
147
148   // Return the number of color components.
149   virtual int getNComps() = 0;
150
151   // Return the default ranges for each component, assuming an image
152   // with a max pixel value of <maxImgPixel>.
153   virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
154                                 int maxImgPixel);
155
156   // Return the number of color space modes
157   static int getNumColorSpaceModes();
158
159   // Return the name of the <idx>th color space mode.
160   static char *getColorSpaceModeName(int idx);
161
162 private:
163 };
164
165 //------------------------------------------------------------------------
166 // GfxDeviceGrayColorSpace
167 //------------------------------------------------------------------------
168
169 class GfxDeviceGrayColorSpace: public GfxColorSpace {
170 public:
171
172   GfxDeviceGrayColorSpace();
173   virtual ~GfxDeviceGrayColorSpace();
174   virtual GfxColorSpace *copy();
175   virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
176
177   virtual void getGray(GfxColor *color, GfxGray *gray);
178   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
179   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
180
181   virtual int getNComps() { return 1; }
182
183 private:
184 };
185
186 //------------------------------------------------------------------------
187 // GfxCalGrayColorSpace
188 //------------------------------------------------------------------------
189
190 class GfxCalGrayColorSpace: public GfxColorSpace {
191 public:
192
193   GfxCalGrayColorSpace();
194   virtual ~GfxCalGrayColorSpace();
195   virtual GfxColorSpace *copy();
196   virtual GfxColorSpaceMode getMode() { return csCalGray; }
197
198   // Construct a CalGray color space.  Returns NULL if unsuccessful.
199   static GfxColorSpace *parse(Array *arr);
200
201   virtual void getGray(GfxColor *color, GfxGray *gray);
202   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
203   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
204
205   virtual int getNComps() { return 1; }
206
207   // CalGray-specific access.
208   double getWhiteX() { return whiteX; }
209   double getWhiteY() { return whiteY; }
210   double getWhiteZ() { return whiteZ; }
211   double getBlackX() { return blackX; }
212   double getBlackY() { return blackY; }
213   double getBlackZ() { return blackZ; }
214   double getGamma() { return gamma; }
215
216 private:
217
218   double whiteX, whiteY, whiteZ;    // white point
219   double blackX, blackY, blackZ;    // black point
220   double gamma;                     // gamma value
221 };
222
223 //------------------------------------------------------------------------
224 // GfxDeviceRGBColorSpace
225 //------------------------------------------------------------------------
226
227 class GfxDeviceRGBColorSpace: public GfxColorSpace {
228 public:
229
230   GfxDeviceRGBColorSpace();
231   virtual ~GfxDeviceRGBColorSpace();
232   virtual GfxColorSpace *copy();
233   virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
234
235   virtual void getGray(GfxColor *color, GfxGray *gray);
236   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
237   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
238
239   virtual int getNComps() { return 3; }
240
241 private:
242 };
243
244 //------------------------------------------------------------------------
245 // GfxCalRGBColorSpace
246 //------------------------------------------------------------------------
247
248 class GfxCalRGBColorSpace: public GfxColorSpace {
249 public:
250
251   GfxCalRGBColorSpace();
252   virtual ~GfxCalRGBColorSpace();
253   virtual GfxColorSpace *copy();
254   virtual GfxColorSpaceMode getMode() { return csCalRGB; }
255
256   // Construct a CalRGB color space.  Returns NULL if unsuccessful.
257   static GfxColorSpace *parse(Array *arr);
258
259   virtual void getGray(GfxColor *color, GfxGray *gray);
260   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
261   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
262
263   virtual int getNComps() { return 3; }
264
265   // CalRGB-specific access.
266   double getWhiteX() { return whiteX; }
267   double getWhiteY() { return whiteY; }
268   double getWhiteZ() { return whiteZ; }
269   double getBlackX() { return blackX; }
270   double getBlackY() { return blackY; }
271   double getBlackZ() { return blackZ; }
272   double getGammaR() { return gammaR; }
273   double getGammaG() { return gammaG; }
274   double getGammaB() { return gammaB; }
275   double *getMatrix() { return mat; }
276
277 private:
278
279   double whiteX, whiteY, whiteZ;    // white point
280   double blackX, blackY, blackZ;    // black point
281   double gammaR, gammaG, gammaB;    // gamma values
282   double mat[9];                    // ABC -> XYZ transform matrix
283 };
284
285 //------------------------------------------------------------------------
286 // GfxDeviceCMYKColorSpace
287 //------------------------------------------------------------------------
288
289 class GfxDeviceCMYKColorSpace: public GfxColorSpace {
290 public:
291
292   GfxDeviceCMYKColorSpace();
293   virtual ~GfxDeviceCMYKColorSpace();
294   virtual GfxColorSpace *copy();
295   virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; }
296
297   virtual void getGray(GfxColor *color, GfxGray *gray);
298   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
299   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
300
301   virtual int getNComps() { return 4; }
302
303 private:
304 };
305
306 //------------------------------------------------------------------------
307 // GfxLabColorSpace
308 //------------------------------------------------------------------------
309
310 class GfxLabColorSpace: public GfxColorSpace {
311 public:
312
313   GfxLabColorSpace();
314   virtual ~GfxLabColorSpace();
315   virtual GfxColorSpace *copy();
316   virtual GfxColorSpaceMode getMode() { return csLab; }
317
318   // Construct a Lab color space.  Returns NULL if unsuccessful.
319   static GfxColorSpace *parse(Array *arr);
320
321   virtual void getGray(GfxColor *color, GfxGray *gray);
322   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
323   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
324
325   virtual int getNComps() { return 3; }
326
327   virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
328                                 int maxImgPixel);
329
330   // Lab-specific access.
331   double getWhiteX() { return whiteX; }
332   double getWhiteY() { return whiteY; }
333   double getWhiteZ() { return whiteZ; }
334   double getBlackX() { return blackX; }
335   double getBlackY() { return blackY; }
336   double getBlackZ() { return blackZ; }
337   double getAMin() { return aMin; }
338   double getAMax() { return aMax; }
339   double getBMin() { return bMin; }
340   double getBMax() { return bMax; }
341
342 private:
343
344   double whiteX, whiteY, whiteZ;    // white point
345   double blackX, blackY, blackZ;    // black point
346   double aMin, aMax, bMin, bMax;    // range for the a and b components
347   double kr, kg, kb;                // gamut mapping mulitpliers
348 };
349
350 //------------------------------------------------------------------------
351 // GfxICCBasedColorSpace
352 //------------------------------------------------------------------------
353
354 class GfxICCBasedColorSpace: public GfxColorSpace {
355 public:
356
357   GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
358                         Ref *iccProfileStreamA);
359   virtual ~GfxICCBasedColorSpace();
360   virtual GfxColorSpace *copy();
361   virtual GfxColorSpaceMode getMode() { return csICCBased; }
362
363   // Construct an ICCBased color space.  Returns NULL if unsuccessful.
364   static GfxColorSpace *parse(Array *arr);
365
366   virtual void getGray(GfxColor *color, GfxGray *gray);
367   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
368   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
369
370   virtual int getNComps() { return nComps; }
371
372   virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
373                                 int maxImgPixel);
374
375   // ICCBased-specific access.
376   GfxColorSpace *getAlt() { return alt; }
377
378 private:
379
380   int nComps;                   // number of color components (1, 3, or 4)
381   GfxColorSpace *alt;           // alternate color space
382   double rangeMin[4];           // min values for each component
383   double rangeMax[4];           // max values for each component
384   Ref iccProfileStream;         // the ICC profile
385 };
386
387 //------------------------------------------------------------------------
388 // GfxIndexedColorSpace
389 //------------------------------------------------------------------------
390
391 class GfxIndexedColorSpace: public GfxColorSpace {
392 public:
393
394   GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA);
395   virtual ~GfxIndexedColorSpace();
396   virtual GfxColorSpace *copy();
397   virtual GfxColorSpaceMode getMode() { return csIndexed; }
398
399   // Construct a Lab color space.  Returns NULL if unsuccessful.
400   static GfxColorSpace *parse(Array *arr);
401
402   virtual void getGray(GfxColor *color, GfxGray *gray);
403   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
404   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
405
406   virtual int getNComps() { return 1; }
407
408   virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
409                                 int maxImgPixel);
410
411   // Indexed-specific access.
412   GfxColorSpace *getBase() { return base; }
413   int getIndexHigh() { return indexHigh; }
414   Guchar *getLookup() { return lookup; }
415   GfxColor *mapColorToBase(GfxColor *color, GfxColor *baseColor);
416
417 private:
418
419   GfxColorSpace *base;          // base color space
420   int indexHigh;                // max pixel value
421   Guchar *lookup;               // lookup table
422 };
423
424 //------------------------------------------------------------------------
425 // GfxSeparationColorSpace
426 //------------------------------------------------------------------------
427
428 class GfxSeparationColorSpace: public GfxColorSpace {
429 public:
430
431   GfxSeparationColorSpace(GString *nameA, GfxColorSpace *altA,
432                           Function *funcA);
433   virtual ~GfxSeparationColorSpace();
434   virtual GfxColorSpace *copy();
435   virtual GfxColorSpaceMode getMode() { return csSeparation; }
436
437   // Construct a Separation color space.  Returns NULL if unsuccessful.
438   static GfxColorSpace *parse(Array *arr);
439
440   virtual void getGray(GfxColor *color, GfxGray *gray);
441   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
442   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
443
444   virtual int getNComps() { return 1; }
445
446   // Separation-specific access.
447   GString *getName() { return name; }
448   GfxColorSpace *getAlt() { return alt; }
449   Function *getFunc() { return func; }
450
451 private:
452
453   GString *name;                // colorant name
454   GfxColorSpace *alt;           // alternate color space
455   Function *func;               // tint transform (into alternate color space)
456 };
457
458 //------------------------------------------------------------------------
459 // GfxDeviceNColorSpace
460 //------------------------------------------------------------------------
461
462 class GfxDeviceNColorSpace: public GfxColorSpace {
463 public:
464
465   GfxDeviceNColorSpace(int nCompsA, GfxColorSpace *alt, Function *func);
466   virtual ~GfxDeviceNColorSpace();
467   virtual GfxColorSpace *copy();
468   virtual GfxColorSpaceMode getMode() { return csDeviceN; }
469
470   // Construct a DeviceN color space.  Returns NULL if unsuccessful.
471   static GfxColorSpace *parse(Array *arr);
472
473   virtual void getGray(GfxColor *color, GfxGray *gray);
474   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
475   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
476
477   virtual int getNComps() { return nComps; }
478
479   // DeviceN-specific access.
480   GString *getColorantName(int i) { return names[i]; }
481   GfxColorSpace *getAlt() { return alt; }
482   Function *getTintTransformFunc() { return func; }
483
484 private:
485
486   int nComps;                   // number of components
487   GString                       // colorant names
488     *names[gfxColorMaxComps];
489   GfxColorSpace *alt;           // alternate color space
490   Function *func;               // tint transform (into alternate color space)
491 };
492
493 //------------------------------------------------------------------------
494 // GfxPatternColorSpace
495 //------------------------------------------------------------------------
496
497 class GfxPatternColorSpace: public GfxColorSpace {
498 public:
499
500   GfxPatternColorSpace(GfxColorSpace *underA);
501   virtual ~GfxPatternColorSpace();
502   virtual GfxColorSpace *copy();
503   virtual GfxColorSpaceMode getMode() { return csPattern; }
504
505   // Construct a Pattern color space.  Returns NULL if unsuccessful.
506   static GfxColorSpace *parse(Array *arr);
507
508   virtual void getGray(GfxColor *color, GfxGray *gray);
509   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
510   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
511
512   virtual int getNComps() { return 0; }
513
514   // Pattern-specific access.
515   GfxColorSpace *getUnder() { return under; }
516
517 private:
518
519   GfxColorSpace *under;         // underlying color space (for uncolored
520                                 //   patterns)
521 };
522
523 //------------------------------------------------------------------------
524 // GfxPattern
525 //------------------------------------------------------------------------
526
527 class GfxPattern {
528 public:
529
530   GfxPattern(int typeA);
531   virtual ~GfxPattern();
532
533   static GfxPattern *parse(Object *obj);
534
535   virtual GfxPattern *copy() = 0;
536
537   int getType() { return type; }
538
539 private:
540
541   int type;
542 };
543
544 //------------------------------------------------------------------------
545 // GfxTilingPattern
546 //------------------------------------------------------------------------
547
548 class GfxTilingPattern: public GfxPattern {
549 public:
550
551   static GfxTilingPattern *parse(Object *patObj);
552   virtual ~GfxTilingPattern();
553
554   virtual GfxPattern *copy();
555
556   int getPaintType() { return paintType; }
557   int getTilingType() { return tilingType; }
558   double *getBBox() { return bbox; }
559   double getXStep() { return xStep; }
560   double getYStep() { return yStep; }
561   Dict *getResDict()
562     { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
563   double *getMatrix() { return matrix; }
564   Object *getContentStream() { return &contentStream; }
565
566 private:
567
568   GfxTilingPattern(int paintTypeA, int tilingTypeA,
569                    double *bboxA, double xStepA, double yStepA,
570                    Object *resDictA, double *matrixA,
571                    Object *contentStreamA);
572
573   int paintType;
574   int tilingType;
575   double bbox[4];
576   double xStep, yStep;
577   Object resDict;
578   double matrix[6];
579   Object contentStream;
580 };
581
582 //------------------------------------------------------------------------
583 // GfxShadingPattern
584 //------------------------------------------------------------------------
585
586 class GfxShadingPattern: public GfxPattern {
587 public:
588
589   static GfxShadingPattern *parse(Object *patObj);
590   virtual ~GfxShadingPattern();
591
592   virtual GfxPattern *copy();
593
594   GfxShading *getShading() { return shading; }
595   double *getMatrix() { return matrix; }
596
597 private:
598
599   GfxShadingPattern(GfxShading *shadingA, double *matrixA);
600
601   GfxShading *shading;
602   double matrix[6];
603 };
604
605 //------------------------------------------------------------------------
606 // GfxShading
607 //------------------------------------------------------------------------
608
609 class GfxShading {
610 public:
611
612   GfxShading(int typeA);
613   GfxShading(GfxShading *shading);
614   virtual ~GfxShading();
615
616   static GfxShading *parse(Object *obj);
617
618   virtual GfxShading *copy() = 0;
619
620   int getType() { return type; }
621   GfxColorSpace *getColorSpace() { return colorSpace; }
622   GfxColor *getBackground() { return &background; }
623   GBool getHasBackground() { return hasBackground; }
624   void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
625     { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
626   GBool getHasBBox() { return hasBBox; }
627
628 protected:
629
630   GBool init(Dict *dict);
631
632   int type;
633   GfxColorSpace *colorSpace;
634   GfxColor background;
635   GBool hasBackground;
636   double xMin, yMin, xMax, yMax;
637   GBool hasBBox;
638 };
639
640 //------------------------------------------------------------------------
641 // GfxFunctionShading
642 //------------------------------------------------------------------------
643
644 class GfxFunctionShading: public GfxShading {
645 public:
646
647   GfxFunctionShading(double x0A, double y0A,
648                      double x1A, double y1A,
649                      double *matrixA,
650                      Function **funcsA, int nFuncsA);
651   GfxFunctionShading(GfxFunctionShading *shading);
652   virtual ~GfxFunctionShading();
653
654   static GfxFunctionShading *parse(Dict *dict);
655
656   virtual GfxShading *copy();
657
658   void getDomain(double *x0A, double *y0A, double *x1A, double *y1A)
659     { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
660   double *getMatrix() { return matrix; }
661   int getNFuncs() { return nFuncs; }
662   Function *getFunc(int i) { return funcs[i]; }
663   void getColor(double x, double y, GfxColor *color);
664
665 private:
666
667   double x0, y0, x1, y1;
668   double matrix[6];
669   Function *funcs[gfxColorMaxComps];
670   int nFuncs;
671 };
672
673 //------------------------------------------------------------------------
674 // GfxAxialShading
675 //------------------------------------------------------------------------
676
677 class GfxAxialShading: public GfxShading {
678 public:
679
680   GfxAxialShading(double x0A, double y0A,
681                   double x1A, double y1A,
682                   double t0A, double t1A,
683                   Function **funcsA, int nFuncsA,
684                   GBool extend0A, GBool extend1A);
685   GfxAxialShading(GfxAxialShading *shading);
686   virtual ~GfxAxialShading();
687
688   static GfxAxialShading *parse(Dict *dict);
689
690   virtual GfxShading *copy();
691
692   void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
693     { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
694   double getDomain0() { return t0; }
695   double getDomain1() { return t1; }
696   GBool getExtend0() { return extend0; }
697   GBool getExtend1() { return extend1; }
698   int getNFuncs() { return nFuncs; }
699   Function *getFunc(int i) { return funcs[i]; }
700   void getColor(double t, GfxColor *color);
701
702 private:
703
704   double x0, y0, x1, y1;
705   double t0, t1;
706   Function *funcs[gfxColorMaxComps];
707   int nFuncs;
708   GBool extend0, extend1;
709 };
710
711 //------------------------------------------------------------------------
712 // GfxRadialShading
713 //------------------------------------------------------------------------
714
715 class GfxRadialShading: public GfxShading {
716 public:
717
718   GfxRadialShading(double x0A, double y0A, double r0A,
719                    double x1A, double y1A, double r1A,
720                    double t0A, double t1A,
721                    Function **funcsA, int nFuncsA,
722                    GBool extend0A, GBool extend1A);
723   GfxRadialShading(GfxRadialShading *shading);
724   virtual ~GfxRadialShading();
725
726   static GfxRadialShading *parse(Dict *dict);
727
728   virtual GfxShading *copy();
729
730   void getCoords(double *x0A, double *y0A, double *r0A,
731                  double *x1A, double *y1A, double *r1A)
732     { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
733   double getDomain0() { return t0; }
734   double getDomain1() { return t1; }
735   GBool getExtend0() { return extend0; }
736   GBool getExtend1() { return extend1; }
737   int getNFuncs() { return nFuncs; }
738   Function *getFunc(int i) { return funcs[i]; }
739   void getColor(double t, GfxColor *color);
740
741 private:
742
743   double x0, y0, r0, x1, y1, r1;
744   double t0, t1;
745   Function *funcs[gfxColorMaxComps];
746   int nFuncs;
747   GBool extend0, extend1;
748 };
749
750 //------------------------------------------------------------------------
751 // GfxGouraudTriangleShading
752 //------------------------------------------------------------------------
753
754 struct GfxGouraudVertex {
755   double x, y;
756   GfxColor color;
757 };
758
759 class GfxGouraudTriangleShading: public GfxShading {
760 public:
761
762   GfxGouraudTriangleShading(int typeA,
763                             GfxGouraudVertex *verticesA, int nVerticesA,
764                             int (*trianglesA)[3], int nTrianglesA,
765                             Function **funcsA, int nFuncsA);
766   GfxGouraudTriangleShading(GfxGouraudTriangleShading *shading);
767   virtual ~GfxGouraudTriangleShading();
768
769   static GfxGouraudTriangleShading *parse(int typeA, Dict *dict, Stream *str);
770
771   virtual GfxShading *copy();
772
773   int getNTriangles() { return nTriangles; }
774   void getTriangle(int i, double *x0, double *y0, GfxColor *color0,
775                    double *x1, double *y1, GfxColor *color1,
776                    double *x2, double *y2, GfxColor *color2);
777
778 private:
779
780   GfxGouraudVertex *vertices;
781   int nVertices;
782   int (*triangles)[3];
783   int nTriangles;
784   Function *funcs[gfxColorMaxComps];
785   int nFuncs;
786 };
787
788 //------------------------------------------------------------------------
789 // GfxPatchMeshShading
790 //------------------------------------------------------------------------
791
792 struct GfxPatch {
793   double x[4][4];
794   double y[4][4];
795   GfxColor color[2][2];
796 };
797
798 class GfxPatchMeshShading: public GfxShading {
799 public:
800
801   GfxPatchMeshShading(int typeA, GfxPatch *patchesA, int nPatchesA,
802                       Function **funcsA, int nFuncsA);
803   GfxPatchMeshShading(GfxPatchMeshShading *shading);
804   virtual ~GfxPatchMeshShading();
805
806   static GfxPatchMeshShading *parse(int typeA, Dict *dict, Stream *str);
807
808   virtual GfxShading *copy();
809
810   int getNPatches() { return nPatches; }
811   GfxPatch *getPatch(int i) { return &patches[i]; }
812
813 private:
814
815   GfxPatch *patches;
816   int nPatches;
817   Function *funcs[gfxColorMaxComps];
818   int nFuncs;
819 };
820
821 //------------------------------------------------------------------------
822 // GfxImageColorMap
823 //------------------------------------------------------------------------
824
825 class GfxImageColorMap {
826 public:
827
828   // Constructor.
829   GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA);
830
831   // Destructor.
832   ~GfxImageColorMap();
833
834   // Return a copy of this color map.
835   GfxImageColorMap *copy() { return new GfxImageColorMap(this); }
836
837   // Is color map valid?
838   GBool isOk() { return ok; }
839
840   // Get the color space.
841   GfxColorSpace *getColorSpace() { return colorSpace; }
842
843   // Get stream decoding info.
844   int getNumPixelComps() { return nComps; }
845   int getBits() { return bits; }
846
847   // Get decode table.
848   double getDecodeLow(int i) { return decodeLow[i]; }
849   double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
850
851   // Convert an image pixel to a color.
852   void getGray(Guchar *x, GfxGray *gray);
853   void getRGB(Guchar *x, GfxRGB *rgb);
854   void getCMYK(Guchar *x, GfxCMYK *cmyk);
855   void getColor(Guchar *x, GfxColor *color);
856
857 private:
858
859   GfxImageColorMap(GfxImageColorMap *colorMap);
860
861   GfxColorSpace *colorSpace;    // the image color space
862   int bits;                     // bits per component
863   int nComps;                   // number of components in a pixel
864   GfxColorSpace *colorSpace2;   // secondary color space
865   int nComps2;                  // number of components in colorSpace2
866   GfxColorComp *                // lookup table
867     lookup[gfxColorMaxComps];
868   double                        // minimum values for each component
869     decodeLow[gfxColorMaxComps];
870   double                        // max - min value for each component
871     decodeRange[gfxColorMaxComps];
872   GBool ok;
873 };
874
875 //------------------------------------------------------------------------
876 // GfxSubpath and GfxPath
877 //------------------------------------------------------------------------
878
879 class GfxSubpath {
880 public:
881
882   // Constructor.
883   GfxSubpath(double x1, double y1);
884
885   // Destructor.
886   ~GfxSubpath();
887
888   // Copy.
889   GfxSubpath *copy() { return new GfxSubpath(this); }
890
891   // Get points.
892   int getNumPoints() { return n; }
893   double getX(int i) { return x[i]; }
894   double getY(int i) { return y[i]; }
895   GBool getCurve(int i) { return curve[i]; }
896
897   // Get last point.
898   double getLastX() { return x[n-1]; }
899   double getLastY() { return y[n-1]; }
900
901   // Add a line segment.
902   void lineTo(double x1, double y1);
903
904   // Add a Bezier curve.
905   void curveTo(double x1, double y1, double x2, double y2,
906                double x3, double y3);
907
908   // Close the subpath.
909   void close();
910   GBool isClosed() { return closed; }
911
912   // Add (<dx>, <dy>) to each point in the subpath.
913   void offset(double dx, double dy);
914
915 private:
916
917   double *x, *y;                // points
918   GBool *curve;                 // curve[i] => point i is a control point
919                                 //   for a Bezier curve
920   int n;                        // number of points
921   int size;                     // size of x/y arrays
922   GBool closed;                 // set if path is closed
923
924   GfxSubpath(GfxSubpath *subpath);
925 };
926
927 class GfxPath {
928 public:
929
930   // Constructor.
931   GfxPath();
932
933   // Destructor.
934   ~GfxPath();
935
936   // Copy.
937   GfxPath *copy()
938     { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); }
939
940   // Is there a current point?
941   GBool isCurPt() { return n > 0 || justMoved; }
942
943   // Is the path non-empty, i.e., is there at least one segment?
944   GBool isPath() { return n > 0; }
945
946   // Get subpaths.
947   int getNumSubpaths() { return n; }
948   GfxSubpath *getSubpath(int i) { return subpaths[i]; }
949
950   // Get last point on last subpath.
951   double getLastX() { return subpaths[n-1]->getLastX(); }
952   double getLastY() { return subpaths[n-1]->getLastY(); }
953
954   // Move the current point.
955   void moveTo(double x, double y);
956
957   // Add a segment to the last subpath.
958   void lineTo(double x, double y);
959
960   // Add a Bezier curve to the last subpath
961   void curveTo(double x1, double y1, double x2, double y2,
962                double x3, double y3);
963
964   // Close the last subpath.
965   void close();
966
967   // Append <path> to <this>.
968   void append(GfxPath *path);
969
970   // Add (<dx>, <dy>) to each point in the path.
971   void offset(double dx, double dy);
972
973 private:
974
975   GBool justMoved;              // set if a new subpath was just started
976   double firstX, firstY;        // first point in new subpath
977   GfxSubpath **subpaths;        // subpaths
978   int n;                        // number of subpaths
979   int size;                     // size of subpaths array
980
981   GfxPath(GBool justMoved1, double firstX1, double firstY1,
982           GfxSubpath **subpaths1, int n1, int size1);
983 };
984
985 //------------------------------------------------------------------------
986 // GfxState
987 //------------------------------------------------------------------------
988
989 class GfxState {
990 public:
991
992   // Construct a default GfxState, for a device with resolution <hDPI>
993   // x <vDPI>, page box <pageBox>, page rotation <rotateA>, and
994   // coordinate system specified by <upsideDown>.
995   GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
996            int rotateA, GBool upsideDown);
997
998   // Destructor.
999   ~GfxState();
1000
1001   // Copy.
1002   GfxState *copy() { return new GfxState(this); }
1003
1004   // Accessors.
1005   double *getCTM() { return ctm; }
1006   double getX1() { return px1; }
1007   double getY1() { return py1; }
1008   double getX2() { return px2; }
1009   double getY2() { return py2; }
1010   double getPageWidth() { return pageWidth; }
1011   double getPageHeight() { return pageHeight; }
1012   int getRotate() { return rotate; }
1013   GfxColor *getFillColor() { return &fillColor; }
1014   GfxColor *getStrokeColor() { return &strokeColor; }
1015   void getFillGray(GfxGray *gray)
1016     { fillColorSpace->getGray(&fillColor, gray); }
1017   void getStrokeGray(GfxGray *gray)
1018     { strokeColorSpace->getGray(&strokeColor, gray); }
1019   void getFillRGB(GfxRGB *rgb)
1020     { fillColorSpace->getRGB(&fillColor, rgb); }
1021   void getStrokeRGB(GfxRGB *rgb)
1022     { strokeColorSpace->getRGB(&strokeColor, rgb); }
1023   void getFillCMYK(GfxCMYK *cmyk)
1024     { fillColorSpace->getCMYK(&fillColor, cmyk); }
1025   void getStrokeCMYK(GfxCMYK *cmyk)
1026     { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
1027   GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
1028   GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
1029   GfxPattern *getFillPattern() { return fillPattern; }
1030   GfxPattern *getStrokePattern() { return strokePattern; }
1031   GfxBlendMode getBlendMode() { return blendMode; }
1032   double getFillOpacity() { return fillOpacity; }
1033   double getStrokeOpacity() { return strokeOpacity; }
1034   GBool getFillOverprint() { return fillOverprint; }
1035   GBool getStrokeOverprint() { return strokeOverprint; }
1036   double getLineWidth() { return lineWidth; }
1037   void getLineDash(double **dash, int *length, double *start)
1038     { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
1039   int getFlatness() { return flatness; }
1040   int getLineJoin() { return lineJoin; }
1041   int getLineCap() { return lineCap; }
1042   double getMiterLimit() { return miterLimit; }
1043   GfxFont *getFont() { return font; }
1044   double getFontSize() { return fontSize; }
1045   double *getTextMat() { return textMat; }
1046   double getCharSpace() { return charSpace; }
1047   double getWordSpace() { return wordSpace; }
1048   double getHorizScaling() { return horizScaling; }
1049   double getLeading() { return leading; }
1050   double getRise() { return rise; }
1051   int getRender() { return render; }
1052   GfxPath *getPath() { return path; }
1053   void setPath(GfxPath *pathA);
1054   double getCurX() { return curX; }
1055   double getCurY() { return curY; }
1056   void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax)
1057     { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
1058   void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax);
1059   double getLineX() { return lineX; }
1060   double getLineY() { return lineY; }
1061
1062   // Is there a current point/path?
1063   GBool isCurPt() { return path->isCurPt(); }
1064   GBool isPath() { return path->isPath(); }
1065
1066   // Transforms.
1067   void transform(double x1, double y1, double *x2, double *y2)
1068     { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4];
1069       *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; }
1070   void transformDelta(double x1, double y1, double *x2, double *y2)
1071     { *x2 = ctm[0] * x1 + ctm[2] * y1;
1072       *y2 = ctm[1] * x1 + ctm[3] * y1; }
1073   void textTransform(double x1, double y1, double *x2, double *y2)
1074     { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4];
1075       *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; }
1076   void textTransformDelta(double x1, double y1, double *x2, double *y2)
1077     { *x2 = textMat[0] * x1 + textMat[2] * y1;
1078       *y2 = textMat[1] * x1 + textMat[3] * y1; }
1079   double transformWidth(double w);
1080   double getTransformedLineWidth()
1081     { return transformWidth(lineWidth); }
1082   double getTransformedFontSize();
1083   void getFontTransMat(double *m11, double *m12, double *m21, double *m22);
1084
1085   // Change state parameters.
1086   void setCTM(double a, double b, double c,
1087               double d, double e, double f);
1088   void concatCTM(double a, double b, double c,
1089                  double d, double e, double f);
1090   void setFillColorSpace(GfxColorSpace *colorSpace);
1091   void setStrokeColorSpace(GfxColorSpace *colorSpace);
1092   void setFillColor(GfxColor *color) { fillColor = *color; }
1093   void setStrokeColor(GfxColor *color) { strokeColor = *color; }
1094   void setFillPattern(GfxPattern *pattern);
1095   void setStrokePattern(GfxPattern *pattern);
1096   void setBlendMode(GfxBlendMode mode) { blendMode = mode; }
1097   void setFillOpacity(double opac) { fillOpacity = opac; }
1098   void setStrokeOpacity(double opac) { strokeOpacity = opac; }
1099   void setFillOverprint(GBool op) { fillOverprint = op; }
1100   void setStrokeOverprint(GBool op) { strokeOverprint = op; }
1101   void setLineWidth(double width) { lineWidth = width; }
1102   void setLineDash(double *dash, int length, double start);
1103   void setFlatness(int flatness1) { flatness = flatness1; }
1104   void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
1105   void setLineCap(int lineCap1) { lineCap = lineCap1; }
1106   void setMiterLimit(double limit) { miterLimit = limit; }
1107   void setFont(GfxFont *fontA, double fontSizeA)
1108     { font = fontA; fontSize = fontSizeA; }
1109   void setTextMat(double a, double b, double c,
1110                   double d, double e, double f)
1111     { textMat[0] = a; textMat[1] = b; textMat[2] = c;
1112       textMat[3] = d; textMat[4] = e; textMat[5] = f; }
1113   void setCharSpace(double space)
1114     { charSpace = space; }
1115   void setWordSpace(double space)
1116     { wordSpace = space; }
1117   void setHorizScaling(double scale)
1118     { horizScaling = 0.01 * scale; }
1119   void setLeading(double leadingA)
1120     { leading = leadingA; }
1121   void setRise(double riseA)
1122     { rise = riseA; }
1123   void setRender(int renderA)
1124     { render = renderA; }
1125
1126   // Add to path.
1127   void moveTo(double x, double y)
1128     { path->moveTo(curX = x, curY = y); }
1129   void lineTo(double x, double y)
1130     { path->lineTo(curX = x, curY = y); }
1131   void curveTo(double x1, double y1, double x2, double y2,
1132                double x3, double y3)
1133     { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); }
1134   void closePath()
1135     { path->close(); curX = path->getLastX(); curY = path->getLastY(); }
1136   void clearPath();
1137
1138   // Update clip region.
1139   void clip();
1140
1141   // Text position.
1142   void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; }
1143   void textMoveTo(double tx, double ty)
1144     { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); }
1145   void textShift(double tx, double ty);
1146   void shift(double dx, double dy);
1147
1148   // Push/pop GfxState on/off stack.
1149   GfxState *save();
1150   GfxState *restore();
1151   GBool hasSaves() { return saved != NULL; }
1152
1153   // Misc
1154   GBool parseBlendMode(Object *obj, GfxBlendMode *mode);
1155
1156 private:
1157
1158   double ctm[6];                // coord transform matrix
1159   double px1, py1, px2, py2;    // page corners (user coords)
1160   double pageWidth, pageHeight; // page size (pixels)
1161   int rotate;                   // page rotation angle
1162
1163   GfxColorSpace *fillColorSpace;   // fill color space
1164   GfxColorSpace *strokeColorSpace; // stroke color space
1165   GfxColor fillColor;           // fill color
1166   GfxColor strokeColor;         // stroke color
1167   GfxPattern *fillPattern;      // fill pattern
1168   GfxPattern *strokePattern;    // stroke pattern
1169   GfxBlendMode blendMode;       // transparency blend mode
1170   double fillOpacity;           // fill opacity
1171   double strokeOpacity;         // stroke opacity
1172   GBool fillOverprint;          // fill overprint
1173   GBool strokeOverprint;        // stroke overprint
1174
1175   double lineWidth;             // line width
1176   double *lineDash;             // line dash
1177   int lineDashLength;
1178   double lineDashStart;
1179   int flatness;                 // curve flatness
1180   int lineJoin;                 // line join style
1181   int lineCap;                  // line cap style
1182   double miterLimit;            // line miter limit
1183
1184   GfxFont *font;                // font
1185   double fontSize;              // font size
1186   double textMat[6];            // text matrix
1187   double charSpace;             // character spacing
1188   double wordSpace;             // word spacing
1189   double horizScaling;          // horizontal scaling
1190   double leading;               // text leading
1191   double rise;                  // text rise
1192   int render;                   // text rendering mode
1193
1194   GfxPath *path;                // array of path elements
1195   double curX, curY;            // current point (user coords)
1196   double lineX, lineY;          // start of current text line (text coords)
1197
1198   double clipXMin, clipYMin,    // bounding box for clip region
1199          clipXMax, clipYMax;
1200
1201   GfxState *saved;              // next GfxState on stack
1202
1203   GfxState(GfxState *state);
1204 };
1205
1206 #endif