/src/harfbuzz/src/hb-draw.cc
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright © 2019-2020 Ebrahim Byagowi |
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_DRAW |
28 | | |
29 | | #include "hb-draw.hh" |
30 | | |
31 | | /** |
32 | | * SECTION:hb-draw |
33 | | * @title: hb-draw |
34 | | * @short_description: Glyph drawing |
35 | | * @include: hb.h |
36 | | * |
37 | | * Functions for drawing (extracting) glyph shapes. |
38 | | **/ |
39 | | |
40 | | static void |
41 | | hb_draw_move_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, |
42 | | hb_draw_state_t *st HB_UNUSED, |
43 | | float to_x HB_UNUSED, float to_y HB_UNUSED, |
44 | 105k | void *user_data HB_UNUSED) {} |
45 | | |
46 | | static void |
47 | | hb_draw_line_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, |
48 | | hb_draw_state_t *st HB_UNUSED, |
49 | | float to_x HB_UNUSED, float to_y HB_UNUSED, |
50 | 1.37M | void *user_data HB_UNUSED) {} |
51 | | |
52 | | static void |
53 | | hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data, |
54 | | hb_draw_state_t *st, |
55 | | float control_x, float control_y, |
56 | | float to_x, float to_y, |
57 | | void *user_data HB_UNUSED) |
58 | 668k | { |
59 | 2.67M | #define HB_ONE_THIRD 0.33333333f |
60 | 668k | dfuncs->emit_cubic_to (draw_data, *st, |
61 | 668k | (st->current_x + 2.f * control_x) * HB_ONE_THIRD, |
62 | 668k | (st->current_y + 2.f * control_y) * HB_ONE_THIRD, |
63 | 668k | (to_x + 2.f * control_x) * HB_ONE_THIRD, |
64 | 668k | (to_y + 2.f * control_y) * HB_ONE_THIRD, |
65 | 668k | to_x, to_y); |
66 | 668k | #undef HB_ONE_THIRD |
67 | 668k | } |
68 | | |
69 | | static void |
70 | | hb_draw_cubic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, |
71 | | hb_draw_state_t *st HB_UNUSED, |
72 | | float control1_x HB_UNUSED, float control1_y HB_UNUSED, |
73 | | float control2_x HB_UNUSED, float control2_y HB_UNUSED, |
74 | | float to_x HB_UNUSED, float to_y HB_UNUSED, |
75 | 1.07M | void *user_data HB_UNUSED) {} |
76 | | |
77 | | static void |
78 | | hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, |
79 | | hb_draw_state_t *st HB_UNUSED, |
80 | 105k | void *user_data HB_UNUSED) {} |
81 | | |
82 | | |
83 | | #define HB_DRAW_FUNC_IMPLEMENT(name) \ |
84 | | \ |
85 | | void \ |
86 | | hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \ |
87 | | hb_draw_##name##_func_t func, \ |
88 | | void *user_data, \ |
89 | 0 | hb_destroy_func_t destroy) \ |
90 | 0 | { \ |
91 | 0 | if (hb_object_is_immutable (dfuncs)) \ |
92 | 0 | return; \ |
93 | 0 | \ |
94 | 0 | if (dfuncs->destroy && dfuncs->destroy->name) \ |
95 | 0 | dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \ |
96 | 0 | \ |
97 | 0 | if (user_data && !dfuncs->user_data) \ |
98 | 0 | { \ |
99 | 0 | dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \ |
100 | 0 | if (unlikely (!dfuncs->user_data)) \ |
101 | 0 | goto fail; \ |
102 | 0 | } \ |
103 | 0 | if (destroy && !dfuncs->destroy) \ |
104 | 0 | { \ |
105 | 0 | dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \ |
106 | 0 | if (unlikely (!dfuncs->destroy)) \ |
107 | 0 | goto fail; \ |
108 | 0 | } \ |
109 | 0 | \ |
110 | 0 | if (func) { \ |
111 | 0 | dfuncs->func.name = func; \ |
112 | 0 | if (dfuncs->user_data) \ |
113 | 0 | dfuncs->user_data->name = user_data; \ |
114 | 0 | if (dfuncs->destroy) \ |
115 | 0 | dfuncs->destroy->name = destroy; \ |
116 | 0 | } else { \ |
117 | 0 | dfuncs->func.name = hb_draw_##name##_nil; \ |
118 | 0 | if (dfuncs->user_data) \ |
119 | 0 | dfuncs->user_data->name = nullptr; \ |
120 | 0 | if (dfuncs->destroy) \ |
121 | 0 | dfuncs->destroy->name = nullptr; \ |
122 | 0 | } \ |
123 | 0 | return; \ |
124 | 0 | \ |
125 | 0 | fail: \ |
126 | 0 | if (destroy) \ |
127 | 0 | destroy (user_data); \ |
128 | 0 | } Unexecuted instantiation: hb_draw_funcs_set_move_to_func Unexecuted instantiation: hb_draw_funcs_set_line_to_func Unexecuted instantiation: hb_draw_funcs_set_quadratic_to_func Unexecuted instantiation: hb_draw_funcs_set_cubic_to_func Unexecuted instantiation: hb_draw_funcs_set_close_path_func |
129 | | |
130 | | HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS |
131 | | #undef HB_DRAW_FUNC_IMPLEMENT |
132 | | |
133 | | /** |
134 | | * hb_draw_funcs_create: |
135 | | * |
136 | | * Creates a new draw callbacks object. |
137 | | * |
138 | | * Return value: (transfer full): |
139 | | * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial |
140 | | * reference count should be released with hb_draw_funcs_destroy when you are |
141 | | * done using the #hb_draw_funcs_t. This function never returns `NULL`. If |
142 | | * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will |
143 | | * be returned. |
144 | | * |
145 | | * Since: 4.0.0 |
146 | | **/ |
147 | | hb_draw_funcs_t * |
148 | | hb_draw_funcs_create () |
149 | 241k | { |
150 | 241k | hb_draw_funcs_t *dfuncs; |
151 | 241k | if (unlikely (!(dfuncs = hb_object_create<hb_draw_funcs_t> ()))) |
152 | 1.57k | return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t)); |
153 | | |
154 | 239k | dfuncs->func = Null (hb_draw_funcs_t).func; |
155 | | |
156 | 239k | return dfuncs; |
157 | 241k | } |
158 | | |
159 | | DEFINE_NULL_INSTANCE (hb_draw_funcs_t) = |
160 | | { |
161 | | HB_OBJECT_HEADER_STATIC, |
162 | | |
163 | | { |
164 | | #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil, |
165 | | HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS |
166 | | #undef HB_DRAW_FUNC_IMPLEMENT |
167 | | } |
168 | | }; |
169 | | |
170 | | |
171 | | /** |
172 | | * hb_draw_funcs_reference: (skip) |
173 | | * @dfuncs: draw functions |
174 | | * |
175 | | * Increases the reference count on @dfuncs by one. This prevents @buffer from |
176 | | * being destroyed until a matching call to hb_draw_funcs_destroy() is made. |
177 | | * |
178 | | * Return value: (transfer full): |
179 | | * The referenced #hb_draw_funcs_t. |
180 | | * |
181 | | * Since: 4.0.0 |
182 | | **/ |
183 | | hb_draw_funcs_t * |
184 | | hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs) |
185 | 0 | { |
186 | 0 | return hb_object_reference (dfuncs); |
187 | 0 | } |
188 | | |
189 | | /** |
190 | | * hb_draw_funcs_destroy: (skip) |
191 | | * @dfuncs: draw functions |
192 | | * |
193 | | * Deallocate the @dfuncs. |
194 | | * Decreases the reference count on @dfuncs by one. If the result is zero, then |
195 | | * @dfuncs and all associated resources are freed. See hb_draw_funcs_reference(). |
196 | | * |
197 | | * Since: 4.0.0 |
198 | | **/ |
199 | | void |
200 | | hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) |
201 | 241k | { |
202 | 241k | if (!hb_object_destroy (dfuncs)) return; |
203 | | |
204 | 239k | if (dfuncs->destroy) |
205 | 0 | { |
206 | 0 | #define HB_DRAW_FUNC_IMPLEMENT(name) \ |
207 | 0 | if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); |
208 | 0 | HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS |
209 | 0 | #undef HB_DRAW_FUNC_IMPLEMENT |
210 | 0 | } |
211 | | |
212 | 239k | hb_free (dfuncs->destroy); |
213 | 239k | hb_free (dfuncs->user_data); |
214 | | |
215 | 239k | hb_free (dfuncs); |
216 | 239k | } |
217 | | |
218 | | /** |
219 | | * hb_draw_funcs_make_immutable: |
220 | | * @dfuncs: draw functions |
221 | | * |
222 | | * Makes @dfuncs object immutable. |
223 | | * |
224 | | * Since: 4.0.0 |
225 | | **/ |
226 | | void |
227 | | hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs) |
228 | 0 | { |
229 | 0 | if (hb_object_is_immutable (dfuncs)) |
230 | 0 | return; |
231 | | |
232 | 0 | hb_object_make_immutable (dfuncs); |
233 | 0 | } |
234 | | |
235 | | /** |
236 | | * hb_draw_funcs_is_immutable: |
237 | | * @dfuncs: draw functions |
238 | | * |
239 | | * Checks whether @dfuncs is immutable. |
240 | | * |
241 | | * Return value: `true` if @dfuncs is immutable, `false` otherwise |
242 | | * |
243 | | * Since: 4.0.0 |
244 | | **/ |
245 | | hb_bool_t |
246 | | hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs) |
247 | 0 | { |
248 | 0 | return hb_object_is_immutable (dfuncs); |
249 | 0 | } |
250 | | |
251 | | |
252 | | /** |
253 | | * hb_draw_move_to: |
254 | | * @dfuncs: draw functions |
255 | | * @draw_data: associated draw data passed by the caller |
256 | | * @st: current draw state |
257 | | * @to_x: X component of target point |
258 | | * @to_y: Y component of target point |
259 | | * |
260 | | * Perform a "move-to" draw operation. |
261 | | * |
262 | | * Since: 4.0.0 |
263 | | **/ |
264 | | void |
265 | | hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data, |
266 | | hb_draw_state_t *st, |
267 | | float to_x, float to_y) |
268 | 0 | { |
269 | 0 | dfuncs->move_to (draw_data, *st, |
270 | 0 | to_x, to_y); |
271 | 0 | } |
272 | | |
273 | | /** |
274 | | * hb_draw_line_to: |
275 | | * @dfuncs: draw functions |
276 | | * @draw_data: associated draw data passed by the caller |
277 | | * @st: current draw state |
278 | | * @to_x: X component of target point |
279 | | * @to_y: Y component of target point |
280 | | * |
281 | | * Perform a "line-to" draw operation. |
282 | | * |
283 | | * Since: 4.0.0 |
284 | | **/ |
285 | | void |
286 | | hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data, |
287 | | hb_draw_state_t *st, |
288 | | float to_x, float to_y) |
289 | 0 | { |
290 | 0 | dfuncs->line_to (draw_data, *st, |
291 | 0 | to_x, to_y); |
292 | 0 | } |
293 | | |
294 | | /** |
295 | | * hb_draw_quadratic_to: |
296 | | * @dfuncs: draw functions |
297 | | * @draw_data: associated draw data passed by the caller |
298 | | * @st: current draw state |
299 | | * @control_x: X component of control point |
300 | | * @control_y: Y component of control point |
301 | | * @to_x: X component of target point |
302 | | * @to_y: Y component of target point |
303 | | * |
304 | | * Perform a "quadratic-to" draw operation. |
305 | | * |
306 | | * Since: 4.0.0 |
307 | | **/ |
308 | | void |
309 | | hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data, |
310 | | hb_draw_state_t *st, |
311 | | float control_x, float control_y, |
312 | | float to_x, float to_y) |
313 | 0 | { |
314 | 0 | dfuncs->quadratic_to (draw_data, *st, |
315 | 0 | control_x, control_y, |
316 | 0 | to_x, to_y); |
317 | 0 | } |
318 | | |
319 | | /** |
320 | | * hb_draw_cubic_to: |
321 | | * @dfuncs: draw functions |
322 | | * @draw_data: associated draw data passed by the caller |
323 | | * @st: current draw state |
324 | | * @control1_x: X component of first control point |
325 | | * @control1_y: Y component of first control point |
326 | | * @control2_x: X component of second control point |
327 | | * @control2_y: Y component of second control point |
328 | | * @to_x: X component of target point |
329 | | * @to_y: Y component of target point |
330 | | * |
331 | | * Perform a "cubic-to" draw operation. |
332 | | * |
333 | | * Since: 4.0.0 |
334 | | **/ |
335 | | void |
336 | | hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data, |
337 | | hb_draw_state_t *st, |
338 | | float control1_x, float control1_y, |
339 | | float control2_x, float control2_y, |
340 | | float to_x, float to_y) |
341 | 0 | { |
342 | 0 | dfuncs->cubic_to (draw_data, *st, |
343 | 0 | control1_x, control1_y, |
344 | 0 | control2_x, control2_y, |
345 | 0 | to_x, to_y); |
346 | 0 | } |
347 | | |
348 | | /** |
349 | | * hb_draw_close_path: |
350 | | * @dfuncs: draw functions |
351 | | * @draw_data: associated draw data passed by the caller |
352 | | * @st: current draw state |
353 | | * |
354 | | * Perform a "close-path" draw operation. |
355 | | * |
356 | | * Since: 4.0.0 |
357 | | **/ |
358 | | void |
359 | | hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data, |
360 | | hb_draw_state_t *st) |
361 | 0 | { |
362 | 0 | dfuncs->close_path (draw_data, *st); |
363 | 0 | } |
364 | | |
365 | | |
366 | | #endif |