Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "mupdf/fitz.h"
2
3
void *
4
fz_new_device(fz_context *ctx, int size)
5
{
6
return Memento_label(fz_calloc(ctx, 1, size), "fz_device");
7
}
8
9
void
10
fz_drop_device(fz_context *ctx, fz_device *dev)
11
{
12
if (dev == NULL)
13
return;
14
if (dev->drop_imp)
15
dev->drop_imp(ctx, dev);
16
fz_free(ctx, dev->container);
17
fz_free(ctx, dev);
18
}
19
20
void
21
fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints)
22
{
23
dev->hints |= hints;
24
}
25
26
void
27
fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints)
28
{
29
dev->hints &= ~hints;
30
}
31
32
void
33
fz_begin_page(fz_context *ctx, fz_device *dev, const fz_rect *rect, const fz_matrix *ctm)
34
{
35
if (dev->begin_page)
36
dev->begin_page(ctx, dev, rect, ctm);
37
}
38
39
void
40
fz_end_page(fz_context *ctx, fz_device *dev)
41
{
42
if (dev->end_page)
43
dev->end_page(ctx, dev);
44
}
45
46
static void
47
push_clip_stack(fz_context *ctx, fz_device *dev, const fz_rect *rect, int flags)
48
{
49
if (dev->container_len == dev->container_cap)
50
{
51
int newmax = dev->container_cap * 2;
52
if (newmax == 0)
53
newmax = 4;
54
dev->container = fz_resize_array(ctx, dev->container, newmax, sizeof(*dev->container));
55
dev->container_cap = newmax;
56
}
57
if (dev->container_len == 0)
58
dev->container[0].scissor = *rect;
59
else
60
{
61
dev->container[dev->container_len].scissor = dev->container[dev->container_len-1].scissor;
62
fz_intersect_rect(&dev->container[dev->container_len].scissor, rect);
63
}
64
dev->container[dev->container_len].flags = flags;
65
dev->container[dev->container_len].user = 0;
66
dev->container_len++;
67
}
68
69
static void
70
push_clip_stack_accumulate(fz_context *ctx, fz_device *dev, const fz_rect *rect, int accumulate)
71
{
72
if (accumulate <= 1)
73
{
74
dev->scissor_accumulator = *rect;
75
if (dev->container_len == dev->container_cap)
76
{
77
int newmax = dev->container_cap * 2;
78
if (newmax == 0)
79
newmax = 4;
80
dev->container = fz_resize_array(ctx, dev->container, newmax, sizeof(*dev->container));
81
dev->container_cap = newmax;
82
}
83
if (dev->container_len > 0)
84
dev->container[dev->container_len].scissor = dev->container[dev->container_len-1].scissor;
85
else
86
dev->container[dev->container_len].scissor = fz_infinite_rect;
87
fz_intersect_rect(&dev->container[dev->container_len].scissor, rect);
88
dev->container[dev->container_len].flags = fz_device_container_stack_is_clip_text;
89
dev->container[dev->container_len].user = 0;
90
dev->container_len++;
91
}
92
else
93
{
94
if (dev->container_len <= 0)
95
return;
96
fz_union_rect(&dev->scissor_accumulator, rect);
97
fz_intersect_rect(&dev->container[dev->container_len-1].scissor, &dev->scissor_accumulator);
98
}
99
}
100
101
static void
102
pop_clip_stack(fz_context *ctx, fz_device *dev)
103
{
104
if (dev->container_len > 0)
105
dev->container_len--;
106
}
107
108
void
109
fz_fill_path(fz_context *ctx, fz_device *dev, fz_path *path, int even_odd, const fz_matrix *ctm,
110
fz_colorspace *colorspace, float *color, float alpha)
111
{
112
if (dev->error_depth)
113
return;
114
if (dev->fill_path)
115
dev->fill_path(ctx, dev, path, even_odd, ctm, colorspace, color, alpha);
116
}
117
118
void
119
fz_stroke_path(fz_context *ctx, fz_device *dev, fz_path *path, fz_stroke_state *stroke, const fz_matrix *ctm,
120
fz_colorspace *colorspace, float *color, float alpha)
121
{
122
if (dev->error_depth)
123
return;
124
if (dev->stroke_path)
125
dev->stroke_path(ctx, dev, path, stroke, ctm, colorspace, color, alpha);
126
}
127
128
void
129
fz_clip_path(fz_context *ctx, fz_device *dev, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm)
130
{
131
if (dev->error_depth)
132
{
133
dev->error_depth++;
134
return;
135
}
136
137
fz_try(ctx)
138
{
139
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
140
{
141
if (rect == NULL)
142
{
143
fz_rect bbox;
144
fz_bound_path(ctx, path, NULL, ctm, &bbox);
145
push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_path);
146
}
147
else
148
push_clip_stack(ctx, dev, rect, fz_device_container_stack_is_clip_path);
149
}
150
if (dev->clip_path)
151
dev->clip_path(ctx, dev, path, rect, even_odd, ctm);
152
}
153
fz_catch(ctx)
154
{
155
dev->error_depth = 1;
156
strcpy(dev->errmess, fz_caught_message(ctx));
157
/* Error swallowed */
158
}
159
}
160
161
void
162
fz_clip_stroke_path(fz_context *ctx, fz_device *dev, fz_path *path, const fz_rect *rect, fz_stroke_state *stroke, const fz_matrix *ctm)
163
{
164
if (dev->error_depth)
165
{
166
dev->error_depth++;
167
return;
168
}
169
170
fz_try(ctx)
171
{
172
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
173
{
174
if (rect == NULL)
175
{
176
fz_rect bbox;
177
fz_bound_path(ctx, path, stroke, ctm, &bbox);
178
push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_stroke_path);
179
}
180
else
181
push_clip_stack(ctx, dev, rect, fz_device_container_stack_is_clip_stroke_path);
182
}
183
if (dev->clip_stroke_path)
184
dev->clip_stroke_path(ctx, dev, path, rect, stroke, ctm);
185
}
186
fz_catch(ctx)
187
{
188
dev->error_depth = 1;
189
strcpy(dev->errmess, fz_caught_message(ctx));
190
/* Error swallowed */
191
}
192
}
193
194
void
195
fz_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm,
196
fz_colorspace *colorspace, float *color, float alpha)
197
{
198
if (dev->error_depth)
199
return;
200
if (dev->fill_text)
201
dev->fill_text(ctx, dev, text, ctm, colorspace, color, alpha);
202
}
203
204
void
205
fz_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm,
206
fz_colorspace *colorspace, float *color, float alpha)
207
{
208
if (dev->error_depth)
209
return;
210
if (dev->stroke_text)
211
dev->stroke_text(ctx, dev, text, stroke, ctm, colorspace, color, alpha);
212
}
213
214
void
215
fz_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate)
216
{
217
if (dev->error_depth)
218
{
219
if (accumulate == 0 || accumulate == 1)
220
dev->error_depth++;
221
return;
222
}
223
224
fz_try(ctx)
225
{
226
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
227
{
228
fz_rect bbox;
229
fz_bound_text(ctx, text, NULL, ctm, &bbox);
230
push_clip_stack_accumulate(ctx, dev, &bbox, accumulate);
231
}
232
if (dev->clip_text)
233
dev->clip_text(ctx, dev, text, ctm, accumulate);
234
}
235
fz_catch(ctx)
236
{
237
if (accumulate == 2)
238
fz_rethrow(ctx);
239
dev->error_depth = 1;
240
strcpy(dev->errmess, fz_caught_message(ctx));
241
/* Error swallowed */
242
}
243
}
244
245
void
246
fz_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm)
247
{
248
if (dev->error_depth)
249
{
250
dev->error_depth++;
251
return;
252
}
253
254
fz_try(ctx)
255
{
256
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
257
{
258
fz_rect bbox;
259
fz_bound_text(ctx, text, stroke, ctm, &bbox);
260
push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_stroke_text);
261
}
262
if (dev->clip_stroke_text)
263
dev->clip_stroke_text(ctx, dev, text, stroke, ctm);
264
}
265
fz_catch(ctx)
266
{
267
dev->error_depth = 1;
268
strcpy(dev->errmess, fz_caught_message(ctx));
269
/* Error swallowed */
270
}
271
}
272
273
void
274
fz_ignore_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm)
275
{
276
if (dev->error_depth)
277
return;
278
if (dev->ignore_text)
279
dev->ignore_text(ctx, dev, text, ctm);
280
}
281
282
void
283
fz_pop_clip(fz_context *ctx, fz_device *dev)
284
{
285
if (dev->error_depth)
286
{
287
dev->error_depth--;
288
if (dev->error_depth == 0)
289
fz_throw(ctx, FZ_ERROR_GENERIC, "%s", dev->errmess);
290
return;
291
}
292
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
293
pop_clip_stack(ctx, dev);
294
if (dev->pop_clip)
295
dev->pop_clip(ctx, dev);
296
}
297
298
void
299
fz_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_matrix *ctm, float alpha)
300
{
301
if (dev->error_depth)
302
return;
303
if (dev->fill_shade)
304
dev->fill_shade(ctx, dev, shade, ctm, alpha);
305
}
306
307
void
308
fz_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, float alpha)
309
{
310
if (dev->error_depth)
311
return;
312
if (dev->fill_image)
313
dev->fill_image(ctx, dev, image, ctm, alpha);
314
}
315
316
void
317
fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm,
318
fz_colorspace *colorspace, float *color, float alpha)
319
{
320
if (dev->error_depth)
321
return;
322
if (dev->fill_image_mask)
323
dev->fill_image_mask(ctx, dev, image, ctm, colorspace, color, alpha);
324
}
325
326
void
327
fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_rect *rect, const fz_matrix *ctm)
328
{
329
if (dev->error_depth)
330
{
331
dev->error_depth++;
332
return;
333
}
334
335
fz_try(ctx)
336
{
337
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
338
push_clip_stack(ctx, dev, rect, fz_device_container_stack_is_clip_image_mask);
339
if (dev->clip_image_mask)
340
dev->clip_image_mask(ctx, dev, image, rect, ctm);
341
}
342
fz_catch(ctx)
343
{
344
dev->error_depth = 1;
345
strcpy(dev->errmess, fz_caught_message(ctx));
346
/* Error swallowed */
347
}
348
}
349
350
void
351
fz_begin_mask(fz_context *ctx, fz_device *dev, const fz_rect *area, int luminosity, fz_colorspace *colorspace, float *bc)
352
{
353
if (dev->error_depth)
354
{
355
dev->error_depth++;
356
return;
357
}
358
359
fz_try(ctx)
360
{
361
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
362
push_clip_stack(ctx, dev, area, fz_device_container_stack_in_mask);
363
if (dev->begin_mask)
364
dev->begin_mask(ctx, dev, area, luminosity, colorspace, bc);
365
}
366
fz_catch(ctx)
367
{
368
dev->error_depth = 1;
369
strcpy(dev->errmess, fz_caught_message(ctx));
370
/* Error swallowed */
371
}
372
}
373
374
void
375
fz_end_mask(fz_context *ctx, fz_device *dev)
376
{
377
if (dev->error_depth)
378
{
379
/* Converts from mask to clip, so no change in stack depth */
380
return;
381
}
382
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
383
{
384
dev->container[dev->container_len-1].flags &= ~fz_device_container_stack_in_mask;
385
dev->container[dev->container_len-1].flags |= fz_device_container_stack_is_mask;
386
}
387
fz_try(ctx)
388
{
389
if (dev->end_mask)
390
dev->end_mask(ctx, dev);
391
}
392
fz_catch(ctx)
393
{
394
dev->error_depth = 1;
395
strcpy(dev->errmess, fz_caught_message(ctx));
396
/* Error swallowed */
397
}
398
}
399
400
void
401
fz_begin_group(fz_context *ctx, fz_device *dev, const fz_rect *area, int isolated, int knockout, int blendmode, float alpha)
402
{
403
if (dev->error_depth)
404
{
405
dev->error_depth++;
406
return;
407
}
408
409
fz_try(ctx)
410
{
411
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
412
push_clip_stack(ctx, dev, area, fz_device_container_stack_is_group);
413
if (dev->begin_group)
414
dev->begin_group(ctx, dev, area, isolated, knockout, blendmode, alpha);
415
}
416
fz_catch(ctx)
417
{
418
dev->error_depth = 1;
419
strcpy(dev->errmess, fz_caught_message(ctx));
420
/* Error swallowed */
421
}
422
}
423
424
void
425
fz_end_group(fz_context *ctx, fz_device *dev)
426
{
427
if (dev->error_depth)
428
{
429
dev->error_depth--;
430
if (dev->error_depth == 0)
431
fz_throw(ctx, FZ_ERROR_GENERIC, "%s", dev->errmess);
432
return;
433
}
434
if (dev->end_group)
435
dev->end_group(ctx, dev);
436
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
437
pop_clip_stack(ctx, dev);
438
}
439
440
void
441
fz_begin_tile(fz_context *ctx, fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm)
442
{
443
(void)fz_begin_tile_id(ctx, dev, area, view, xstep, ystep, ctm, 0);
444
}
445
446
int
447
fz_begin_tile_id(fz_context *ctx, fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id)
448
{
449
int ret = 0;
450
451
if (dev->error_depth)
452
{
453
dev->error_depth++;
454
return 0;
455
}
456
457
if (xstep < 0)
458
xstep = -xstep;
459
if (ystep < 0)
460
ystep = -ystep;
461
462
fz_var(ret);
463
464
fz_try(ctx)
465
{
466
if (dev->begin_tile)
467
ret = dev->begin_tile(ctx, dev, area, view, xstep, ystep, ctm, id);
468
}
469
fz_catch(ctx)
470
{
471
dev->error_depth = 1;
472
strcpy(dev->errmess, fz_caught_message(ctx));
473
/* Error swallowed */
474
}
475
return ret;
476
}
477
478
void
479
fz_end_tile(fz_context *ctx, fz_device *dev)
480
{
481
if (dev->error_depth)
482
{
483
dev->error_depth--;
484
if (dev->error_depth == 0)
485
fz_throw(ctx, FZ_ERROR_GENERIC, "%s", dev->errmess);
486
return;
487
}
488
if (dev->end_tile)
489
dev->end_tile(ctx, dev);
490
}
491
492