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