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