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-2021 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 "poppler_private_export.h"
39 #include "OutputDev.h"
40 #include "GfxState.h"
41 #include "GlobalParams.h"
42 
43 class PDFDoc;
44 class Gfx8BitFont;
45 class SplashBitmap;
46 class Splash;
47 class SplashPath;
48 class SplashFontEngine;
49 class SplashFont;
50 class T3FontCache;
51 struct T3FontCacheTag;
52 struct T3GlyphStack;
53 struct SplashTransparencyGroup;
54 
55 //------------------------------------------------------------------------
56 // Splash dynamic pattern
57 //------------------------------------------------------------------------
58 
59 class SplashFunctionPattern : public SplashPattern
60 {
61 public:
62     SplashFunctionPattern(SplashColorMode colorMode, GfxState *state, GfxFunctionShading *shading);
63 
copy()64     SplashPattern *copy() const override { return new SplashFunctionPattern(colorMode, state, (GfxFunctionShading *)shading); }
65 
66     ~SplashFunctionPattern() override;
67 
testPosition(int x,int y)68     bool testPosition(int x, int y) override { return true; }
69 
isStatic()70     bool isStatic() override { return false; }
71 
72     bool getColor(int x, int y, SplashColorPtr c) override;
73 
getShading()74     virtual GfxFunctionShading *getShading() { return shading; }
75 
isCMYK()76     bool isCMYK() override { return gfxMode == csDeviceCMYK; }
77 
78 protected:
79     Matrix ictm;
80     double xMin, yMin, xMax, yMax;
81     GfxFunctionShading *shading;
82     GfxState *state;
83     SplashColorMode colorMode;
84     GfxColorSpaceMode gfxMode;
85 };
86 
87 class SplashUnivariatePattern : public SplashPattern
88 {
89 public:
90     SplashUnivariatePattern(SplashColorMode colorMode, GfxState *state, GfxUnivariateShading *shading);
91 
92     ~SplashUnivariatePattern() override;
93 
94     bool getColor(int x, int y, SplashColorPtr c) override;
95 
96     bool testPosition(int x, int y) override;
97 
isStatic()98     bool isStatic() override { return false; }
99 
100     virtual bool getParameter(double xs, double ys, double *t) = 0;
101 
getShading()102     virtual GfxUnivariateShading *getShading() { return shading; }
103 
isCMYK()104     bool isCMYK() override { return gfxMode == csDeviceCMYK; }
105 
106 protected:
107     Matrix ictm;
108     double t0, t1, dt;
109     GfxUnivariateShading *shading;
110     GfxState *state;
111     SplashColorMode colorMode;
112     GfxColorSpaceMode gfxMode;
113 };
114 
115 class SplashAxialPattern : public SplashUnivariatePattern
116 {
117 public:
118     SplashAxialPattern(SplashColorMode colorMode, GfxState *state, GfxAxialShading *shading);
119 
copy()120     SplashPattern *copy() const override { return new SplashAxialPattern(colorMode, state, (GfxAxialShading *)shading); }
121 
122     ~SplashAxialPattern() override;
123 
124     bool getParameter(double xc, double yc, double *t) override;
125 
126 private:
127     double x0, y0, x1, y1;
128     double dx, dy, mul;
129 };
130 
131 // see GfxState.h, GfxGouraudTriangleShading
132 class SplashGouraudPattern : public SplashGouraudColor
133 {
134 public:
135     SplashGouraudPattern(bool bDirectColorTranslation, GfxState *state, GfxGouraudTriangleShading *shading);
136 
copy()137     SplashPattern *copy() const override { return new SplashGouraudPattern(bDirectColorTranslation, state, shading); }
138 
139     ~SplashGouraudPattern() override;
140 
getColor(int x,int y,SplashColorPtr c)141     bool getColor(int x, int y, SplashColorPtr c) override { return false; }
142 
testPosition(int x,int y)143     bool testPosition(int x, int y) override { return false; }
144 
isStatic()145     bool isStatic() override { return false; }
146 
isCMYK()147     bool isCMYK() override { return gfxMode == csDeviceCMYK; }
148 
isParameterized()149     bool isParameterized() override { return shading->isParameterized(); }
getNTriangles()150     int getNTriangles() override { return shading->getNTriangles(); }
getParametrizedTriangle(int i,double * x0,double * y0,double * color0,double * x1,double * y1,double * color1,double * x2,double * y2,double * color2)151     void getParametrizedTriangle(int i, double *x0, double *y0, double *color0, double *x1, double *y1, double *color1, double *x2, double *y2, double *color2) override
152     {
153         shading->getTriangle(i, x0, y0, color0, x1, y1, color1, x2, y2, color2);
154     }
155 
156     void getNonParametrizedTriangle(int i, SplashColorMode mode, double *x0, double *y0, SplashColorPtr color0, double *x1, double *y1, SplashColorPtr color1, double *x2, double *y2, SplashColorPtr color2) override;
157 
158     void getParameterizedColor(double colorinterp, SplashColorMode mode, SplashColorPtr dest) override;
159 
160 private:
161     GfxGouraudTriangleShading *shading;
162     GfxState *state;
163     bool bDirectColorTranslation;
164     GfxColorSpaceMode gfxMode;
165 };
166 
167 // see GfxState.h, GfxRadialShading
168 class SplashRadialPattern : public SplashUnivariatePattern
169 {
170 public:
171     SplashRadialPattern(SplashColorMode colorMode, GfxState *state, GfxRadialShading *shading);
172 
copy()173     SplashPattern *copy() const override { return new SplashRadialPattern(colorMode, state, (GfxRadialShading *)shading); }
174 
175     ~SplashRadialPattern() override;
176 
177     bool getParameter(double xs, double ys, double *t) override;
178 
179 private:
180     double x0, y0, r0, dx, dy, dr;
181     double a, inva;
182 };
183 
184 //------------------------------------------------------------------------
185 
186 // number of Type 3 fonts to cache
187 #define splashOutT3FontCacheSize 8
188 
189 //------------------------------------------------------------------------
190 // SplashOutputDev
191 //------------------------------------------------------------------------
192 
193 class POPPLER_PRIVATE_EXPORT SplashOutputDev : public OutputDev
194 {
195 public:
196     // Constructor.
197     SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA, bool reverseVideoA, SplashColorPtr paperColorA, bool bitmapTopDownA = true, SplashThinLineMode thinLineMode = splashThinLineDefault, bool overprintPreviewA = false);
198 
199     // Destructor.
200     ~SplashOutputDev() override;
201 
202     //----- get info about output device
203 
204     // Does this device use tilingPatternFill()?  If this returns false,
205     // tiling pattern fills will be reduced to a series of other drawing
206     // operations.
useTilingPatternFill()207     bool useTilingPatternFill() override { return true; }
208 
209     // Does this device use functionShadedFill(), axialShadedFill(), and
210     // radialShadedFill()?  If this returns false, these shaded fills
211     // will be reduced to a series of other drawing operations.
useShadedFills(int type)212     bool useShadedFills(int type) override { return (type >= 1 && type <= 5) ? true : false; }
213 
214     // Does this device use upside-down coordinates?
215     // (Upside-down means (0,0) is the top left corner of the page.)
upsideDown()216     bool upsideDown() override { return bitmapTopDown; }
217 
218     // Does this device use drawChar() or drawString()?
useDrawChar()219     bool useDrawChar() override { return true; }
220 
221     // Does this device use beginType3Char/endType3Char?  Otherwise,
222     // text in Type 3 fonts will be drawn with drawChar/drawString.
interpretType3Chars()223     bool interpretType3Chars() override { return true; }
224 
225     //----- initialization and control
226 
227     // Start a page.
228     void startPage(int pageNum, GfxState *state, XRef *xref) override;
229 
230     // End a page.
231     void endPage() override;
232 
233     //----- save/restore graphics state
234     void saveState(GfxState *state) override;
235     void restoreState(GfxState *state) override;
236 
237     //----- update graphics state
238     void updateAll(GfxState *state) override;
239     void updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) override;
240     void updateLineDash(GfxState *state) override;
241     void updateFlatness(GfxState *state) override;
242     void updateLineJoin(GfxState *state) override;
243     void updateLineCap(GfxState *state) override;
244     void updateMiterLimit(GfxState *state) override;
245     void updateLineWidth(GfxState *state) override;
246     void updateStrokeAdjust(GfxState *state) override;
247     void updateFillColorSpace(GfxState *state) override;
248     void updateStrokeColorSpace(GfxState *state) override;
249     void updateFillColor(GfxState *state) override;
250     void updateStrokeColor(GfxState *state) override;
251     void updateBlendMode(GfxState *state) override;
252     void updateFillOpacity(GfxState *state) override;
253     void updateStrokeOpacity(GfxState *state) override;
254     void updatePatternOpacity(GfxState *state) override;
255     void clearPatternOpacity(GfxState *state) override;
256     void updateFillOverprint(GfxState *state) override;
257     void updateStrokeOverprint(GfxState *state) override;
258     void updateOverprintMode(GfxState *state) override;
259     void updateTransfer(GfxState *state) override;
260 
261     //----- update text state
262     void updateFont(GfxState *state) override;
263 
264     //----- path painting
265     void stroke(GfxState *state) override;
266     void fill(GfxState *state) override;
267     void eoFill(GfxState *state) override;
268     bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *catalog, GfxTilingPattern *tPat, const double *mat, int x0, int y0, int x1, int y1, double xStep, double yStep) override;
269     bool functionShadedFill(GfxState *state, GfxFunctionShading *shading) override;
270     bool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) override;
271     bool radialShadedFill(GfxState *state, GfxRadialShading *shading, double tMin, double tMax) override;
272     bool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading) override;
273 
274     //----- path clipping
275     void clip(GfxState *state) override;
276     void eoClip(GfxState *state) override;
277     void clipToStrokePath(GfxState *state) override;
278 
279     //----- text drawing
280     void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, const Unicode *u, int uLen) override;
281     bool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, const Unicode *u, int uLen) override;
282     void endType3Char(GfxState *state) override;
283     void beginTextObject(GfxState *state) override;
284     void endTextObject(GfxState *state) override;
285 
286     //----- image drawing
287     void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg) override;
288     void setSoftMaskFromImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool inlineImg, double *baseMatrix) override;
289     void unsetSoftMaskFromImageMask(GfxState *state, double *baseMatrix) override;
290     void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg) override;
291     void drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, bool maskInvert, bool maskInterpolate) override;
292     void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap,
293                              bool maskInterpolate) override;
294 
295     //----- Type 3 font operators
296     void type3D0(GfxState *state, double wx, double wy) override;
297     void type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury) override;
298 
299     //----- transparency groups and soft masks
300     bool checkTransparencyGroup(GfxState *state, bool knockout) override;
301     void beginTransparencyGroup(GfxState *state, const double *bbox, GfxColorSpace *blendingColorSpace, bool isolated, bool knockout, bool forSoftMask) override;
302     void endTransparencyGroup(GfxState *state) override;
303     void paintTransparencyGroup(GfxState *state, const double *bbox) override;
304     void setSoftMask(GfxState *state, const double *bbox, bool alpha, Function *transferFunc, GfxColor *backdropColor) override;
305     void clearSoftMask(GfxState *state) override;
306 
307     //----- special access
308 
309     // Called to indicate that a new PDF document has been loaded.
310     void startDoc(PDFDoc *docA);
311 
312     void setPaperColor(SplashColorPtr paperColorA);
313 
isReverseVideo()314     bool isReverseVideo() { return reverseVideo; }
setReverseVideo(bool reverseVideoA)315     void setReverseVideo(bool reverseVideoA) { reverseVideo = reverseVideoA; }
316 
317     // Get the bitmap and its size.
getBitmap()318     SplashBitmap *getBitmap() { return bitmap; }
319     int getBitmapWidth();
320     int getBitmapHeight();
321 
322     // Returns the last rasterized bitmap, transferring ownership to the
323     // caller.
324     SplashBitmap *takeBitmap();
325 
326     // Get the Splash object.
getSplash()327     Splash *getSplash() { return splash; }
328 
getCurrentFont()329     SplashFont *getCurrentFont() { return font; }
330 
331     // If <skipTextA> is true, don't draw horizontal text.
332     // If <skipRotatedTextA> is true, don't draw rotated (non-horizontal) text.
setSkipText(bool skipHorizTextA,bool skipRotatedTextA)333     void setSkipText(bool skipHorizTextA, bool skipRotatedTextA)
334     {
335         skipHorizText = skipHorizTextA;
336         skipRotatedText = skipRotatedTextA;
337     }
338 
339 #if 1 //~tmp: turn off anti-aliasing temporarily
340     bool getVectorAntialias() override;
341     void setVectorAntialias(bool vaa) override;
342 #endif
343 
getFontAntialias()344     bool getFontAntialias() { return fontAntialias; }
setFontAntialias(bool anti)345     void setFontAntialias(bool anti) { fontAntialias = anti; }
346 
347     void setFreeTypeHinting(bool enable, bool enableSlightHinting);
setEnableFreeType(bool enable)348     void setEnableFreeType(bool enable) { enableFreeType = enable; }
349 
350 protected:
351     void doUpdateFont(GfxState *state);
352 
353 private:
354     bool univariateShadedFill(GfxState *state, SplashUnivariatePattern *pattern, double tMin, double tMax);
355 
356     void setupScreenParams(double hDPI, double vDPI);
357     SplashPattern *getColor(GfxGray gray);
358     SplashPattern *getColor(GfxRGB *rgb);
359     SplashPattern *getColor(GfxCMYK *cmyk);
360     SplashPattern *getColor(GfxColor *deviceN);
361     static void getMatteColor(SplashColorMode colorMode, GfxImageColorMap *colorMap, const GfxColor *matteColor, SplashColor splashMatteColor);
362     void setOverprintMask(GfxColorSpace *colorSpace, bool overprintFlag, int overprintMode, const GfxColor *singleColor, bool grayIndexed = false);
363     SplashPath convertPath(GfxState *state, const GfxPath *path, bool dropEmptySubpaths);
364     void drawType3Glyph(GfxState *state, T3FontCache *t3Font, T3FontCacheTag *tag, unsigned char *data);
365 #ifdef USE_CMS
366     bool useIccImageSrc(void *data);
367     static void iccTransform(void *data, SplashBitmap *bitmap);
368     static bool iccImageSrc(void *data, SplashColorPtr colorLine, unsigned char *alphaLine);
369 #endif
370     static bool imageMaskSrc(void *data, SplashColorPtr line);
371     static bool imageSrc(void *data, SplashColorPtr colorLine, unsigned char *alphaLine);
372     static bool alphaImageSrc(void *data, SplashColorPtr line, unsigned char *alphaLine);
373     static bool maskedImageSrc(void *data, SplashColorPtr line, unsigned char *alphaLine);
374     static bool tilingBitmapSrc(void *data, SplashColorPtr line, unsigned char *alphaLine);
375 
376     bool keepAlphaChannel; // don't fill with paper color, keep alpha channel
377 
378     SplashColorMode colorMode;
379     int bitmapRowPad;
380     bool bitmapTopDown;
381     bool fontAntialias;
382     bool vectorAntialias;
383     bool overprintPreview;
384     bool enableFreeType;
385     bool enableFreeTypeHinting;
386     bool enableSlightHinting;
387     bool reverseVideo; // reverse video mode
388     SplashColor paperColor; // paper color
389     SplashScreenParams screenParams;
390     bool skipHorizText;
391     bool skipRotatedText;
392 
393     PDFDoc *doc; // the current document
394     XRef *xref; // the xref of the current document
395 
396     SplashBitmap *bitmap;
397     Splash *splash;
398     SplashFontEngine *fontEngine;
399 
400     T3FontCache * // Type 3 font cache
401             t3FontCache[splashOutT3FontCacheSize];
402     int nT3Fonts; // number of valid entries in t3FontCache
403     T3GlyphStack *t3GlyphStack; // Type 3 glyph context stack
404 
405     SplashFont *font; // current font
406     bool needFontUpdate; // set when the font needs to be updated
407     SplashPath *textClipPath; // clipping path built with text object
408 
409     SplashTransparencyGroup * // transparency group stack
410             transpGroupStack;
411 };
412 
413 #endif
414