1 //========================================================================
2 //
3 // SplashOutputDev.h
4 //
5 // Copyright 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 Takashi Iwai <tiwai@suse.de>
17 // Copyright (C) 2009-2016 Thomas Freitag <Thomas.Freitag@alfa.de>
18 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
19 // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
20 // Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
21 // Copyright (C) 2011 Andrea Canciani <ranma42@gmail.com>
22 // Copyright (C) 2011, 2017 Adrian Johnson <ajohnson@redneon.com>
23 // Copyright (C) 2012, 2015, 2018 Albert Astals Cid <aacid@kde.org>
24 // Copyright (C) 2015, 2016 William Bader <williambader@hotmail.com>
25 // Copyright (C) 2018 Stefan Brüns <stefan.bruens@rwth-aachen.de>
26 //
27 // To see a description of the changes please see the Changelog file that
28 // came with your tarball or type make ChangeLog if you are building from git
29 //
30 //========================================================================
31 
32 #ifndef SPLASHOUTPUTDEV_H
33 #define SPLASHOUTPUTDEV_H
34 
35 #include "splash/SplashTypes.h"
36 #include "splash/SplashPattern.h"
37 #include "poppler-config.h"
38 #include "OutputDev.h"
39 #include "GfxState.h"
40 #include "GlobalParams.h"
41 
42 class PDFDoc;
43 class Gfx8BitFont;
44 class SplashBitmap;
45 class Splash;
46 class SplashPath;
47 class SplashFontEngine;
48 class SplashFont;
49 class T3FontCache;
50 struct T3FontCacheTag;
51 struct T3GlyphStack;
52 struct SplashTransparencyGroup;
53 
54 //------------------------------------------------------------------------
55 // Splash dynamic pattern
56 //------------------------------------------------------------------------
57 
58 class SplashFunctionPattern : public SplashPattern {
59 public:
60 
61     SplashFunctionPattern(SplashColorMode colorMode, GfxState *state, GfxFunctionShading *shading);
62 
copy()63     SplashPattern *copy() override {
64         return new SplashFunctionPattern(colorMode, state, (GfxFunctionShading *) shading);
65     }
66 
67     ~SplashFunctionPattern();
68 
testPosition(int x,int y)69     bool testPosition(int x, int y) override {
70         return true;
71     }
72 
isStatic()73     bool isStatic() override {
74         return false;
75     }
76 
77     bool getColor(int x, int y, SplashColorPtr c) override;
78 
getShading()79     virtual GfxFunctionShading *getShading() {
80         return shading;
81     }
82 
isCMYK()83     bool isCMYK() override {
84         return gfxMode == csDeviceCMYK;
85     }
86 
87 protected:
88     Matrix ictm;
89     double xMin, yMin, xMax, yMax;
90     GfxFunctionShading *shading;
91     GfxState *state;
92     SplashColorMode colorMode;
93     GfxColorSpaceMode gfxMode;
94 };
95 
96 class SplashUnivariatePattern : public SplashPattern {
97 public:
98 
99     SplashUnivariatePattern(SplashColorMode colorMode, GfxState *state, GfxUnivariateShading *shading);
100 
101     ~SplashUnivariatePattern();
102 
103     bool getColor(int x, int y, SplashColorPtr c) override;
104 
105     bool testPosition(int x, int y) override;
106 
isStatic()107     bool isStatic() override {
108         return false;
109     }
110 
111     virtual bool getParameter(double xs, double ys, double *t) = 0;
112 
getShading()113     virtual GfxUnivariateShading *getShading() {
114         return shading;
115     }
116 
isCMYK()117     bool isCMYK() override {
118         return gfxMode == csDeviceCMYK;
119     }
120 
121 protected:
122     Matrix ictm;
123     double t0, t1, dt;
124     GfxUnivariateShading *shading;
125     GfxState *state;
126     SplashColorMode colorMode;
127     GfxColorSpaceMode gfxMode;
128 };
129 
130 class SplashAxialPattern : public SplashUnivariatePattern {
131 public:
132 
133     SplashAxialPattern(SplashColorMode colorMode, GfxState *state, GfxAxialShading *shading);
134 
copy()135     SplashPattern *copy() override {
136         return new SplashAxialPattern(colorMode, state, (GfxAxialShading *) shading);
137     }
138 
139     ~SplashAxialPattern();
140 
141     bool getParameter(double xs, double ys, double *t) override;
142 
143 private:
144     double x0, y0, x1, y1;
145     double dx, dy, mul;
146 };
147 
148 // see GfxState.h, GfxGouraudTriangleShading
149 class SplashGouraudPattern : public SplashGouraudColor {
150 public:
151 
152     SplashGouraudPattern(bool bDirectColorTranslation, GfxState *state, GfxGouraudTriangleShading *shading);
153 
copy()154     SplashPattern *copy() override {
155         return new SplashGouraudPattern(bDirectColorTranslation, state, shading);
156     }
157 
158     ~SplashGouraudPattern();
159 
getColor(int x,int y,SplashColorPtr c)160     bool getColor(int x, int y, SplashColorPtr c) override {
161         return false;
162     }
163 
testPosition(int x,int y)164     bool testPosition(int x, int y) override {
165         return false;
166     }
167 
isStatic()168     bool isStatic() override {
169         return false;
170     }
171 
isCMYK()172     bool isCMYK() override {
173         return gfxMode == csDeviceCMYK;
174     }
175 
isParameterized()176     bool isParameterized() override {
177         return shading->isParameterized();
178     }
getNTriangles()179     int getNTriangles() override {
180         return shading->getNTriangles();
181     }
getTriangle(int i,double * x0,double * y0,double * color0,double * x1,double * y1,double * color1,double * x2,double * y2,double * color2)182     void getTriangle(int i, double *x0, double *y0, double *color0,
183                      double *x1, double *y1, double *color1,
184                      double *x2, double *y2, double *color2) override
185     {
186         shading->getTriangle(i, x0, y0, color0, x1, y1, color1, x2, y2, color2);
187     }
188 
189     void getParameterizedColor(double t, SplashColorMode mode, SplashColorPtr c) override;
190 
191 private:
192     GfxGouraudTriangleShading *shading;
193     GfxState *state;
194     bool bDirectColorTranslation;
195     GfxColorSpaceMode gfxMode;
196 };
197 
198 // see GfxState.h, GfxRadialShading
199 class SplashRadialPattern : public SplashUnivariatePattern {
200 public:
201 
202     SplashRadialPattern(SplashColorMode colorMode, GfxState *state, GfxRadialShading *shading);
203 
copy()204     SplashPattern *copy() override {
205         return new SplashRadialPattern(colorMode, state, (GfxRadialShading *) shading);
206     }
207 
208     ~SplashRadialPattern();
209 
210     bool getParameter(double xs, double ys, double *t) override;
211 
212 private:
213     double x0, y0, r0, dx, dy, dr;
214     double a, inva;
215 };
216 
217 //------------------------------------------------------------------------
218 
219 // number of Type 3 fonts to cache
220 #define splashOutT3FontCacheSize 8
221 
222 //------------------------------------------------------------------------
223 // SplashOutputDev
224 //------------------------------------------------------------------------
225 
226 class SplashOutputDev : public OutputDev {
227 public:
228 
229     // Constructor.
230     SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA,
231                     bool reverseVideoA, SplashColorPtr paperColorA,
232                     bool bitmapTopDownA = true,
233                     SplashThinLineMode thinLineMode = splashThinLineDefault,
234                     bool overprintPreviewA = globalParams->getOverprintPreview());
235 
236     // Destructor.
237     ~SplashOutputDev();
238 
239     //----- get info about output device
240 
241     // Does this device use tilingPatternFill()?  If this returns false,
242     // tiling pattern fills will be reduced to a series of other drawing
243     // operations.
useTilingPatternFill()244     bool useTilingPatternFill() override {
245         return true;
246     }
247 
248     // Does this device use functionShadedFill(), axialShadedFill(), and
249     // radialShadedFill()?  If this returns false, these shaded fills
250     // will be reduced to a series of other drawing operations.
useShadedFills(int type)251     bool useShadedFills(int type) override
252     {
253         return (type >= 1 && type <= 5) ? true : false;
254     }
255 
256     // Does this device use upside-down coordinates?
257     // (Upside-down means (0,0) is the top left corner of the page.)
upsideDown()258     bool upsideDown() override {
259         return bitmapTopDown ^ bitmapUpsideDown;
260     }
261 
262     // Does this device use drawChar() or drawString()?
useDrawChar()263     bool useDrawChar() override {
264         return true;
265     }
266 
267     // Does this device use beginType3Char/endType3Char?  Otherwise,
268     // text in Type 3 fonts will be drawn with drawChar/drawString.
interpretType3Chars()269     bool interpretType3Chars() override {
270         return true;
271     }
272 
273     //----- initialization and control
274 
275     // Start a page.
276     void startPage(int pageNum, GfxState *state, XRef *xref) override;
277 
278     // End a page.
279     void endPage() override;
280 
281     //----- save/restore graphics state
282     void saveState(GfxState *state) override;
283     void restoreState(GfxState *state) override;
284 
285     //----- update graphics state
286     void updateAll(GfxState *state) override;
287     void updateCTM(GfxState *state, double m11, double m12,
288                    double m21, double m22, double m31, double m32) override;
289     void updateLineDash(GfxState *state) override;
290     void updateFlatness(GfxState *state) override;
291     void updateLineJoin(GfxState *state) override;
292     void updateLineCap(GfxState *state) override;
293     void updateMiterLimit(GfxState *state) override;
294     void updateLineWidth(GfxState *state) override;
295     void updateStrokeAdjust(GfxState *state) override;
296     void updateFillColorSpace(GfxState *state) override;
297     void updateStrokeColorSpace(GfxState *state) override;
298     void updateFillColor(GfxState *state) override;
299     void updateStrokeColor(GfxState *state) override;
300     void updateBlendMode(GfxState *state) override;
301     void updateFillOpacity(GfxState *state) override;
302     void updateStrokeOpacity(GfxState *state) override;
303     void updatePatternOpacity(GfxState *state) override;
304     void clearPatternOpacity(GfxState *state) override;
305     void updateFillOverprint(GfxState *state) override;
306     void updateStrokeOverprint(GfxState *state) override;
307     void updateOverprintMode(GfxState *state) override;
308     void updateTransfer(GfxState *state) override;
309 
310     //----- update text state
311     void updateFont(GfxState *state) override;
312 
313     //----- path painting
314     void stroke(GfxState *state) override;
315     void fill(GfxState *state) override;
316     void eoFill(GfxState *state) override;
317     bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *catalog, Object *str,
318                            const double *pmat, int paintType, int tilingType, Dict *resDict,
319                            const double *mat, const double *bbox,
320                            int x0, int y0, int x1, int y1,
321                            double xStep, double yStep) override;
322     bool functionShadedFill(GfxState *state, GfxFunctionShading *shading) override;
323     bool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) override;
324     bool radialShadedFill(GfxState *state, GfxRadialShading *shading, double tMin, double tMax) override;
325     bool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading) override;
326 
327     //----- path clipping
328     void clip(GfxState *state) override;
329     void eoClip(GfxState *state) override;
330     void clipToStrokePath(GfxState *state) override;
331 
332     //----- text drawing
333     void drawChar(GfxState *state, double x, double y,
334                   double dx, double dy,
335                   double originX, double originY,
336                   CharCode code, int nBytes, Unicode *u, int uLen) override;
337     bool beginType3Char(GfxState *state, double x, double y,
338                         double dx, double dy,
339                         CharCode code, Unicode *u, int uLen) override;
340     void endType3Char(GfxState *state) override;
341     void beginTextObject(GfxState *state) override;
342     void endTextObject(GfxState *state) override;
343 
344     //----- image drawing
345     void drawImageMask(GfxState *state, Object *ref, Stream *str,
346                        int width, int height, bool invert,
347                        bool interpolate, bool inlineImg) override;
348     void setSoftMaskFromImageMask(GfxState *state,
349                                   Object *ref, Stream *str,
350                                   int width, int height, bool invert,
351                                   bool inlineImg, double *baseMatrix) override;
352     void unsetSoftMaskFromImageMask(GfxState *state, double *baseMatrix) override;
353     void drawImage(GfxState *state, Object *ref, Stream *str,
354                    int width, int height, GfxImageColorMap *colorMap,
355                    bool interpolate, int *maskColors, bool inlineImg) override;
356     void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
357                          int width, int height,
358                          GfxImageColorMap *colorMap,
359                          bool interpolate,
360                          Stream *maskStr, int maskWidth, int maskHeight,
361                          bool maskInvert, bool maskInterpolate) override;
362     void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
363                              int width, int height,
364                              GfxImageColorMap *colorMap,
365                              bool interpolate,
366                              Stream *maskStr,
367                              int maskWidth, int maskHeight,
368                              GfxImageColorMap *maskColorMap,
369                              bool maskInterpolate) override;
370 
371     //----- Type 3 font operators
372     void type3D0(GfxState *state, double wx, double wy) override;
373     void type3D1(GfxState *state, double wx, double wy,
374                  double llx, double lly, double urx, double ury) override;
375 
376     //----- transparency groups and soft masks
377     bool checkTransparencyGroup(GfxState *state, bool knockout) override;
378     void beginTransparencyGroup(GfxState *state, const double *bbox,
379                                 GfxColorSpace *blendingColorSpace,
380                                 bool isolated, bool knockout,
381                                 bool forSoftMask) override;
382     void endTransparencyGroup(GfxState *state) override;
383     void paintTransparencyGroup(GfxState *state, const double *bbox) override;
384     void setSoftMask(GfxState *state, const double *bbox, bool alpha,
385                      Function *transferFunc, GfxColor *backdropColor) override;
386     void clearSoftMask(GfxState *state) override;
387 
388     //----- special access
389 
390     // Called to indicate that a new PDF document has been loaded.
391     void startDoc(PDFDoc *docA);
392 
393     void setPaperColor(SplashColorPtr paperColorA);
394 
isReverseVideo()395     bool isReverseVideo() {
396         return reverseVideo;
397     }
setReverseVideo(bool reverseVideoA)398     void setReverseVideo(bool reverseVideoA) {
399         reverseVideo = reverseVideoA;
400     }
401 
402     // Get the bitmap and its size.
getBitmap()403     SplashBitmap *getBitmap() {
404         return bitmap;
405     }
406     int getBitmapWidth();
407     int getBitmapHeight();
408 
409     // Returns the last rasterized bitmap, transferring ownership to the
410     // caller.
411     SplashBitmap *takeBitmap();
412 
413     // Set this flag to true to generate an upside-down bitmap (useful
414     // for Windows BMP files).
setBitmapUpsideDown(bool f)415     void setBitmapUpsideDown(bool f) {
416         bitmapUpsideDown = f;
417     }
418 
419     // Get the Splash object.
getSplash()420     Splash *getSplash() {
421         return splash;
422     }
423 
424     // Get the modified region.
425     void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax);
426 
427     // Clear the modified region.
428     void clearModRegion();
429 
getCurrentFont()430     SplashFont *getCurrentFont() {
431         return font;
432     }
433 
434     // If <skipTextA> is true, don't draw horizontal text.
435     // If <skipRotatedTextA> is true, don't draw rotated (non-horizontal) text.
setSkipText(bool skipHorizTextA,bool skipRotatedTextA)436     void setSkipText(bool skipHorizTextA, bool skipRotatedTextA)
437     {
438         skipHorizText = skipHorizTextA; skipRotatedText = skipRotatedTextA;
439     }
440 
getNestCount()441     int getNestCount() {
442         return nestCount;
443     }
444 
445 #if 1 //~tmp: turn off anti-aliasing temporarily
446     bool getVectorAntialias() override;
447     void setVectorAntialias(bool vaa) override;
448 #endif
449 
getFontAntialias()450     bool getFontAntialias() {
451         return fontAntialias;
452     }
setFontAntialias(bool anti)453     void setFontAntialias(bool anti) {
454         fontAntialias = anti;
455     }
456 
457     void setFreeTypeHinting(bool enable, bool enableSlightHinting);
458 
459 protected:
460     void doUpdateFont(GfxState *state);
461 
462 private:
463     bool univariateShadedFill(GfxState *state, SplashUnivariatePattern *pattern, double tMin, double tMax);
464 
465     void setupScreenParams(double hDPI, double vDPI);
466     SplashPattern *getColor(GfxGray gray);
467     SplashPattern *getColor(GfxRGB *rgb);
468 #ifdef SPLASH_CMYK
469     SplashPattern *getColor(GfxCMYK *cmyk);
470     SplashPattern *getColor(GfxColor *deviceN);
471 #endif
472     static void getMatteColor( SplashColorMode colorMode, GfxImageColorMap *colorMap, const GfxColor * matteColor, SplashColor splashMatteColor);
473     void setOverprintMask(GfxColorSpace *colorSpace, bool overprintFlag,
474                           int overprintMode, const GfxColor *singleColor, bool grayIndexed = false);
475     SplashPath convertPath(GfxState *state, GfxPath *path,
476                            bool dropEmptySubpaths);
477     void drawType3Glyph(GfxState *state, T3FontCache *t3Font,
478                         T3FontCacheTag *tag, unsigned char *data);
479 #ifdef USE_CMS
480     bool useIccImageSrc(void *data);
481     static void iccTransform(void *data, SplashBitmap *bitmap);
482     static bool iccImageSrc(void *data, SplashColorPtr colorLine,
483                             unsigned char *alphaLine);
484 #endif
485     static bool imageMaskSrc(void *data, SplashColorPtr line);
486     static bool imageSrc(void *data, SplashColorPtr colorLine,
487                          unsigned char *alphaLine);
488     static bool alphaImageSrc(void *data, SplashColorPtr line,
489                               unsigned char *alphaLine);
490     static bool maskedImageSrc(void *data, SplashColorPtr line,
491                                unsigned char *alphaLine);
492     static bool tilingBitmapSrc(void *data, SplashColorPtr line,
493                                 unsigned char *alphaLine);
494 
495     bool keepAlphaChannel;  // don't fill with paper color, keep alpha channel
496 
497     SplashColorMode colorMode;
498     int bitmapRowPad;
499     bool bitmapTopDown;
500     bool bitmapUpsideDown;
501     bool fontAntialias;
502     bool vectorAntialias;
503     bool overprintPreview;
504     bool enableFreeTypeHinting;
505     bool enableSlightHinting;
506     bool reverseVideo;      // reverse video mode
507     SplashColor paperColor; // paper color
508     SplashScreenParams screenParams;
509     bool skipHorizText;
510     bool skipRotatedText;
511 
512     PDFDoc *doc;        // the current document
513     XRef *xref;     // the xref of the current document
514 
515     SplashBitmap *bitmap;
516     Splash *splash;
517     SplashFontEngine *fontEngine;
518 
519     T3FontCache *       // Type 3 font cache
520         t3FontCache[splashOutT3FontCacheSize];
521     int nT3Fonts;       // number of valid entries in t3FontCache
522     T3GlyphStack *t3GlyphStack; // Type 3 glyph context stack
523 
524     SplashFont *font;   // current font
525     bool needFontUpdate;    // set when the font needs to be updated
526     SplashPath *textClipPath; // clipping path built with text object
527 
528     SplashTransparencyGroup * // transparency group stack
529         transpGroupStack;
530     int nestCount;
531 };
532 
533 #endif
534