/src/mupdf/source/fitz/bbox-device.c
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (C) 2004-2021 Artifex Software, Inc. |
2 | | // |
3 | | // This file is part of MuPDF. |
4 | | // |
5 | | // MuPDF is free software: you can redistribute it and/or modify it under the |
6 | | // terms of the GNU Affero General Public License as published by the Free |
7 | | // Software Foundation, either version 3 of the License, or (at your option) |
8 | | // any later version. |
9 | | // |
10 | | // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY |
11 | | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12 | | // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
13 | | // details. |
14 | | // |
15 | | // You should have received a copy of the GNU Affero General Public License |
16 | | // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> |
17 | | // |
18 | | // Alternative licensing terms are available from the licensor. |
19 | | // For commercial licensing, see <https://www.artifex.com/> or contact |
20 | | // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
21 | | // CA 94129, USA, for further information. |
22 | | |
23 | | #include "mupdf/fitz.h" |
24 | | |
25 | | #include <assert.h> |
26 | | |
27 | 13.7k | #define STACK_SIZE 96 |
28 | | |
29 | | typedef struct fz_bbox_device_s |
30 | | { |
31 | | fz_device super; |
32 | | |
33 | | fz_rect *result; |
34 | | int top; |
35 | | fz_rect stack[STACK_SIZE]; |
36 | | /* mask content and tiles are ignored */ |
37 | | int ignore; |
38 | | } fz_bbox_device; |
39 | | |
40 | | static void |
41 | | fz_bbox_add_rect(fz_context *ctx, fz_device *dev, fz_rect rect, int clip) |
42 | 6.46k | { |
43 | 6.46k | fz_bbox_device *bdev = (fz_bbox_device*)dev; |
44 | | |
45 | 6.46k | if (0 < bdev->top && bdev->top <= STACK_SIZE) |
46 | 825 | { |
47 | 825 | rect = fz_intersect_rect(rect, bdev->stack[bdev->top-1]); |
48 | 825 | } |
49 | 6.46k | if (!clip && bdev->top <= STACK_SIZE && !bdev->ignore) |
50 | 5.68k | { |
51 | 5.68k | *bdev->result = fz_union_rect(*bdev->result, rect); |
52 | 5.68k | } |
53 | 6.46k | if (clip && ++bdev->top <= STACK_SIZE) |
54 | 769 | { |
55 | 769 | bdev->stack[bdev->top-1] = rect; |
56 | 769 | } |
57 | 6.46k | } |
58 | | |
59 | | static void |
60 | | fz_bbox_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, |
61 | | fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) |
62 | 740 | { |
63 | 740 | fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, NULL, ctm), 0); |
64 | 740 | } |
65 | | |
66 | | static void |
67 | | fz_bbox_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, |
68 | | fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) |
69 | 659 | { |
70 | 659 | fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, stroke, ctm), 0); |
71 | 659 | } |
72 | | |
73 | | static void |
74 | | fz_bbox_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, |
75 | | fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) |
76 | 179 | { |
77 | 179 | fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm), 0); |
78 | 179 | } |
79 | | |
80 | | static void |
81 | | fz_bbox_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, |
82 | | fz_matrix ctm, fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) |
83 | 46 | { |
84 | 46 | fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, stroke, ctm), 0); |
85 | 46 | } |
86 | | |
87 | | static void |
88 | | fz_bbox_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha, fz_color_params color_params) |
89 | 0 | { |
90 | 0 | fz_bbox_add_rect(ctx, dev, fz_bound_shade(ctx, shade, ctm), 0); |
91 | 0 | } |
92 | | |
93 | | static void |
94 | | fz_bbox_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, float alpha, fz_color_params color_params) |
95 | 596 | { |
96 | 596 | fz_bbox_add_rect(ctx, dev, fz_transform_rect(fz_unit_rect, ctm), 0); |
97 | 596 | } |
98 | | |
99 | | static void |
100 | | fz_bbox_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, |
101 | | fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) |
102 | 3.45k | { |
103 | 3.45k | fz_bbox_add_rect(ctx, dev, fz_transform_rect(fz_unit_rect, ctm), 0); |
104 | 3.45k | } |
105 | | |
106 | | static void |
107 | | fz_bbox_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_rect scissor) |
108 | 733 | { |
109 | 733 | fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, NULL, ctm), 1); |
110 | 733 | } |
111 | | |
112 | | static void |
113 | | fz_bbox_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor) |
114 | 0 | { |
115 | 0 | fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, stroke, ctm), 1); |
116 | 0 | } |
117 | | |
118 | | static void |
119 | | fz_bbox_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_rect scissor) |
120 | 36 | { |
121 | 36 | fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm), 1); |
122 | 36 | } |
123 | | |
124 | | static void |
125 | | fz_bbox_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor) |
126 | 0 | { |
127 | 0 | fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, stroke, ctm), 1); |
128 | 0 | } |
129 | | |
130 | | static void |
131 | | fz_bbox_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_rect scissor) |
132 | 0 | { |
133 | 0 | fz_bbox_add_rect(ctx, dev, fz_transform_rect(fz_unit_rect, ctm), 1); |
134 | 0 | } |
135 | | |
136 | | static void |
137 | | fz_bbox_pop_clip(fz_context *ctx, fz_device *dev) |
138 | 769 | { |
139 | 769 | fz_bbox_device *bdev = (fz_bbox_device*)dev; |
140 | 769 | if (bdev->top > 0) |
141 | 769 | bdev->top--; |
142 | 0 | else |
143 | 0 | fz_warn(ctx, "unexpected pop clip"); |
144 | 769 | } |
145 | | |
146 | | static void |
147 | | fz_bbox_begin_mask(fz_context *ctx, fz_device *dev, fz_rect rect, int luminosity, fz_colorspace *colorspace, const float *color, fz_color_params color_params) |
148 | 0 | { |
149 | 0 | fz_bbox_device *bdev = (fz_bbox_device*)dev; |
150 | 0 | fz_bbox_add_rect(ctx, dev, rect, 1); |
151 | 0 | bdev->ignore++; |
152 | 0 | } |
153 | | |
154 | | static void |
155 | | fz_bbox_end_mask(fz_context *ctx, fz_device *dev, fz_function *tr) |
156 | 0 | { |
157 | 0 | fz_bbox_device *bdev = (fz_bbox_device*)dev; |
158 | 0 | assert(bdev->ignore > 0); |
159 | 0 | bdev->ignore--; |
160 | 0 | } |
161 | | |
162 | | static void |
163 | | fz_bbox_begin_group(fz_context *ctx, fz_device *dev, fz_rect rect, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha) |
164 | 0 | { |
165 | 0 | fz_bbox_add_rect(ctx, dev, rect, 1); |
166 | 0 | } |
167 | | |
168 | | static void |
169 | | fz_bbox_end_group(fz_context *ctx, fz_device *dev) |
170 | 0 | { |
171 | 0 | fz_bbox_pop_clip(ctx, dev); |
172 | 0 | } |
173 | | |
174 | | static int |
175 | | fz_bbox_begin_tile(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id) |
176 | 25 | { |
177 | 25 | fz_bbox_device *bdev = (fz_bbox_device*)dev; |
178 | 25 | fz_bbox_add_rect(ctx, dev, fz_transform_rect(area, ctm), 0); |
179 | 25 | bdev->ignore++; |
180 | 25 | return 0; |
181 | 25 | } |
182 | | |
183 | | static void |
184 | | fz_bbox_end_tile(fz_context *ctx, fz_device *dev) |
185 | 25 | { |
186 | 25 | fz_bbox_device *bdev = (fz_bbox_device*)dev; |
187 | 25 | assert(bdev->ignore > 0); |
188 | 25 | bdev->ignore--; |
189 | 25 | } |
190 | | |
191 | | fz_device * |
192 | | fz_new_bbox_device(fz_context *ctx, fz_rect *result) |
193 | 4.58k | { |
194 | 4.58k | fz_bbox_device *dev = fz_new_derived_device(ctx, fz_bbox_device); |
195 | | |
196 | 4.58k | dev->super.fill_path = fz_bbox_fill_path; |
197 | 4.58k | dev->super.stroke_path = fz_bbox_stroke_path; |
198 | 4.58k | dev->super.clip_path = fz_bbox_clip_path; |
199 | 4.58k | dev->super.clip_stroke_path = fz_bbox_clip_stroke_path; |
200 | | |
201 | 4.58k | dev->super.fill_text = fz_bbox_fill_text; |
202 | 4.58k | dev->super.stroke_text = fz_bbox_stroke_text; |
203 | 4.58k | dev->super.clip_text = fz_bbox_clip_text; |
204 | 4.58k | dev->super.clip_stroke_text = fz_bbox_clip_stroke_text; |
205 | | |
206 | 4.58k | dev->super.fill_shade = fz_bbox_fill_shade; |
207 | 4.58k | dev->super.fill_image = fz_bbox_fill_image; |
208 | 4.58k | dev->super.fill_image_mask = fz_bbox_fill_image_mask; |
209 | 4.58k | dev->super.clip_image_mask = fz_bbox_clip_image_mask; |
210 | | |
211 | 4.58k | dev->super.pop_clip = fz_bbox_pop_clip; |
212 | | |
213 | 4.58k | dev->super.begin_mask = fz_bbox_begin_mask; |
214 | 4.58k | dev->super.end_mask = fz_bbox_end_mask; |
215 | 4.58k | dev->super.begin_group = fz_bbox_begin_group; |
216 | 4.58k | dev->super.end_group = fz_bbox_end_group; |
217 | | |
218 | 4.58k | dev->super.begin_tile = fz_bbox_begin_tile; |
219 | 4.58k | dev->super.end_tile = fz_bbox_end_tile; |
220 | | |
221 | 4.58k | dev->result = result; |
222 | 4.58k | dev->top = 0; |
223 | 4.58k | dev->ignore = 0; |
224 | | |
225 | 4.58k | *result = fz_empty_rect; |
226 | | |
227 | 4.58k | return (fz_device*)dev; |
228 | 4.58k | } |