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