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