1 #ifndef MUPDF_FITZ_DEVICE_H 2 #define MUPDF_FITZ_DEVICE_H 3 4 #include "mupdf/fitz/system.h" 5 #include "mupdf/fitz/context.h" 6 #include "mupdf/fitz/geometry.h" 7 #include "mupdf/fitz/image.h" 8 #include "mupdf/fitz/shade.h" 9 #include "mupdf/fitz/path.h" 10 #include "mupdf/fitz/text.h" 11 12 /** 13 The different format handlers (pdf, xps etc) interpret pages to 14 a device. These devices can then process the stream of calls 15 they receive in various ways: 16 The trace device outputs debugging information for the calls. 17 The draw device will render them. 18 The list device stores them in a list to play back later. 19 The text device performs text extraction and searching. 20 The bbox device calculates the bounding box for the page. 21 Other devices can (and will) be written in the future. 22 */ 23 typedef struct fz_device fz_device; 24 25 enum 26 { 27 /* Flags */ 28 FZ_DEVFLAG_MASK = 1, 29 FZ_DEVFLAG_COLOR = 2, 30 FZ_DEVFLAG_UNCACHEABLE = 4, 31 FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8, 32 FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16, 33 FZ_DEVFLAG_STARTCAP_UNDEFINED = 32, 34 FZ_DEVFLAG_DASHCAP_UNDEFINED = 64, 35 FZ_DEVFLAG_ENDCAP_UNDEFINED = 128, 36 FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256, 37 FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512, 38 FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024, 39 /* Arguably we should have a bit for the dash pattern itself 40 * being undefined, but that causes problems; do we assume that 41 * it should always be set to non-dashing at the start of every 42 * glyph? */ 43 FZ_DEVFLAG_BBOX_DEFINED = 2048, 44 FZ_DEVFLAG_GRIDFIT_AS_TILED = 4096, 45 }; 46 47 enum 48 { 49 /* PDF 1.4 -- standard separable */ 50 FZ_BLEND_NORMAL, 51 FZ_BLEND_MULTIPLY, 52 FZ_BLEND_SCREEN, 53 FZ_BLEND_OVERLAY, 54 FZ_BLEND_DARKEN, 55 FZ_BLEND_LIGHTEN, 56 FZ_BLEND_COLOR_DODGE, 57 FZ_BLEND_COLOR_BURN, 58 FZ_BLEND_HARD_LIGHT, 59 FZ_BLEND_SOFT_LIGHT, 60 FZ_BLEND_DIFFERENCE, 61 FZ_BLEND_EXCLUSION, 62 63 /* PDF 1.4 -- standard non-separable */ 64 FZ_BLEND_HUE, 65 FZ_BLEND_SATURATION, 66 FZ_BLEND_COLOR, 67 FZ_BLEND_LUMINOSITY, 68 69 /* For packing purposes */ 70 FZ_BLEND_MODEMASK = 15, 71 FZ_BLEND_ISOLATED = 16, 72 FZ_BLEND_KNOCKOUT = 32 73 }; 74 75 /** 76 Map from (case sensitive) blend mode string to enumeration. 77 */ 78 int fz_lookup_blendmode(const char *name); 79 80 /** 81 Map from enumeration to blend mode string. 82 83 The string is static, with arbitrary lifespan. 84 */ 85 const char *fz_blendmode_name(int blendmode); 86 87 /** 88 The device structure is public to allow devices to be 89 implemented outside of fitz. 90 91 Device methods should always be called using e.g. 92 fz_fill_path(ctx, dev, ...) rather than 93 dev->fill_path(ctx, dev, ...) 94 */ 95 96 /** 97 Devices can keep track of containers (clips/masks/groups/tiles) 98 as they go to save callers having to do it. 99 */ 100 typedef struct 101 { 102 fz_rect scissor; 103 int type; 104 int user; 105 } fz_device_container_stack; 106 107 enum 108 { 109 fz_device_container_stack_is_clip, 110 fz_device_container_stack_is_mask, 111 fz_device_container_stack_is_group, 112 fz_device_container_stack_is_tile, 113 }; 114 115 struct fz_device 116 { 117 int refs; 118 int hints; 119 int flags; 120 121 void (*close_device)(fz_context *, fz_device *); 122 void (*drop_device)(fz_context *, fz_device *); 123 124 void (*fill_path)(fz_context *, fz_device *, const fz_path *, int even_odd, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params ); 125 void (*stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params ); 126 void (*clip_path)(fz_context *, fz_device *, const fz_path *, int even_odd, fz_matrix, fz_rect scissor); 127 void (*clip_stroke_path)(fz_context *, fz_device *, const fz_path *, const fz_stroke_state *, fz_matrix, fz_rect scissor); 128 129 void (*fill_text)(fz_context *, fz_device *, const fz_text *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params ); 130 void (*stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, fz_matrix, fz_colorspace *, const float *color, float alpha, fz_color_params ); 131 void (*clip_text)(fz_context *, fz_device *, const fz_text *, fz_matrix, fz_rect scissor); 132 void (*clip_stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, fz_matrix, fz_rect scissor); 133 void (*ignore_text)(fz_context *, fz_device *, const fz_text *, fz_matrix ); 134 135 void (*fill_shade)(fz_context *, fz_device *, fz_shade *shd, fz_matrix ctm, float alpha, fz_color_params color_params); 136 void (*fill_image)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, float alpha, fz_color_params color_params); 137 void (*fill_image_mask)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, fz_colorspace *, const float *color, float alpha, fz_color_params color_params); 138 void (*clip_image_mask)(fz_context *, fz_device *, fz_image *img, fz_matrix ctm, fz_rect scissor); 139 140 void (*pop_clip)(fz_context *, fz_device *); 141 142 void (*begin_mask)(fz_context *, fz_device *, fz_rect area, int luminosity, fz_colorspace *, const float *bc, fz_color_params ); 143 void (*end_mask)(fz_context *, fz_device *); 144 void (*begin_group)(fz_context *, fz_device *, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha); 145 void (*end_group)(fz_context *, fz_device *); 146 147 int (*begin_tile)(fz_context *, fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id); 148 void (*end_tile)(fz_context *, fz_device *); 149 150 void (*render_flags)(fz_context *, fz_device *, int set, int clear); 151 void (*set_default_colorspaces)(fz_context *, fz_device *, fz_default_colorspaces *); 152 153 void (*begin_layer)(fz_context *, fz_device *, const char *layer_name); 154 void (*end_layer)(fz_context *, fz_device *); 155 156 fz_rect d1_rect; 157 158 int container_len; 159 int container_cap; 160 fz_device_container_stack *container; 161 }; 162 163 /** 164 Device calls; graphics primitives and containers. 165 */ 166 void fz_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params); 167 void fz_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params); 168 void fz_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_rect scissor); 169 void fz_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor); 170 void fz_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params); 171 void fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params); 172 void fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_rect scissor); 173 void fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor); 174 void fz_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm); 175 void fz_pop_clip(fz_context *ctx, fz_device *dev); 176 void fz_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha, fz_color_params color_params); 177 void fz_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, float alpha, fz_color_params color_params); 178 void fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params); 179 void fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_rect scissor); 180 void fz_begin_mask(fz_context *ctx, fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, const float *bc, fz_color_params color_params); 181 void fz_end_mask(fz_context *ctx, fz_device *dev); 182 void fz_begin_group(fz_context *ctx, fz_device *dev, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha); 183 void fz_end_group(fz_context *ctx, fz_device *dev); 184 void fz_begin_tile(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); 185 int fz_begin_tile_id(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id); 186 void fz_end_tile(fz_context *ctx, fz_device *dev); 187 void fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear); 188 void fz_set_default_colorspaces(fz_context *ctx, fz_device *dev, fz_default_colorspaces *default_cs); 189 void fz_begin_layer(fz_context *ctx, fz_device *dev, const char *layer_name); 190 void fz_end_layer(fz_context *ctx, fz_device *dev); 191 192 /** 193 Devices are created by calls to device implementations, for 194 instance: foo_new_device(). These will be implemented by calling 195 fz_new_derived_device(ctx, foo_device) where foo_device is a 196 structure "derived from" fz_device, for instance 197 typedef struct { fz_device base; ...extras...} foo_device; 198 */ 199 fz_device *fz_new_device_of_size(fz_context *ctx, int size); 200 #define fz_new_derived_device(CTX, TYPE) \ 201 ((TYPE *)Memento_label(fz_new_device_of_size(ctx,sizeof(TYPE)),#TYPE)) 202 203 /** 204 Signal the end of input, and flush any buffered output. 205 This is NOT called implicitly on fz_drop_device. This 206 may throw exceptions. 207 */ 208 void fz_close_device(fz_context *ctx, fz_device *dev); 209 210 /** 211 Reduce the reference count on a device. When the reference count 212 reaches zero, the device and its resources will be freed. 213 Don't forget to call fz_close_device before dropping the device, 214 or you may get incomplete output! 215 216 Never throws exceptions. 217 */ 218 void fz_drop_device(fz_context *ctx, fz_device *dev); 219 220 /** 221 Increment the reference count for a device. Returns the same 222 pointer. 223 224 Never throws exceptions. 225 */ 226 fz_device *fz_keep_device(fz_context *ctx, fz_device *dev); 227 228 /** 229 Enable (set) hint bits within the hint bitfield for a device. 230 */ 231 void fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints); 232 233 /** 234 Disable (clear) hint bits within the hint bitfield for a device. 235 */ 236 void fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints); 237 238 /** 239 Find current scissor region as tracked by the device. 240 */ 241 fz_rect fz_device_current_scissor(fz_context *ctx, fz_device *dev); 242 243 enum 244 { 245 /* Hints */ 246 FZ_DONT_INTERPOLATE_IMAGES = 1, 247 FZ_NO_CACHE = 2, 248 }; 249 250 /** 251 Cookie support - simple communication channel between app/library. 252 */ 253 254 /** 255 Provide two-way communication between application and library. 256 Intended for multi-threaded applications where one thread is 257 rendering pages and another thread wants to read progress 258 feedback or abort a job that takes a long time to finish. The 259 communication is unsynchronized without locking. 260 261 abort: The application should set this field to 0 before 262 calling fz_run_page to render a page. At any point when the 263 page is being rendered the application my set this field to 1 264 which will cause the rendering to finish soon. This field is 265 checked periodically when the page is rendered, but exactly 266 when is not known, therefore there is no upper bound on 267 exactly when the rendering will abort. If the application 268 did not provide a set of locks to fz_new_context, it must also 269 await the completion of fz_run_page before issuing another 270 call to fz_run_page. Note that once the application has set 271 this field to 1 after it called fz_run_page it may not change 272 the value again. 273 274 progress: Communicates rendering progress back to the 275 application and is read only. Increments as a page is being 276 rendered. The value starts out at 0 and is limited to less 277 than or equal to progress_max, unless progress_max is -1. 278 279 progress_max: Communicates the known upper bound of rendering 280 back to the application and is read only. The maximum value 281 that the progress field may take. If there is no known upper 282 bound on how long the rendering may take this value is -1 and 283 progress is not limited. Note that the value of progress_max 284 may change from -1 to a positive value once an upper bound is 285 known, so take this into consideration when comparing the 286 value of progress to that of progress_max. 287 288 errors: count of errors during current rendering. 289 290 incomplete: Initially should be set to 0. Will be set to 291 non-zero if a TRYLATER error is thrown during rendering. 292 */ 293 typedef struct 294 { 295 int abort; 296 int progress; 297 size_t progress_max; /* (size_t)-1 for unknown */ 298 int errors; 299 int incomplete; 300 } fz_cookie; 301 302 /** 303 Create a device to print a debug trace of all device calls. 304 */ 305 fz_device *fz_new_trace_device(fz_context *ctx, fz_output *out); 306 307 /** 308 Create a device to output raw information. 309 */ 310 fz_device *fz_new_xmltext_device(fz_context *ctx, fz_output *out); 311 312 /** 313 Create a device to compute the bounding 314 box of all marks on a page. 315 316 The returned bounding box will be the union of all bounding 317 boxes of all objects on a page. 318 */ 319 fz_device *fz_new_bbox_device(fz_context *ctx, fz_rect *rectp); 320 321 /** 322 Create a device to test for features. 323 324 Currently only tests for the presence of non-grayscale colors. 325 326 is_color: Possible values returned: 327 0: Definitely greyscale 328 1: Probably color (all colors were grey, but there 329 were images or shadings in a non grey colorspace). 330 2: Definitely color 331 332 threshold: The difference from grayscale that will be tolerated. 333 Typical values to use are either 0 (be exact) and 0.02 (allow an 334 imperceptible amount of slop). 335 336 options: A set of bitfield options, from the FZ_TEST_OPT set. 337 338 passthrough: A device to pass all calls through to, or NULL. 339 If set, then the test device can both test and pass through to 340 an underlying device (like, say, the display list device). This 341 means that a display list can be created and at the end we'll 342 know if it's colored or not. 343 344 In the absence of a passthrough device, the device will throw 345 an exception to stop page interpretation when color is found. 346 */ 347 fz_device *fz_new_test_device(fz_context *ctx, int *is_color, float threshold, int options, fz_device *passthrough); 348 349 enum 350 { 351 /* If set, test every pixel of images exhaustively. 352 * If clear, just look at colorspaces for images. */ 353 FZ_TEST_OPT_IMAGES = 1, 354 355 /* If set, test every pixel of shadings. */ 356 /* If clear, just look at colorspaces for shadings. */ 357 FZ_TEST_OPT_SHADINGS = 2 358 }; 359 360 /** 361 Create a device to draw on a pixmap. 362 363 dest: Target pixmap for the draw device. See fz_new_pixmap* 364 for how to obtain a pixmap. The pixmap is not cleared by the 365 draw device, see fz_clear_pixmap* for how to clear it prior to 366 calling fz_new_draw_device. Free the device by calling 367 fz_drop_device. 368 369 transform: Transform from user space in points to device space 370 in pixels. 371 */ 372 fz_device *fz_new_draw_device(fz_context *ctx, fz_matrix transform, fz_pixmap *dest); 373 374 /** 375 Create a device to draw on a pixmap. 376 377 dest: Target pixmap for the draw device. See fz_new_pixmap* 378 for how to obtain a pixmap. The pixmap is not cleared by the 379 draw device, see fz_clear_pixmap* for how to clear it prior to 380 calling fz_new_draw_device. Free the device by calling 381 fz_drop_device. 382 383 transform: Transform from user space in points to device space 384 in pixels. 385 386 clip: Bounding box to restrict any marking operations of the 387 draw device. 388 */ 389 fz_device *fz_new_draw_device_with_bbox(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip); 390 391 /** 392 Create a device to draw on a pixmap. 393 394 dest: Target pixmap for the draw device. See fz_new_pixmap* 395 for how to obtain a pixmap. The pixmap is not cleared by the 396 draw device, see fz_clear_pixmap* for how to clear it prior to 397 calling fz_new_draw_device. Free the device by calling 398 fz_drop_device. 399 400 transform: Transform from user space in points to device space 401 in pixels. 402 403 proof_cs: Intermediate color space to map though when mapping to 404 color space defined by pixmap. 405 */ 406 fz_device *fz_new_draw_device_with_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, fz_colorspace *proof_cs); 407 408 /** 409 Create a device to draw on a pixmap. 410 411 dest: Target pixmap for the draw device. See fz_new_pixmap* 412 for how to obtain a pixmap. The pixmap is not cleared by the 413 draw device, see fz_clear_pixmap* for how to clear it prior to 414 calling fz_new_draw_device. Free the device by calling 415 fz_drop_device. 416 417 transform: Transform from user space in points to device space 418 in pixels. 419 420 clip: Bounding box to restrict any marking operations of the 421 draw device. 422 423 proof_cs: Color space to render to prior to mapping to color 424 space defined by pixmap. 425 */ 426 fz_device *fz_new_draw_device_with_bbox_proof(fz_context *ctx, fz_matrix transform, fz_pixmap *dest, const fz_irect *clip, fz_colorspace *cs); 427 428 fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_matrix transform, fz_pixmap *dest); 429 430 /** 431 struct fz_draw_options: Options for creating a pixmap and draw 432 device. 433 */ 434 typedef struct 435 { 436 int rotate; 437 int x_resolution; 438 int y_resolution; 439 int width; 440 int height; 441 fz_colorspace *colorspace; 442 int alpha; 443 int graphics; 444 int text; 445 } fz_draw_options; 446 447 extern const char *fz_draw_options_usage; 448 449 /** 450 Parse draw device options from a comma separated key-value string. 451 */ 452 fz_draw_options *fz_parse_draw_options(fz_context *ctx, fz_draw_options *options, const char *string); 453 454 /** 455 Create a new pixmap and draw device, using the specified options. 456 457 options: Options to configure the draw device, and choose the 458 resolution and colorspace. 459 460 mediabox: The bounds of the page in points. 461 462 pixmap: An out parameter containing the newly created pixmap. 463 */ 464 fz_device *fz_new_draw_device_with_options(fz_context *ctx, const fz_draw_options *options, fz_rect mediabox, fz_pixmap **pixmap); 465 466 #endif 467