Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/harfbuzz/src/hb-paint-extents.cc
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2022 Behdad Esfahbod
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 */
24
25
#include "hb.hh"
26
27
#ifndef HB_NO_PAINT
28
29
#include "hb-paint-extents.hh"
30
31
#include "hb-draw.hh"
32
33
#include "hb-machinery.hh"
34
35
36
/*
37
 * This file implements bounds-extraction computation of COLRv1 fonts as described in:
38
 *
39
 * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness
40
 */
41
42
static void
43
hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED,
44
         void *paint_data,
45
         float xx, float yx,
46
         float xy, float yy,
47
         float dx, float dy,
48
         void *user_data HB_UNUSED)
49
0
{
50
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
51
52
0
  c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy});
53
0
}
54
55
static void
56
hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED,
57
              void *paint_data,
58
        void *user_data HB_UNUSED)
59
0
{
60
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
61
62
0
  c->pop_transform ();
63
0
}
64
65
static void
66
hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
67
          void *paint_data,
68
          hb_codepoint_t glyph,
69
          hb_font_t *font,
70
          void *user_data HB_UNUSED)
71
0
{
72
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
73
74
0
  hb_extents_t extents;
75
0
  hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs ();
76
0
  hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents);
77
0
  c->push_clip (extents);
78
0
}
79
80
static void
81
hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED,
82
              void *paint_data,
83
              float xmin, float ymin, float xmax, float ymax,
84
              void *user_data)
85
0
{
86
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
87
88
0
  hb_extents_t extents = {xmin, ymin, xmax, ymax};
89
0
  c->push_clip (extents);
90
0
}
91
92
static void
93
hb_paint_extents_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED,
94
         void *paint_data,
95
         void *user_data HB_UNUSED)
96
0
{
97
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
98
99
0
  c->pop_clip ();
100
0
}
101
102
static void
103
hb_paint_extents_push_group (hb_paint_funcs_t *funcs HB_UNUSED,
104
           void *paint_data,
105
           void *user_data HB_UNUSED)
106
0
{
107
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
108
109
0
  c->push_group ();
110
0
}
111
112
static void
113
hb_paint_extents_pop_group (hb_paint_funcs_t *funcs HB_UNUSED,
114
          void *paint_data,
115
          hb_paint_composite_mode_t mode,
116
          void *user_data HB_UNUSED)
117
0
{
118
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
119
120
0
  c->pop_group (mode);
121
0
}
122
123
static hb_bool_t
124
hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED,
125
            void *paint_data,
126
            hb_blob_t *blob HB_UNUSED,
127
            unsigned int width HB_UNUSED,
128
            unsigned int height HB_UNUSED,
129
            hb_tag_t format HB_UNUSED,
130
            float slant HB_UNUSED,
131
            hb_glyph_extents_t *glyph_extents,
132
            void *user_data HB_UNUSED)
133
0
{
134
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
135
136
0
  if (!glyph_extents)
137
0
    return false; // Happens with SVG images.
138
139
0
  hb_extents_t extents = {(float) glyph_extents->x_bearing,
140
0
        (float) glyph_extents->y_bearing + glyph_extents->height,
141
0
        (float) glyph_extents->x_bearing + glyph_extents->width,
142
0
        (float) glyph_extents->y_bearing};
143
0
  c->push_clip (extents);
144
0
  c->paint ();
145
0
  c->pop_clip ();
146
147
0
  return true;
148
0
}
149
150
static void
151
hb_paint_extents_paint_color (hb_paint_funcs_t *funcs HB_UNUSED,
152
            void *paint_data,
153
            hb_bool_t use_foreground HB_UNUSED,
154
            hb_color_t color HB_UNUSED,
155
            void *user_data HB_UNUSED)
156
0
{
157
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
158
159
0
  c->paint ();
160
0
}
161
162
static void
163
hb_paint_extents_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
164
                void *paint_data,
165
                hb_color_line_t *color_line HB_UNUSED,
166
                float x0 HB_UNUSED, float y0 HB_UNUSED,
167
                float x1 HB_UNUSED, float y1 HB_UNUSED,
168
                float x2 HB_UNUSED, float y2 HB_UNUSED,
169
                void *user_data HB_UNUSED)
170
0
{
171
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
172
173
0
  c->paint ();
174
0
}
175
176
static void
177
hb_paint_extents_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
178
                void *paint_data,
179
                hb_color_line_t *color_line HB_UNUSED,
180
                float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED,
181
                float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED,
182
                void *user_data HB_UNUSED)
183
0
{
184
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
185
186
0
  c->paint ();
187
0
}
188
189
static void
190
hb_paint_extents_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
191
               void *paint_data,
192
               hb_color_line_t *color_line HB_UNUSED,
193
               float cx HB_UNUSED, float cy HB_UNUSED,
194
               float start_angle HB_UNUSED,
195
               float end_angle HB_UNUSED,
196
               void *user_data HB_UNUSED)
197
0
{
198
0
  hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
199
200
0
  c->paint ();
201
0
}
202
203
static inline void free_static_paint_extents_funcs ();
204
205
static struct hb_paint_extents_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_paint_extents_funcs_lazy_loader_t>
206
{
207
  static hb_paint_funcs_t *create ()
208
0
  {
209
0
    hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
210
211
0
    hb_paint_funcs_set_push_transform_func (funcs, hb_paint_extents_push_transform, nullptr, nullptr);
212
0
    hb_paint_funcs_set_pop_transform_func (funcs, hb_paint_extents_pop_transform, nullptr, nullptr);
213
0
    hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_extents_push_clip_glyph, nullptr, nullptr);
214
0
    hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_extents_push_clip_rectangle, nullptr, nullptr);
215
0
    hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_extents_pop_clip, nullptr, nullptr);
216
0
    hb_paint_funcs_set_push_group_func (funcs, hb_paint_extents_push_group, nullptr, nullptr);
217
0
    hb_paint_funcs_set_pop_group_func (funcs, hb_paint_extents_pop_group, nullptr, nullptr);
218
0
    hb_paint_funcs_set_color_func (funcs, hb_paint_extents_paint_color, nullptr, nullptr);
219
0
    hb_paint_funcs_set_image_func (funcs, hb_paint_extents_paint_image, nullptr, nullptr);
220
0
    hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_extents_paint_linear_gradient, nullptr, nullptr);
221
0
    hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_extents_paint_radial_gradient, nullptr, nullptr);
222
0
    hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_extents_paint_sweep_gradient, nullptr, nullptr);
223
224
0
    hb_paint_funcs_make_immutable (funcs);
225
226
0
    hb_atexit (free_static_paint_extents_funcs);
227
228
0
    return funcs;
229
0
  }
230
} static_paint_extents_funcs;
231
232
static inline
233
void free_static_paint_extents_funcs ()
234
0
{
235
0
  static_paint_extents_funcs.free_instance ();
236
0
}
237
238
hb_paint_funcs_t *
239
hb_paint_extents_get_funcs ()
240
0
{
241
0
  return static_paint_extents_funcs.get_unconst ();
242
0
}
243
244
245
#endif