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