1 | /* |
2 | * Copyright © 2022 Matthias Clasen |
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.hh" |
30 | |
31 | /** |
32 | * SECTION: hb-paint |
33 | * @title: hb-paint |
34 | * @short_description: Glyph painting |
35 | * @include: hb.h |
36 | * |
37 | * Functions for painting glyphs. |
38 | * |
39 | * The main purpose of these functions is to paint (extract) color glyph layers |
40 | * from the COLRv1 table, but the API works for drawing ordinary outlines and |
41 | * images as well. |
42 | * |
43 | * The #hb_paint_funcs_t struct can be used with hb_font_paint_glyph(). |
44 | **/ |
45 | |
46 | static void |
47 | hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, |
48 | float xx, float yx, |
49 | float xy, float yy, |
50 | float dx, float dy, |
51 | void *user_data) {} |
52 | |
53 | static void |
54 | hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, |
55 | void *user_data) {} |
56 | |
57 | static void |
58 | hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, |
59 | hb_codepoint_t glyph, |
60 | hb_font_t *font, |
61 | void *user_data) {} |
62 | |
63 | static void |
64 | hb_paint_push_clip_rectangle_nil (hb_paint_funcs_t *funcs, void *paint_data, |
65 | float xmin, float ymin, float xmax, float ymax, |
66 | void *user_data) {} |
67 | |
68 | static void |
69 | hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data, |
70 | void *user_data) {} |
71 | |
72 | static void |
73 | hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, |
74 | hb_bool_t is_foreground, |
75 | hb_color_t color, |
76 | void *user_data) {} |
77 | |
78 | static hb_bool_t |
79 | hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, |
80 | hb_blob_t *image, |
81 | unsigned int width, |
82 | unsigned int height, |
83 | hb_tag_t format, |
84 | float slant_xy, |
85 | hb_glyph_extents_t *extents, |
86 | void *user_data) { return false; } |
87 | |
88 | static void |
89 | hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, |
90 | hb_color_line_t *color_line, |
91 | float x0, float y0, |
92 | float x1, float y1, |
93 | float x2, float y2, |
94 | void *user_data) {} |
95 | |
96 | static void |
97 | hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, |
98 | hb_color_line_t *color_line, |
99 | float x0, float y0, float r0, |
100 | float x1, float y1, float r1, |
101 | void *user_data) {} |
102 | |
103 | static void |
104 | hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data, |
105 | hb_color_line_t *color_line, |
106 | float x0, float y0, |
107 | float start_angle, |
108 | float end_angle, |
109 | void *user_data) {} |
110 | |
111 | static void |
112 | hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data, |
113 | void *user_data) {} |
114 | |
115 | static void |
116 | hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data, |
117 | hb_paint_composite_mode_t mode, |
118 | void *user_data) {} |
119 | |
120 | static hb_bool_t |
121 | hb_paint_custom_palette_color_nil (hb_paint_funcs_t *funcs, void *paint_data, |
122 | unsigned int color_index, |
123 | hb_color_t *color, |
124 | void *user_data) { return false; } |
125 | |
126 | static bool |
127 | _hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs, |
128 | bool func_is_null, |
129 | void **user_data, |
130 | hb_destroy_func_t *destroy) |
131 | { |
132 | if (hb_object_is_immutable (funcs)) |
133 | { |
134 | if (*destroy) |
135 | (*destroy) (*user_data); |
136 | return false; |
137 | } |
138 | |
139 | if (func_is_null) |
140 | { |
141 | if (*destroy) |
142 | (*destroy) (*user_data); |
143 | *destroy = nullptr; |
144 | *user_data = nullptr; |
145 | } |
146 | |
147 | return true; |
148 | } |
149 | |
150 | static bool |
151 | _hb_paint_funcs_set_middle (hb_paint_funcs_t *funcs, |
152 | void *user_data, |
153 | hb_destroy_func_t destroy) |
154 | { |
155 | if (user_data && !funcs->user_data) |
156 | { |
157 | funcs->user_data = (decltype (funcs->user_data)) hb_calloc (1, sizeof (*funcs->user_data)); |
158 | if (unlikely (!funcs->user_data)) |
159 | goto fail; |
160 | } |
161 | if (destroy && !funcs->destroy) |
162 | { |
163 | funcs->destroy = (decltype (funcs->destroy)) hb_calloc (1, sizeof (*funcs->destroy)); |
164 | if (unlikely (!funcs->destroy)) |
165 | goto fail; |
166 | } |
167 | |
168 | return true; |
169 | |
170 | fail: |
171 | if (destroy) |
172 | (destroy) (user_data); |
173 | return false; |
174 | } |
175 | |
176 | #define HB_PAINT_FUNC_IMPLEMENT(name) \ |
177 | \ |
178 | void \ |
179 | hb_paint_funcs_set_##name##_func (hb_paint_funcs_t *funcs, \ |
180 | hb_paint_##name##_func_t func, \ |
181 | void *user_data, \ |
182 | hb_destroy_func_t destroy) \ |
183 | { \ |
184 | if (!_hb_paint_funcs_set_preamble (funcs, !func, &user_data, &destroy)) \ |
185 | return; \ |
186 | \ |
187 | if (funcs->destroy && funcs->destroy->name) \ |
188 | funcs->destroy->name (!funcs->user_data ? nullptr : funcs->user_data->name);\ |
189 | \ |
190 | if (!_hb_paint_funcs_set_middle (funcs, user_data, destroy)) \ |
191 | return; \ |
192 | \ |
193 | if (func) \ |
194 | funcs->func.name = func; \ |
195 | else \ |
196 | funcs->func.name = hb_paint_##name##_nil; \ |
197 | \ |
198 | if (funcs->user_data) \ |
199 | funcs->user_data->name = user_data; \ |
200 | if (funcs->destroy) \ |
201 | funcs->destroy->name = destroy; \ |
202 | } |
203 | |
204 | HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS |
205 | #undef HB_PAINT_FUNC_IMPLEMENT |
206 | |
207 | /** |
208 | * hb_paint_funcs_create: |
209 | * |
210 | * Creates a new #hb_paint_funcs_t structure of paint functions. |
211 | * |
212 | * The initial reference count of 1 should be released with hb_paint_funcs_destroy() |
213 | * when you are done using the #hb_paint_funcs_t. This function never returns |
214 | * `NULL`. If memory cannot be allocated, a special singleton #hb_paint_funcs_t |
215 | * object will be returned. |
216 | * |
217 | * Returns value: (transfer full): the paint-functions structure |
218 | * |
219 | * Since: 7.0.0 |
220 | */ |
221 | hb_paint_funcs_t * |
222 | hb_paint_funcs_create () |
223 | { |
224 | hb_paint_funcs_t *funcs; |
225 | if (unlikely (!(funcs = hb_object_create<hb_paint_funcs_t> ()))) |
226 | return const_cast<hb_paint_funcs_t *> (&Null (hb_paint_funcs_t)); |
227 | |
228 | funcs->func = Null (hb_paint_funcs_t).func; |
229 | |
230 | return funcs; |
231 | } |
232 | |
233 | DEFINE_NULL_INSTANCE (hb_paint_funcs_t) = |
234 | { |
235 | HB_OBJECT_HEADER_STATIC, |
236 | |
237 | { |
238 | #define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_nil, |
239 | HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS |
240 | #undef HB_PAINT_FUNC_IMPLEMENT |
241 | } |
242 | }; |
243 | |
244 | /** |
245 | * hb_paint_funcs_get_empty: |
246 | * |
247 | * Fetches the singleton empty paint-functions structure. |
248 | * |
249 | * Return value: (transfer full): The empty paint-functions structure |
250 | * |
251 | * Since: 7.0.0 |
252 | **/ |
253 | hb_paint_funcs_t * |
254 | hb_paint_funcs_get_empty () |
255 | { |
256 | return const_cast<hb_paint_funcs_t *> (&Null (hb_paint_funcs_t)); |
257 | } |
258 | |
259 | /** |
260 | * hb_paint_funcs_reference: (skip) |
261 | * @funcs: The paint-functions structure |
262 | * |
263 | * Increases the reference count on a paint-functions structure. |
264 | * |
265 | * This prevents @funcs from being destroyed until a matching |
266 | * call to hb_paint_funcs_destroy() is made. |
267 | * |
268 | * Return value: The paint-functions structure |
269 | * |
270 | * Since: 7.0.0 |
271 | */ |
272 | hb_paint_funcs_t * |
273 | hb_paint_funcs_reference (hb_paint_funcs_t *funcs) |
274 | { |
275 | return hb_object_reference (funcs); |
276 | } |
277 | |
278 | /** |
279 | * hb_paint_funcs_destroy: (skip) |
280 | * @funcs: The paint-functions structure |
281 | * |
282 | * Decreases the reference count on a paint-functions structure. |
283 | * |
284 | * When the reference count reaches zero, the structure |
285 | * is destroyed, freeing all memory. |
286 | * |
287 | * Since: 7.0.0 |
288 | */ |
289 | void |
290 | hb_paint_funcs_destroy (hb_paint_funcs_t *funcs) |
291 | { |
292 | if (!hb_object_destroy (funcs)) return; |
293 | |
294 | if (funcs->destroy) |
295 | { |
296 | #define HB_PAINT_FUNC_IMPLEMENT(name) \ |
297 | if (funcs->destroy->name) funcs->destroy->name (!funcs->user_data ? nullptr : funcs->user_data->name); |
298 | HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS |
299 | #undef HB_PAINT_FUNC_IMPLEMENT |
300 | } |
301 | |
302 | hb_free (funcs->destroy); |
303 | hb_free (funcs->user_data); |
304 | hb_free (funcs); |
305 | } |
306 | |
307 | /** |
308 | * hb_paint_funcs_set_user_data: (skip) |
309 | * @funcs: The paint-functions structure |
310 | * @key: The user-data key |
311 | * @data: A pointer to the user data |
312 | * @destroy: (nullable): A callback to call when @data is not needed anymore |
313 | * @replace: Whether to replace an existing data with the same key |
314 | * |
315 | * Attaches a user-data key/data pair to the specified paint-functions structure. |
316 | * |
317 | * Return value: `true` if success, `false` otherwise |
318 | * |
319 | * Since: 7.0.0 |
320 | **/ |
321 | hb_bool_t |
322 | hb_paint_funcs_set_user_data (hb_paint_funcs_t *funcs, |
323 | hb_user_data_key_t *key, |
324 | void * data, |
325 | hb_destroy_func_t destroy, |
326 | hb_bool_t replace) |
327 | { |
328 | return hb_object_set_user_data (funcs, key, data, destroy, replace); |
329 | } |
330 | |
331 | /** |
332 | * hb_paint_funcs_get_user_data: (skip) |
333 | * @funcs: The paint-functions structure |
334 | * @key: The user-data key to query |
335 | * |
336 | * Fetches the user-data associated with the specified key, |
337 | * attached to the specified paint-functions structure. |
338 | * |
339 | * Return value: (transfer none): A pointer to the user data |
340 | * |
341 | * Since: 7.0.0 |
342 | **/ |
343 | void * |
344 | hb_paint_funcs_get_user_data (const hb_paint_funcs_t *funcs, |
345 | hb_user_data_key_t *key) |
346 | { |
347 | return hb_object_get_user_data (funcs, key); |
348 | } |
349 | |
350 | /** |
351 | * hb_paint_funcs_make_immutable: |
352 | * @funcs: The paint-functions structure |
353 | * |
354 | * Makes a paint-functions structure immutable. |
355 | * |
356 | * After this call, all attempts to set one of the callbacks |
357 | * on @funcs will fail. |
358 | * |
359 | * Since: 7.0.0 |
360 | */ |
361 | void |
362 | hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs) |
363 | { |
364 | if (hb_object_is_immutable (funcs)) |
365 | return; |
366 | |
367 | hb_object_make_immutable (funcs); |
368 | } |
369 | |
370 | /** |
371 | * hb_paint_funcs_is_immutable: |
372 | * @funcs: The paint-functions structure |
373 | * |
374 | * Tests whether a paint-functions structure is immutable. |
375 | * |
376 | * Return value: `true` if @funcs is immutable, `false` otherwise |
377 | * |
378 | * Since: 7.0.0 |
379 | */ |
380 | hb_bool_t |
381 | hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs) |
382 | { |
383 | return hb_object_is_immutable (funcs); |
384 | } |
385 | |
386 | |
387 | /** |
388 | * hb_color_line_get_color_stops: |
389 | * @color_line: a #hb_color_line_t object |
390 | * @start: the index of the first color stop to return |
391 | * @count: (inout) (optional): Input = the maximum number of feature tags to return; |
392 | * Output = the actual number of feature tags returned (may be zero) |
393 | * @color_stops: (out) (array length=count) (optional): Array of #hb_color_stop_t to populate |
394 | * |
395 | * Fetches a list of color stops from the given color line object. |
396 | * |
397 | * Note that due to variations being applied, the returned color stops |
398 | * may be out of order. It is the callers responsibility to ensure that |
399 | * color stops are sorted by their offset before they are used. |
400 | * |
401 | * Return value: the total number of color stops in @color_line |
402 | * |
403 | * Since: 7.0.0 |
404 | */ |
405 | unsigned int |
406 | hb_color_line_get_color_stops (hb_color_line_t *color_line, |
407 | unsigned int start, |
408 | unsigned int *count, |
409 | hb_color_stop_t *color_stops) |
410 | { |
411 | return color_line->get_color_stops (color_line, |
412 | color_line->data, |
413 | start, count, |
414 | color_stops, |
415 | color_line->get_color_stops_user_data); |
416 | } |
417 | |
418 | /** |
419 | * hb_color_line_get_extend: |
420 | * @color_line: a #hb_color_line_t object |
421 | * |
422 | * Fetches the extend mode of the color line object. |
423 | * |
424 | * Return value: the extend mode of @color_line |
425 | * |
426 | * Since: 7.0.0 |
427 | */ |
428 | hb_paint_extend_t |
429 | hb_color_line_get_extend (hb_color_line_t *color_line) |
430 | { |
431 | return color_line->get_extend (color_line, |
432 | color_line->data, |
433 | color_line->get_extend_user_data); |
434 | } |
435 | |
436 | |
437 | /** |
438 | * hb_paint_push_transform: |
439 | * @funcs: paint functions |
440 | * @paint_data: associated data passed by the caller |
441 | * @xx: xx component of the transform matrix |
442 | * @yx: yx component of the transform matrix |
443 | * @xy: xy component of the transform matrix |
444 | * @yy: yy component of the transform matrix |
445 | * @dx: dx component of the transform matrix |
446 | * @dy: dy component of the transform matrix |
447 | * |
448 | * Perform a "push-transform" paint operation. |
449 | * |
450 | * Since: 7.0.0 |
451 | */ |
452 | void |
453 | hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, |
454 | float xx, float yx, |
455 | float xy, float yy, |
456 | float dx, float dy) |
457 | { |
458 | funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); |
459 | } |
460 | |
461 | /** |
462 | * hb_paint_pop_transform: |
463 | * @funcs: paint functions |
464 | * @paint_data: associated data passed by the caller |
465 | * |
466 | * Perform a "pop-transform" paint operation. |
467 | * |
468 | * Since: 7.0.0 |
469 | */ |
470 | void |
471 | hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) |
472 | { |
473 | funcs->pop_transform (paint_data); |
474 | } |
475 | |
476 | /** |
477 | * hb_paint_push_clip_glyph: |
478 | * @funcs: paint functions |
479 | * @paint_data: associated data passed by the caller |
480 | * @glyph: the glyph ID |
481 | * @font: the font |
482 | * |
483 | * Perform a "push-clip-glyph" paint operation. |
484 | * |
485 | * Since: 7.0.0 |
486 | */ |
487 | void |
488 | hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, |
489 | hb_codepoint_t glyph, |
490 | hb_font_t *font) |
491 | { |
492 | funcs->push_clip_glyph (paint_data, glyph, font); |
493 | } |
494 | |
495 | /** |
496 | * hb_paint_push_clip_rectangle: |
497 | * @funcs: paint functions |
498 | * @paint_data: associated data passed by the caller |
499 | * @xmin: min X for the rectangle |
500 | * @ymin: min Y for the rectangle |
501 | * @xmax: max X for the rectangle |
502 | * @ymax: max Y for the rectangle |
503 | * |
504 | * Perform a "push-clip-rect" paint operation. |
505 | * |
506 | * Since: 7.0.0 |
507 | */ |
508 | void |
509 | hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data, |
510 | float xmin, float ymin, float xmax, float ymax) |
511 | { |
512 | funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax); |
513 | } |
514 | |
515 | /** |
516 | * hb_paint_pop_clip: |
517 | * @funcs: paint functions |
518 | * @paint_data: associated data passed by the caller |
519 | * |
520 | * Perform a "pop-clip" paint operation. |
521 | * |
522 | * Since: 7.0.0 |
523 | */ |
524 | void |
525 | hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data) |
526 | { |
527 | funcs->pop_clip (paint_data); |
528 | } |
529 | |
530 | /** |
531 | * hb_paint_color: |
532 | * @funcs: paint functions |
533 | * @paint_data: associated data passed by the caller |
534 | * @is_foreground: whether the color is the foreground |
535 | * @color: The color to use |
536 | * |
537 | * Perform a "color" paint operation. |
538 | * |
539 | * Since: 7.0.0 |
540 | */ |
541 | void |
542 | hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, |
543 | hb_bool_t is_foreground, |
544 | hb_color_t color) |
545 | { |
546 | funcs->color (paint_data, is_foreground, color); |
547 | } |
548 | |
549 | /** |
550 | * hb_paint_image: |
551 | * @funcs: paint functions |
552 | * @paint_data: associated data passed by the caller |
553 | * @image: image data |
554 | * @width: width of the raster image in pixels, or 0 |
555 | * @height: height of the raster image in pixels, or 0 |
556 | * @format: the image format as a tag |
557 | * @slant: the synthetic slant ratio to be applied to the image during rendering |
558 | * @extents: (nullable): the extents of the glyph |
559 | * |
560 | * Perform a "image" paint operation. |
561 | * |
562 | * Since: 7.0.0 |
563 | */ |
564 | void |
565 | hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, |
566 | hb_blob_t *image, |
567 | unsigned int width, |
568 | unsigned int height, |
569 | hb_tag_t format, |
570 | float slant, |
571 | hb_glyph_extents_t *extents) |
572 | { |
573 | funcs->image (paint_data, image, width, height, format, slant, extents); |
574 | } |
575 | |
576 | /** |
577 | * hb_paint_linear_gradient: |
578 | * @funcs: paint functions |
579 | * @paint_data: associated data passed by the caller |
580 | * @color_line: Color information for the gradient |
581 | * @x0: X coordinate of the first point |
582 | * @y0: Y coordinate of the first point |
583 | * @x1: X coordinate of the second point |
584 | * @y1: Y coordinate of the second point |
585 | * @x2: X coordinate of the third point |
586 | * @y2: Y coordinate of the third point |
587 | * |
588 | * Perform a "linear-gradient" paint operation. |
589 | * |
590 | * Since: 7.0.0 |
591 | */ |
592 | void |
593 | hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, |
594 | hb_color_line_t *color_line, |
595 | float x0, float y0, |
596 | float x1, float y1, |
597 | float x2, float y2) |
598 | { |
599 | funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); |
600 | } |
601 | |
602 | /** |
603 | * hb_paint_radial_gradient: |
604 | * @funcs: paint functions |
605 | * @paint_data: associated data passed by the caller |
606 | * @color_line: Color information for the gradient |
607 | * @x0: X coordinate of the first circle's center |
608 | * @y0: Y coordinate of the first circle's center |
609 | * @r0: radius of the first circle |
610 | * @x1: X coordinate of the second circle's center |
611 | * @y1: Y coordinate of the second circle's center |
612 | * @r1: radius of the second circle |
613 | * |
614 | * Perform a "radial-gradient" paint operation. |
615 | * |
616 | * Since: 7.0.0 |
617 | */ |
618 | void |
619 | hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, |
620 | hb_color_line_t *color_line, |
621 | float x0, float y0, float r0, |
622 | float x1, float y1, float r1) |
623 | { |
624 | funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); |
625 | } |
626 | |
627 | /** |
628 | * hb_paint_sweep_gradient: |
629 | * @funcs: paint functions |
630 | * @paint_data: associated data passed by the caller |
631 | * @color_line: Color information for the gradient |
632 | * @x0: X coordinate of the circle's center |
633 | * @y0: Y coordinate of the circle's center |
634 | * @start_angle: the start angle |
635 | * @end_angle: the end angle |
636 | * |
637 | * Perform a "sweep-gradient" paint operation. |
638 | * |
639 | * Since: 7.0.0 |
640 | */ |
641 | void |
642 | hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, |
643 | hb_color_line_t *color_line, |
644 | float x0, float y0, |
645 | float start_angle, float end_angle) |
646 | { |
647 | funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); |
648 | } |
649 | |
650 | /** |
651 | * hb_paint_push_group: |
652 | * @funcs: paint functions |
653 | * @paint_data: associated data passed by the caller |
654 | * |
655 | * Perform a "push-group" paint operation. |
656 | * |
657 | * Since: 7.0.0 |
658 | */ |
659 | void |
660 | hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data) |
661 | { |
662 | funcs->push_group (paint_data); |
663 | } |
664 | |
665 | /** |
666 | * hb_paint_pop_group: |
667 | * @funcs: paint functions |
668 | * @paint_data: associated data passed by the caller |
669 | * @mode: the compositing mode to use |
670 | * |
671 | * Perform a "pop-group" paint operation. |
672 | * |
673 | * Since: 7.0.0 |
674 | */ |
675 | void |
676 | hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, |
677 | hb_paint_composite_mode_t mode) |
678 | { |
679 | funcs->pop_group (paint_data, mode); |
680 | } |
681 | |
682 | /** |
683 | * hb_paint_custom_palette_color: |
684 | * @funcs: paint functions |
685 | * @paint_data: associated data passed by the caller |
686 | * @color_index: color index |
687 | * @color: (out): fetched color |
688 | * |
689 | * Gets the custom palette color for @color_index. |
690 | * |
691 | * Return value: `true` if found, `false` otherwise |
692 | * |
693 | * Since: 7.0.0 |
694 | */ |
695 | hb_bool_t |
696 | hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data, |
697 | unsigned int color_index, |
698 | hb_color_t *color) |
699 | { |
700 | return funcs->custom_palette_color (paint_data, color_index, color); |
701 | } |
702 | |
703 | #endif |
704 | |