Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "mupdf/fitz.h"
2
3
#define STACK_SIZE 96
4
5
typedef struct fz_bbox_device_s
6
{
7
fz_device super;
8
9
fz_rect *result;
10
int top;
11
fz_rect stack[STACK_SIZE];
12
/* mask content and tiles are ignored */
13
int ignore;
14
} fz_bbox_device;
15
16
static void
17
fz_bbox_add_rect(fz_context *ctx, fz_device *dev, const fz_rect *rect, int clip)
18
{
19
fz_bbox_device *bdev = (fz_bbox_device*)dev;
20
fz_rect r = *rect;
21
22
if (0 < bdev->top && bdev->top <= STACK_SIZE)
23
{
24
fz_intersect_rect(&r, &bdev->stack[bdev->top-1]);
25
}
26
if (!clip && bdev->top <= STACK_SIZE && !bdev->ignore)
27
{
28
fz_union_rect(bdev->result, &r);
29
}
30
if (clip && ++bdev->top <= STACK_SIZE)
31
{
32
bdev->stack[bdev->top-1] = r;
33
}
34
}
35
36
static void
37
fz_bbox_fill_path(fz_context *ctx, fz_device *dev, fz_path *path, int even_odd, const fz_matrix *ctm,
38
fz_colorspace *colorspace, float *color, float alpha)
39
{
40
fz_rect r;
41
fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, NULL, ctm, &r), 0);
42
}
43
44
static void
45
fz_bbox_stroke_path(fz_context *ctx, fz_device *dev, fz_path *path, fz_stroke_state *stroke,
46
const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha)
47
{
48
fz_rect r;
49
fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, stroke, ctm, &r), 0);
50
}
51
52
static void
53
fz_bbox_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm,
54
fz_colorspace *colorspace, float *color, float alpha)
55
{
56
fz_rect r;
57
fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm, &r), 0);
58
}
59
60
static void
61
fz_bbox_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke,
62
const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha)
63
{
64
fz_rect r;
65
fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, stroke, ctm, &r), 0);
66
}
67
68
static void
69
fz_bbox_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_matrix *ctm, float alpha)
70
{
71
fz_rect r;
72
fz_bbox_add_rect(ctx, dev, fz_bound_shade(ctx, shade, ctm, &r), 0);
73
}
74
75
static void
76
fz_bbox_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, float alpha)
77
{
78
fz_rect r = fz_unit_rect;
79
fz_bbox_add_rect(ctx, dev, fz_transform_rect(&r, ctm), 0);
80
}
81
82
static void
83
fz_bbox_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm,
84
fz_colorspace *colorspace, float *color, float alpha)
85
{
86
fz_rect r = fz_unit_rect;
87
fz_bbox_add_rect(ctx, dev, fz_transform_rect(&r, ctm), 0);
88
}
89
90
static void
91
fz_bbox_clip_path(fz_context *ctx, fz_device *dev, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm)
92
{
93
fz_rect r;
94
fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, NULL, ctm, &r), 1);
95
}
96
97
static void
98
fz_bbox_clip_stroke_path(fz_context *ctx, fz_device *dev, fz_path *path, const fz_rect *rect, fz_stroke_state *stroke, const fz_matrix *ctm)
99
{
100
fz_rect r;
101
fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, stroke, ctm, &r), 1);
102
}
103
104
static void
105
fz_bbox_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate)
106
{
107
fz_rect r = fz_infinite_rect;
108
if (accumulate)
109
fz_bbox_add_rect(ctx, dev, &r, accumulate != 2);
110
else
111
fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm, &r), 1);
112
}
113
114
static void
115
fz_bbox_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm)
116
{
117
fz_rect r;
118
fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, stroke, ctm, &r), 1);
119
}
120
121
static void
122
fz_bbox_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_rect *rect, const fz_matrix *ctm)
123
{
124
fz_rect r = fz_unit_rect;
125
fz_bbox_add_rect(ctx, dev, fz_transform_rect(&r, ctm), 1);
126
}
127
128
static void
129
fz_bbox_pop_clip(fz_context *ctx, fz_device *dev)
130
{
131
fz_bbox_device *bdev = (fz_bbox_device*)dev;
132
if (bdev->top > 0)
133
bdev->top--;
134
else
135
fz_warn(ctx, "unexpected pop clip");
136
}
137
138
static void
139
fz_bbox_begin_mask(fz_context *ctx, fz_device *dev, const fz_rect *rect, int luminosity, fz_colorspace *colorspace, float *color)
140
{
141
fz_bbox_device *bdev = (fz_bbox_device*)dev;
142
fz_bbox_add_rect(ctx, dev, rect, 1);
143
bdev->ignore++;
144
}
145
146
static void
147
fz_bbox_end_mask(fz_context *ctx, fz_device *dev)
148
{
149
fz_bbox_device *bdev = (fz_bbox_device*)dev;
150
assert(bdev->ignore > 0);
151
bdev->ignore--;
152
}
153
154
static void
155
fz_bbox_begin_group(fz_context *ctx, fz_device *dev, const fz_rect *rect, int isolated, int knockout, int blendmode, float alpha)
156
{
157
fz_bbox_add_rect(ctx, dev, rect, 1);
158
}
159
160
static void
161
fz_bbox_end_group(fz_context *ctx, fz_device *dev)
162
{
163
fz_bbox_pop_clip(ctx, dev);
164
}
165
166
static int
167
fz_bbox_begin_tile(fz_context *ctx, fz_device *dev, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id)
168
{
169
fz_bbox_device *bdev = (fz_bbox_device*)dev;
170
fz_rect r = *area;
171
fz_bbox_add_rect(ctx, dev, fz_transform_rect(&r, ctm), 0);
172
bdev->ignore++;
173
return 0;
174
}
175
176
static void
177
fz_bbox_end_tile(fz_context *ctx, fz_device *dev)
178
{
179
fz_bbox_device *bdev = (fz_bbox_device*)dev;
180
assert(bdev->ignore > 0);
181
bdev->ignore--;
182
}
183
184
static void
185
fz_bbox_drop_imp(fz_context *ctx, fz_device *dev)
186
{
187
fz_bbox_device *bdev = (fz_bbox_device*)dev;
188
if (bdev->top > 0)
189
fz_warn(ctx, "items left on stack in bbox device: %d", bdev->top);
190
}
191
192
fz_device *
193
fz_new_bbox_device(fz_context *ctx, fz_rect *result)
194
{
195
fz_bbox_device *dev = fz_new_device(ctx, sizeof *dev);
196
197
dev->super.drop_imp = fz_bbox_drop_imp;
198
199
dev->super.fill_path = fz_bbox_fill_path;
200
dev->super.stroke_path = fz_bbox_stroke_path;
201
dev->super.clip_path = fz_bbox_clip_path;
202
dev->super.clip_stroke_path = fz_bbox_clip_stroke_path;
203
204
dev->super.fill_text = fz_bbox_fill_text;
205
dev->super.stroke_text = fz_bbox_stroke_text;
206
dev->super.clip_text = fz_bbox_clip_text;
207
dev->super.clip_stroke_text = fz_bbox_clip_stroke_text;
208
209
dev->super.fill_shade = fz_bbox_fill_shade;
210
dev->super.fill_image = fz_bbox_fill_image;
211
dev->super.fill_image_mask = fz_bbox_fill_image_mask;
212
dev->super.clip_image_mask = fz_bbox_clip_image_mask;
213
214
dev->super.pop_clip = fz_bbox_pop_clip;
215
216
dev->super.begin_mask = fz_bbox_begin_mask;
217
dev->super.end_mask = fz_bbox_end_mask;
218
dev->super.begin_group = fz_bbox_begin_group;
219
dev->super.end_group = fz_bbox_end_group;
220
221
dev->super.begin_tile = fz_bbox_begin_tile;
222
dev->super.end_tile = fz_bbox_end_tile;
223
224
dev->result = result;
225
dev->top = 0;
226
dev->ignore = 0;
227
228
*result = fz_empty_rect;
229
230
return (fz_device*)dev;
231
}
232
233