Coverage Report

Created: 2023-06-07 06:20

/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
18.5k
#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
8.83k
{
43
8.83k
  fz_bbox_device *bdev = (fz_bbox_device*)dev;
44
45
8.83k
  if (0 < bdev->top && bdev->top <= STACK_SIZE)
46
918
  {
47
918
    rect = fz_intersect_rect(rect, bdev->stack[bdev->top-1]);
48
918
  }
49
8.83k
  if (!clip && bdev->top <= STACK_SIZE && !bdev->ignore)
50
8.01k
  {
51
8.01k
    *bdev->result = fz_union_rect(*bdev->result, rect);
52
8.01k
  }
53
8.83k
  if (clip && ++bdev->top <= STACK_SIZE)
54
821
  {
55
821
    bdev->stack[bdev->top-1] = rect;
56
821
  }
57
8.83k
}
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
1.66k
{
63
1.66k
  fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, NULL, ctm), 0);
64
1.66k
}
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
703
{
70
703
  fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, stroke, ctm), 0);
71
703
}
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
247
{
77
247
  fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm), 0);
78
247
}
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
105
{
84
105
  fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, stroke, ctm), 0);
85
105
}
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
3.06k
{
96
3.06k
  fz_bbox_add_rect(ctx, dev, fz_transform_rect(fz_unit_rect, ctm), 0);
97
3.06k
}
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
2.21k
{
103
2.21k
  fz_bbox_add_rect(ctx, dev, fz_transform_rect(fz_unit_rect, ctm), 0);
104
2.21k
}
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
801
{
109
801
  fz_bbox_add_rect(ctx, dev, fz_bound_path(ctx, path, NULL, ctm), 1);
110
801
}
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
20
{
121
20
  fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm), 1);
122
20
}
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
821
{
139
821
  fz_bbox_device *bdev = (fz_bbox_device*)dev;
140
821
  if (bdev->top > 0)
141
821
    bdev->top--;
142
0
  else
143
0
    fz_warn(ctx, "unexpected pop clip");
144
821
}
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)
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
9
{
177
9
  fz_bbox_device *bdev = (fz_bbox_device*)dev;
178
9
  fz_bbox_add_rect(ctx, dev, fz_transform_rect(area, ctm), 0);
179
9
  bdev->ignore++;
180
9
  return 0;
181
9
}
182
183
static void
184
fz_bbox_end_tile(fz_context *ctx, fz_device *dev)
185
9
{
186
9
  fz_bbox_device *bdev = (fz_bbox_device*)dev;
187
9
  assert(bdev->ignore > 0);
188
9
  bdev->ignore--;
189
9
}
190
191
fz_device *
192
fz_new_bbox_device(fz_context *ctx, fz_rect *result)
193
4.19k
{
194
4.19k
  fz_bbox_device *dev = fz_new_derived_device(ctx, fz_bbox_device);
195
196
4.19k
  dev->super.fill_path = fz_bbox_fill_path;
197
4.19k
  dev->super.stroke_path = fz_bbox_stroke_path;
198
4.19k
  dev->super.clip_path = fz_bbox_clip_path;
199
4.19k
  dev->super.clip_stroke_path = fz_bbox_clip_stroke_path;
200
201
4.19k
  dev->super.fill_text = fz_bbox_fill_text;
202
4.19k
  dev->super.stroke_text = fz_bbox_stroke_text;
203
4.19k
  dev->super.clip_text = fz_bbox_clip_text;
204
4.19k
  dev->super.clip_stroke_text = fz_bbox_clip_stroke_text;
205
206
4.19k
  dev->super.fill_shade = fz_bbox_fill_shade;
207
4.19k
  dev->super.fill_image = fz_bbox_fill_image;
208
4.19k
  dev->super.fill_image_mask = fz_bbox_fill_image_mask;
209
4.19k
  dev->super.clip_image_mask = fz_bbox_clip_image_mask;
210
211
4.19k
  dev->super.pop_clip = fz_bbox_pop_clip;
212
213
4.19k
  dev->super.begin_mask = fz_bbox_begin_mask;
214
4.19k
  dev->super.end_mask = fz_bbox_end_mask;
215
4.19k
  dev->super.begin_group = fz_bbox_begin_group;
216
4.19k
  dev->super.end_group = fz_bbox_end_group;
217
218
4.19k
  dev->super.begin_tile = fz_bbox_begin_tile;
219
4.19k
  dev->super.end_tile = fz_bbox_end_tile;
220
221
4.19k
  dev->result = result;
222
4.19k
  dev->top = 0;
223
4.19k
  dev->ignore = 0;
224
225
4.19k
  *result = fz_empty_rect;
226
227
4.19k
  return (fz_device*)dev;
228
4.19k
}