1 : //========================================================================
2 : //
3 : // GfxState.h
4 : //
5 : // Copyright 1996-2003 Glyph & Cog, LLC
6 : //
7 : //========================================================================
8 :
9 : //========================================================================
10 : //
11 : // Modified under the Poppler project - http://poppler.freedesktop.org
12 : //
13 : // All changes made under the Poppler project to this file are licensed
14 : // under GPL version 2 or later
15 : //
16 : // Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
17 : // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
18 : // Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
19 : // Copyright (C) 2009 Koji Otani <sho@bbr.jp>
20 : // Copyright (C) 2009-2011 Albert Astals Cid <aacid@kde.org>
21 : // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
22 : // Copyright (C) 2011 Andrea Canciani <ranma42@gmail.com>
23 : // Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
24 : // Copyright (C) 2013 Lu Wang <coolwanglu@gmail.com>
25 : //
26 : // To see a description of the changes please see the Changelog file that
27 : // came with your tarball or type make ChangeLog if you are building from git
28 : //
29 : //========================================================================
30 :
31 : #ifndef GFXSTATE_H
32 : #define GFXSTATE_H
33 :
34 : #ifdef USE_GCC_PRAGMAS
35 : #pragma interface
36 : #endif
37 :
38 : #include "poppler-config.h"
39 :
40 : #include "goo/gtypes.h"
41 : #include "Object.h"
42 : #include "Function.h"
43 :
44 : #include <assert.h>
45 :
46 : class Array;
47 : class Gfx;
48 : class GfxFont;
49 : class PDFRectangle;
50 : class GfxShading;
51 : class PopplerCache;
52 : class GooList;
53 :
54 : class Matrix {
55 : public:
56 : double m[6];
57 :
58 : GBool invertTo(Matrix *other) const;
59 : void transform(double x, double y, double *tx, double *ty) const;
60 : double determinant() const { return m[0] * m[3] - m[1] * m[2]; }
61 : double norm() const;
62 : };
63 :
64 : //------------------------------------------------------------------------
65 : // GfxBlendMode
66 : //------------------------------------------------------------------------
67 :
68 : enum GfxBlendMode {
69 : gfxBlendNormal,
70 : gfxBlendMultiply,
71 : gfxBlendScreen,
72 : gfxBlendOverlay,
73 : gfxBlendDarken,
74 : gfxBlendLighten,
75 : gfxBlendColorDodge,
76 : gfxBlendColorBurn,
77 : gfxBlendHardLight,
78 : gfxBlendSoftLight,
79 : gfxBlendDifference,
80 : gfxBlendExclusion,
81 : gfxBlendHue,
82 : gfxBlendSaturation,
83 : gfxBlendColor,
84 : gfxBlendLuminosity
85 : };
86 :
87 : //------------------------------------------------------------------------
88 : // GfxColorComp
89 : //------------------------------------------------------------------------
90 :
91 : // 16.16 fixed point color component
92 : typedef int GfxColorComp;
93 :
94 : #define gfxColorComp1 0x10000
95 :
96 : static inline GfxColorComp dblToCol(double x) {
97 : return (GfxColorComp)(x * gfxColorComp1);
98 : }
99 :
100 : static inline double colToDbl(GfxColorComp x) {
101 : return (double)x / (double)gfxColorComp1;
102 : }
103 :
104 : static inline Guchar dblToByte(double x) {
105 : return (x * 255.0);
106 : }
107 :
108 : static inline double byteToDbl(Guchar x) {
109 : return (double)x / (double)255.0;
110 : }
111 :
112 : static inline GfxColorComp byteToCol(Guchar x) {
113 : // (x / 255) << 16 = (0.0000000100000001... * x) << 16
114 : // = ((x << 8) + (x) + (x >> 8) + ...) << 16
115 : // = (x << 8) + (x) + (x >> 7)
116 : // [for rounding]
117 : return (GfxColorComp)((x << 8) + x + (x >> 7));
118 : }
119 :
120 : static inline Guchar colToByte(GfxColorComp x) {
121 : // 255 * x + 0.5 = 256 * x - x + 0x8000
122 : return (Guchar)(((x << 8) - x + 0x8000) >> 16);
123 : }
124 :
125 : //------------------------------------------------------------------------
126 : // GfxColor
127 : //------------------------------------------------------------------------
128 :
129 : #define gfxColorMaxComps funcMaxOutputs
130 :
131 : struct GfxColor {
132 : GfxColorComp c[gfxColorMaxComps];
133 : };
134 :
135 : //------------------------------------------------------------------------
136 : // GfxGray
137 : //------------------------------------------------------------------------
138 :
139 : typedef GfxColorComp GfxGray;
140 :
141 : //------------------------------------------------------------------------
142 : // GfxRGB
143 : //------------------------------------------------------------------------
144 :
145 : struct GfxRGB {
146 : GfxColorComp r, g, b;
147 : };
148 :
149 : //------------------------------------------------------------------------
150 : // GfxCMYK
151 : //------------------------------------------------------------------------
152 :
153 : struct GfxCMYK {
154 : GfxColorComp c, m, y, k;
155 : };
156 :
157 : //------------------------------------------------------------------------
158 : // GfxColorSpace
159 : //------------------------------------------------------------------------
160 :
161 : // NB: The nGfxColorSpaceModes constant and the gfxColorSpaceModeNames
162 : // array defined in GfxState.cc must match this enum.
163 : enum GfxColorSpaceMode {
164 : csDeviceGray,
165 : csCalGray,
166 : csDeviceRGB,
167 : csCalRGB,
168 : csDeviceCMYK,
169 : csLab,
170 : csICCBased,
171 : csIndexed,
172 : csSeparation,
173 : csDeviceN,
174 : csPattern
175 : };
176 :
177 : // wrapper of cmsHTRANSFORM to copy
178 : class GfxColorTransform {
179 : public:
180 : void doTransform(void *in, void *out, unsigned int size);
181 : // transformA should be a cmsHTRANSFORM
182 : GfxColorTransform(void *transformA);
183 : ~GfxColorTransform();
184 : void ref();
185 : unsigned int unref();
186 : private:
187 : GfxColorTransform() {}
188 : void *transform;
189 : unsigned int refCount;
190 : };
191 :
192 : class GfxColorSpace {
193 : public:
194 :
195 : GfxColorSpace();
196 : virtual ~GfxColorSpace();
197 : virtual GfxColorSpace *copy() = 0;
198 : virtual GfxColorSpaceMode getMode() = 0;
199 :
200 : // Construct a color space. Returns NULL if unsuccessful.
201 : static GfxColorSpace *parse(Object *csObj, Gfx *gfx, int recursion = 0);
202 :
203 : // Convert to gray, RGB, or CMYK.
204 : virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
205 : virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
206 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
207 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN) = 0;
208 : virtual void getGrayLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getGrayLine this should not happen"); }
209 : virtual void getRGBLine(Guchar * /*in*/, unsigned int * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getRGBLine (first variant) this should not happen"); }
210 : virtual void getRGBLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getRGBLine (second variant) this should not happen"); }
211 : virtual void getRGBXLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getRGBXLine this should not happen"); }
212 :
213 : // create mapping for spot colorants
214 : virtual void createMapping(GooList *separationList, int maxSepComps);
215 :
216 : // Does this ColorSpace support getRGBLine?
217 : virtual GBool useGetRGBLine() { return gFalse; }
218 : // Does this ColorSpace support getGrayLine?
219 : virtual GBool useGetGrayLine() { return gFalse; }
220 :
221 : // Return the number of color components.
222 : virtual int getNComps() = 0;
223 :
224 : // Get this color space's default color.
225 : virtual void getDefaultColor(GfxColor *color) = 0;
226 :
227 : // Return the default ranges for each component, assuming an image
228 : // with a max pixel value of <maxImgPixel>.
229 : virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
230 : int maxImgPixel);
231 :
232 : // Returns true if painting operations in this color space never
233 : // mark the page (e.g., the "None" colorant).
234 : virtual GBool isNonMarking() { return gFalse; }
235 :
236 : // Return the color space's overprint mask.
237 : Guint getOverprintMask() { return overprintMask; }
238 :
239 : // Return the number of color space modes
240 : static int getNumColorSpaceModes();
241 :
242 : // Return the name of the <idx>th color space mode.
243 : static const char *getColorSpaceModeName(int idx);
244 :
245 : #ifdef USE_CMS
246 : static int setupColorProfiles();
247 : // displayProfileA should be a cmsHPROFILE
248 : static void setDisplayProfile(void *displayProfileA);
249 : static void setDisplayProfileName(GooString *name);
250 : // result will be a cmsHPROFILE
251 : static void *getRGBProfile();
252 : // result will be a cmsHPROFILE
253 : static void *getDisplayProfile();
254 : #endif
255 : protected:
256 :
257 : Guint overprintMask;
258 : int *mapping;
259 : };
260 :
261 : //------------------------------------------------------------------------
262 : // GfxDeviceGrayColorSpace
263 : //------------------------------------------------------------------------
264 :
265 : class GfxDeviceGrayColorSpace: public GfxColorSpace {
266 : public:
267 :
268 : GfxDeviceGrayColorSpace();
269 : virtual ~GfxDeviceGrayColorSpace();
270 : virtual GfxColorSpace *copy();
271 : virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
272 :
273 : virtual void getGray(GfxColor *color, GfxGray *gray);
274 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
275 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
276 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
277 : virtual void getGrayLine(Guchar *in, Guchar *out, int length);
278 : virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
279 : virtual void getRGBLine(Guchar *in, Guchar *out, int length);
280 : virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
281 :
282 : virtual GBool useGetRGBLine() { return gTrue; }
283 : virtual GBool useGetGrayLine() { return gTrue; }
284 :
285 : virtual int getNComps() { return 1; }
286 : virtual void getDefaultColor(GfxColor *color);
287 :
288 : private:
289 : };
290 :
291 : //------------------------------------------------------------------------
292 : // GfxCalGrayColorSpace
293 : //------------------------------------------------------------------------
294 :
295 : class GfxCalGrayColorSpace: public GfxColorSpace {
296 : public:
297 :
298 : GfxCalGrayColorSpace();
299 : virtual ~GfxCalGrayColorSpace();
300 : virtual GfxColorSpace *copy();
301 : virtual GfxColorSpaceMode getMode() { return csCalGray; }
302 :
303 : // Construct a CalGray color space. Returns NULL if unsuccessful.
304 : static GfxColorSpace *parse(Array *arr);
305 :
306 : virtual void getGray(GfxColor *color, GfxGray *gray);
307 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
308 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
309 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
310 :
311 : virtual int getNComps() { return 1; }
312 : virtual void getDefaultColor(GfxColor *color);
313 :
314 : // CalGray-specific access.
315 : double getWhiteX() { return whiteX; }
316 : double getWhiteY() { return whiteY; }
317 : double getWhiteZ() { return whiteZ; }
318 : double getBlackX() { return blackX; }
319 : double getBlackY() { return blackY; }
320 : double getBlackZ() { return blackZ; }
321 : double getGamma() { return gamma; }
322 :
323 : private:
324 :
325 : double whiteX, whiteY, whiteZ; // white point
326 : double blackX, blackY, blackZ; // black point
327 : double gamma; // gamma value
328 : double kr, kg, kb; // gamut mapping mulitpliers
329 : void getXYZ(GfxColor *color, double *pX, double *pY, double *pZ);
330 : };
331 :
332 : //------------------------------------------------------------------------
333 : // GfxDeviceRGBColorSpace
334 : //------------------------------------------------------------------------
335 :
336 : class GfxDeviceRGBColorSpace: public GfxColorSpace {
337 : public:
338 :
339 : GfxDeviceRGBColorSpace();
340 : virtual ~GfxDeviceRGBColorSpace();
341 : virtual GfxColorSpace *copy();
342 : virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
343 :
344 : virtual void getGray(GfxColor *color, GfxGray *gray);
345 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
346 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
347 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
348 : virtual void getGrayLine(Guchar *in, Guchar *out, int length);
349 : virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
350 : virtual void getRGBLine(Guchar *in, Guchar *out, int length);
351 : virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
352 :
353 : virtual GBool useGetRGBLine() { return gTrue; }
354 : virtual GBool useGetGrayLine() { return gTrue; }
355 :
356 : virtual int getNComps() { return 3; }
357 : virtual void getDefaultColor(GfxColor *color);
358 :
359 : private:
360 : };
361 :
362 : //------------------------------------------------------------------------
363 : // GfxCalRGBColorSpace
364 : //------------------------------------------------------------------------
365 :
366 : class GfxCalRGBColorSpace: public GfxColorSpace {
367 : public:
368 :
369 : GfxCalRGBColorSpace();
370 : virtual ~GfxCalRGBColorSpace();
371 : virtual GfxColorSpace *copy();
372 : virtual GfxColorSpaceMode getMode() { return csCalRGB; }
373 :
374 : // Construct a CalRGB color space. Returns NULL if unsuccessful.
375 : static GfxColorSpace *parse(Array *arr);
376 :
377 : virtual void getGray(GfxColor *color, GfxGray *gray);
378 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
379 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
380 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
381 :
382 : virtual int getNComps() { return 3; }
383 : virtual void getDefaultColor(GfxColor *color);
384 :
385 : // CalRGB-specific access.
386 : double getWhiteX() { return whiteX; }
387 : double getWhiteY() { return whiteY; }
388 : double getWhiteZ() { return whiteZ; }
389 : double getBlackX() { return blackX; }
390 : double getBlackY() { return blackY; }
391 : double getBlackZ() { return blackZ; }
392 : double getGammaR() { return gammaR; }
393 : double getGammaG() { return gammaG; }
394 : double getGammaB() { return gammaB; }
395 : double *getMatrix() { return mat; }
396 :
397 : private:
398 :
399 : double whiteX, whiteY, whiteZ; // white point
400 : double blackX, blackY, blackZ; // black point
401 : double gammaR, gammaG, gammaB; // gamma values
402 : double mat[9]; // ABC -> XYZ transform matrix
403 : double kr, kg, kb; // gamut mapping mulitpliers
404 : void getXYZ(GfxColor *color, double *pX, double *pY, double *pZ);
405 : };
406 :
407 : //------------------------------------------------------------------------
408 : // GfxDeviceCMYKColorSpace
409 : //------------------------------------------------------------------------
410 :
411 : class GfxDeviceCMYKColorSpace: public GfxColorSpace {
412 : public:
413 :
414 : GfxDeviceCMYKColorSpace();
415 : virtual ~GfxDeviceCMYKColorSpace();
416 : virtual GfxColorSpace *copy();
417 : virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; }
418 :
419 : virtual void getGray(GfxColor *color, GfxGray *gray);
420 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
421 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
422 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
423 : virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
424 : virtual void getRGBLine(Guchar *, Guchar *out, int length);
425 : virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
426 : virtual GBool useGetRGBLine() { return gTrue; }
427 :
428 : virtual int getNComps() { return 4; }
429 : virtual void getDefaultColor(GfxColor *color);
430 :
431 : private:
432 : };
433 :
434 : //------------------------------------------------------------------------
435 : // GfxLabColorSpace
436 : //------------------------------------------------------------------------
437 :
438 : class GfxLabColorSpace: public GfxColorSpace {
439 : public:
440 :
441 : GfxLabColorSpace();
442 : virtual ~GfxLabColorSpace();
443 : virtual GfxColorSpace *copy();
444 : virtual GfxColorSpaceMode getMode() { return csLab; }
445 :
446 : // Construct a Lab color space. Returns NULL if unsuccessful.
447 : static GfxColorSpace *parse(Array *arr);
448 :
449 : virtual void getGray(GfxColor *color, GfxGray *gray);
450 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
451 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
452 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
453 :
454 : virtual int getNComps() { return 3; }
455 : virtual void getDefaultColor(GfxColor *color);
456 :
457 : virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
458 : int maxImgPixel);
459 :
460 : // Lab-specific access.
461 : double getWhiteX() { return whiteX; }
462 : double getWhiteY() { return whiteY; }
463 : double getWhiteZ() { return whiteZ; }
464 : double getBlackX() { return blackX; }
465 : double getBlackY() { return blackY; }
466 : double getBlackZ() { return blackZ; }
467 : double getAMin() { return aMin; }
468 : double getAMax() { return aMax; }
469 : double getBMin() { return bMin; }
470 : double getBMax() { return bMax; }
471 :
472 : private:
473 :
474 : double whiteX, whiteY, whiteZ; // white point
475 : double blackX, blackY, blackZ; // black point
476 : double aMin, aMax, bMin, bMax; // range for the a and b components
477 : double kr, kg, kb; // gamut mapping mulitpliers
478 : void getXYZ(GfxColor *color, double *pX, double *pY, double *pZ);
479 : };
480 :
481 : //------------------------------------------------------------------------
482 : // GfxICCBasedColorSpace
483 : //------------------------------------------------------------------------
484 :
485 : class GfxICCBasedColorSpace: public GfxColorSpace {
486 : public:
487 :
488 : GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
489 : Ref *iccProfileStreamA);
490 : virtual ~GfxICCBasedColorSpace();
491 : virtual GfxColorSpace *copy();
492 : virtual GfxColorSpaceMode getMode() { return csICCBased; }
493 :
494 : // Construct an ICCBased color space. Returns NULL if unsuccessful.
495 : static GfxColorSpace *parse(Array *arr, Gfx *gfx, int recursion);
496 :
497 : virtual void getGray(GfxColor *color, GfxGray *gray);
498 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
499 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
500 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
501 : virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
502 : virtual void getRGBLine(Guchar *in, Guchar *out, int length);
503 : virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
504 :
505 : virtual GBool useGetRGBLine();
506 :
507 : virtual int getNComps() { return nComps; }
508 : virtual void getDefaultColor(GfxColor *color);
509 :
510 : virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
511 : int maxImgPixel);
512 :
513 : // ICCBased-specific access.
514 : GfxColorSpace *getAlt() { return alt; }
515 :
516 : private:
517 :
518 : int nComps; // number of color components (1, 3, or 4)
519 : GfxColorSpace *alt; // alternate color space
520 : double rangeMin[4]; // min values for each component
521 : double rangeMax[4]; // max values for each component
522 : Ref iccProfileStream; // the ICC profile
523 : #ifdef USE_CMS
524 : GfxColorTransform *transform;
525 : GfxColorTransform *lineTransform; // color transform for line
526 : #endif
527 : };
528 : //------------------------------------------------------------------------
529 : // GfxIndexedColorSpace
530 : //------------------------------------------------------------------------
531 :
532 : class GfxIndexedColorSpace: public GfxColorSpace {
533 : public:
534 :
535 : GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA);
536 : virtual ~GfxIndexedColorSpace();
537 : virtual GfxColorSpace *copy();
538 : virtual GfxColorSpaceMode getMode() { return csIndexed; }
539 :
540 : // Construct an Indexed color space. Returns NULL if unsuccessful.
541 : static GfxColorSpace *parse(Array *arr, Gfx *gfx, int recursion);
542 :
543 : virtual void getGray(GfxColor *color, GfxGray *gray);
544 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
545 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
546 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
547 : virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
548 : virtual void getRGBLine(Guchar *in, Guchar *out, int length);
549 : virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
550 :
551 : virtual GBool useGetRGBLine() { return gTrue; }
552 :
553 : virtual int getNComps() { return 1; }
554 : virtual void getDefaultColor(GfxColor *color);
555 :
556 : virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
557 : int maxImgPixel);
558 :
559 : // Indexed-specific access.
560 : GfxColorSpace *getBase() { return base; }
561 : int getIndexHigh() { return indexHigh; }
562 : Guchar *getLookup() { return lookup; }
563 : GfxColor *mapColorToBase(GfxColor *color, GfxColor *baseColor);
564 : Guint getOverprintMask() { return base->getOverprintMask(); }
565 : virtual void createMapping(GooList *separationList, int maxSepComps)
566 : { base->createMapping(separationList, maxSepComps); }
567 :
568 :
569 : private:
570 :
571 : GfxColorSpace *base; // base color space
572 : int indexHigh; // max pixel value
573 : Guchar *lookup; // lookup table
574 : };
575 :
576 : //------------------------------------------------------------------------
577 : // GfxSeparationColorSpace
578 : //------------------------------------------------------------------------
579 :
580 : class GfxSeparationColorSpace: public GfxColorSpace {
581 : public:
582 :
583 : GfxSeparationColorSpace(GooString *nameA, GfxColorSpace *altA,
584 : Function *funcA);
585 : virtual ~GfxSeparationColorSpace();
586 : virtual GfxColorSpace *copy();
587 : virtual GfxColorSpaceMode getMode() { return csSeparation; }
588 :
589 : // Construct a Separation color space. Returns NULL if unsuccessful.
590 : static GfxColorSpace *parse(Array *arr, Gfx *gfx, int recursion);
591 :
592 : virtual void getGray(GfxColor *color, GfxGray *gray);
593 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
594 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
595 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
596 :
597 : virtual void createMapping(GooList *separationList, int maxSepComps);
598 :
599 : virtual int getNComps() { return 1; }
600 : virtual void getDefaultColor(GfxColor *color);
601 :
602 : virtual GBool isNonMarking() { return nonMarking; }
603 :
604 : // Separation-specific access.
605 : GooString *getName() { return name; }
606 : GfxColorSpace *getAlt() { return alt; }
607 : Function *getFunc() { return func; }
608 :
609 : private:
610 :
611 : GfxSeparationColorSpace(GooString *nameA, GfxColorSpace *altA,
612 : Function *funcA, GBool nonMarkingA,
613 : Guint overprintMaskA, int *mappingA);
614 :
615 : GooString *name; // colorant name
616 : GfxColorSpace *alt; // alternate color space
617 : Function *func; // tint transform (into alternate color space)
618 : GBool nonMarking;
619 : };
620 :
621 : //------------------------------------------------------------------------
622 : // GfxDeviceNColorSpace
623 : //------------------------------------------------------------------------
624 :
625 : class GfxDeviceNColorSpace: public GfxColorSpace {
626 : public:
627 :
628 : GfxDeviceNColorSpace(int nCompsA, GooString **namesA,
629 : GfxColorSpace *alt, Function *func, GooList *sepsCS);
630 : virtual ~GfxDeviceNColorSpace();
631 : virtual GfxColorSpace *copy();
632 : virtual GfxColorSpaceMode getMode() { return csDeviceN; }
633 :
634 : // Construct a DeviceN color space. Returns NULL if unsuccessful.
635 : static GfxColorSpace *parse(Array *arr, Gfx *gfx, int recursion);
636 :
637 : virtual void getGray(GfxColor *color, GfxGray *gray);
638 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
639 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
640 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
641 :
642 : virtual void createMapping(GooList *separationList, int maxSepComps);
643 :
644 : virtual int getNComps() { return nComps; }
645 : virtual void getDefaultColor(GfxColor *color);
646 :
647 : virtual GBool isNonMarking() { return nonMarking; }
648 :
649 : // DeviceN-specific access.
650 : GooString *getColorantName(int i) { return names[i]; }
651 : GfxColorSpace *getAlt() { return alt; }
652 : Function *getTintTransformFunc() { return func; }
653 :
654 : private:
655 :
656 : GfxDeviceNColorSpace(int nCompsA, GooString **namesA,
657 : GfxColorSpace *alt, Function *func, GooList *sepsCSA,
658 : int *mappingA, GBool nonMarkingA, Guint overprintMaskA);
659 :
660 : int nComps; // number of components
661 : GooString // colorant names
662 : *names[gfxColorMaxComps];
663 : GfxColorSpace *alt; // alternate color space
664 : Function *func; // tint transform (into alternate color space)
665 : GBool nonMarking;
666 : GooList *sepsCS; // list of separation cs for spot colorants;
667 : };
668 :
669 : //------------------------------------------------------------------------
670 : // GfxPatternColorSpace
671 : //------------------------------------------------------------------------
672 :
673 : class GfxPatternColorSpace: public GfxColorSpace {
674 : public:
675 :
676 : GfxPatternColorSpace(GfxColorSpace *underA);
677 : virtual ~GfxPatternColorSpace();
678 : virtual GfxColorSpace *copy();
679 : virtual GfxColorSpaceMode getMode() { return csPattern; }
680 :
681 : // Construct a Pattern color space. Returns NULL if unsuccessful.
682 : static GfxColorSpace *parse(Array *arr, Gfx *gfx, int recursion);
683 :
684 : virtual void getGray(GfxColor *color, GfxGray *gray);
685 : virtual void getRGB(GfxColor *color, GfxRGB *rgb);
686 : virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
687 : virtual void getDeviceN(GfxColor *color, GfxColor *deviceN);
688 :
689 : virtual int getNComps() { return 0; }
690 : virtual void getDefaultColor(GfxColor *color);
691 :
692 : // Pattern-specific access.
693 : GfxColorSpace *getUnder() { return under; }
694 :
695 : private:
696 :
697 : GfxColorSpace *under; // underlying color space (for uncolored
698 : // patterns)
699 : };
700 :
701 : //------------------------------------------------------------------------
702 : // GfxPattern
703 : //------------------------------------------------------------------------
704 :
705 : class GfxPattern {
706 : public:
707 :
708 : GfxPattern(int typeA);
709 : virtual ~GfxPattern();
710 :
711 : static GfxPattern *parse(Object *obj, Gfx *gfx);
712 :
713 : virtual GfxPattern *copy() = 0;
714 :
715 : int getType() { return type; }
716 :
717 : private:
718 :
719 : int type;
720 : };
721 :
722 : //------------------------------------------------------------------------
723 : // GfxTilingPattern
724 : //------------------------------------------------------------------------
725 :
726 : class GfxTilingPattern: public GfxPattern {
727 : public:
728 :
729 : static GfxTilingPattern *parse(Object *patObj);
730 : virtual ~GfxTilingPattern();
731 :
732 : virtual GfxPattern *copy();
733 :
734 : int getPaintType() { return paintType; }
735 : int getTilingType() { return tilingType; }
736 : double *getBBox() { return bbox; }
737 : double getXStep() { return xStep; }
738 : double getYStep() { return yStep; }
739 : Dict *getResDict()
740 : { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
741 : double *getMatrix() { return matrix; }
742 : Object *getContentStream() { return &contentStream; }
743 :
744 : private:
745 :
746 : GfxTilingPattern(int paintTypeA, int tilingTypeA,
747 : double *bboxA, double xStepA, double yStepA,
748 : Object *resDictA, double *matrixA,
749 : Object *contentStreamA);
750 :
751 : int paintType;
752 : int tilingType;
753 : double bbox[4];
754 : double xStep, yStep;
755 : Object resDict;
756 : double matrix[6];
757 : Object contentStream;
758 : };
759 :
760 : //------------------------------------------------------------------------
761 : // GfxShadingPattern
762 : //------------------------------------------------------------------------
763 :
764 : class GfxShadingPattern: public GfxPattern {
765 : public:
766 :
767 : static GfxShadingPattern *parse(Object *patObj, Gfx *gfx);
768 : virtual ~GfxShadingPattern();
769 :
770 : virtual GfxPattern *copy();
771 :
772 : GfxShading *getShading() { return shading; }
773 : double *getMatrix() { return matrix; }
774 :
775 : private:
776 :
777 : GfxShadingPattern(GfxShading *shadingA, double *matrixA);
778 :
779 : GfxShading *shading;
780 : double matrix[6];
781 : };
782 :
783 : //------------------------------------------------------------------------
784 : // GfxShading
785 : //------------------------------------------------------------------------
786 :
787 : class GfxShading {
788 : public:
789 :
790 : GfxShading(int typeA);
791 : GfxShading(GfxShading *shading);
792 : virtual ~GfxShading();
793 :
794 : static GfxShading *parse(Object *obj, Gfx *gfx);
795 :
796 : virtual GfxShading *copy() = 0;
797 :
798 : int getType() { return type; }
799 : GfxColorSpace *getColorSpace() { return colorSpace; }
800 : GfxColor *getBackground() { return &background; }
801 : GBool getHasBackground() { return hasBackground; }
802 : void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
803 : { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
804 : GBool getHasBBox() { return hasBBox; }
805 :
806 : protected:
807 :
808 : GBool init(Dict *dict, Gfx *gfx);
809 :
810 : int type;
811 : GfxColorSpace *colorSpace;
812 : GfxColor background;
813 : GBool hasBackground;
814 : double xMin, yMin, xMax, yMax;
815 : GBool hasBBox;
816 : };
817 :
818 : //------------------------------------------------------------------------
819 : // GfxUnivariateShading
820 : //------------------------------------------------------------------------
821 :
822 : class GfxUnivariateShading: public GfxShading {
823 : public:
824 :
825 : GfxUnivariateShading(int typeA,
826 : double t0A, double t1A,
827 : Function **funcsA, int nFuncsA,
828 : GBool extend0A, GBool extend1A);
829 : GfxUnivariateShading(GfxUnivariateShading *shading);
830 : virtual ~GfxUnivariateShading();
831 :
832 : double getDomain0() { return t0; }
833 : double getDomain1() { return t1; }
834 : GBool getExtend0() { return extend0; }
835 : GBool getExtend1() { return extend1; }
836 : int getNFuncs() { return nFuncs; }
837 : Function *getFunc(int i) { return funcs[i]; }
838 : void getColor(double t, GfxColor *color);
839 :
840 : void setupCache(const Matrix *ctm,
841 : double xMin, double yMin,
842 : double xMax, double yMax);
843 :
844 : virtual void getParameterRange(double *lower, double *upper,
845 : double xMin, double yMin,
846 : double xMax, double yMax) = 0;
847 :
848 : virtual double getDistance(double tMin, double tMax) = 0;
849 :
850 : private:
851 :
852 : double t0, t1;
853 : Function *funcs[gfxColorMaxComps];
854 : int nFuncs;
855 : GBool extend0, extend1;
856 :
857 : int cacheSize, lastMatch;
858 : double *cacheBounds;
859 : double *cacheCoeff;
860 : double *cacheValues;
861 : };
862 :
863 : //------------------------------------------------------------------------
864 : // GfxFunctionShading
865 : //------------------------------------------------------------------------
866 :
867 : class GfxFunctionShading: public GfxShading {
868 : public:
869 :
870 : GfxFunctionShading(double x0A, double y0A,
871 : double x1A, double y1A,
872 : double *matrixA,
873 : Function **funcsA, int nFuncsA);
874 : GfxFunctionShading(GfxFunctionShading *shading);
875 : virtual ~GfxFunctionShading();
876 :
877 : static GfxFunctionShading *parse(Dict *dict, Gfx *gfx);
878 :
879 : virtual GfxShading *copy();
880 :
881 : void getDomain(double *x0A, double *y0A, double *x1A, double *y1A)
882 : { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
883 : double *getMatrix() { return matrix; }
884 : int getNFuncs() { return nFuncs; }
885 : Function *getFunc(int i) { return funcs[i]; }
886 : void getColor(double x, double y, GfxColor *color);
887 :
888 : private:
889 :
890 : double x0, y0, x1, y1;
891 : double matrix[6];
892 : Function *funcs[gfxColorMaxComps];
893 : int nFuncs;
894 : };
895 :
896 : //------------------------------------------------------------------------
897 : // GfxAxialShading
898 : //------------------------------------------------------------------------
899 :
900 : class GfxAxialShading: public GfxUnivariateShading {
901 : public:
902 :
903 : GfxAxialShading(double x0A, double y0A,
904 : double x1A, double y1A,
905 : double t0A, double t1A,
906 : Function **funcsA, int nFuncsA,
907 : GBool extend0A, GBool extend1A);
908 : GfxAxialShading(GfxAxialShading *shading);
909 : virtual ~GfxAxialShading();
910 :
911 : static GfxAxialShading *parse(Dict *dict, Gfx *gfx);
912 :
913 : virtual GfxShading *copy();
914 :
915 : void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
916 : { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
917 :
918 : virtual void getParameterRange(double *lower, double *upper,
919 : double xMin, double yMin,
920 : double xMax, double yMax);
921 :
922 : virtual double getDistance(double tMin, double tMax);
923 :
924 : private:
925 :
926 : double x0, y0, x1, y1;
927 : };
928 :
929 : //------------------------------------------------------------------------
930 : // GfxRadialShading
931 : //------------------------------------------------------------------------
932 :
933 : class GfxRadialShading: public GfxUnivariateShading {
934 : public:
935 :
936 : GfxRadialShading(double x0A, double y0A, double r0A,
937 : double x1A, double y1A, double r1A,
938 : double t0A, double t1A,
939 : Function **funcsA, int nFuncsA,
940 : GBool extend0A, GBool extend1A);
941 : GfxRadialShading(GfxRadialShading *shading);
942 : virtual ~GfxRadialShading();
943 :
944 : static GfxRadialShading *parse(Dict *dict, Gfx *gfx);
945 :
946 : virtual GfxShading *copy();
947 :
948 : void getCoords(double *x0A, double *y0A, double *r0A,
949 : double *x1A, double *y1A, double *r1A)
950 : { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
951 :
952 : virtual void getParameterRange(double *lower, double *upper,
953 : double xMin, double yMin,
954 : double xMax, double yMax);
955 :
956 : virtual double getDistance(double tMin, double tMax);
957 :
958 : private:
959 :
960 : double x0, y0, r0, x1, y1, r1;
961 : };
962 :
963 : //------------------------------------------------------------------------
964 : // GfxGouraudTriangleShading
965 : //------------------------------------------------------------------------
966 :
967 : struct GfxGouraudVertex {
968 : double x, y;
969 : GfxColor color;
970 : };
971 :
972 : class GfxGouraudTriangleShading: public GfxShading {
973 : public:
974 :
975 : GfxGouraudTriangleShading(int typeA,
976 : GfxGouraudVertex *verticesA, int nVerticesA,
977 : int (*trianglesA)[3], int nTrianglesA,
978 : Function **funcsA, int nFuncsA);
979 : GfxGouraudTriangleShading(GfxGouraudTriangleShading *shading);
980 : virtual ~GfxGouraudTriangleShading();
981 :
982 : static GfxGouraudTriangleShading *parse(int typeA, Dict *dict, Stream *str, Gfx *gfx);
983 :
984 : virtual GfxShading *copy();
985 :
986 : int getNTriangles() { return nTriangles; }
987 :
988 : bool isParameterized() const { return nFuncs > 0; }
989 :
990 : /**
991 : * @precondition isParameterized() == true
992 : */
993 : double getParameterDomainMin() const { assert(isParameterized()); return funcs[0]->getDomainMin(0); }
994 :
995 : /**
996 : * @precondition isParameterized() == true
997 : */
998 : double getParameterDomainMax() const { assert(isParameterized()); return funcs[0]->getDomainMax(0); }
999 :
1000 : /**
1001 : * @precondition isParameterized() == false
1002 : */
1003 : void getTriangle(int i, double *x0, double *y0, GfxColor *color0,
1004 : double *x1, double *y1, GfxColor *color1,
1005 : double *x2, double *y2, GfxColor *color2);
1006 :
1007 : /**
1008 : * Variant for functions.
1009 : *
1010 : * @precondition isParameterized() == true
1011 : */
1012 : void getTriangle(int i, double *x0, double *y0, double *color0,
1013 : double *x1, double *y1, double *color1,
1014 : double *x2, double *y2, double *color2);
1015 :
1016 : void getParameterizedColor(double t, GfxColor *color);
1017 :
1018 : private:
1019 :
1020 : GfxGouraudVertex *vertices;
1021 : int nVertices;
1022 : int (*triangles)[3];
1023 : int nTriangles;
1024 : Function *funcs[gfxColorMaxComps];
1025 : int nFuncs;
1026 : };
1027 :
1028 : //------------------------------------------------------------------------
1029 : // GfxPatchMeshShading
1030 : //------------------------------------------------------------------------
1031 :
1032 : /**
1033 : * A tensor product cubic bezier patch consisting of 4x4 points and 4 color
1034 : * values.
1035 : *
1036 : * See the Shading Type 7 specifications. Note that Shading Type 6 is also
1037 : * represented using GfxPatch.
1038 : */
1039 : struct GfxPatch {
1040 : /**
1041 : * Represents a single color value for the patch.
1042 : */
1043 : struct ColorValue {
1044 : /**
1045 : * For parameterized patches, only element 0 is valid; it contains
1046 : * the single parameter.
1047 : *
1048 : * For non-parameterized patches, c contains all color components
1049 : * as decoded from the input stream. In this case, you will need to
1050 : * use dblToCol() before assigning them to GfxColor.
1051 : */
1052 : double c[gfxColorMaxComps];
1053 : };
1054 :
1055 : double x[4][4];
1056 : double y[4][4];
1057 : ColorValue color[2][2];
1058 : };
1059 :
1060 : class GfxPatchMeshShading: public GfxShading {
1061 : public:
1062 :
1063 : GfxPatchMeshShading(int typeA, GfxPatch *patchesA, int nPatchesA,
1064 : Function **funcsA, int nFuncsA);
1065 : GfxPatchMeshShading(GfxPatchMeshShading *shading);
1066 : virtual ~GfxPatchMeshShading();
1067 :
1068 : static GfxPatchMeshShading *parse(int typeA, Dict *dict, Stream *str, Gfx *gfx);
1069 :
1070 : virtual GfxShading *copy();
1071 :
1072 : int getNPatches() { return nPatches; }
1073 : GfxPatch *getPatch(int i) { return &patches[i]; }
1074 :
1075 : bool isParameterized() const { return nFuncs > 0; }
1076 :
1077 : /**
1078 : * @precondition isParameterized() == true
1079 : */
1080 : double getParameterDomainMin() const { assert(isParameterized()); return funcs[0]->getDomainMin(0); }
1081 :
1082 : /**
1083 : * @precondition isParameterized() == true
1084 : */
1085 : double getParameterDomainMax() const { assert(isParameterized()); return funcs[0]->getDomainMax(0); }
1086 :
1087 : void getParameterizedColor(double t, GfxColor *color);
1088 :
1089 : private:
1090 :
1091 : GfxPatch *patches;
1092 : int nPatches;
1093 : Function *funcs[gfxColorMaxComps];
1094 : int nFuncs;
1095 : };
1096 :
1097 : //------------------------------------------------------------------------
1098 : // GfxImageColorMap
1099 : //------------------------------------------------------------------------
1100 :
1101 : class GfxImageColorMap {
1102 : public:
1103 :
1104 : // Constructor.
1105 : GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA);
1106 :
1107 : // Destructor.
1108 : ~GfxImageColorMap();
1109 :
1110 : // Return a copy of this color map.
1111 : GfxImageColorMap *copy() { return new GfxImageColorMap(this); }
1112 :
1113 : // Is color map valid?
1114 : GBool isOk() { return ok; }
1115 :
1116 : // Get the color space.
1117 : GfxColorSpace *getColorSpace() { return colorSpace; }
1118 :
1119 : // Get stream decoding info.
1120 0 : int getNumPixelComps() { return nComps; }
1121 3 : int getBits() { return bits; }
1122 :
1123 : // Get decode table.
1124 : double getDecodeLow(int i) { return decodeLow[i]; }
1125 : double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
1126 :
1127 : bool useRGBLine() { return (colorSpace2 && colorSpace2->useGetRGBLine ()) || (!colorSpace2 && colorSpace->useGetRGBLine ()); }
1128 :
1129 : // Convert an image pixel to a color.
1130 : void getGray(Guchar *x, GfxGray *gray);
1131 : void getRGB(Guchar *x, GfxRGB *rgb);
1132 : void getRGBLine(Guchar *in, unsigned int *out, int length);
1133 : void getRGBLine(Guchar *in, Guchar *out, int length);
1134 : void getRGBXLine(Guchar *in, Guchar *out, int length);
1135 : void getGrayLine(Guchar *in, Guchar *out, int length);
1136 : void getCMYK(Guchar *x, GfxCMYK *cmyk);
1137 : void getDeviceN(Guchar *x, GfxColor *deviceN);
1138 : void getColor(Guchar *x, GfxColor *color);
1139 :
1140 : private:
1141 :
1142 : GfxImageColorMap(GfxImageColorMap *colorMap);
1143 :
1144 : GfxColorSpace *colorSpace; // the image color space
1145 : int bits; // bits per component
1146 : int nComps; // number of components in a pixel
1147 : GfxColorSpace *colorSpace2; // secondary color space
1148 : int nComps2; // number of components in colorSpace2
1149 : GfxColorComp * // lookup table
1150 : lookup[gfxColorMaxComps];
1151 : GfxColorComp * // optimized case lookup table
1152 : lookup2[gfxColorMaxComps];
1153 : Guchar *byte_lookup;
1154 : double // minimum values for each component
1155 : decodeLow[gfxColorMaxComps];
1156 : double // max - min value for each component
1157 : decodeRange[gfxColorMaxComps];
1158 : GBool ok;
1159 : };
1160 :
1161 : //------------------------------------------------------------------------
1162 : // GfxSubpath and GfxPath
1163 : //------------------------------------------------------------------------
1164 :
1165 : class GfxSubpath {
1166 : public:
1167 :
1168 : // Constructor.
1169 : GfxSubpath(double x1, double y1);
1170 :
1171 : // Destructor.
1172 : ~GfxSubpath();
1173 :
1174 : // Copy.
1175 : GfxSubpath *copy() { return new GfxSubpath(this); }
1176 :
1177 : // Get points.
1178 : int getNumPoints() { return n; }
1179 : double getX(int i) { return x[i]; }
1180 : double getY(int i) { return y[i]; }
1181 : GBool getCurve(int i) { return curve[i]; }
1182 :
1183 : void setX(int i, double a) { x[i] = a; }
1184 : void setY(int i, double a) { y[i] = a; }
1185 :
1186 : // Get last point.
1187 : double getLastX() { return x[n-1]; }
1188 : double getLastY() { return y[n-1]; }
1189 :
1190 : // Add a line segment.
1191 : void lineTo(double x1, double y1);
1192 :
1193 : // Add a Bezier curve.
1194 : void curveTo(double x1, double y1, double x2, double y2,
1195 : double x3, double y3);
1196 :
1197 : // Close the subpath.
1198 : void close();
1199 : GBool isClosed() { return closed; }
1200 :
1201 : // Add (<dx>, <dy>) to each point in the subpath.
1202 : void offset(double dx, double dy);
1203 :
1204 : private:
1205 :
1206 : double *x, *y; // points
1207 : GBool *curve; // curve[i] => point i is a control point
1208 : // for a Bezier curve
1209 : int n; // number of points
1210 : int size; // size of x/y arrays
1211 : GBool closed; // set if path is closed
1212 :
1213 : GfxSubpath(GfxSubpath *subpath);
1214 : };
1215 :
1216 : class GfxPath {
1217 : public:
1218 :
1219 : // Constructor.
1220 : GfxPath();
1221 :
1222 : // Destructor.
1223 : ~GfxPath();
1224 :
1225 : // Copy.
1226 : GfxPath *copy()
1227 : { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); }
1228 :
1229 : // Is there a current point?
1230 : GBool isCurPt() { return n > 0 || justMoved; }
1231 :
1232 : // Is the path non-empty, i.e., is there at least one segment?
1233 : GBool isPath() { return n > 0; }
1234 :
1235 : // Get subpaths.
1236 : int getNumSubpaths() { return n; }
1237 : GfxSubpath *getSubpath(int i) { return subpaths[i]; }
1238 :
1239 : // Get last point on last subpath.
1240 : double getLastX() { return subpaths[n-1]->getLastX(); }
1241 : double getLastY() { return subpaths[n-1]->getLastY(); }
1242 :
1243 : // Move the current point.
1244 : void moveTo(double x, double y);
1245 :
1246 : // Add a segment to the last subpath.
1247 : void lineTo(double x, double y);
1248 :
1249 : // Add a Bezier curve to the last subpath
1250 : void curveTo(double x1, double y1, double x2, double y2,
1251 : double x3, double y3);
1252 :
1253 : // Close the last subpath.
1254 : void close();
1255 :
1256 : // Append <path> to <this>.
1257 : void append(GfxPath *path);
1258 :
1259 : // Add (<dx>, <dy>) to each point in the path.
1260 : void offset(double dx, double dy);
1261 :
1262 : private:
1263 :
1264 : GBool justMoved; // set if a new subpath was just started
1265 : double firstX, firstY; // first point in new subpath
1266 : GfxSubpath **subpaths; // subpaths
1267 : int n; // number of subpaths
1268 : int size; // size of subpaths array
1269 :
1270 : GfxPath(GBool justMoved1, double firstX1, double firstY1,
1271 : GfxSubpath **subpaths1, int n1, int size1);
1272 : };
1273 :
1274 : //------------------------------------------------------------------------
1275 : // GfxState
1276 : //------------------------------------------------------------------------
1277 :
1278 : class GfxState {
1279 : public:
1280 : /**
1281 : * When GfxState::getReusablePath() is invoked, the currently active
1282 : * path is taken per reference and its coordinates can be re-edited.
1283 : *
1284 : * A ReusablePathIterator is intented to reduce overhead when the same
1285 : * path type is used a lot of times, only with different coordinates. It
1286 : * allows just to update the coordinates (occuring in the same order as
1287 : * in the original path).
1288 : */
1289 : class ReusablePathIterator {
1290 : public:
1291 : /**
1292 : * Creates the ReusablePathIterator. This should only be done from
1293 : * GfxState::getReusablePath().
1294 : *
1295 : * @param path the path as it is used so far. Changing this path,
1296 : * deleting it or starting a new path from scratch will most likely
1297 : * invalidate the iterator (and may cause serious problems). Make
1298 : * sure the path's memory structure is not changed during the
1299 : * lifetime of the ReusablePathIterator.
1300 : */
1301 : ReusablePathIterator( GfxPath* path );
1302 :
1303 : /**
1304 : * Returns true if and only if the current iterator position is
1305 : * beyond the last valid point.
1306 : *
1307 : * A call to setCoord() will be undefined.
1308 : */
1309 : bool isEnd() const;
1310 :
1311 : /**
1312 : * Advances the iterator.
1313 : */
1314 : void next();
1315 :
1316 : /**
1317 : * Updates the coordinates associated to the current iterator
1318 : * position.
1319 : */
1320 : void setCoord( double x, double y );
1321 :
1322 : /**
1323 : * Resets the iterator.
1324 : */
1325 : void reset();
1326 : private:
1327 : GfxPath *path;
1328 : int subPathOff;
1329 :
1330 : int coordOff;
1331 : int numCoords;
1332 :
1333 : GfxSubpath *curSubPath;
1334 : };
1335 :
1336 : // Construct a default GfxState, for a device with resolution <hDPI>
1337 : // x <vDPI>, page box <pageBox>, page rotation <rotateA>, and
1338 : // coordinate system specified by <upsideDown>.
1339 : GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
1340 : int rotateA, GBool upsideDown);
1341 :
1342 : // Destructor.
1343 : ~GfxState();
1344 :
1345 : // Copy.
1346 : GfxState *copy(GBool copyPath = gFalse)
1347 : { return new GfxState(this, copyPath); }
1348 :
1349 : // Accessors.
1350 : double getHDPI() { return hDPI; }
1351 : double getVDPI() { return vDPI; }
1352 : double *getCTM() { return ctm; }
1353 : void getCTM(Matrix *m) { memcpy (m->m, ctm, sizeof m->m); }
1354 : double getX1() { return px1; }
1355 : double getY1() { return py1; }
1356 : double getX2() { return px2; }
1357 : double getY2() { return py2; }
1358 : double getPageWidth() { return pageWidth; }
1359 : double getPageHeight() { return pageHeight; }
1360 : int getRotate() { return rotate; }
1361 : GfxColor *getFillColor() { return &fillColor; }
1362 : GfxColor *getStrokeColor() { return &strokeColor; }
1363 : void getFillGray(GfxGray *gray)
1364 : { fillColorSpace->getGray(&fillColor, gray); }
1365 : void getStrokeGray(GfxGray *gray)
1366 : { strokeColorSpace->getGray(&strokeColor, gray); }
1367 : void getFillRGB(GfxRGB *rgb)
1368 : { fillColorSpace->getRGB(&fillColor, rgb); }
1369 : void getStrokeRGB(GfxRGB *rgb)
1370 : { strokeColorSpace->getRGB(&strokeColor, rgb); }
1371 : void getFillCMYK(GfxCMYK *cmyk)
1372 : { fillColorSpace->getCMYK(&fillColor, cmyk); }
1373 : void getFillDeviceN(GfxColor *deviceN)
1374 : { fillColorSpace->getDeviceN(&fillColor, deviceN); }
1375 : void getStrokeCMYK(GfxCMYK *cmyk)
1376 : { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
1377 : void getStrokeDeviceN(GfxColor *deviceN)
1378 : { strokeColorSpace->getDeviceN(&strokeColor, deviceN); }
1379 : GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
1380 : GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
1381 : GfxPattern *getFillPattern() { return fillPattern; }
1382 : GfxPattern *getStrokePattern() { return strokePattern; }
1383 : GfxBlendMode getBlendMode() { return blendMode; }
1384 : double getFillOpacity() { return fillOpacity; }
1385 : double getStrokeOpacity() { return strokeOpacity; }
1386 : GBool getFillOverprint() { return fillOverprint; }
1387 : GBool getStrokeOverprint() { return strokeOverprint; }
1388 : int getOverprintMode() { return overprintMode; }
1389 : Function **getTransfer() { return transfer; }
1390 : double getLineWidth() { return lineWidth; }
1391 : void getLineDash(double **dash, int *length, double *start)
1392 : { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
1393 : int getFlatness() { return flatness; }
1394 : int getLineJoin() { return lineJoin; }
1395 : int getLineCap() { return lineCap; }
1396 : double getMiterLimit() { return miterLimit; }
1397 : GBool getStrokeAdjust() { return strokeAdjust; }
1398 : GBool getAlphaIsShape() { return alphaIsShape; }
1399 : GBool getTextKnockout() { return textKnockout; }
1400 : GfxFont *getFont() { return font; }
1401 : double getFontSize() { return fontSize; }
1402 : double *getTextMat() { return textMat; }
1403 : double getCharSpace() { return charSpace; }
1404 : double getWordSpace() { return wordSpace; }
1405 : double getHorizScaling() { return horizScaling; }
1406 : double getLeading() { return leading; }
1407 : double getRise() { return rise; }
1408 : int getRender() { return render; }
1409 : GfxPath *getPath() { return path; }
1410 : void setPath(GfxPath *pathA);
1411 : double getCurX() { return curX; }
1412 : double getCurY() { return curY; }
1413 : void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax)
1414 : { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
1415 : void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax);
1416 : double getLineX() { return lineX; }
1417 : double getLineY() { return lineY; }
1418 :
1419 : // Is there a current point/path?
1420 : GBool isCurPt() { return path->isCurPt(); }
1421 : GBool isPath() { return path->isPath(); }
1422 :
1423 : // Transforms.
1424 : void transform(double x1, double y1, double *x2, double *y2)
1425 : { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4];
1426 : *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; }
1427 : void transformDelta(double x1, double y1, double *x2, double *y2)
1428 : { *x2 = ctm[0] * x1 + ctm[2] * y1;
1429 : *y2 = ctm[1] * x1 + ctm[3] * y1; }
1430 : void textTransform(double x1, double y1, double *x2, double *y2)
1431 : { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4];
1432 : *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; }
1433 : void textTransformDelta(double x1, double y1, double *x2, double *y2)
1434 : { *x2 = textMat[0] * x1 + textMat[2] * y1;
1435 : *y2 = textMat[1] * x1 + textMat[3] * y1; }
1436 : double transformWidth(double w);
1437 : double getTransformedLineWidth()
1438 : { return transformWidth(lineWidth); }
1439 : double getTransformedFontSize();
1440 : void getFontTransMat(double *m11, double *m12, double *m21, double *m22);
1441 :
1442 : // Change state parameters.
1443 : void setCTM(double a, double b, double c,
1444 : double d, double e, double f);
1445 : void concatCTM(double a, double b, double c,
1446 : double d, double e, double f);
1447 : void shiftCTMAndClip(double tx, double ty);
1448 : void setFillColorSpace(GfxColorSpace *colorSpace);
1449 : void setStrokeColorSpace(GfxColorSpace *colorSpace);
1450 : void setFillColor(GfxColor *color) { fillColor = *color; }
1451 : void setStrokeColor(GfxColor *color) { strokeColor = *color; }
1452 : void setFillPattern(GfxPattern *pattern);
1453 : void setStrokePattern(GfxPattern *pattern);
1454 : void setBlendMode(GfxBlendMode mode) { blendMode = mode; }
1455 : void setFillOpacity(double opac) { fillOpacity = opac; }
1456 : void setStrokeOpacity(double opac) { strokeOpacity = opac; }
1457 : void setFillOverprint(GBool op) { fillOverprint = op; }
1458 : void setStrokeOverprint(GBool op) { strokeOverprint = op; }
1459 : void setOverprintMode(int op) { overprintMode = op; }
1460 : void setTransfer(Function **funcs);
1461 : void setLineWidth(double width) { lineWidth = width; }
1462 : void setLineDash(double *dash, int length, double start);
1463 : void setFlatness(int flatness1) { flatness = flatness1; }
1464 : void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
1465 : void setLineCap(int lineCap1) { lineCap = lineCap1; }
1466 : void setMiterLimit(double limit) { miterLimit = limit; }
1467 : void setStrokeAdjust(GBool sa) { strokeAdjust = sa; }
1468 : void setAlphaIsShape(GBool ais) { alphaIsShape = ais; }
1469 : void setTextKnockout(GBool tk) { textKnockout = tk; }
1470 : void setFont(GfxFont *fontA, double fontSizeA);
1471 : void setTextMat(double a, double b, double c,
1472 : double d, double e, double f)
1473 : { textMat[0] = a; textMat[1] = b; textMat[2] = c;
1474 : textMat[3] = d; textMat[4] = e; textMat[5] = f; }
1475 : void setCharSpace(double space)
1476 : { charSpace = space; }
1477 : void setWordSpace(double space)
1478 : { wordSpace = space; }
1479 : void setHorizScaling(double scale)
1480 : { horizScaling = 0.01 * scale; }
1481 : void setLeading(double leadingA)
1482 : { leading = leadingA; }
1483 : void setRise(double riseA)
1484 : { rise = riseA; }
1485 : void setRender(int renderA)
1486 : { render = renderA; }
1487 :
1488 : // Add to path.
1489 : void moveTo(double x, double y)
1490 : { path->moveTo(curX = x, curY = y); }
1491 : void lineTo(double x, double y)
1492 : { path->lineTo(curX = x, curY = y); }
1493 : void curveTo(double x1, double y1, double x2, double y2,
1494 : double x3, double y3)
1495 : { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); }
1496 : void closePath()
1497 : { path->close(); curX = path->getLastX(); curY = path->getLastY(); }
1498 : void clearPath();
1499 :
1500 : // Update clip region.
1501 : void clip();
1502 : void clipToStrokePath();
1503 : void clipToRect(double xMin, double yMin, double xMax, double yMax);
1504 :
1505 : // Text position.
1506 : void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; }
1507 : void textMoveTo(double tx, double ty)
1508 : { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); }
1509 : void textShift(double tx, double ty);
1510 : void shift(double dx, double dy);
1511 :
1512 : // Push/pop GfxState on/off stack.
1513 : GfxState *save();
1514 : GfxState *restore();
1515 : GBool hasSaves() { return saved != NULL; }
1516 : GBool isParentState(GfxState *state) { return saved == state || (saved && saved->isParentState(state)); }
1517 :
1518 : // Misc
1519 : GBool parseBlendMode(Object *obj, GfxBlendMode *mode);
1520 :
1521 : ReusablePathIterator *getReusablePath() { return new ReusablePathIterator(path); }
1522 : private:
1523 :
1524 : double hDPI, vDPI; // resolution
1525 : double ctm[6]; // coord transform matrix
1526 : double px1, py1, px2, py2; // page corners (user coords)
1527 : double pageWidth, pageHeight; // page size (pixels)
1528 : int rotate; // page rotation angle
1529 :
1530 : GfxColorSpace *fillColorSpace; // fill color space
1531 : GfxColorSpace *strokeColorSpace; // stroke color space
1532 : GfxColor fillColor; // fill color
1533 : GfxColor strokeColor; // stroke color
1534 : GfxPattern *fillPattern; // fill pattern
1535 : GfxPattern *strokePattern; // stroke pattern
1536 : GfxBlendMode blendMode; // transparency blend mode
1537 : double fillOpacity; // fill opacity
1538 : double strokeOpacity; // stroke opacity
1539 : GBool fillOverprint; // fill overprint
1540 : GBool strokeOverprint; // stroke overprint
1541 : int overprintMode; // overprint mode
1542 : Function *transfer[4]; // transfer function (entries may be: all
1543 : // NULL = identity; last three NULL =
1544 : // single function; all four non-NULL =
1545 : // R,G,B,gray functions)
1546 :
1547 : double lineWidth; // line width
1548 : double *lineDash; // line dash
1549 : int lineDashLength;
1550 : double lineDashStart;
1551 : int flatness; // curve flatness
1552 : int lineJoin; // line join style
1553 : int lineCap; // line cap style
1554 : double miterLimit; // line miter limit
1555 : GBool strokeAdjust; // stroke adjustment
1556 : GBool alphaIsShape; // alpha is shape
1557 : GBool textKnockout; // text knockout
1558 :
1559 : GfxFont *font; // font
1560 : double fontSize; // font size
1561 : double textMat[6]; // text matrix
1562 : double charSpace; // character spacing
1563 : double wordSpace; // word spacing
1564 : double horizScaling; // horizontal scaling
1565 : double leading; // text leading
1566 : double rise; // text rise
1567 : int render; // text rendering mode
1568 :
1569 : GfxPath *path; // array of path elements
1570 : double curX, curY; // current point (user coords)
1571 : double lineX, lineY; // start of current text line (text coords)
1572 :
1573 : double clipXMin, clipYMin, // bounding box for clip region
1574 : clipXMax, clipYMax;
1575 :
1576 : GfxState *saved; // next GfxState on stack
1577 :
1578 : GfxState(GfxState *state, GBool copyPath);
1579 : };
1580 :
1581 : #endif
|