2 * Copyright © 2019-2020 Ebrahim Byagowi
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
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.
34 * @short_description: Glyph drawing
37 * Functions for drawing (extracting) glyph shapes.
39 * The #hb_draw_funcs_t struct can be used with hb_font_draw_glyph().
43 hb_draw_move_to_nil (hb_draw_funcs_t
*dfuncs HB_UNUSED
, void *draw_data HB_UNUSED
,
44 hb_draw_state_t
*st HB_UNUSED
,
45 float to_x HB_UNUSED
, float to_y HB_UNUSED
,
46 void *user_data HB_UNUSED
) {}
49 hb_draw_line_to_nil (hb_draw_funcs_t
*dfuncs HB_UNUSED
, void *draw_data HB_UNUSED
,
50 hb_draw_state_t
*st HB_UNUSED
,
51 float to_x HB_UNUSED
, float to_y HB_UNUSED
,
52 void *user_data HB_UNUSED
) {}
55 hb_draw_quadratic_to_nil (hb_draw_funcs_t
*dfuncs
, void *draw_data
,
57 float control_x
, float control_y
,
58 float to_x
, float to_y
,
59 void *user_data HB_UNUSED
)
61 #define HB_ONE_THIRD 0.33333333f
62 dfuncs
->emit_cubic_to (draw_data
, *st
,
63 (st
->current_x
+ 2.f
* control_x
) * HB_ONE_THIRD
,
64 (st
->current_y
+ 2.f
* control_y
) * HB_ONE_THIRD
,
65 (to_x
+ 2.f
* control_x
) * HB_ONE_THIRD
,
66 (to_y
+ 2.f
* control_y
) * HB_ONE_THIRD
,
72 hb_draw_cubic_to_nil (hb_draw_funcs_t
*dfuncs HB_UNUSED
, void *draw_data HB_UNUSED
,
73 hb_draw_state_t
*st HB_UNUSED
,
74 float control1_x HB_UNUSED
, float control1_y HB_UNUSED
,
75 float control2_x HB_UNUSED
, float control2_y HB_UNUSED
,
76 float to_x HB_UNUSED
, float to_y HB_UNUSED
,
77 void *user_data HB_UNUSED
) {}
80 hb_draw_close_path_nil (hb_draw_funcs_t
*dfuncs HB_UNUSED
, void *draw_data HB_UNUSED
,
81 hb_draw_state_t
*st HB_UNUSED
,
82 void *user_data HB_UNUSED
) {}
86 _hb_draw_funcs_set_preamble (hb_draw_funcs_t
*dfuncs
,
89 hb_destroy_func_t
*destroy
)
91 if (hb_object_is_immutable (dfuncs
))
94 (*destroy
) (*user_data
);
101 (*destroy
) (*user_data
);
103 *user_data
= nullptr;
110 _hb_draw_funcs_set_middle (hb_draw_funcs_t
*dfuncs
,
112 hb_destroy_func_t destroy
)
114 if (user_data
&& !dfuncs
->user_data
)
116 dfuncs
->user_data
= (decltype (dfuncs
->user_data
)) hb_calloc (1, sizeof (*dfuncs
->user_data
));
117 if (unlikely (!dfuncs
->user_data
))
120 if (destroy
&& !dfuncs
->destroy
)
122 dfuncs
->destroy
= (decltype (dfuncs
->destroy
)) hb_calloc (1, sizeof (*dfuncs
->destroy
));
123 if (unlikely (!dfuncs
->destroy
))
131 (destroy
) (user_data
);
135 #define HB_DRAW_FUNC_IMPLEMENT(name) \
138 hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \
139 hb_draw_##name##_func_t func, \
141 hb_destroy_func_t destroy) \
143 if (!_hb_draw_funcs_set_preamble (dfuncs, !func, &user_data, &destroy))\
146 if (dfuncs->destroy && dfuncs->destroy->name) \
147 dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \
149 if (!_hb_draw_funcs_set_middle (dfuncs, user_data, destroy)) \
153 dfuncs->func.name = func; \
155 dfuncs->func.name = hb_draw_##name##_nil; \
157 if (dfuncs->user_data) \
158 dfuncs->user_data->name = user_data; \
159 if (dfuncs->destroy) \
160 dfuncs->destroy->name = destroy; \
163 HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
164 #undef HB_DRAW_FUNC_IMPLEMENT
167 * hb_draw_funcs_create:
169 * Creates a new draw callbacks object.
171 * Return value: (transfer full):
172 * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial
173 * reference count should be released with hb_draw_funcs_destroy when you are
174 * done using the #hb_draw_funcs_t. This function never returns `NULL`. If
175 * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will
181 hb_draw_funcs_create ()
183 hb_draw_funcs_t
*dfuncs
;
184 if (unlikely (!(dfuncs
= hb_object_create
<hb_draw_funcs_t
> ())))
185 return const_cast<hb_draw_funcs_t
*> (&Null (hb_draw_funcs_t
));
187 dfuncs
->func
= Null (hb_draw_funcs_t
).func
;
192 DEFINE_NULL_INSTANCE (hb_draw_funcs_t
) =
194 HB_OBJECT_HEADER_STATIC
,
197 #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil,
198 HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
199 #undef HB_DRAW_FUNC_IMPLEMENT
204 * hb_draw_funcs_get_empty:
206 * Fetches the singleton empty draw-functions structure.
208 * Return value: (transfer full): The empty draw-functions structure
213 hb_draw_funcs_get_empty ()
215 return const_cast<hb_draw_funcs_t
*> (&Null (hb_draw_funcs_t
));
219 * hb_draw_funcs_reference: (skip)
220 * @dfuncs: draw functions
222 * Increases the reference count on @dfuncs by one.
224 * This prevents @dfuncs from being destroyed until a matching
225 * call to hb_draw_funcs_destroy() is made.
227 * Return value: (transfer full):
228 * The referenced #hb_draw_funcs_t.
233 hb_draw_funcs_reference (hb_draw_funcs_t
*dfuncs
)
235 return hb_object_reference (dfuncs
);
239 * hb_draw_funcs_destroy: (skip)
240 * @dfuncs: draw functions
242 * Deallocate the @dfuncs.
243 * Decreases the reference count on @dfuncs by one. If the result is zero, then
244 * @dfuncs and all associated resources are freed. See hb_draw_funcs_reference().
249 hb_draw_funcs_destroy (hb_draw_funcs_t
*dfuncs
)
251 if (!hb_object_destroy (dfuncs
)) return;
255 #define HB_DRAW_FUNC_IMPLEMENT(name) \
256 if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name);
257 HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
258 #undef HB_DRAW_FUNC_IMPLEMENT
261 hb_free (dfuncs
->destroy
);
262 hb_free (dfuncs
->user_data
);
268 * hb_draw_funcs_set_user_data: (skip)
269 * @dfuncs: The draw-functions structure
270 * @key: The user-data key
271 * @data: A pointer to the user data
272 * @destroy: (nullable): A callback to call when @data is not needed anymore
273 * @replace: Whether to replace an existing data with the same key
275 * Attaches a user-data key/data pair to the specified draw-functions structure.
277 * Return value: `true` if success, `false` otherwise
282 hb_draw_funcs_set_user_data (hb_draw_funcs_t
*dfuncs
,
283 hb_user_data_key_t
*key
,
285 hb_destroy_func_t destroy
,
288 return hb_object_set_user_data (dfuncs
, key
, data
, destroy
, replace
);
292 * hb_draw_funcs_get_user_data: (skip)
293 * @dfuncs: The draw-functions structure
294 * @key: The user-data key to query
296 * Fetches the user-data associated with the specified key,
297 * attached to the specified draw-functions structure.
299 * Return value: (transfer none): A pointer to the user data
304 hb_draw_funcs_get_user_data (const hb_draw_funcs_t
*dfuncs
,
305 hb_user_data_key_t
*key
)
307 return hb_object_get_user_data (dfuncs
, key
);
311 * hb_draw_funcs_make_immutable:
312 * @dfuncs: draw functions
314 * Makes @dfuncs object immutable.
319 hb_draw_funcs_make_immutable (hb_draw_funcs_t
*dfuncs
)
321 if (hb_object_is_immutable (dfuncs
))
324 hb_object_make_immutable (dfuncs
);
328 * hb_draw_funcs_is_immutable:
329 * @dfuncs: draw functions
331 * Checks whether @dfuncs is immutable.
333 * Return value: `true` if @dfuncs is immutable, `false` otherwise
338 hb_draw_funcs_is_immutable (hb_draw_funcs_t
*dfuncs
)
340 return hb_object_is_immutable (dfuncs
);
346 * @dfuncs: draw functions
347 * @draw_data: associated draw data passed by the caller
348 * @st: current draw state
349 * @to_x: X component of target point
350 * @to_y: Y component of target point
352 * Perform a "move-to" draw operation.
357 hb_draw_move_to (hb_draw_funcs_t
*dfuncs
, void *draw_data
,
359 float to_x
, float to_y
)
361 dfuncs
->move_to (draw_data
, *st
,
367 * @dfuncs: draw functions
368 * @draw_data: associated draw data passed by the caller
369 * @st: current draw state
370 * @to_x: X component of target point
371 * @to_y: Y component of target point
373 * Perform a "line-to" draw operation.
378 hb_draw_line_to (hb_draw_funcs_t
*dfuncs
, void *draw_data
,
380 float to_x
, float to_y
)
382 dfuncs
->line_to (draw_data
, *st
,
387 * hb_draw_quadratic_to:
388 * @dfuncs: draw functions
389 * @draw_data: associated draw data passed by the caller
390 * @st: current draw state
391 * @control_x: X component of control point
392 * @control_y: Y component of control point
393 * @to_x: X component of target point
394 * @to_y: Y component of target point
396 * Perform a "quadratic-to" draw operation.
401 hb_draw_quadratic_to (hb_draw_funcs_t
*dfuncs
, void *draw_data
,
403 float control_x
, float control_y
,
404 float to_x
, float to_y
)
406 dfuncs
->quadratic_to (draw_data
, *st
,
407 control_x
, control_y
,
413 * @dfuncs: draw functions
414 * @draw_data: associated draw data passed by the caller
415 * @st: current draw state
416 * @control1_x: X component of first control point
417 * @control1_y: Y component of first control point
418 * @control2_x: X component of second control point
419 * @control2_y: Y component of second control point
420 * @to_x: X component of target point
421 * @to_y: Y component of target point
423 * Perform a "cubic-to" draw operation.
428 hb_draw_cubic_to (hb_draw_funcs_t
*dfuncs
, void *draw_data
,
430 float control1_x
, float control1_y
,
431 float control2_x
, float control2_y
,
432 float to_x
, float to_y
)
434 dfuncs
->cubic_to (draw_data
, *st
,
435 control1_x
, control1_y
,
436 control2_x
, control2_y
,
441 * hb_draw_close_path:
442 * @dfuncs: draw functions
443 * @draw_data: associated draw data passed by the caller
444 * @st: current draw state
446 * Perform a "close-path" draw operation.
451 hb_draw_close_path (hb_draw_funcs_t
*dfuncs
, void *draw_data
,
454 dfuncs
->close_path (draw_data
, *st
);