Coverage Report

Created: 2024-05-20 06:23

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