1 //======================================================================== 2 // 3 // CairoOutputDev.h 4 // 5 // Copyright 2003 Glyph & Cog, LLC 6 // Copyright 2004 Red Hat, INC 7 // 8 //======================================================================== 9 10 //======================================================================== 11 // 12 // Modified under the Poppler project - http://poppler.freedesktop.org 13 // 14 // All changes made under the Poppler project to this file are licensed 15 // under GPL version 2 or later 16 // 17 // Copyright (C) 2005-2008 Jeff Muizelaar <jeff@infidigm.net> 18 // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com> 19 // Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru> 20 // Copyright (C) 2006-2011, 2013 Carlos Garcia Campos <carlosgc@gnome.org> 21 // Copyright (C) 2008, 2009, 2011-2015 Adrian Johnson <ajohnson@redneon.com> 22 // Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu> 23 // Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag@alfa.de> 24 // Copyright (C) 2015 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp> 25 // Copyright (C) 2016 Jason Crain <jason@aquaticape.us> 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 CAIROOUTPUTDEV_H 33 #define CAIROOUTPUTDEV_H 34 35 #ifdef USE_GCC_PRAGMAS 36 #pragma interface 37 #endif 38 39 #include "goo/gtypes.h" 40 #include <cairo-ft.h> 41 #include "OutputDev.h" 42 #include "TextOutputDev.h" 43 #include "GfxState.h" 44 45 class PDFDoc; 46 class GfxState; 47 class GfxPath; 48 class Gfx8BitFont; 49 struct GfxRGB; 50 class CairoFontEngine; 51 class CairoFont; 52 53 //------------------------------------------------------------------------ 54 55 //------------------------------------------------------------------------ 56 // CairoImage 57 //------------------------------------------------------------------------ 58 class CairoImage { 59 public: 60 // Constructor. 61 CairoImage (double x1, double y1, double x2, double y2); 62 63 // Destructor. 64 ~CairoImage (); 65 66 // Set the image cairo surface 67 void setImage (cairo_surface_t *image); 68 69 // Get the image cairo surface getImage()70 cairo_surface_t *getImage () const { return image; } 71 72 // Get the image rectangle getRect(double * xa1,double * ya1,double * xa2,double * ya2)73 void getRect (double *xa1, double *ya1, double *xa2, double *ya2) 74 { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; } 75 76 private: 77 cairo_surface_t *image; // image cairo surface 78 double x1, y1; // upper left corner 79 double x2, y2; // lower right corner 80 }; 81 82 83 //------------------------------------------------------------------------ 84 // CairoOutputDev 85 //------------------------------------------------------------------------ 86 87 class CairoOutputDev: public OutputDev { 88 public: 89 90 // Constructor. 91 CairoOutputDev(); 92 93 // Destructor. 94 virtual ~CairoOutputDev(); 95 96 //----- get info about output device 97 98 // Does this device use upside-down coordinates? 99 // (Upside-down means (0,0) is the top left corner of the page.) upsideDown()100 virtual GBool upsideDown() { return gTrue; } 101 102 // Does this device use drawChar() or drawString()? useDrawChar()103 virtual GBool useDrawChar() { return gTrue; } 104 105 // Does this device use tilingPatternFill()? If this returns false, 106 // tiling pattern fills will be reduced to a series of other drawing 107 // operations. useTilingPatternFill()108 virtual GBool useTilingPatternFill() { return gTrue; } 109 110 // Does this device use functionShadedFill(), axialShadedFill(), and 111 // radialShadedFill()? If this returns false, these shaded fills 112 // will be reduced to a series of other drawing operations. 113 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0) useShadedFills(int type)114 virtual GBool useShadedFills(int type) { return type <= 7; } 115 #else useShadedFills(int type)116 virtual GBool useShadedFills(int type) { return type > 1 && type < 4; } 117 #endif 118 119 // Does this device use FillColorStop()? useFillColorStop()120 virtual GBool useFillColorStop() { return gTrue; } 121 122 // Does this device use beginType3Char/endType3Char? Otherwise, 123 // text in Type 3 fonts will be drawn with drawChar/drawString. interpretType3Chars()124 virtual GBool interpretType3Chars() { return gFalse; } 125 126 // Does this device need to clip pages to the crop box even when the 127 // box is the crop box? needClipToCropBox()128 virtual GBool needClipToCropBox() { return gTrue; } 129 130 //----- initialization and control 131 132 // Start a page. 133 virtual void startPage(int pageNum, GfxState *state, XRef *xref); 134 135 // End a page. 136 virtual void endPage(); 137 138 //----- save/restore graphics state 139 virtual void saveState(GfxState *state); 140 virtual void restoreState(GfxState *state); 141 142 //----- update graphics state 143 virtual void updateAll(GfxState *state); 144 virtual void setDefaultCTM(double *ctm); 145 virtual void updateCTM(GfxState *state, double m11, double m12, 146 double m21, double m22, double m31, double m32); 147 virtual void updateLineDash(GfxState *state); 148 virtual void updateFlatness(GfxState *state); 149 virtual void updateLineJoin(GfxState *state); 150 virtual void updateLineCap(GfxState *state); 151 virtual void updateMiterLimit(GfxState *state); 152 virtual void updateLineWidth(GfxState *state); 153 virtual void updateFillColor(GfxState *state); 154 virtual void updateStrokeColor(GfxState *state); 155 virtual void updateFillOpacity(GfxState *state); 156 virtual void updateStrokeOpacity(GfxState *state); 157 virtual void updateFillColorStop(GfxState *state, double offset); 158 virtual void updateBlendMode(GfxState *state); 159 160 //----- update text state 161 virtual void updateFont(GfxState *state); 162 163 //----- path painting 164 virtual void stroke(GfxState *state); 165 virtual void fill(GfxState *state); 166 virtual void eoFill(GfxState *state); 167 virtual void clipToStrokePath(GfxState *state); 168 virtual GBool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str, 169 double *pmat, int paintType, int tilingType, Dict *resDict, 170 double *mat, double *bbox, 171 int x0, int y0, int x1, int y1, 172 double xStep, double yStep); 173 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0) 174 virtual GBool functionShadedFill(GfxState *state, GfxFunctionShading *shading); 175 #endif 176 virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax); 177 virtual GBool axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading); 178 virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax); 179 virtual GBool radialShadedSupportExtend(GfxState *state, GfxRadialShading *shading); 180 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0) 181 virtual GBool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading); 182 virtual GBool patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading); 183 #endif 184 185 //----- path clipping 186 virtual void clip(GfxState *state); 187 virtual void eoClip(GfxState *state); 188 189 //----- text drawing 190 void beginString(GfxState *state, GooString *s); 191 void endString(GfxState *state); 192 void drawChar(GfxState *state, double x, double y, 193 double dx, double dy, 194 double originX, double originY, 195 CharCode code, int nBytes, Unicode *u, int uLen); 196 void beginActualText(GfxState *state, GooString *text); 197 void endActualText(GfxState *state); 198 199 virtual GBool beginType3Char(GfxState *state, double x, double y, 200 double dx, double dy, 201 CharCode code, Unicode *u, int uLen); 202 virtual void endType3Char(GfxState *state); 203 virtual void beginTextObject(GfxState *state); 204 virtual void endTextObject(GfxState *state); 205 206 //----- image drawing 207 virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, 208 int width, int height, GBool invert, GBool interpolate, 209 GBool inlineImg); 210 virtual void setSoftMaskFromImageMask(GfxState *state, 211 Object *ref, Stream *str, 212 int width, int height, GBool invert, 213 GBool inlineImg, double *baseMatrix); 214 virtual void unsetSoftMaskFromImageMask(GfxState *state, double *baseMatrix); 215 void drawImageMaskPrescaled(GfxState *state, Object *ref, Stream *str, 216 int width, int height, GBool invert, GBool interpolate, 217 GBool inlineImg); 218 void drawImageMaskRegular(GfxState *state, Object *ref, Stream *str, 219 int width, int height, GBool invert, GBool interpolate, 220 GBool inlineImg); 221 222 virtual void drawImage(GfxState *state, Object *ref, Stream *str, 223 int width, int height, GfxImageColorMap *colorMap, 224 GBool interpolate, int *maskColors, GBool inlineImg); 225 virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, 226 int width, int height, 227 GfxImageColorMap *colorMap, 228 GBool interpolate, 229 Stream *maskStr, 230 int maskWidth, int maskHeight, 231 GfxImageColorMap *maskColorMap, 232 GBool maskInterpolate); 233 234 virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, 235 int width, int height, 236 GfxImageColorMap *colorMap, 237 GBool interpolate, 238 Stream *maskStr, 239 int maskWidth, int maskHeight, 240 GBool maskInvert, GBool maskInterpolate); 241 242 //----- transparency groups and soft masks 243 virtual void beginTransparencyGroup(GfxState * /*state*/, double * /*bbox*/, 244 GfxColorSpace * /*blendingColorSpace*/, 245 GBool /*isolated*/, GBool /*knockout*/, 246 GBool /*forSoftMask*/); 247 virtual void endTransparencyGroup(GfxState * /*state*/); 248 void popTransparencyGroup(); 249 virtual void paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/); 250 virtual void setSoftMask(GfxState * /*state*/, double * /*bbox*/, GBool /*alpha*/, 251 Function * /*transferFunc*/, GfxColor * /*backdropColor*/); 252 virtual void clearSoftMask(GfxState * /*state*/); 253 254 //----- Type 3 font operators 255 virtual void type3D0(GfxState *state, double wx, double wy); 256 virtual void type3D1(GfxState *state, double wx, double wy, 257 double llx, double lly, double urx, double ury); 258 259 //----- special access 260 261 // Called to indicate that a new PDF document has been loaded. 262 void startDoc(PDFDoc *docA, CairoFontEngine *fontEngine = NULL); 263 isReverseVideo()264 GBool isReverseVideo() { return gFalse; } 265 266 void setCairo (cairo_t *cr); 267 void setTextPage (TextPage *text); setPrinting(GBool printing)268 void setPrinting (GBool printing) { this->printing = printing; needFontUpdate = gTrue; } 269 void setAntialias(cairo_antialias_t antialias); 270 setInType3Char(GBool inType3Char)271 void setInType3Char(GBool inType3Char) { this->inType3Char = inType3Char; } getType3GlyphWidth(double * wx,double * wy)272 void getType3GlyphWidth (double *wx, double *wy) { *wx = t3_glyph_wx; *wy = t3_glyph_wy; } hasType3GlyphBBox()273 GBool hasType3GlyphBBox () { return t3_glyph_has_bbox; } getType3GlyphBBox()274 double *getType3GlyphBBox () { return t3_glyph_bbox; } 275 276 protected: 277 void doPath(cairo_t *cairo, GfxState *state, GfxPath *path); 278 cairo_surface_t *downscaleSurface(cairo_surface_t *orig_surface); 279 void getScaledSize(const cairo_matrix_t *matrix, 280 int orig_width, int orig_height, 281 int *scaledWidth, int *scaledHeight); 282 cairo_filter_t getFilterForSurface(cairo_surface_t *image, 283 GBool interpolate); 284 GBool getStreamData (Stream *str, char **buffer, int *length); 285 void setMimeData(GfxState *state, Stream *str, Object *ref, 286 GfxImageColorMap *colorMap, cairo_surface_t *image); 287 void fillToStrokePathClip(GfxState *state); 288 void alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y); 289 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) 290 GBool setMimeDataForJBIG2Globals (Stream *str, cairo_surface_t *image); 291 #endif 292 void setAntialias(cairo_t *cr, cairo_antialias_t antialias); 293 294 GfxRGB fill_color, stroke_color; 295 cairo_pattern_t *fill_pattern, *stroke_pattern; 296 double fill_opacity; 297 double stroke_opacity; 298 GBool stroke_adjust; 299 GBool adjusted_stroke_width; 300 GBool align_stroke_coords; 301 CairoFont *currentFont; 302 XRef *xref; 303 304 struct StrokePathClip { 305 GfxPath *path; 306 cairo_matrix_t ctm; 307 double line_width; 308 double *dashes; 309 int dash_count; 310 double dash_offset; 311 cairo_line_cap_t cap; 312 cairo_line_join_t join; 313 double miter; 314 int ref_count; 315 } *strokePathClip; 316 317 PDFDoc *doc; // the current document 318 319 static FT_Library ft_lib; 320 static GBool ft_lib_initialized; 321 322 CairoFontEngine *fontEngine; 323 GBool fontEngine_owner; 324 325 cairo_t *cairo; 326 cairo_matrix_t orig_matrix; 327 GBool needFontUpdate; // set when the font needs to be updated 328 GBool printing; 329 GBool use_show_text_glyphs; 330 GBool text_matrix_valid; 331 cairo_surface_t *surface; 332 cairo_glyph_t *glyphs; 333 int glyphCount; 334 cairo_text_cluster_t *clusters; 335 int clusterCount; 336 char *utf8; 337 int utf8Count; 338 int utf8Max; 339 cairo_path_t *textClipPath; 340 GBool inUncoloredPattern; // inside a uncolored pattern (PaintType = 2) 341 GBool inType3Char; // inside a Type 3 CharProc 342 double t3_glyph_wx, t3_glyph_wy; 343 GBool t3_glyph_has_bbox; 344 double t3_glyph_bbox[4]; 345 cairo_antialias_t antialias; 346 GBool prescaleImages; 347 348 TextPage *text; // text for the current page 349 ActualText *actualText; 350 351 cairo_pattern_t *group; 352 cairo_pattern_t *shape; 353 cairo_pattern_t *mask; 354 cairo_matrix_t mask_matrix; 355 cairo_surface_t *cairo_shape_surface; 356 cairo_t *cairo_shape; 357 int knockoutCount; 358 struct ColorSpaceStack { 359 GBool knockout; 360 GfxColorSpace *cs; 361 cairo_matrix_t group_matrix; 362 struct ColorSpaceStack *next; 363 } * groupColorSpaceStack; 364 365 struct MaskStack { 366 cairo_pattern_t *mask; 367 cairo_matrix_t mask_matrix; 368 struct MaskStack *next; 369 } *maskStack; 370 371 }; 372 373 //------------------------------------------------------------------------ 374 // CairoImageOutputDev 375 //------------------------------------------------------------------------ 376 377 //XXX: this should ideally not inherit from CairoOutputDev but use it instead perhaps 378 class CairoImageOutputDev: public CairoOutputDev { 379 public: 380 381 // Constructor. 382 CairoImageOutputDev(); 383 384 // Destructor. 385 virtual ~CairoImageOutputDev(); 386 387 //----- get info about output device 388 389 // Does this device use upside-down coordinates? 390 // (Upside-down means (0,0) is the top left corner of the page.) upsideDown()391 virtual GBool upsideDown() { return gTrue; } 392 393 // Does this device use drawChar() or drawString()? useDrawChar()394 virtual GBool useDrawChar() { return gFalse; } 395 396 // Does this device use tilingPatternFill()? If this returns false, 397 // tiling pattern fills will be reduced to a series of other drawing 398 // operations. useTilingPatternFill()399 virtual GBool useTilingPatternFill() { return gTrue; } 400 401 // Does this device use functionShadedFill(), axialShadedFill(), and 402 // radialShadedFill()? If this returns false, these shaded fills 403 // will be reduced to a series of other drawing operations. 404 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) useShadedFills(int type)405 virtual GBool useShadedFills(int type) { return type <= 7; } 406 #else useShadedFills(int type)407 virtual GBool useShadedFills(int type) { return type < 4; } 408 #endif 409 410 // Does this device use FillColorStop()? useFillColorStop()411 virtual GBool useFillColorStop() { return gFalse; } 412 413 // Does this device use beginType3Char/endType3Char? Otherwise, 414 // text in Type 3 fonts will be drawn with drawChar/drawString. interpretType3Chars()415 virtual GBool interpretType3Chars() { return gFalse; } 416 417 // Does this device need non-text content? needNonText()418 virtual GBool needNonText() { return gTrue; } 419 420 //----- save/restore graphics state saveState(GfxState * state)421 virtual void saveState(GfxState *state) { } restoreState(GfxState * state)422 virtual void restoreState(GfxState *state) { } 423 424 //----- update graphics state updateAll(GfxState * state)425 virtual void updateAll(GfxState *state) { } setDefaultCTM(double * ctm)426 virtual void setDefaultCTM(double *ctm) { } updateCTM(GfxState * state,double m11,double m12,double m21,double m22,double m31,double m32)427 virtual void updateCTM(GfxState *state, double m11, double m12, 428 double m21, double m22, double m31, double m32) { } updateLineDash(GfxState * state)429 virtual void updateLineDash(GfxState *state) { } updateFlatness(GfxState * state)430 virtual void updateFlatness(GfxState *state) { } updateLineJoin(GfxState * state)431 virtual void updateLineJoin(GfxState *state) { } updateLineCap(GfxState * state)432 virtual void updateLineCap(GfxState *state) { } updateMiterLimit(GfxState * state)433 virtual void updateMiterLimit(GfxState *state) { } updateLineWidth(GfxState * state)434 virtual void updateLineWidth(GfxState *state) { } updateFillColor(GfxState * state)435 virtual void updateFillColor(GfxState *state) { } updateStrokeColor(GfxState * state)436 virtual void updateStrokeColor(GfxState *state) { } updateFillOpacity(GfxState * state)437 virtual void updateFillOpacity(GfxState *state) { } updateStrokeOpacity(GfxState * state)438 virtual void updateStrokeOpacity(GfxState *state) { } updateBlendMode(GfxState * state)439 virtual void updateBlendMode(GfxState *state) { } 440 441 //----- update text state updateFont(GfxState * state)442 virtual void updateFont(GfxState *state) { } 443 444 //----- path painting stroke(GfxState * state)445 virtual void stroke(GfxState *state) { } fill(GfxState * state)446 virtual void fill(GfxState *state) { } eoFill(GfxState * state)447 virtual void eoFill(GfxState *state) { } clipToStrokePath(GfxState * state)448 virtual void clipToStrokePath(GfxState *state) { } tilingPatternFill(GfxState * state,Gfx * gfx,Catalog * cat,Object * str,double * pmat,int paintType,int tilingType,Dict * resDict,double * mat,double * bbox,int x0,int y0,int x1,int y1,double xStep,double yStep)449 virtual GBool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str, 450 double *pmat, int paintType, int tilingType, Dict *resDict, 451 double *mat, double *bbox, 452 int x0, int y0, int x1, int y1, 453 double xStep, double yStep) { return gTrue; } axialShadedFill(GfxState * state,GfxAxialShading * shading,double tMin,double tMax)454 virtual GBool axialShadedFill(GfxState *state, 455 GfxAxialShading *shading, 456 double tMin, double tMax) { return gTrue; } radialShadedFill(GfxState * state,GfxRadialShading * shading,double sMin,double sMax)457 virtual GBool radialShadedFill(GfxState *state, 458 GfxRadialShading *shading, 459 double sMin, double sMax) { return gTrue; } 460 461 //----- path clipping clip(GfxState * state)462 virtual void clip(GfxState *state) { } eoClip(GfxState * state)463 virtual void eoClip(GfxState *state) { } 464 465 //----- image drawing 466 virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, 467 int width, int height, GBool invert, 468 GBool interpolate, GBool inlineImg); 469 virtual void drawImage(GfxState *state, Object *ref, Stream *str, 470 int width, int height, GfxImageColorMap *colorMap, 471 GBool interpolate, int *maskColors, GBool inlineImg); 472 virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, 473 int width, int height, 474 GfxImageColorMap *colorMap, 475 GBool interpolate, 476 Stream *maskStr, 477 int maskWidth, int maskHeight, 478 GfxImageColorMap *maskColorMap, 479 GBool maskInterpolate); 480 virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str, 481 int width, int height, 482 GfxImageColorMap *colorMap, 483 GBool interpolate, 484 Stream *maskStr, 485 int maskWidth, int maskHeight, 486 GBool maskInvert, GBool maskInterpolate); 487 virtual void setSoftMaskFromImageMask(GfxState *state, Object *ref, Stream *str, 488 int width, int height, GBool invert, 489 GBool inlineImg, double *baseMatrix); unsetSoftMaskFromImageMask(GfxState * state,double * baseMatrix)490 virtual void unsetSoftMaskFromImageMask(GfxState *state, double *baseMatrix) {} 491 492 493 //----- transparency groups and soft masks beginTransparencyGroup(GfxState *,double *,GfxColorSpace *,GBool,GBool,GBool)494 virtual void beginTransparencyGroup(GfxState * /*state*/, double * /*bbox*/, 495 GfxColorSpace * /*blendingColorSpace*/, 496 GBool /*isolated*/, GBool /*knockout*/, 497 GBool /*forSoftMask*/) {} endTransparencyGroup(GfxState *)498 virtual void endTransparencyGroup(GfxState * /*state*/) {} paintTransparencyGroup(GfxState *,double *)499 virtual void paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/) {} setSoftMask(GfxState *,double *,GBool,Function *,GfxColor *)500 virtual void setSoftMask(GfxState * /*state*/, double * /*bbox*/, GBool /*alpha*/, 501 Function * /*transferFunc*/, GfxColor * /*backdropColor*/) {} clearSoftMask(GfxState *)502 virtual void clearSoftMask(GfxState * /*state*/) {} 503 504 //----- Image list 505 // By default images are not rendred setImageDrawDecideCbk(GBool (* cbk)(int img_id,void * data),void * data)506 void setImageDrawDecideCbk(GBool (*cbk)(int img_id, void *data), 507 void *data) { imgDrawCbk = cbk; imgDrawCbkData = data; } 508 // Iterate through list of images. getNumImages()509 int getNumImages() const { return numImages; } getImage(int i)510 CairoImage *getImage(int i) const { return images[i]; } 511 512 private: 513 void saveImage(CairoImage *image); 514 void getBBox(GfxState *state, int width, int height, 515 double *x1, double *y1, double *x2, double *y2); 516 517 CairoImage **images; 518 int numImages; 519 int size; 520 GBool (*imgDrawCbk)(int img_id, void *data); 521 void *imgDrawCbkData; 522 }; 523 524 #endif 525