Bug 1862332 [wpt PR 42877] - WebKit export of https://bugs.webkit.org/show_bug.cgi...
[gecko.git] / gfx / harfbuzz / src / hb-paint-extents.cc
blob2393322b715aa82036323039585cb4afea016f8e
1 /*
2 * Copyright © 2022 Behdad Esfahbod
4 * This is part of HarfBuzz, a text shaping library.
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.
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.
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.
25 #include "hb.hh"
27 #ifndef HB_NO_PAINT
29 #include "hb-paint-extents.hh"
31 #include "hb-draw.h"
33 #include "hb-machinery.hh"
37 * This file implements bounds-extraction as well as boundedness
38 * computation of COLRv1 fonts as described in:
40 * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness
43 static void
44 hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED,
45 void *paint_data,
46 float xx, float yx,
47 float xy, float yy,
48 float dx, float dy,
49 void *user_data HB_UNUSED)
51 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
53 c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy});
56 static void
57 hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED,
58 void *paint_data,
59 void *user_data HB_UNUSED)
61 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
63 c->pop_transform ();
66 static void
67 hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
68 void *data,
69 hb_draw_state_t *st,
70 float to_x, float to_y,
71 void *user_data HB_UNUSED)
73 hb_extents_t *extents = (hb_extents_t *) data;
75 extents->add_point (to_x, to_y);
78 static void
79 hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
80 void *data,
81 hb_draw_state_t *st,
82 float to_x, float to_y,
83 void *user_data HB_UNUSED)
85 hb_extents_t *extents = (hb_extents_t *) data;
87 extents->add_point (to_x, to_y);
90 static void
91 hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
92 void *data,
93 hb_draw_state_t *st,
94 float control_x, float control_y,
95 float to_x, float to_y,
96 void *user_data HB_UNUSED)
98 hb_extents_t *extents = (hb_extents_t *) data;
100 extents->add_point (control_x, control_y);
101 extents->add_point (to_x, to_y);
104 static void
105 hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
106 void *data,
107 hb_draw_state_t *st,
108 float control1_x, float control1_y,
109 float control2_x, float control2_y,
110 float to_x, float to_y,
111 void *user_data HB_UNUSED)
113 hb_extents_t *extents = (hb_extents_t *) data;
115 extents->add_point (control1_x, control1_y);
116 extents->add_point (control2_x, control2_y);
117 extents->add_point (to_x, to_y);
120 static inline void free_static_draw_extents_funcs ();
122 static struct hb_draw_extents_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_draw_extents_funcs_lazy_loader_t>
124 static hb_draw_funcs_t *create ()
126 hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
128 hb_draw_funcs_set_move_to_func (funcs, hb_draw_extents_move_to, nullptr, nullptr);
129 hb_draw_funcs_set_line_to_func (funcs, hb_draw_extents_line_to, nullptr, nullptr);
130 hb_draw_funcs_set_quadratic_to_func (funcs, hb_draw_extents_quadratic_to, nullptr, nullptr);
131 hb_draw_funcs_set_cubic_to_func (funcs, hb_draw_extents_cubic_to, nullptr, nullptr);
133 hb_draw_funcs_make_immutable (funcs);
135 hb_atexit (free_static_draw_extents_funcs);
137 return funcs;
139 } static_draw_extents_funcs;
141 static inline
142 void free_static_draw_extents_funcs ()
144 static_draw_extents_funcs.free_instance ();
147 static hb_draw_funcs_t *
148 hb_draw_extents_get_funcs ()
150 return static_draw_extents_funcs.get_unconst ();
153 static void
154 hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
155 void *paint_data,
156 hb_codepoint_t glyph,
157 hb_font_t *font,
158 void *user_data HB_UNUSED)
160 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
162 hb_extents_t extents;
163 hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs ();
164 hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents);
165 c->push_clip (extents);
168 static void
169 hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED,
170 void *paint_data,
171 float xmin, float ymin, float xmax, float ymax,
172 void *user_data)
174 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
176 hb_extents_t extents = {xmin, ymin, xmax, ymax};
177 c->push_clip (extents);
180 static void
181 hb_paint_extents_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED,
182 void *paint_data,
183 void *user_data HB_UNUSED)
185 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
187 c->pop_clip ();
190 static void
191 hb_paint_extents_push_group (hb_paint_funcs_t *funcs HB_UNUSED,
192 void *paint_data,
193 void *user_data HB_UNUSED)
195 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
197 c->push_group ();
200 static void
201 hb_paint_extents_pop_group (hb_paint_funcs_t *funcs HB_UNUSED,
202 void *paint_data,
203 hb_paint_composite_mode_t mode,
204 void *user_data HB_UNUSED)
206 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
208 c->pop_group (mode);
211 static hb_bool_t
212 hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED,
213 void *paint_data,
214 hb_blob_t *blob HB_UNUSED,
215 unsigned int width HB_UNUSED,
216 unsigned int height HB_UNUSED,
217 hb_tag_t format HB_UNUSED,
218 float slant HB_UNUSED,
219 hb_glyph_extents_t *glyph_extents,
220 void *user_data HB_UNUSED)
222 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
224 hb_extents_t extents = {(float) glyph_extents->x_bearing,
225 (float) glyph_extents->y_bearing + glyph_extents->height,
226 (float) glyph_extents->x_bearing + glyph_extents->width,
227 (float) glyph_extents->y_bearing};
228 c->push_clip (extents);
229 c->paint ();
230 c->pop_clip ();
232 return true;
235 static void
236 hb_paint_extents_paint_color (hb_paint_funcs_t *funcs HB_UNUSED,
237 void *paint_data,
238 hb_bool_t use_foreground HB_UNUSED,
239 hb_color_t color HB_UNUSED,
240 void *user_data HB_UNUSED)
242 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
244 c->paint ();
247 static void
248 hb_paint_extents_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
249 void *paint_data,
250 hb_color_line_t *color_line HB_UNUSED,
251 float x0 HB_UNUSED, float y0 HB_UNUSED,
252 float x1 HB_UNUSED, float y1 HB_UNUSED,
253 float x2 HB_UNUSED, float y2 HB_UNUSED,
254 void *user_data HB_UNUSED)
256 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
258 c->paint ();
261 static void
262 hb_paint_extents_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
263 void *paint_data,
264 hb_color_line_t *color_line HB_UNUSED,
265 float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED,
266 float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED,
267 void *user_data HB_UNUSED)
269 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
271 c->paint ();
274 static void
275 hb_paint_extents_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
276 void *paint_data,
277 hb_color_line_t *color_line HB_UNUSED,
278 float cx HB_UNUSED, float cy HB_UNUSED,
279 float start_angle HB_UNUSED,
280 float end_angle HB_UNUSED,
281 void *user_data HB_UNUSED)
283 hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
285 c->paint ();
288 static inline void free_static_paint_extents_funcs ();
290 static struct hb_paint_extents_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_paint_extents_funcs_lazy_loader_t>
292 static hb_paint_funcs_t *create ()
294 hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
296 hb_paint_funcs_set_push_transform_func (funcs, hb_paint_extents_push_transform, nullptr, nullptr);
297 hb_paint_funcs_set_pop_transform_func (funcs, hb_paint_extents_pop_transform, nullptr, nullptr);
298 hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_extents_push_clip_glyph, nullptr, nullptr);
299 hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_extents_push_clip_rectangle, nullptr, nullptr);
300 hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_extents_pop_clip, nullptr, nullptr);
301 hb_paint_funcs_set_push_group_func (funcs, hb_paint_extents_push_group, nullptr, nullptr);
302 hb_paint_funcs_set_pop_group_func (funcs, hb_paint_extents_pop_group, nullptr, nullptr);
303 hb_paint_funcs_set_color_func (funcs, hb_paint_extents_paint_color, nullptr, nullptr);
304 hb_paint_funcs_set_image_func (funcs, hb_paint_extents_paint_image, nullptr, nullptr);
305 hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_extents_paint_linear_gradient, nullptr, nullptr);
306 hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_extents_paint_radial_gradient, nullptr, nullptr);
307 hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_extents_paint_sweep_gradient, nullptr, nullptr);
309 hb_paint_funcs_make_immutable (funcs);
311 hb_atexit (free_static_paint_extents_funcs);
313 return funcs;
315 } static_paint_extents_funcs;
317 static inline
318 void free_static_paint_extents_funcs ()
320 static_paint_extents_funcs.free_instance ();
323 hb_paint_funcs_t *
324 hb_paint_extents_get_funcs ()
326 return static_paint_extents_funcs.get_unconst ();
330 #endif