Coverage Report

Created: 2024-05-20 06:23

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