1 //======================================================================== 2 // 3 // Splash.h 4 // 5 // Copyright 2003-2013 Glyph & Cog, LLC 6 // 7 //======================================================================== 8 9 #ifndef SPLASH_H 10 #define SPLASH_H 11 12 #include <aconf.h> 13 14 #ifdef USE_GCC_PRAGMAS 15 #pragma interface 16 #endif 17 18 #include "SplashTypes.h" 19 #include "SplashClip.h" 20 21 class GString; 22 class Splash; 23 class SplashBitmap; 24 struct SplashGlyphBitmap; 25 class SplashState; 26 class SplashPattern; 27 class SplashScreen; 28 class SplashPath; 29 class SplashXPath; 30 class SplashFont; 31 struct SplashPipe; 32 struct SplashDrawImageMaskRowData; 33 class ImageScaler; 34 typedef void (Splash::*SplashDrawImageMaskRowFunc)( 35 SplashDrawImageMaskRowData *data, 36 Guchar *maskData, 37 int x, int y, int width); 38 struct SplashDrawImageRowData; 39 typedef void (Splash::*SplashDrawImageRowFunc)(SplashDrawImageRowData *data, 40 Guchar *colorData, 41 Guchar *alphaData, 42 int x, int y, int width); 43 44 //------------------------------------------------------------------------ 45 46 // Retrieves the next line of pixels in an image mask. Normally, 47 // fills in *<line> and returns true. If the image stream is 48 // exhausted, returns false. 49 typedef GBool (*SplashImageMaskSource)(void *data, Guchar *pixel); 50 51 // Retrieves the next line of pixels in an image. Normally, fills in 52 // *<line> and returns true. If the image stream is exhausted, 53 // returns false. 54 typedef GBool (*SplashImageSource)(void *data, SplashColorPtr colorLine, 55 Guchar *alphaLine); 56 57 58 //------------------------------------------------------------------------ 59 60 enum SplashPipeResultColorCtrl { 61 splashPipeResultColorNoAlphaBlendMono, 62 splashPipeResultColorNoAlphaBlendRGB, 63 #if SPLASH_CMYK 64 splashPipeResultColorNoAlphaBlendCMYK, 65 #endif 66 splashPipeResultColorAlphaNoBlendMono, 67 splashPipeResultColorAlphaNoBlendRGB, 68 #if SPLASH_CMYK 69 splashPipeResultColorAlphaNoBlendCMYK, 70 #endif 71 splashPipeResultColorAlphaBlendMono, 72 splashPipeResultColorAlphaBlendRGB 73 #if SPLASH_CMYK 74 , 75 splashPipeResultColorAlphaBlendCMYK 76 #endif 77 }; 78 79 //------------------------------------------------------------------------ 80 81 // Transparency group destination bitmap initialization control. 82 enum SplashGroupDestInitMode { 83 splashGroupDestPreInit, // dest is already initialized 84 splashGroupDestInitZero, // initialize to zero (isolated group) 85 splashGroupDestInitCopy // copy backdrop (non-isolated group) 86 }; 87 88 //------------------------------------------------------------------------ 89 // SplashImageCache 90 //------------------------------------------------------------------------ 91 92 // This holds a cached image, and is shared by multiple Splash objects 93 // in the same thread. 94 class SplashImageCache { 95 public: 96 97 SplashImageCache(); 98 ~SplashImageCache(); 99 GBool match(GString *aTag, int aWidth, int aHeight, 100 SplashColorMode aMode, GBool aAlpha, 101 GBool aInterpolate); 102 void reset(GString *aTag, int aWidth, int aHeight, 103 SplashColorMode aMode, GBool aAlpha, 104 GBool aInterpolate); 105 void incRefCount(); 106 void decRefCount(); 107 108 GString *tag; 109 int width; 110 int height; 111 SplashColorMode mode; 112 GBool alpha; 113 GBool interpolate; 114 Guchar *colorData; 115 Guchar *alphaData; 116 117 int refCount; 118 }; 119 120 //------------------------------------------------------------------------ 121 // Splash 122 //------------------------------------------------------------------------ 123 124 class Splash { 125 public: 126 127 // Create a new rasterizer object. 128 Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA, 129 SplashImageCache *imageCacheA, 130 SplashScreenParams *screenParams = NULL); 131 Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA, 132 SplashImageCache *imageCacheA, SplashScreen *screenA); 133 134 ~Splash(); 135 136 //----- state read 137 138 SplashCoord *getMatrix(); 139 SplashPattern *getStrokePattern(); 140 SplashPattern *getFillPattern(); 141 SplashScreen *getScreen(); 142 SplashBlendFunc getBlendFunc(); 143 SplashCoord getStrokeAlpha(); 144 SplashCoord getFillAlpha(); 145 SplashCoord getLineWidth(); 146 int getLineCap(); 147 int getLineJoin(); 148 SplashCoord getMiterLimit(); 149 SplashCoord getFlatness(); 150 SplashCoord *getLineDash(); 151 int getLineDashLength(); 152 SplashCoord getLineDashPhase(); 153 SplashStrokeAdjustMode getStrokeAdjust(); 154 SplashClip *getClip(); 155 SplashBitmap *getSoftMask(); 156 GBool getInNonIsolatedGroup(); 157 GBool getInKnockoutGroup(); 158 159 //----- state write 160 161 void setMatrix(SplashCoord *matrix); 162 void setStrokePattern(SplashPattern *strokeColor); 163 void setFillPattern(SplashPattern *fillColor); 164 void setScreen(SplashScreen *screen); 165 void setBlendFunc(SplashBlendFunc func); 166 void setStrokeAlpha(SplashCoord alpha); 167 void setFillAlpha(SplashCoord alpha); 168 void setLineWidth(SplashCoord lineWidth); 169 void setLineCap(int lineCap); 170 void setLineJoin(int lineJoin); 171 void setMiterLimit(SplashCoord miterLimit); 172 void setFlatness(SplashCoord flatness); 173 // the <lineDash> array will be copied 174 void setLineDash(SplashCoord *lineDash, int lineDashLength, 175 SplashCoord lineDashPhase); 176 void setStrokeAdjust(SplashStrokeAdjustMode strokeAdjust); 177 // NB: uses transformed coordinates. 178 void clipResetToRect(SplashCoord x0, SplashCoord y0, 179 SplashCoord x1, SplashCoord y1); 180 // NB: uses transformed coordinates. 181 SplashError clipToRect(SplashCoord x0, SplashCoord y0, 182 SplashCoord x1, SplashCoord y1); 183 // NB: uses untransformed coordinates. 184 SplashError clipToPath(SplashPath *path, GBool eo); 185 void setSoftMask(SplashBitmap *softMask); 186 void setInTransparencyGroup(SplashBitmap *groupBackBitmapA, 187 int groupBackXA, int groupBackYA, 188 SplashGroupDestInitMode groupDestInitModeA, 189 GBool nonIsolated, GBool knockout); 190 void forceDeferredInit(int y, int h); 191 void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray); 192 void setOverprintMask(Guint overprintMask); 193 void setEnablePathSimplification(GBool en); 194 195 //----- state save/restore 196 197 void saveState(); 198 SplashError restoreState(); 199 200 //----- drawing operations 201 202 // Fill the bitmap with <color>. This is not subject to clipping. 203 void clear(SplashColorPtr color, Guchar alpha = 0x00); 204 205 // Stroke a path using the current stroke pattern. 206 SplashError stroke(SplashPath *path); 207 208 // Fill a path using the current fill pattern. 209 SplashError fill(SplashPath *path, GBool eo); 210 211 // Draw a character, using the current fill pattern. 212 SplashError fillChar(SplashCoord x, SplashCoord y, int c, SplashFont *font); 213 214 // Draw a glyph, using the current fill pattern. This function does 215 // not free any data, i.e., it ignores glyph->freeData. 216 SplashError fillGlyph(SplashCoord x, SplashCoord y, 217 SplashGlyphBitmap *glyph); 218 219 // Draws an image mask using the fill color. This will read <h> 220 // lines of <w> pixels from <src>, starting with the top line. "1" 221 // pixels will be drawn with the current fill color; "0" pixels are 222 // transparent. The matrix: 223 // [ mat[0] mat[1] 0 ] 224 // [ mat[2] mat[3] 0 ] 225 // [ mat[4] mat[5] 1 ] 226 // maps a unit square to the desired destination for the image, in 227 // PostScript style: 228 // [x' y' 1] = [x y 1] * mat 229 // Note that the Splash y axis points downward, and the image source 230 // is assumed to produce pixels in raster order, starting from the 231 // top line. 232 SplashError fillImageMask(GString *imageTag, 233 SplashImageMaskSource src, void *srcData, 234 int w, int h, SplashCoord *mat, 235 GBool glyphMode, GBool interpolate); 236 237 // Draw an image. This will read <h> lines of <w> pixels from 238 // <src>, starting with the top line. These pixels are assumed to 239 // be in the source mode, <srcMode>. If <srcAlpha> is true, the 240 // alpha values returned by <src> are used; otherwise they are 241 // ignored. The following combinations of source and target modes 242 // are supported: 243 // source target 244 // ------ ------ 245 // Mono8 Mono1 -- with dithering 246 // Mono8 Mono8 247 // RGB8 RGB8 248 // BGR8 RGB8 249 // CMYK8 CMYK8 250 // The matrix behaves as for fillImageMask. 251 SplashError drawImage(GString *imageTag, 252 SplashImageSource src, void *srcData, 253 SplashColorMode srcMode, GBool srcAlpha, 254 int w, int h, SplashCoord *mat, 255 GBool interpolate); 256 257 // Composite a rectangular region from <src> onto this Splash 258 // object. 259 SplashError composite(SplashBitmap *src, int xSrc, int ySrc, 260 int xDest, int yDest, int w, int h, 261 GBool noClip, GBool nonIsolated); 262 263 // Composite a rectangular region from <src> onto this Splash 264 // object, using <srcOverprintMaskBitmap> as the overprint mask per 265 // pixel. This is only supported for CMYK and DeviceN bitmaps. 266 SplashError compositeWithOverprint(SplashBitmap *src, 267 Guint *srcOverprintMaskBitmap, 268 int xSrc, int ySrc, 269 int xDest, int yDest, int w, int h, 270 GBool noClip, GBool nonIsolated); 271 272 // Composite this Splash object onto a background color. The 273 // background alpha is assumed to be 1. 274 void compositeBackground(SplashColorPtr color); 275 276 // Copy a rectangular region from <src> onto the bitmap belonging to 277 // this Splash object. The destination alpha values are all set to 278 // zero. 279 SplashError blitTransparent(SplashBitmap *src, int xSrc, int ySrc, 280 int xDest, int yDest, int w, int h); 281 282 // Copy a rectangular region from the bitmap belonging to this 283 // Splash object to <dest>. The alpha values are corrected for a 284 // non-isolated group. 285 SplashError blitCorrectedAlpha(SplashBitmap *dest, int xSrc, int ySrc, 286 int xDest, int yDest, int w, int h); 287 288 //----- misc 289 290 // Construct a path for a stroke, given the path to be stroked and 291 // the line width <w>. All other stroke parameters are taken from 292 // the current state. If <flatten> is true, this function will 293 // first flatten the path and handle the linedash. 294 SplashPath *makeStrokePath(SplashPath *path, SplashCoord w, 295 int lineCap, int lineJoin, 296 GBool flatten = gTrue); 297 298 // Reduce the size of a rectangle as much as possible by moving any 299 // edges that are completely outside the clip region. Returns the 300 // clipping status of the resulting rectangle. 301 SplashClipResult limitRectToClipRect(int *xMin, int *yMin, 302 int *xMax, int *yMax); 303 304 // Return the associated bitmap. getBitmap()305 SplashBitmap *getBitmap() { return bitmap; } 306 307 // Enable writing the per-pixel overprint mask to a separate bitmap. setOverprintMaskBitmap(Guint * overprintMaskBitmapA)308 void setOverprintMaskBitmap(Guint *overprintMaskBitmapA) 309 { overprintMaskBitmap = overprintMaskBitmapA; } 310 311 // Set the minimum line width. setMinLineWidth(SplashCoord w)312 void setMinLineWidth(SplashCoord w) { minLineWidth = w; } 313 314 // Get a bounding box which includes all modifications since the 315 // last call to clearModRegion. getModRegion(int * xMin,int * yMin,int * xMax,int * yMax)316 void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax) 317 { *xMin = modXMin; *yMin = modYMin; *xMax = modXMax; *yMax = modYMax; } 318 319 // Clear the modified region bounding box. 320 void clearModRegion(); 321 322 // Get clipping status for the last drawing operation subject to 323 // clipping. getClipRes()324 SplashClipResult getClipRes() { return opClipRes; } 325 326 // Toggle debug mode on or off. setDebugMode(GBool debugModeA)327 void setDebugMode(GBool debugModeA) { debugMode = debugModeA; } 328 getImageCache()329 SplashImageCache *getImageCache() { return imageCache; } 330 331 #if 1 //~tmp: turn off anti-aliasing temporarily setInShading(GBool sh)332 void setInShading(GBool sh) { inShading = sh; } 333 #endif 334 335 336 private: 337 338 void pipeInit(SplashPipe *pipe, SplashPattern *pattern, 339 Guchar aInput, GBool usesShape, 340 GBool nonIsolatedGroup, GBool usesSrcOverprint = gFalse); 341 void pipeRun(SplashPipe *pipe, int x0, int x1, int y, 342 Guchar *shapePtr, SplashColorPtr cSrcPtr); 343 void pipeRunSimpleMono1(SplashPipe *pipe, int x0, int x1, int y, 344 Guchar *shapePtr, SplashColorPtr cSrcPtr); 345 void pipeRunSimpleMono8(SplashPipe *pipe, int x0, int x1, int y, 346 Guchar *shapePtr, SplashColorPtr cSrcPtr); 347 void pipeRunSimpleRGB8(SplashPipe *pipe, int x0, int x1, int y, 348 Guchar *shapePtr, SplashColorPtr cSrcPtr); 349 void pipeRunSimpleBGR8(SplashPipe *pipe, int x0, int x1, int y, 350 Guchar *shapePtr, SplashColorPtr cSrcPtr); 351 #if SPLASH_CMYK 352 void pipeRunSimpleCMYK8(SplashPipe *pipe, int x0, int x1, int y, 353 Guchar *shapePtr, SplashColorPtr cSrcPtr); 354 #endif 355 void pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y, 356 Guchar *shapePtr, SplashColorPtr cSrcPtr); 357 void pipeRunShapeMono8(SplashPipe *pipe, int x0, int x1, int y, 358 Guchar *shapePtr, SplashColorPtr cSrcPtr); 359 void pipeRunShapeRGB8(SplashPipe *pipe, int x0, int x1, int y, 360 Guchar *shapePtr, SplashColorPtr cSrcPtr); 361 void pipeRunShapeBGR8(SplashPipe *pipe, int x0, int x1, int y, 362 Guchar *shapePtr, SplashColorPtr cSrcPtr); 363 #if SPLASH_CMYK 364 void pipeRunShapeCMYK8(SplashPipe *pipe, int x0, int x1, int y, 365 Guchar *shapePtr, SplashColorPtr cSrcPtr); 366 #endif 367 void pipeRunShapeNoAlphaMono8(SplashPipe *pipe, int x0, int x1, int y, 368 Guchar *shapePtr, SplashColorPtr cSrcPtr); 369 void pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y, 370 Guchar *shapePtr, SplashColorPtr cSrcPtr); 371 void pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y, 372 Guchar *shapePtr, SplashColorPtr cSrcPtr); 373 void pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y, 374 Guchar *shapePtr, SplashColorPtr cSrcPtr); 375 void pipeRunAABGR8(SplashPipe *pipe, int x0, int x1, int y, 376 Guchar *shapePtr, SplashColorPtr cSrcPtr); 377 #if SPLASH_CMYK 378 void pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y, 379 Guchar *shapePtr, SplashColorPtr cSrcPtr); 380 #endif 381 void pipeRunSoftMaskMono8(SplashPipe *pipe, int x0, int x1, int y, 382 Guchar *shapePtr, SplashColorPtr cSrcPtr); 383 void pipeRunSoftMaskRGB8(SplashPipe *pipe, int x0, int x1, int y, 384 Guchar *shapePtr, SplashColorPtr cSrcPtr); 385 void pipeRunSoftMaskBGR8(SplashPipe *pipe, int x0, int x1, int y, 386 Guchar *shapePtr, SplashColorPtr cSrcPtr); 387 #if SPLASH_CMYK 388 void pipeRunSoftMaskCMYK8(SplashPipe *pipe, int x0, int x1, int y, 389 Guchar *shapePtr, SplashColorPtr cSrcPtr); 390 #endif 391 void pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y, 392 Guchar *shapePtr, SplashColorPtr cSrcPtr); 393 void pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y, 394 Guchar *shapePtr, SplashColorPtr cSrcPtr); 395 void pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y, 396 Guchar *shapePtr, SplashColorPtr cSrcPtr); 397 #if SPLASH_CMYK 398 void pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y, 399 Guchar *shapePtr, SplashColorPtr cSrcPtr); 400 #endif 401 void useDestRow(int y); 402 void copyGroupBackdropRow(int y); 403 void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi, 404 SplashCoord *xo, SplashCoord *yo); 405 void updateModX(int x); 406 void updateModY(int y); 407 void strokeNarrow(SplashPath *path); 408 void drawStrokeSpan(SplashPipe *pipe, int x0, int x1, int y, GBool noClip); 409 void strokeWide(SplashPath *path, SplashCoord w, 410 int lineCap, int lineJoin); 411 SplashPath *flattenPath(SplashPath *path, SplashCoord *matrix, 412 SplashCoord flatness); 413 void flattenCurve(SplashCoord x0, SplashCoord y0, 414 SplashCoord x1, SplashCoord y1, 415 SplashCoord x2, SplashCoord y2, 416 SplashCoord x3, SplashCoord y3, 417 SplashCoord *matrix, SplashCoord flatness2, 418 SplashPath *fPath); 419 SplashPath *makeDashedPath(SplashPath *xPath); 420 SplashError fillWithPattern(SplashPath *path, GBool eo, 421 SplashPattern *pattern, SplashCoord alpha); 422 SplashPath *tweakFillPath(SplashPath *path); 423 GBool pathAllOutside(SplashPath *path); 424 SplashError fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph); 425 void getImageBounds(SplashCoord xyMin, SplashCoord xyMax, 426 int *xyMinI, int *xyMaxI); 427 void drawImageMaskArbitraryNoInterp(Guchar *scaledMask, 428 SplashDrawImageMaskRowData *dd, 429 SplashDrawImageMaskRowFunc drawRowFunc, 430 SplashCoord *invMat, 431 int scaledWidth, int scaledHeight, 432 int xMin, int yMin, int xMax, int yMax); 433 void drawImageMaskArbitraryInterp(Guchar *scaledMask, 434 SplashDrawImageMaskRowData *dd, 435 SplashDrawImageMaskRowFunc drawRowFunc, 436 SplashCoord *invMat, 437 int scaledWidth, int scaledHeight, 438 int xMin, int yMin, int xMax, int yMax); 439 void mirrorImageMaskRow(Guchar *maskIn, Guchar *maskOut, int width); 440 void drawImageMaskRowNoClip(SplashDrawImageMaskRowData *data, 441 Guchar *maskData, 442 int x, int y, int width); 443 void drawImageMaskRowClipNoAA(SplashDrawImageMaskRowData *data, 444 Guchar *maskData, 445 int x, int y, int width); 446 void drawImageMaskRowClipAA(SplashDrawImageMaskRowData *data, 447 Guchar *maskData, 448 int x, int y, int width); 449 ImageScaler *getImageScaler(GString *imageTag, 450 SplashImageSource src, void *srcData, 451 int w, int h, int nComps, 452 int scaledWidth, int scaledHeight, 453 SplashColorMode srcMode, 454 GBool srcAlpha, GBool interpolate); 455 void getScaledImage(GString *imageTag, 456 SplashImageSource src, void *srcData, 457 int w, int h, int nComps, 458 int scaledWidth, int scaledHeight, 459 SplashColorMode srcMode, 460 GBool srcAlpha, GBool interpolate, 461 Guchar **scaledColor, Guchar **scaledAlpha, 462 GBool *freeScaledImage); 463 void drawImageArbitraryNoInterp(Guchar *scaledColor, Guchar *scaledAlpha, 464 SplashDrawImageRowData *dd, 465 SplashDrawImageRowFunc drawRowFunc, 466 SplashCoord *invMat, 467 int scaledWidth, int scaledHeight, 468 int xMin, int yMin, int xMax, int yMax, 469 int nComps, GBool srcAlpha); 470 void drawImageArbitraryInterp(Guchar *scaledColor, Guchar *scaledAlpha, 471 SplashDrawImageRowData *dd, 472 SplashDrawImageRowFunc drawRowFunc, 473 SplashCoord *invMat, 474 int scaledWidth, int scaledHeight, 475 int xMin, int yMin, int xMax, int yMax, 476 int nComps, GBool srcAlpha); 477 void mirrorImageRow(Guchar *colorIn, Guchar *alphaIn, 478 Guchar *colorOut, Guchar *alphaOut, 479 int width, int nComps, GBool srcAlpha); 480 void drawImageRowNoClipNoAlpha(SplashDrawImageRowData *data, 481 Guchar *colorData, Guchar *alphaData, 482 int x, int y, int width); 483 void drawImageRowNoClipAlpha(SplashDrawImageRowData *data, 484 Guchar *colorData, Guchar *alphaData, 485 int x, int y, int width); 486 void drawImageRowClipNoAlphaNoAA(SplashDrawImageRowData *data, 487 Guchar *colorData, 488 Guchar *alphaData, 489 int x, int y, int width); 490 void drawImageRowClipNoAlphaAA(SplashDrawImageRowData *data, 491 Guchar *colorData, 492 Guchar *alphaData, 493 int x, int y, int width); 494 void drawImageRowClipAlphaNoAA(SplashDrawImageRowData *data, 495 Guchar *colorData, 496 Guchar *alphaData, 497 int x, int y, int width); 498 void drawImageRowClipAlphaAA(SplashDrawImageRowData *data, 499 Guchar *colorData, 500 Guchar *alphaData, 501 int x, int y, int width); 502 void dumpPath(SplashPath *path); 503 void dumpXPath(SplashXPath *path); 504 505 506 static SplashPipeResultColorCtrl pipeResultColorNoAlphaBlend[]; 507 static SplashPipeResultColorCtrl pipeResultColorAlphaNoBlend[]; 508 static SplashPipeResultColorCtrl pipeResultColorAlphaBlend[]; 509 static int pipeNonIsoGroupCorrection[]; 510 511 SplashBitmap *bitmap; 512 int bitmapComps; 513 SplashState *state; 514 Guchar *scanBuf; 515 Guchar *scanBuf2; 516 SplashBitmap // for transparency groups, this is the bitmap 517 *groupBackBitmap; // containing the alpha0/color0 values 518 int groupBackX, groupBackY; // offset within groupBackBitmap 519 SplashGroupDestInitMode groupDestInitMode; 520 int groupDestInitYMin, groupDestInitYMax; 521 Guint *overprintMaskBitmap; 522 SplashCoord minLineWidth; 523 int modXMin, modYMin, modXMax, modYMax; 524 SplashClipResult opClipRes; 525 GBool vectorAntialias; 526 GBool inShading; 527 GBool debugMode; 528 529 SplashImageCache *imageCache; 530 }; 531 532 #endif 533