comparison mupdf-source/source/fitz/draw-rasterize.c @ 3:2c135c81b16c

MERGE: upstream PyMuPDF 1.26.4 with MuPDF 1.26.7
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:44:09 +0200
parents b50eed0cc0ef
children
comparison
equal deleted inserted replaced
0:6015a75abc2d 3:2c135c81b16c
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 "draw-imp.h"
26 #include "pixmap-imp.h"
27
28 #include <string.h>
29
30 void fz_init_aa_context(fz_context *ctx)
31 {
32 #ifndef AA_BITS
33 ctx->aa.hscale = 17;
34 ctx->aa.vscale = 15;
35 ctx->aa.scale = 256;
36 ctx->aa.bits = 8;
37 ctx->aa.text_bits = 8;
38 #endif
39 }
40
41 int
42 fz_aa_level(fz_context *ctx)
43 {
44 return fz_aa_bits;
45 }
46
47 int
48 fz_graphics_aa_level(fz_context *ctx)
49 {
50 return fz_aa_bits;
51 }
52
53 int
54 fz_text_aa_level(fz_context *ctx)
55 {
56 return fz_aa_text_bits;
57 }
58
59 int
60 fz_rasterizer_graphics_aa_level(fz_rasterizer *ras)
61 {
62 return fz_rasterizer_aa_bits(ras);
63 }
64
65 int
66 fz_rasterizer_text_aa_level(fz_rasterizer *ras)
67 {
68 return fz_rasterizer_aa_text_bits(ras);
69 }
70
71 void
72 fz_set_rasterizer_text_aa_level(fz_context *ctx, fz_aa_context *aa, int level)
73 {
74 #ifdef AA_BITS
75 if (level != fz_aa_bits)
76 {
77 if (fz_aa_bits == 10)
78 fz_warn(ctx, "Only the Any-part-of-a-pixel rasterizer was compiled in");
79 else if (fz_aa_bits == 9)
80 fz_warn(ctx, "Only the Centre-of-a-pixel rasterizer was compiled in");
81 else
82 fz_warn(ctx, "Only the %d bit anti-aliasing rasterizer was compiled in", fz_aa_bits);
83 }
84 #else
85 if (level > 8)
86 aa->text_bits = 0;
87 else if (level > 6)
88 aa->text_bits = 8;
89 else if (level > 4)
90 aa->text_bits = 6;
91 else if (level > 2)
92 aa->text_bits = 4;
93 else if (level > 0)
94 aa->text_bits = 2;
95 else
96 aa->text_bits = 0;
97 #endif
98 }
99
100 void
101 fz_set_rasterizer_graphics_aa_level(fz_context *ctx, fz_aa_context *aa, int level)
102 {
103 #ifdef AA_BITS
104 if (level != fz_aa_bits)
105 {
106 if (fz_aa_bits == 10)
107 fz_warn(ctx, "Only the Any-part-of-a-pixel rasterizer was compiled in");
108 else if (fz_aa_bits == 9)
109 fz_warn(ctx, "Only the Centre-of-a-pixel rasterizer was compiled in");
110 else
111 fz_warn(ctx, "Only the %d bit anti-aliasing rasterizer was compiled in", fz_aa_bits);
112 }
113 #else
114 if (level == 9 || level == 10)
115 {
116 aa->hscale = 1;
117 aa->vscale = 1;
118 aa->bits = level;
119 }
120 else if (level > 6)
121 {
122 aa->hscale = 17;
123 aa->vscale = 15;
124 aa->bits = 8;
125 }
126 else if (level > 4)
127 {
128 aa->hscale = 8;
129 aa->vscale = 8;
130 aa->bits = 6;
131 }
132 else if (level > 2)
133 {
134 aa->hscale = 5;
135 aa->vscale = 3;
136 aa->bits = 4;
137 }
138 else if (level > 0)
139 {
140 aa->hscale = 2;
141 aa->vscale = 2;
142 aa->bits = 2;
143 }
144 else
145 {
146 aa->hscale = 1;
147 aa->vscale = 1;
148 aa->bits = 0;
149 }
150 aa->scale = 0xFF00 / (aa->hscale * aa->vscale);
151 #endif
152 }
153
154 void
155 fz_set_aa_level(fz_context *ctx, int level)
156 {
157 fz_set_rasterizer_graphics_aa_level(ctx, &ctx->aa, level);
158 fz_set_rasterizer_text_aa_level(ctx, &ctx->aa, level);
159 }
160
161 void
162 fz_set_text_aa_level(fz_context *ctx, int level)
163 {
164 fz_set_rasterizer_text_aa_level(ctx, &ctx->aa, level);
165 }
166
167 void
168 fz_set_graphics_aa_level(fz_context *ctx, int level)
169 {
170 fz_set_rasterizer_graphics_aa_level(ctx, &ctx->aa, level);
171 }
172
173 void
174 fz_set_graphics_min_line_width(fz_context *ctx, float min_line_width)
175 {
176 ctx->aa.min_line_width = min_line_width;
177 }
178
179 float
180 fz_graphics_min_line_width(fz_context *ctx)
181 {
182 return ctx->aa.min_line_width;
183 }
184
185 float
186 fz_rasterizer_graphics_min_line_width(fz_rasterizer *ras)
187 {
188 return ras->aa.min_line_width;
189 }
190
191 fz_irect
192 fz_bound_rasterizer(fz_context *ctx, const fz_rasterizer *rast)
193 {
194 fz_irect bbox;
195 const int hscale = fz_rasterizer_aa_hscale(rast);
196 const int vscale = fz_rasterizer_aa_vscale(rast);
197
198 if (rast->bbox.x1 < rast->bbox.x0 || rast->bbox.y1 < rast->bbox.y0)
199 {
200 bbox = fz_empty_irect;
201 }
202 else
203 {
204 bbox.x0 = fz_idiv(rast->bbox.x0, hscale);
205 bbox.y0 = fz_idiv(rast->bbox.y0, vscale);
206 bbox.x1 = fz_idiv_up(rast->bbox.x1, hscale);
207 bbox.y1 = fz_idiv_up(rast->bbox.y1, vscale);
208 }
209 return bbox;
210 }
211
212 fz_rect fz_scissor_rasterizer(fz_context *ctx, const fz_rasterizer *rast)
213 {
214 fz_rect r;
215 const int hscale = fz_rasterizer_aa_hscale(rast);
216 const int vscale = fz_rasterizer_aa_vscale(rast);
217
218 r.x0 = ((float)rast->clip.x0) / hscale;
219 r.y0 = ((float)rast->clip.y0) / vscale;
220 r.x1 = ((float)rast->clip.x1) / hscale;
221 r.y1 = ((float)rast->clip.y1) / vscale;
222
223 return r;
224 }
225
226 static fz_irect fz_clip_rasterizer(fz_context *ctx, const fz_rasterizer *rast)
227 {
228 fz_irect r;
229 const int hscale = fz_rasterizer_aa_hscale(rast);
230 const int vscale = fz_rasterizer_aa_vscale(rast);
231
232 r.x0 = fz_idiv(rast->clip.x0, hscale);
233 r.y0 = fz_idiv(rast->clip.y0, vscale);
234 r.x1 = fz_idiv_up(rast->clip.x1, hscale);
235 r.y1 = fz_idiv_up(rast->clip.y1, vscale);
236
237 return r;
238 }
239
240 int fz_reset_rasterizer(fz_context *ctx, fz_rasterizer *rast, fz_irect clip)
241 {
242 const int hscale = fz_rasterizer_aa_hscale(rast);
243 const int vscale = fz_rasterizer_aa_vscale(rast);
244
245 if (fz_is_infinite_irect(clip))
246 {
247 rast->clip.x0 = rast->clip.y0 = BBOX_MIN;
248 rast->clip.x1 = rast->clip.y1 = BBOX_MAX;
249 }
250 else {
251 rast->clip.x0 = clip.x0 * hscale;
252 rast->clip.x1 = clip.x1 * hscale;
253 rast->clip.y0 = clip.y0 * vscale;
254 rast->clip.y1 = clip.y1 * vscale;
255 }
256
257 rast->bbox.x0 = rast->bbox.y0 = BBOX_MAX;
258 rast->bbox.x1 = rast->bbox.y1 = BBOX_MIN;
259
260 if (rast->fns.reset)
261 return rast->fns.reset(ctx, rast);
262 return 0;
263 }
264
265 void *fz_new_rasterizer_of_size(fz_context *ctx, int size, const fz_rasterizer_fns *fns)
266 {
267 fz_rasterizer *rast = fz_calloc(ctx, 1, size);
268
269 rast->fns = *fns;
270 rast->clip.x0 = rast->clip.y0 = BBOX_MIN;
271 rast->clip.x1 = rast->clip.y1 = BBOX_MAX;
272
273 rast->bbox.x0 = rast->bbox.y0 = BBOX_MAX;
274 rast->bbox.x1 = rast->bbox.y1 = BBOX_MIN;
275
276 return rast;
277 }
278
279 fz_rasterizer *fz_new_rasterizer(fz_context *ctx, const fz_aa_context *aa)
280 {
281 fz_rasterizer *r;
282 int bits;
283
284 #ifdef AA_BITS
285 bits = AA_BITS;
286 #else
287 if (aa == NULL)
288 aa = &ctx->aa;
289 bits = aa->bits;
290 #endif
291 if (bits == 10)
292 r = fz_new_edgebuffer(ctx, FZ_EDGEBUFFER_ANY_PART_OF_PIXEL);
293 else if (bits == 9)
294 r = fz_new_edgebuffer(ctx, FZ_EDGEBUFFER_CENTER_OF_PIXEL);
295 else
296 r = fz_new_gel(ctx);
297 #ifndef AA_BITS
298 r->aa = *aa;
299 #endif
300
301 return r;
302 }
303
304 void fz_convert_rasterizer(fz_context *ctx, fz_rasterizer *r, int eofill, fz_pixmap *pix, unsigned char *colorbv, fz_overprint *eop)
305 {
306 fz_irect clip = fz_bound_rasterizer(ctx, r);
307 clip = fz_intersect_irect(clip, fz_pixmap_bbox_no_ctx(pix));
308 clip = fz_intersect_irect(clip, fz_clip_rasterizer(ctx, r));
309 if (!fz_is_empty_irect(clip))
310 r->fns.convert(ctx, r, eofill, &clip, pix, colorbv, eop);
311 }