/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 |