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