hb-font.cc (100087B)
1 /* 2 * Copyright © 2009 Red Hat, Inc. 3 * Copyright © 2012 Google, Inc. 4 * 5 * This is part of HarfBuzz, a text shaping library. 6 * 7 * Permission is hereby granted, without written agreement and without 8 * license or royalty fees, to use, copy, modify, and distribute this 9 * software and its documentation for any purpose, provided that the 10 * above copyright notice and the following two paragraphs appear in 11 * all copies of this software. 12 * 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 * DAMAGE. 18 * 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 * 25 * Red Hat Author(s): Behdad Esfahbod 26 * Google Author(s): Behdad Esfahbod 27 */ 28 29 #include "hb.hh" 30 31 #include "hb-font.hh" 32 #include "hb-draw.hh" 33 #include "hb-paint.hh" 34 #include "hb-machinery.hh" 35 36 #include "hb-ot.h" 37 38 #include "hb-ot-var-avar-table.hh" 39 #include "hb-ot-var-fvar-table.hh" 40 41 #ifndef HB_NO_OT_FONT 42 #include "hb-ot.h" 43 #endif 44 #ifdef HAVE_FREETYPE 45 #include "hb-ft.h" 46 #endif 47 #ifdef HAVE_FONTATIONS 48 #include "hb-fontations.h" 49 #endif 50 #ifdef HAVE_CORETEXT 51 #include "hb-coretext.h" 52 #endif 53 #ifdef HAVE_DIRECTWRITE 54 #include "hb-directwrite.h" 55 #endif 56 57 58 /** 59 * SECTION:hb-font 60 * @title: hb-font 61 * @short_description: Font objects 62 * @include: hb.h 63 * 64 * Functions for working with font objects. 65 * 66 * A font object represents a font face at a specific size and with 67 * certain other parameters (pixels-per-em, points-per-em, variation 68 * settings) specified. Font objects are created from font face 69 * objects, and are used as input to hb_shape(), among other things. 70 * 71 * Client programs can optionally pass in their own functions that 72 * implement the basic, lower-level queries of font objects. This set 73 * of font functions is defined by the virtual methods in 74 * #hb_font_funcs_t. 75 * 76 * HarfBuzz provides a built-in set of lightweight default 77 * functions for each method in #hb_font_funcs_t. 78 * 79 * The default font functions are implemented in terms of the 80 * #hb_font_funcs_t methods of the parent font object. This allows 81 * client programs to override only the methods they need to, and 82 * otherwise inherit the parent font's implementation, if any. 83 **/ 84 85 86 /* 87 * hb_font_funcs_t 88 */ 89 90 static hb_bool_t 91 hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED, 92 void *font_data HB_UNUSED, 93 hb_font_extents_t *extents, 94 void *user_data HB_UNUSED) 95 { 96 hb_memset (extents, 0, sizeof (*extents)); 97 return false; 98 } 99 100 static hb_bool_t 101 hb_font_get_font_h_extents_default (hb_font_t *font, 102 void *font_data HB_UNUSED, 103 hb_font_extents_t *extents, 104 void *user_data HB_UNUSED) 105 { 106 hb_bool_t ret = font->parent->get_font_h_extents (extents, false); 107 if (ret) { 108 extents->ascender = font->parent_scale_y_distance (extents->ascender); 109 extents->descender = font->parent_scale_y_distance (extents->descender); 110 extents->line_gap = font->parent_scale_y_distance (extents->line_gap); 111 } 112 return ret; 113 } 114 115 static hb_bool_t 116 hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED, 117 void *font_data HB_UNUSED, 118 hb_font_extents_t *extents, 119 void *user_data HB_UNUSED) 120 { 121 hb_memset (extents, 0, sizeof (*extents)); 122 return false; 123 } 124 125 static hb_bool_t 126 hb_font_get_font_v_extents_default (hb_font_t *font, 127 void *font_data HB_UNUSED, 128 hb_font_extents_t *extents, 129 void *user_data HB_UNUSED) 130 { 131 hb_bool_t ret = font->parent->get_font_v_extents (extents, false); 132 if (ret) { 133 extents->ascender = font->parent_scale_x_distance (extents->ascender); 134 extents->descender = font->parent_scale_x_distance (extents->descender); 135 extents->line_gap = font->parent_scale_x_distance (extents->line_gap); 136 } 137 return ret; 138 } 139 140 static hb_bool_t 141 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, 142 void *font_data HB_UNUSED, 143 hb_codepoint_t unicode HB_UNUSED, 144 hb_codepoint_t *glyph, 145 void *user_data HB_UNUSED) 146 { 147 *glyph = 0; 148 return false; 149 } 150 151 static hb_bool_t 152 hb_font_get_nominal_glyph_default (hb_font_t *font, 153 void *font_data HB_UNUSED, 154 hb_codepoint_t unicode, 155 hb_codepoint_t *glyph, 156 void *user_data HB_UNUSED) 157 { 158 if (font->has_nominal_glyphs_func_set ()) 159 { 160 return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0); 161 } 162 return font->parent->get_nominal_glyph (unicode, glyph); 163 } 164 165 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default 166 167 static unsigned int 168 hb_font_get_nominal_glyphs_default (hb_font_t *font, 169 void *font_data HB_UNUSED, 170 unsigned int count, 171 const hb_codepoint_t *first_unicode, 172 unsigned int unicode_stride, 173 hb_codepoint_t *first_glyph, 174 unsigned int glyph_stride, 175 void *user_data HB_UNUSED) 176 { 177 if (font->has_nominal_glyph_func_set ()) 178 { 179 for (unsigned int i = 0; i < count; i++) 180 { 181 if (!font->get_nominal_glyph (*first_unicode, first_glyph)) 182 return i; 183 184 first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride); 185 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 186 } 187 return count; 188 } 189 190 return font->parent->get_nominal_glyphs (count, 191 first_unicode, unicode_stride, 192 first_glyph, glyph_stride); 193 } 194 195 static hb_bool_t 196 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, 197 void *font_data HB_UNUSED, 198 hb_codepoint_t unicode HB_UNUSED, 199 hb_codepoint_t variation_selector HB_UNUSED, 200 hb_codepoint_t *glyph, 201 void *user_data HB_UNUSED) 202 { 203 *glyph = 0; 204 return false; 205 } 206 207 static hb_bool_t 208 hb_font_get_variation_glyph_default (hb_font_t *font, 209 void *font_data HB_UNUSED, 210 hb_codepoint_t unicode, 211 hb_codepoint_t variation_selector, 212 hb_codepoint_t *glyph, 213 void *user_data HB_UNUSED) 214 { 215 return font->parent->get_variation_glyph (unicode, variation_selector, glyph); 216 } 217 218 219 static hb_position_t 220 hb_font_get_glyph_h_advance_nil (hb_font_t *font, 221 void *font_data HB_UNUSED, 222 hb_codepoint_t glyph HB_UNUSED, 223 void *user_data HB_UNUSED) 224 { 225 return font->x_scale; 226 } 227 228 static hb_position_t 229 hb_font_get_glyph_h_advance_default (hb_font_t *font, 230 void *font_data HB_UNUSED, 231 hb_codepoint_t glyph, 232 void *user_data HB_UNUSED) 233 { 234 if (font->has_glyph_h_advances_func_set ()) 235 { 236 hb_position_t ret; 237 font->get_glyph_h_advances (1, &glyph, 0, &ret, 0, false); 238 return ret; 239 } 240 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph, false)); 241 } 242 243 static hb_position_t 244 hb_font_get_glyph_v_advance_nil (hb_font_t *font, 245 void *font_data HB_UNUSED, 246 hb_codepoint_t glyph HB_UNUSED, 247 void *user_data HB_UNUSED) 248 { 249 return -font->y_scale; 250 } 251 252 static hb_position_t 253 hb_font_get_glyph_v_advance_default (hb_font_t *font, 254 void *font_data HB_UNUSED, 255 hb_codepoint_t glyph, 256 void *user_data HB_UNUSED) 257 { 258 if (font->has_glyph_v_advances_func_set ()) 259 { 260 hb_position_t ret; 261 font->get_glyph_v_advances (1, &glyph, 0, &ret, 0, false); 262 return ret; 263 } 264 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph, false)); 265 } 266 267 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default 268 269 static void 270 hb_font_get_glyph_h_advances_default (hb_font_t* font, 271 void* font_data HB_UNUSED, 272 unsigned int count, 273 const hb_codepoint_t *first_glyph, 274 unsigned int glyph_stride, 275 hb_position_t *first_advance, 276 unsigned int advance_stride, 277 void *user_data HB_UNUSED) 278 { 279 if (font->has_glyph_h_advance_func_set ()) 280 { 281 for (unsigned int i = 0; i < count; i++) 282 { 283 *first_advance = font->get_glyph_h_advance (*first_glyph, false); 284 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 285 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); 286 } 287 return; 288 } 289 290 font->parent->get_glyph_h_advances (count, 291 first_glyph, glyph_stride, 292 first_advance, advance_stride, 293 false); 294 for (unsigned int i = 0; i < count; i++) 295 { 296 *first_advance = font->parent_scale_x_distance (*first_advance); 297 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); 298 } 299 } 300 301 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default 302 static void 303 hb_font_get_glyph_v_advances_default (hb_font_t* font, 304 void* font_data HB_UNUSED, 305 unsigned int count, 306 const hb_codepoint_t *first_glyph, 307 unsigned int glyph_stride, 308 hb_position_t *first_advance, 309 unsigned int advance_stride, 310 void *user_data HB_UNUSED) 311 { 312 if (font->has_glyph_v_advance_func_set ()) 313 { 314 for (unsigned int i = 0; i < count; i++) 315 { 316 *first_advance = font->get_glyph_v_advance (*first_glyph, false); 317 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 318 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); 319 } 320 return; 321 } 322 323 font->parent->get_glyph_v_advances (count, 324 first_glyph, glyph_stride, 325 first_advance, advance_stride, 326 false); 327 for (unsigned int i = 0; i < count; i++) 328 { 329 *first_advance = font->parent_scale_y_distance (*first_advance); 330 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); 331 } 332 } 333 334 static hb_bool_t 335 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, 336 void *font_data HB_UNUSED, 337 hb_codepoint_t glyph HB_UNUSED, 338 hb_position_t *x, 339 hb_position_t *y, 340 void *user_data HB_UNUSED) 341 { 342 *x = *y = 0; 343 return true; 344 } 345 346 static hb_bool_t 347 hb_font_get_glyph_h_origin_default (hb_font_t *font, 348 void *font_data HB_UNUSED, 349 hb_codepoint_t glyph, 350 hb_position_t *x, 351 hb_position_t *y, 352 void *user_data HB_UNUSED) 353 { 354 if (font->has_glyph_h_origins_func_set ()) 355 { 356 return font->get_glyph_h_origins (1, &glyph, 0, x, 0, y, 0, false); 357 } 358 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); 359 if (ret) 360 font->parent_scale_position (x, y); 361 return ret; 362 } 363 364 static hb_bool_t 365 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, 366 void *font_data HB_UNUSED, 367 hb_codepoint_t glyph HB_UNUSED, 368 hb_position_t *x, 369 hb_position_t *y, 370 void *user_data HB_UNUSED) 371 { 372 return false; 373 } 374 375 static hb_bool_t 376 hb_font_get_glyph_v_origin_default (hb_font_t *font, 377 void *font_data HB_UNUSED, 378 hb_codepoint_t glyph, 379 hb_position_t *x, 380 hb_position_t *y, 381 void *user_data HB_UNUSED) 382 { 383 if (font->has_glyph_v_origins_func_set ()) 384 { 385 return font->get_glyph_v_origins (1, &glyph, 0, x, 0, y, 0, false); 386 } 387 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); 388 if (ret) 389 font->parent_scale_position (x, y); 390 return ret; 391 } 392 393 #define hb_font_get_glyph_h_origins_nil hb_font_get_glyph_h_origins_default 394 395 static hb_bool_t 396 hb_font_get_glyph_h_origins_default (hb_font_t *font HB_UNUSED, 397 void *font_data HB_UNUSED, 398 unsigned int count, 399 const hb_codepoint_t *first_glyph HB_UNUSED, 400 unsigned glyph_stride HB_UNUSED, 401 hb_position_t *first_x, 402 unsigned x_stride, 403 hb_position_t *first_y, 404 unsigned y_stride, 405 void *user_data HB_UNUSED) 406 { 407 if (font->has_glyph_h_origin_func_set ()) 408 { 409 for (unsigned int i = 0; i < count; i++) 410 { 411 font->get_glyph_h_origin (*first_glyph, first_x, first_y, false); 412 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 413 first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride); 414 first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride); 415 } 416 return true; 417 } 418 419 hb_bool_t ret = font->parent->get_glyph_h_origins (count, 420 first_glyph, glyph_stride, 421 first_x, x_stride, 422 first_y, y_stride); 423 if (ret) 424 { 425 for (unsigned i = 0; i < count; i++) 426 { 427 font->parent_scale_position (first_x, first_y); 428 first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride); 429 first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride); 430 } 431 } 432 return ret; 433 } 434 435 #define hb_font_get_glyph_v_origins_nil hb_font_get_glyph_v_origins_default 436 437 static hb_bool_t 438 hb_font_get_glyph_v_origins_default (hb_font_t *font HB_UNUSED, 439 void *font_data HB_UNUSED, 440 unsigned int count, 441 const hb_codepoint_t *first_glyph HB_UNUSED, 442 unsigned glyph_stride HB_UNUSED, 443 hb_position_t *first_x, 444 unsigned x_stride, 445 hb_position_t *first_y, 446 unsigned y_stride, 447 void *user_data HB_UNUSED) 448 { 449 if (font->has_glyph_v_origin_func_set ()) 450 { 451 for (unsigned int i = 0; i < count; i++) 452 { 453 font->get_glyph_v_origin (*first_glyph, first_x, first_y, false); 454 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 455 first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride); 456 first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride); 457 } 458 return true; 459 } 460 461 hb_bool_t ret = font->parent->get_glyph_v_origins (count, 462 first_glyph, glyph_stride, 463 first_x, x_stride, 464 first_y, y_stride); 465 if (ret) 466 { 467 for (unsigned i = 0; i < count; i++) 468 { 469 font->parent_scale_position (first_x, first_y); 470 first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride); 471 first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride); 472 } 473 } 474 return ret; 475 } 476 477 static hb_position_t 478 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, 479 void *font_data HB_UNUSED, 480 hb_codepoint_t left_glyph HB_UNUSED, 481 hb_codepoint_t right_glyph HB_UNUSED, 482 void *user_data HB_UNUSED) 483 { 484 return 0; 485 } 486 487 static hb_position_t 488 hb_font_get_glyph_h_kerning_default (hb_font_t *font, 489 void *font_data HB_UNUSED, 490 hb_codepoint_t left_glyph, 491 hb_codepoint_t right_glyph, 492 void *user_data HB_UNUSED) 493 { 494 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); 495 } 496 497 #ifndef HB_DISABLE_DEPRECATED 498 static hb_position_t 499 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, 500 void *font_data HB_UNUSED, 501 hb_codepoint_t top_glyph HB_UNUSED, 502 hb_codepoint_t bottom_glyph HB_UNUSED, 503 void *user_data HB_UNUSED) 504 { 505 return 0; 506 } 507 508 static hb_position_t 509 hb_font_get_glyph_v_kerning_default (hb_font_t *font, 510 void *font_data HB_UNUSED, 511 hb_codepoint_t top_glyph, 512 hb_codepoint_t bottom_glyph, 513 void *user_data HB_UNUSED) 514 { 515 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); 516 } 517 #endif 518 519 static hb_bool_t 520 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, 521 void *font_data HB_UNUSED, 522 hb_codepoint_t glyph HB_UNUSED, 523 hb_glyph_extents_t *extents, 524 void *user_data HB_UNUSED) 525 { 526 hb_memset (extents, 0, sizeof (*extents)); 527 return false; 528 } 529 530 static hb_bool_t 531 hb_font_get_glyph_extents_default (hb_font_t *font, 532 void *font_data HB_UNUSED, 533 hb_codepoint_t glyph, 534 hb_glyph_extents_t *extents, 535 void *user_data HB_UNUSED) 536 { 537 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents, false); 538 if (ret) { 539 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); 540 font->parent_scale_distance (&extents->width, &extents->height); 541 } 542 return ret; 543 } 544 545 static hb_bool_t 546 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, 547 void *font_data HB_UNUSED, 548 hb_codepoint_t glyph HB_UNUSED, 549 unsigned int point_index HB_UNUSED, 550 hb_position_t *x, 551 hb_position_t *y, 552 void *user_data HB_UNUSED) 553 { 554 *x = *y = 0; 555 return false; 556 } 557 558 static hb_bool_t 559 hb_font_get_glyph_contour_point_default (hb_font_t *font, 560 void *font_data HB_UNUSED, 561 hb_codepoint_t glyph, 562 unsigned int point_index, 563 hb_position_t *x, 564 hb_position_t *y, 565 void *user_data HB_UNUSED) 566 { 567 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y, false); 568 if (ret) 569 font->parent_scale_position (x, y); 570 return ret; 571 } 572 573 static hb_bool_t 574 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, 575 void *font_data HB_UNUSED, 576 hb_codepoint_t glyph HB_UNUSED, 577 char *name, 578 unsigned int size, 579 void *user_data HB_UNUSED) 580 { 581 if (size) *name = '\0'; 582 return false; 583 } 584 585 static hb_bool_t 586 hb_font_get_glyph_name_default (hb_font_t *font, 587 void *font_data HB_UNUSED, 588 hb_codepoint_t glyph, 589 char *name, 590 unsigned int size, 591 void *user_data HB_UNUSED) 592 { 593 return font->parent->get_glyph_name (glyph, name, size); 594 } 595 596 static hb_bool_t 597 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, 598 void *font_data HB_UNUSED, 599 const char *name HB_UNUSED, 600 int len HB_UNUSED, /* -1 means nul-terminated */ 601 hb_codepoint_t *glyph, 602 void *user_data HB_UNUSED) 603 { 604 *glyph = 0; 605 return false; 606 } 607 608 static hb_bool_t 609 hb_font_get_glyph_from_name_default (hb_font_t *font, 610 void *font_data HB_UNUSED, 611 const char *name, 612 int len, /* -1 means nul-terminated */ 613 hb_codepoint_t *glyph, 614 void *user_data HB_UNUSED) 615 { 616 return font->parent->get_glyph_from_name (name, len, glyph); 617 } 618 619 static hb_bool_t 620 hb_font_draw_glyph_or_fail_nil (hb_font_t *font HB_UNUSED, 621 void *font_data HB_UNUSED, 622 hb_codepoint_t glyph, 623 hb_draw_funcs_t *draw_funcs, 624 void *draw_data, 625 void *user_data HB_UNUSED) 626 { 627 return false; 628 } 629 630 static hb_bool_t 631 hb_font_paint_glyph_or_fail_nil (hb_font_t *font HB_UNUSED, 632 void *font_data HB_UNUSED, 633 hb_codepoint_t glyph HB_UNUSED, 634 hb_paint_funcs_t *paint_funcs HB_UNUSED, 635 void *paint_data HB_UNUSED, 636 unsigned int palette HB_UNUSED, 637 hb_color_t foreground HB_UNUSED, 638 void *user_data HB_UNUSED) 639 { 640 return false; 641 } 642 643 typedef struct hb_font_draw_glyph_default_adaptor_t { 644 hb_draw_funcs_t *draw_funcs; 645 void *draw_data; 646 float x_scale; 647 float y_scale; 648 } hb_font_draw_glyph_default_adaptor_t; 649 650 static void 651 hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, 652 void *draw_data, 653 hb_draw_state_t *st, 654 float to_x, float to_y, 655 void *user_data HB_UNUSED) 656 { 657 hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; 658 float x_scale = adaptor->x_scale; 659 float y_scale = adaptor->y_scale; 660 661 adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st, 662 x_scale * to_x, y_scale * to_y); 663 } 664 665 static void 666 hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, 667 hb_draw_state_t *st, 668 float to_x, float to_y, 669 void *user_data HB_UNUSED) 670 { 671 hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; 672 float x_scale = adaptor->x_scale; 673 float y_scale = adaptor->y_scale; 674 675 st->current_x = st->current_x * x_scale; 676 st->current_y = st->current_y * y_scale; 677 678 adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st, 679 x_scale * to_x, y_scale * to_y); 680 } 681 682 static void 683 hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, 684 hb_draw_state_t *st, 685 float control_x, float control_y, 686 float to_x, float to_y, 687 void *user_data HB_UNUSED) 688 { 689 hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; 690 float x_scale = adaptor->x_scale; 691 float y_scale = adaptor->y_scale; 692 693 st->current_x = st->current_x * x_scale; 694 st->current_y = st->current_y * y_scale; 695 696 adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st, 697 x_scale * control_x, y_scale * control_y, 698 x_scale * to_x, y_scale * to_y); 699 } 700 701 static void 702 hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, 703 hb_draw_state_t *st, 704 float control1_x, float control1_y, 705 float control2_x, float control2_y, 706 float to_x, float to_y, 707 void *user_data HB_UNUSED) 708 { 709 hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; 710 float x_scale = adaptor->x_scale; 711 float y_scale = adaptor->y_scale; 712 713 st->current_x = st->current_x * x_scale; 714 st->current_y = st->current_y * y_scale; 715 716 adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st, 717 x_scale * control1_x, y_scale * control1_y, 718 x_scale * control2_x, y_scale * control2_y, 719 x_scale * to_x, y_scale * to_y); 720 } 721 722 static void 723 hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, 724 hb_draw_state_t *st, 725 void *user_data HB_UNUSED) 726 { 727 hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; 728 729 adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st); 730 } 731 732 static const hb_draw_funcs_t _hb_draw_funcs_default = { 733 HB_OBJECT_HEADER_STATIC, 734 735 { 736 #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_default, 737 HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS 738 #undef HB_DRAW_FUNC_IMPLEMENT 739 } 740 }; 741 742 static hb_bool_t 743 hb_font_draw_glyph_or_fail_default (hb_font_t *font, 744 void *font_data HB_UNUSED, 745 hb_codepoint_t glyph, 746 hb_draw_funcs_t *draw_funcs, 747 void *draw_data, 748 void *user_data HB_UNUSED) 749 { 750 hb_font_draw_glyph_default_adaptor_t adaptor = { 751 draw_funcs, 752 draw_data, 753 font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, 754 font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f 755 }; 756 757 return font->parent->draw_glyph_or_fail (glyph, 758 const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default), 759 &adaptor, 760 false); 761 } 762 763 static hb_bool_t 764 hb_font_paint_glyph_or_fail_default (hb_font_t *font, 765 void *font_data, 766 hb_codepoint_t glyph, 767 hb_paint_funcs_t *paint_funcs, 768 void *paint_data, 769 unsigned int palette, 770 hb_color_t foreground, 771 void *user_data) 772 { 773 paint_funcs->push_transform (paint_data, 774 font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0, 0, 775 0, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0, 776 0, 0); 777 778 bool ret = font->parent->paint_glyph_or_fail (glyph, paint_funcs, paint_data, palette, foreground); 779 780 paint_funcs->pop_transform (paint_data); 781 782 return ret; 783 } 784 785 DEFINE_NULL_INSTANCE (hb_font_funcs_t) = 786 { 787 HB_OBJECT_HEADER_STATIC, 788 789 nullptr, 790 nullptr, 791 { 792 { 793 #define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_nil, 794 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 795 #undef HB_FONT_FUNC_IMPLEMENT 796 } 797 } 798 }; 799 800 static const hb_font_funcs_t _hb_font_funcs_default = { 801 HB_OBJECT_HEADER_STATIC, 802 803 nullptr, 804 nullptr, 805 { 806 { 807 #define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_default, 808 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 809 #undef HB_FONT_FUNC_IMPLEMENT 810 } 811 } 812 }; 813 814 815 /** 816 * hb_font_funcs_create: 817 * 818 * Creates a new #hb_font_funcs_t structure of font functions. 819 * 820 * Return value: (transfer full): The font-functions structure 821 * 822 * Since: 0.9.2 823 **/ 824 hb_font_funcs_t * 825 hb_font_funcs_create () 826 { 827 hb_font_funcs_t *ffuncs; 828 829 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) 830 return hb_font_funcs_get_empty (); 831 832 ffuncs->get = _hb_font_funcs_default.get; 833 834 return ffuncs; 835 } 836 837 /** 838 * hb_font_funcs_get_empty: 839 * 840 * Fetches an empty font-functions structure. 841 * 842 * Return value: (transfer full): The font-functions structure 843 * 844 * Since: 0.9.2 845 **/ 846 hb_font_funcs_t * 847 hb_font_funcs_get_empty () 848 { 849 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default); 850 } 851 852 /** 853 * hb_font_funcs_reference: (skip) 854 * @ffuncs: The font-functions structure 855 * 856 * Increases the reference count on a font-functions structure. 857 * 858 * Return value: The font-functions structure 859 * 860 * Since: 0.9.2 861 **/ 862 hb_font_funcs_t * 863 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) 864 { 865 return hb_object_reference (ffuncs); 866 } 867 868 /** 869 * hb_font_funcs_destroy: (skip) 870 * @ffuncs: The font-functions structure 871 * 872 * Decreases the reference count on a font-functions structure. When 873 * the reference count reaches zero, the font-functions structure is 874 * destroyed, freeing all memory. 875 * 876 * Since: 0.9.2 877 **/ 878 void 879 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) 880 { 881 if (!hb_object_destroy (ffuncs)) return; 882 883 if (ffuncs->destroy) 884 { 885 #define HB_FONT_FUNC_IMPLEMENT(get_,name) if (ffuncs->destroy->name) \ 886 ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); 887 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 888 #undef HB_FONT_FUNC_IMPLEMENT 889 } 890 891 hb_free (ffuncs->destroy); 892 hb_free (ffuncs->user_data); 893 894 hb_free (ffuncs); 895 } 896 897 /** 898 * hb_font_funcs_set_user_data: (skip) 899 * @ffuncs: The font-functions structure 900 * @key: The user-data key to set 901 * @data: A pointer to the user data set 902 * @destroy: (nullable): A callback to call when @data is not needed anymore 903 * @replace: Whether to replace an existing data with the same key 904 * 905 * Attaches a user-data key/data pair to the specified font-functions structure. 906 * 907 * Return value: `true` if success, `false` otherwise 908 * 909 * Since: 0.9.2 910 **/ 911 hb_bool_t 912 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, 913 hb_user_data_key_t *key, 914 void * data, 915 hb_destroy_func_t destroy /* May be NULL. */, 916 hb_bool_t replace) 917 { 918 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); 919 } 920 921 /** 922 * hb_font_funcs_get_user_data: (skip) 923 * @ffuncs: The font-functions structure 924 * @key: The user-data key to query 925 * 926 * Fetches the user data associated with the specified key, 927 * attached to the specified font-functions structure. 928 * 929 * Return value: (transfer none): A pointer to the user data 930 * 931 * Since: 0.9.2 932 **/ 933 void * 934 hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs, 935 hb_user_data_key_t *key) 936 { 937 return hb_object_get_user_data (ffuncs, key); 938 } 939 940 941 /** 942 * hb_font_funcs_make_immutable: 943 * @ffuncs: The font-functions structure 944 * 945 * Makes a font-functions structure immutable. 946 * 947 * Since: 0.9.2 948 **/ 949 void 950 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) 951 { 952 if (hb_object_is_immutable (ffuncs)) 953 return; 954 955 hb_object_make_immutable (ffuncs); 956 } 957 958 /** 959 * hb_font_funcs_is_immutable: 960 * @ffuncs: The font-functions structure 961 * 962 * Tests whether a font-functions structure is immutable. 963 * 964 * Return value: `true` if @ffuncs is immutable, `false` otherwise 965 * 966 * Since: 0.9.2 967 **/ 968 hb_bool_t 969 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) 970 { 971 return hb_object_is_immutable (ffuncs); 972 } 973 974 975 static bool 976 _hb_font_funcs_set_preamble (hb_font_funcs_t *ffuncs, 977 bool func_is_null, 978 void **user_data, 979 hb_destroy_func_t *destroy) 980 { 981 if (hb_object_is_immutable (ffuncs)) 982 { 983 if (*destroy) 984 (*destroy) (*user_data); 985 return false; 986 } 987 988 if (func_is_null) 989 { 990 if (*destroy) 991 (*destroy) (*user_data); 992 *destroy = nullptr; 993 *user_data = nullptr; 994 } 995 996 return true; 997 } 998 999 static bool 1000 _hb_font_funcs_set_middle (hb_font_funcs_t *ffuncs, 1001 void *user_data, 1002 hb_destroy_func_t destroy) 1003 { 1004 if (user_data && !ffuncs->user_data) 1005 { 1006 ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); 1007 if (unlikely (!ffuncs->user_data)) 1008 goto fail; 1009 } 1010 if (destroy && !ffuncs->destroy) 1011 { 1012 ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); 1013 if (unlikely (!ffuncs->destroy)) 1014 goto fail; 1015 } 1016 1017 return true; 1018 1019 fail: 1020 if (destroy) 1021 (destroy) (user_data); 1022 return false; 1023 } 1024 1025 #define HB_FONT_FUNC_IMPLEMENT(get_,name) \ 1026 \ 1027 void \ 1028 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ 1029 hb_font_##get_##name##_func_t func, \ 1030 void *user_data, \ 1031 hb_destroy_func_t destroy) \ 1032 { \ 1033 if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\ 1034 return; \ 1035 \ 1036 if (ffuncs->destroy && ffuncs->destroy->name) \ 1037 ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \ 1038 \ 1039 if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy)) \ 1040 return; \ 1041 \ 1042 if (func) \ 1043 ffuncs->get.f.name = func; \ 1044 else \ 1045 ffuncs->get.f.name = hb_font_##get_##name##_default; \ 1046 \ 1047 if (ffuncs->user_data) \ 1048 ffuncs->user_data->name = user_data; \ 1049 if (ffuncs->destroy) \ 1050 ffuncs->destroy->name = destroy; \ 1051 } 1052 1053 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 1054 #undef HB_FONT_FUNC_IMPLEMENT 1055 1056 bool 1057 hb_font_t::has_func_set (unsigned int i) 1058 { 1059 return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i]; 1060 } 1061 1062 bool 1063 hb_font_t::has_func (unsigned int i) 1064 { 1065 return has_func_set (i) || 1066 (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i)); 1067 } 1068 1069 /* Public getters */ 1070 1071 /** 1072 * hb_font_get_h_extents: 1073 * @font: #hb_font_t to work upon 1074 * @extents: (out): The font extents retrieved 1075 * 1076 * Fetches the extents for a specified font, for horizontal 1077 * text segments. 1078 * 1079 * Return value: `true` if data found, `false` otherwise 1080 * 1081 * Since: 1.1.3 1082 **/ 1083 hb_bool_t 1084 hb_font_get_h_extents (hb_font_t *font, 1085 hb_font_extents_t *extents) 1086 { 1087 return font->get_font_h_extents (extents); 1088 } 1089 1090 /** 1091 * hb_font_get_v_extents: 1092 * @font: #hb_font_t to work upon 1093 * @extents: (out): The font extents retrieved 1094 * 1095 * Fetches the extents for a specified font, for vertical 1096 * text segments. 1097 * 1098 * Return value: `true` if data found, `false` otherwise 1099 * 1100 * Since: 1.1.3 1101 **/ 1102 hb_bool_t 1103 hb_font_get_v_extents (hb_font_t *font, 1104 hb_font_extents_t *extents) 1105 { 1106 return font->get_font_v_extents (extents); 1107 } 1108 1109 /** 1110 * hb_font_get_glyph: 1111 * @font: #hb_font_t to work upon 1112 * @unicode: The Unicode code point to query 1113 * @variation_selector: A variation-selector code point 1114 * @glyph: (out): The glyph ID retrieved 1115 * 1116 * Fetches the glyph ID for a Unicode code point in the specified 1117 * font, with an optional variation selector. 1118 * 1119 * If @variation_selector is 0, calls hb_font_get_nominal_glyph(); 1120 * otherwise calls hb_font_get_variation_glyph(). 1121 * 1122 * Return value: `true` if data found, `false` otherwise 1123 * 1124 * Since: 0.9.2 1125 **/ 1126 hb_bool_t 1127 hb_font_get_glyph (hb_font_t *font, 1128 hb_codepoint_t unicode, 1129 hb_codepoint_t variation_selector, 1130 hb_codepoint_t *glyph) 1131 { 1132 if (unlikely (variation_selector)) 1133 return font->get_variation_glyph (unicode, variation_selector, glyph); 1134 return font->get_nominal_glyph (unicode, glyph); 1135 } 1136 1137 /** 1138 * hb_font_get_nominal_glyph: 1139 * @font: #hb_font_t to work upon 1140 * @unicode: The Unicode code point to query 1141 * @glyph: (out): The glyph ID retrieved 1142 * 1143 * Fetches the nominal glyph ID for a Unicode code point in the 1144 * specified font. 1145 * 1146 * This version of the function should not be used to fetch glyph IDs 1147 * for code points modified by variation selectors. For variation-selector 1148 * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph(). 1149 * 1150 * Return value: `true` if data found, `false` otherwise 1151 * 1152 * Since: 1.2.3 1153 **/ 1154 hb_bool_t 1155 hb_font_get_nominal_glyph (hb_font_t *font, 1156 hb_codepoint_t unicode, 1157 hb_codepoint_t *glyph) 1158 { 1159 return font->get_nominal_glyph (unicode, glyph); 1160 } 1161 1162 /** 1163 * hb_font_get_nominal_glyphs: 1164 * @font: #hb_font_t to work upon 1165 * @count: number of code points to query 1166 * @first_unicode: The first Unicode code point to query 1167 * @unicode_stride: The stride between successive code points 1168 * @first_glyph: (out): The first glyph ID retrieved 1169 * @glyph_stride: The stride between successive glyph IDs 1170 * 1171 * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph 1172 * IDs must be returned in a #hb_codepoint_t output parameter. Stops at the 1173 * first unsupported glyph ID. 1174 * 1175 * Return value: the number of code points processed 1176 * 1177 * Since: 2.6.3 1178 **/ 1179 unsigned int 1180 hb_font_get_nominal_glyphs (hb_font_t *font, 1181 unsigned int count, 1182 const hb_codepoint_t *first_unicode, 1183 unsigned int unicode_stride, 1184 hb_codepoint_t *first_glyph, 1185 unsigned int glyph_stride) 1186 { 1187 return font->get_nominal_glyphs (count, 1188 first_unicode, unicode_stride, 1189 first_glyph, glyph_stride); 1190 } 1191 1192 /** 1193 * hb_font_get_variation_glyph: 1194 * @font: #hb_font_t to work upon 1195 * @unicode: The Unicode code point to query 1196 * @variation_selector: The variation-selector code point to query 1197 * @glyph: (out): The glyph ID retrieved 1198 * 1199 * Fetches the glyph ID for a Unicode code point when followed by 1200 * by the specified variation-selector code point, in the specified 1201 * font. 1202 * 1203 * Return value: `true` if data found, `false` otherwise 1204 * 1205 * Since: 1.2.3 1206 **/ 1207 hb_bool_t 1208 hb_font_get_variation_glyph (hb_font_t *font, 1209 hb_codepoint_t unicode, 1210 hb_codepoint_t variation_selector, 1211 hb_codepoint_t *glyph) 1212 { 1213 return font->get_variation_glyph (unicode, variation_selector, glyph); 1214 } 1215 1216 /** 1217 * hb_font_get_glyph_h_advance: 1218 * @font: #hb_font_t to work upon 1219 * @glyph: The glyph ID to query 1220 * 1221 * Fetches the advance for a glyph ID in the specified font, 1222 * for horizontal text segments. 1223 * 1224 * Return value: The advance of @glyph within @font 1225 * 1226 * Since: 0.9.2 1227 **/ 1228 hb_position_t 1229 hb_font_get_glyph_h_advance (hb_font_t *font, 1230 hb_codepoint_t glyph) 1231 { 1232 return font->get_glyph_h_advance (glyph); 1233 } 1234 1235 /** 1236 * hb_font_get_glyph_v_advance: 1237 * @font: #hb_font_t to work upon 1238 * @glyph: The glyph ID to query 1239 * 1240 * Fetches the advance for a glyph ID in the specified font, 1241 * for vertical text segments. 1242 * 1243 * Return value: The advance of @glyph within @font 1244 * 1245 * Since: 0.9.2 1246 **/ 1247 hb_position_t 1248 hb_font_get_glyph_v_advance (hb_font_t *font, 1249 hb_codepoint_t glyph) 1250 { 1251 return font->get_glyph_v_advance (glyph); 1252 } 1253 1254 /** 1255 * hb_font_get_glyph_h_advances: 1256 * @font: #hb_font_t to work upon 1257 * @count: The number of glyph IDs in the sequence queried 1258 * @first_glyph: The first glyph ID to query 1259 * @glyph_stride: The stride between successive glyph IDs 1260 * @first_advance: (out): The first advance retrieved 1261 * @advance_stride: The stride between successive advances 1262 * 1263 * Fetches the advances for a sequence of glyph IDs in the specified 1264 * font, for horizontal text segments. 1265 * 1266 * Since: 1.8.6 1267 **/ 1268 void 1269 hb_font_get_glyph_h_advances (hb_font_t* font, 1270 unsigned int count, 1271 const hb_codepoint_t *first_glyph, 1272 unsigned glyph_stride, 1273 hb_position_t *first_advance, 1274 unsigned advance_stride) 1275 { 1276 font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); 1277 } 1278 /** 1279 * hb_font_get_glyph_v_advances: 1280 * @font: #hb_font_t to work upon 1281 * @count: The number of glyph IDs in the sequence queried 1282 * @first_glyph: The first glyph ID to query 1283 * @glyph_stride: The stride between successive glyph IDs 1284 * @first_advance: (out): The first advance retrieved 1285 * @advance_stride: (out): The stride between successive advances 1286 * 1287 * Fetches the advances for a sequence of glyph IDs in the specified 1288 * font, for vertical text segments. 1289 * 1290 * Since: 1.8.6 1291 **/ 1292 void 1293 hb_font_get_glyph_v_advances (hb_font_t* font, 1294 unsigned int count, 1295 const hb_codepoint_t *first_glyph, 1296 unsigned glyph_stride, 1297 hb_position_t *first_advance, 1298 unsigned advance_stride) 1299 { 1300 font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); 1301 } 1302 1303 /** 1304 * hb_font_get_glyph_h_origin: 1305 * @font: #hb_font_t to work upon 1306 * @glyph: The glyph ID to query 1307 * @x: (out): The X coordinate of the origin 1308 * @y: (out): The Y coordinate of the origin 1309 * 1310 * Fetches the (X,Y) coordinates of the origin for a glyph ID 1311 * in the specified font, for horizontal text segments. 1312 * 1313 * Return value: `true` if data found, `false` otherwise 1314 * 1315 * Since: 0.9.2 1316 **/ 1317 hb_bool_t 1318 hb_font_get_glyph_h_origin (hb_font_t *font, 1319 hb_codepoint_t glyph, 1320 hb_position_t *x, 1321 hb_position_t *y) 1322 { 1323 return font->get_glyph_h_origin (glyph, x, y); 1324 } 1325 1326 /** 1327 * hb_font_get_glyph_v_origin: 1328 * @font: #hb_font_t to work upon 1329 * @glyph: The glyph ID to query 1330 * @x: (out): The X coordinate of the origin 1331 * @y: (out): The Y coordinate of the origin 1332 * 1333 * Fetches the (X,Y) coordinates of the origin for a glyph ID 1334 * in the specified font, for vertical text segments. 1335 * 1336 * Return value: `true` if data found, `false` otherwise 1337 * 1338 * Since: 0.9.2 1339 **/ 1340 hb_bool_t 1341 hb_font_get_glyph_v_origin (hb_font_t *font, 1342 hb_codepoint_t glyph, 1343 hb_position_t *x, 1344 hb_position_t *y) 1345 { 1346 return font->get_glyph_v_origin (glyph, x, y); 1347 } 1348 1349 /** 1350 * hb_font_get_glyph_h_origins: 1351 * @font: #hb_font_t to work upon 1352 * @count: The number of glyph IDs in the sequence queried 1353 * @first_glyph: The first glyph ID to query 1354 * @glyph_stride: The stride between successive glyph IDs 1355 * @first_x: (out): The first X coordinate of the origin retrieved 1356 * @x_stride: The stride between successive X coordinates 1357 * @first_y: (out): The first Y coordinate of the origin retrieved 1358 * @y_stride: The stride between successive Y coordinates 1359 * 1360 * Fetches the (X,Y) coordinates of the origin for requested glyph IDs 1361 * in the specified font, for horizontal text segments. 1362 * 1363 * Return value: `true` if data found, `false` otherwise 1364 * 1365 * Since: 11.3.0 1366 **/ 1367 hb_bool_t 1368 hb_font_get_glyph_h_origins (hb_font_t *font, 1369 unsigned int count, 1370 const hb_codepoint_t *first_glyph, 1371 unsigned int glyph_stride, 1372 hb_position_t *first_x, 1373 unsigned int x_stride, 1374 hb_position_t *first_y, 1375 unsigned int y_stride) 1376 1377 { 1378 return font->get_glyph_h_origins (count, 1379 first_glyph, glyph_stride, 1380 first_x, x_stride, 1381 first_y, y_stride); 1382 } 1383 1384 /** 1385 * hb_font_get_glyph_v_origins: 1386 * @font: #hb_font_t to work upon 1387 * @count: The number of glyph IDs in the sequence queried 1388 * @first_glyph: The first glyph ID to query 1389 * @glyph_stride: The stride between successive glyph IDs 1390 * @first_x: (out): The first X coordinate of the origin retrieved 1391 * @x_stride: The stride between successive X coordinates 1392 * @first_y: (out): The first Y coordinate of the origin retrieved 1393 * @y_stride: The stride between successive Y coordinates 1394 * 1395 * Fetches the (X,Y) coordinates of the origin for requested glyph IDs 1396 * in the specified font, for vertical text segments. 1397 * 1398 * Return value: `true` if data found, `false` otherwise 1399 * 1400 * Since: 11.3.0 1401 **/ 1402 hb_bool_t 1403 hb_font_get_glyph_v_origins (hb_font_t *font, 1404 unsigned int count, 1405 const hb_codepoint_t *first_glyph, 1406 unsigned int glyph_stride, 1407 hb_position_t *first_x, 1408 unsigned int x_stride, 1409 hb_position_t *first_y, 1410 unsigned int y_stride) 1411 1412 { 1413 return font->get_glyph_v_origins (count, 1414 first_glyph, glyph_stride, 1415 first_x, x_stride, 1416 first_y, y_stride); 1417 } 1418 1419 1420 /** 1421 * hb_font_get_glyph_h_kerning: 1422 * @font: #hb_font_t to work upon 1423 * @left_glyph: The glyph ID of the left glyph in the glyph pair 1424 * @right_glyph: The glyph ID of the right glyph in the glyph pair 1425 * 1426 * Fetches the kerning-adjustment value for a glyph-pair in 1427 * the specified font, for horizontal text segments. 1428 * 1429 * <note>It handles legacy kerning only (as returned by the corresponding 1430 * #hb_font_funcs_t function).</note> 1431 * 1432 * Return value: The kerning adjustment value 1433 * 1434 * Since: 0.9.2 1435 **/ 1436 hb_position_t 1437 hb_font_get_glyph_h_kerning (hb_font_t *font, 1438 hb_codepoint_t left_glyph, 1439 hb_codepoint_t right_glyph) 1440 { 1441 return font->get_glyph_h_kerning (left_glyph, right_glyph); 1442 } 1443 1444 #ifndef HB_DISABLE_DEPRECATED 1445 /** 1446 * hb_font_get_glyph_v_kerning: 1447 * @font: #hb_font_t to work upon 1448 * @top_glyph: The glyph ID of the top glyph in the glyph pair 1449 * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair 1450 * 1451 * Fetches the kerning-adjustment value for a glyph-pair in 1452 * the specified font, for vertical text segments. 1453 * 1454 * <note>It handles legacy kerning only (as returned by the corresponding 1455 * #hb_font_funcs_t function).</note> 1456 * 1457 * Return value: The kerning adjustment value 1458 * 1459 * Since: 0.9.2 1460 * Deprecated: 2.0.0 1461 **/ 1462 hb_position_t 1463 hb_font_get_glyph_v_kerning (hb_font_t *font, 1464 hb_codepoint_t top_glyph, 1465 hb_codepoint_t bottom_glyph) 1466 { 1467 return font->get_glyph_v_kerning (top_glyph, bottom_glyph); 1468 } 1469 #endif 1470 1471 /** 1472 * hb_font_get_glyph_extents: 1473 * @font: #hb_font_t to work upon 1474 * @glyph: The glyph ID to query 1475 * @extents: (out): The #hb_glyph_extents_t retrieved 1476 * 1477 * Fetches the #hb_glyph_extents_t data for a glyph ID 1478 * in the specified font. 1479 * 1480 * Return value: `true` if data found, `false` otherwise 1481 * 1482 * Since: 0.9.2 1483 **/ 1484 hb_bool_t 1485 hb_font_get_glyph_extents (hb_font_t *font, 1486 hb_codepoint_t glyph, 1487 hb_glyph_extents_t *extents) 1488 { 1489 return font->get_glyph_extents (glyph, extents); 1490 } 1491 1492 /** 1493 * hb_font_get_glyph_contour_point: 1494 * @font: #hb_font_t to work upon 1495 * @glyph: The glyph ID to query 1496 * @point_index: The contour-point index to query 1497 * @x: (out): The X value retrieved for the contour point 1498 * @y: (out): The Y value retrieved for the contour point 1499 * 1500 * Fetches the (x,y) coordinates of a specified contour-point index 1501 * in the specified glyph, within the specified font. 1502 * 1503 * Return value: `true` if data found, `false` otherwise 1504 * 1505 * Since: 0.9.2 1506 **/ 1507 hb_bool_t 1508 hb_font_get_glyph_contour_point (hb_font_t *font, 1509 hb_codepoint_t glyph, 1510 unsigned int point_index, 1511 hb_position_t *x, 1512 hb_position_t *y) 1513 { 1514 return font->get_glyph_contour_point (glyph, point_index, x, y); 1515 } 1516 1517 /** 1518 * hb_font_get_glyph_name: 1519 * @font: #hb_font_t to work upon 1520 * @glyph: The glyph ID to query 1521 * @name: (out) (array length=size): Name string retrieved for the glyph ID 1522 * @size: Length of the glyph-name string retrieved 1523 * 1524 * Fetches the glyph-name string for a glyph ID in the specified @font. 1525 * 1526 * According to the OpenType specification, glyph names are limited to 63 1527 * characters and can only contain (a subset of) ASCII. 1528 * 1529 * Return value: `true` if data found, `false` otherwise 1530 * 1531 * Since: 0.9.2 1532 **/ 1533 hb_bool_t 1534 hb_font_get_glyph_name (hb_font_t *font, 1535 hb_codepoint_t glyph, 1536 char *name, 1537 unsigned int size) 1538 { 1539 return font->get_glyph_name (glyph, name, size); 1540 } 1541 1542 /** 1543 * hb_font_get_glyph_from_name: 1544 * @font: #hb_font_t to work upon 1545 * @name: (array length=len): The name string to query 1546 * @len: The length of the name queried 1547 * @glyph: (out): The glyph ID retrieved 1548 * 1549 * Fetches the glyph ID that corresponds to a name string in the specified @font. 1550 * 1551 * <note>Note: @len == -1 means the name string is null-terminated.</note> 1552 * 1553 * Return value: `true` if data found, `false` otherwise 1554 * 1555 * Since: 0.9.2 1556 **/ 1557 hb_bool_t 1558 hb_font_get_glyph_from_name (hb_font_t *font, 1559 const char *name, 1560 int len, /* -1 means nul-terminated */ 1561 hb_codepoint_t *glyph) 1562 { 1563 return font->get_glyph_from_name (name, len, glyph); 1564 } 1565 1566 #ifndef HB_DISABLE_DEPRECATED 1567 /** 1568 * hb_font_get_glyph_shape: 1569 * @font: #hb_font_t to work upon 1570 * @glyph: The glyph ID 1571 * @dfuncs: #hb_draw_funcs_t to draw to 1572 * @draw_data: User data to pass to draw callbacks 1573 * 1574 * Fetches the glyph shape that corresponds to a glyph in the specified @font. 1575 * The shape is returned by way of calls to the callbacks of the @dfuncs 1576 * objects, with @draw_data passed to them. 1577 * 1578 * Since: 4.0.0 1579 * Deprecated: 7.0.0: Use hb_font_draw_glyph() instead 1580 */ 1581 void 1582 hb_font_get_glyph_shape (hb_font_t *font, 1583 hb_codepoint_t glyph, 1584 hb_draw_funcs_t *dfuncs, void *draw_data) 1585 { 1586 hb_font_draw_glyph (font, glyph, dfuncs, draw_data); 1587 } 1588 #endif 1589 1590 /** 1591 * hb_font_draw_glyph_or_fail: 1592 * @font: #hb_font_t to work upon 1593 * @glyph: The glyph ID 1594 * @dfuncs: #hb_draw_funcs_t to draw to 1595 * @draw_data: User data to pass to draw callbacks 1596 * 1597 * Draws the outline that corresponds to a glyph in the specified @font. 1598 * 1599 * This is a newer name for hb_font_draw_glyph(), that returns `false` 1600 * if the font has no outlines for the glyph. 1601 * 1602 * The outline is returned by way of calls to the callbacks of the @dfuncs 1603 * objects, with @draw_data passed to them. 1604 * 1605 * Return value: `true` if glyph was drawn, `false` otherwise 1606 * 1607 * Since: 11.2.0 1608 **/ 1609 hb_bool_t 1610 hb_font_draw_glyph_or_fail (hb_font_t *font, 1611 hb_codepoint_t glyph, 1612 hb_draw_funcs_t *dfuncs, void *draw_data) 1613 { 1614 return font->draw_glyph_or_fail (glyph, dfuncs, draw_data); 1615 } 1616 1617 /** 1618 * hb_font_paint_glyph_or_fail: 1619 * @font: #hb_font_t to work upon 1620 * @glyph: The glyph ID 1621 * @pfuncs: #hb_paint_funcs_t to paint with 1622 * @paint_data: User data to pass to paint callbacks 1623 * @palette_index: The index of the font's color palette to use 1624 * @foreground: The foreground color, unpremultipled 1625 * 1626 * Paints a color glyph. 1627 * 1628 * This function is similar to, but lower-level than, 1629 * hb_font_paint_glyph(). It is suitable for clients that 1630 * need more control. If there are no color glyphs available, 1631 * it will return `false`. The client can then fall back to 1632 * hb_font_draw_glyph_or_fail() for the monochrome outline glyph. 1633 * 1634 * The painting instructions are returned by way of calls to 1635 * the callbacks of the @funcs object, with @paint_data passed 1636 * to them. 1637 * 1638 * If the font has color palettes (see hb_ot_color_has_palettes()), 1639 * then @palette_index selects the palette to use. If the font only 1640 * has one palette, this will be 0. 1641 * 1642 * Return value: `true` if glyph was painted, `false` otherwise 1643 * 1644 * Since: 11.2.0 1645 */ 1646 hb_bool_t 1647 hb_font_paint_glyph_or_fail (hb_font_t *font, 1648 hb_codepoint_t glyph, 1649 hb_paint_funcs_t *pfuncs, void *paint_data, 1650 unsigned int palette_index, 1651 hb_color_t foreground) 1652 { 1653 return font->paint_glyph_or_fail (glyph, pfuncs, paint_data, palette_index, foreground); 1654 } 1655 1656 /* A bit higher-level, and with fallback */ 1657 1658 void 1659 hb_font_t::paint_glyph (hb_codepoint_t glyph, 1660 hb_paint_funcs_t *paint_funcs, void *paint_data, 1661 unsigned int palette, 1662 hb_color_t foreground) 1663 { 1664 if (paint_glyph_or_fail (glyph, 1665 paint_funcs, paint_data, 1666 palette, foreground)) 1667 return; 1668 1669 /* Fallback for outline glyph. */ 1670 paint_funcs->push_clip_glyph (paint_data, glyph, this); 1671 paint_funcs->color (paint_data, true, foreground); 1672 paint_funcs->pop_clip (paint_data); 1673 } 1674 1675 1676 /** 1677 * hb_font_draw_glyph: 1678 * @font: #hb_font_t to work upon 1679 * @glyph: The glyph ID 1680 * @dfuncs: #hb_draw_funcs_t to draw to 1681 * @draw_data: User data to pass to draw callbacks 1682 * 1683 * Draws the outline that corresponds to a glyph in the specified @font. 1684 * 1685 * This is an older name for hb_font_draw_glyph_or_fail(), with no 1686 * return value. 1687 * 1688 * The outline is returned by way of calls to the callbacks of the @dfuncs 1689 * objects, with @draw_data passed to them. 1690 * 1691 * Since: 7.0.0 1692 **/ 1693 void 1694 hb_font_draw_glyph (hb_font_t *font, 1695 hb_codepoint_t glyph, 1696 hb_draw_funcs_t *dfuncs, void *draw_data) 1697 { 1698 (void) hb_font_draw_glyph_or_fail (font, glyph, dfuncs, draw_data); 1699 } 1700 1701 /** 1702 * hb_font_paint_glyph: 1703 * @font: #hb_font_t to work upon 1704 * @glyph: The glyph ID 1705 * @pfuncs: #hb_paint_funcs_t to paint with 1706 * @paint_data: User data to pass to paint callbacks 1707 * @palette_index: The index of the font's color palette to use 1708 * @foreground: The foreground color, unpremultipled 1709 * 1710 * Paints the glyph. This function is similar to 1711 * hb_font_paint_glyph_or_fail(), but if painting a color glyph 1712 * failed, it will fall back to painting an outline monochrome 1713 * glyph. 1714 * 1715 * The painting instructions are returned by way of calls to 1716 * the callbacks of the @funcs object, with @paint_data passed 1717 * to them. 1718 * 1719 * If the font has color palettes (see hb_ot_color_has_palettes()), 1720 * then @palette_index selects the palette to use. If the font only 1721 * has one palette, this will be 0. 1722 * 1723 * Since: 7.0.0 1724 */ 1725 void 1726 hb_font_paint_glyph (hb_font_t *font, 1727 hb_codepoint_t glyph, 1728 hb_paint_funcs_t *pfuncs, void *paint_data, 1729 unsigned int palette_index, 1730 hb_color_t foreground) 1731 { 1732 font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground); 1733 } 1734 1735 /** 1736 * hb_font_get_extents_for_direction: 1737 * @font: #hb_font_t to work upon 1738 * @direction: The direction of the text segment 1739 * @extents: (out): The #hb_font_extents_t retrieved 1740 * 1741 * Fetches the extents for a font in a text segment of the 1742 * specified direction. 1743 * 1744 * Calls the appropriate direction-specific variant (horizontal 1745 * or vertical) depending on the value of @direction. 1746 * 1747 * Since: 1.1.3 1748 **/ 1749 void 1750 hb_font_get_extents_for_direction (hb_font_t *font, 1751 hb_direction_t direction, 1752 hb_font_extents_t *extents) 1753 { 1754 font->get_extents_for_direction (direction, extents); 1755 } 1756 /** 1757 * hb_font_get_glyph_advance_for_direction: 1758 * @font: #hb_font_t to work upon 1759 * @glyph: The glyph ID to query 1760 * @direction: The direction of the text segment 1761 * @x: (out): The horizontal advance retrieved 1762 * @y: (out): The vertical advance retrieved 1763 * 1764 * Fetches the advance for a glyph ID from the specified font, 1765 * in a text segment of the specified direction. 1766 * 1767 * Calls the appropriate direction-specific variant (horizontal 1768 * or vertical) depending on the value of @direction. 1769 * 1770 * Since: 0.9.2 1771 **/ 1772 void 1773 hb_font_get_glyph_advance_for_direction (hb_font_t *font, 1774 hb_codepoint_t glyph, 1775 hb_direction_t direction, 1776 hb_position_t *x, 1777 hb_position_t *y) 1778 { 1779 font->get_glyph_advance_for_direction (glyph, direction, x, y); 1780 } 1781 /** 1782 * hb_font_get_glyph_advances_for_direction: 1783 * @font: #hb_font_t to work upon 1784 * @direction: The direction of the text segment 1785 * @count: The number of glyph IDs in the sequence queried 1786 * @first_glyph: The first glyph ID to query 1787 * @glyph_stride: The stride between successive glyph IDs 1788 * @first_advance: (out): The first advance retrieved 1789 * @advance_stride: (out): The stride between successive advances 1790 * 1791 * Fetches the advances for a sequence of glyph IDs in the specified 1792 * font, in a text segment of the specified direction. 1793 * 1794 * Calls the appropriate direction-specific variant (horizontal 1795 * or vertical) depending on the value of @direction. 1796 * 1797 * Since: 1.8.6 1798 **/ 1799 HB_EXTERN void 1800 hb_font_get_glyph_advances_for_direction (hb_font_t* font, 1801 hb_direction_t direction, 1802 unsigned int count, 1803 const hb_codepoint_t *first_glyph, 1804 unsigned glyph_stride, 1805 hb_position_t *first_advance, 1806 unsigned advance_stride) 1807 { 1808 font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride); 1809 } 1810 1811 /** 1812 * hb_font_get_glyph_origin_for_direction: 1813 * @font: #hb_font_t to work upon 1814 * @glyph: The glyph ID to query 1815 * @direction: The direction of the text segment 1816 * @x: (out): The X coordinate retrieved for the origin 1817 * @y: (out): The Y coordinate retrieved for the origin 1818 * 1819 * Fetches the (X,Y) coordinates of the origin for a glyph in 1820 * the specified font. 1821 * 1822 * Calls the appropriate direction-specific variant (horizontal 1823 * or vertical) depending on the value of @direction. 1824 * 1825 * Since: 0.9.2 1826 **/ 1827 void 1828 hb_font_get_glyph_origin_for_direction (hb_font_t *font, 1829 hb_codepoint_t glyph, 1830 hb_direction_t direction, 1831 hb_position_t *x, 1832 hb_position_t *y) 1833 { 1834 return font->get_glyph_origin_for_direction (glyph, direction, x, y); 1835 } 1836 1837 /** 1838 * hb_font_add_glyph_origin_for_direction: 1839 * @font: #hb_font_t to work upon 1840 * @glyph: The glyph ID to query 1841 * @direction: The direction of the text segment 1842 * @x: (inout): Input = The original X coordinate 1843 * Output = The X coordinate plus the X-coordinate of the origin 1844 * @y: (inout): Input = The original Y coordinate 1845 * Output = The Y coordinate plus the Y-coordinate of the origin 1846 * 1847 * Adds the origin coordinates to an (X,Y) point coordinate, in 1848 * the specified glyph ID in the specified font. 1849 * 1850 * Calls the appropriate direction-specific variant (horizontal 1851 * or vertical) depending on the value of @direction. 1852 * 1853 * Since: 0.9.2 1854 **/ 1855 void 1856 hb_font_add_glyph_origin_for_direction (hb_font_t *font, 1857 hb_codepoint_t glyph, 1858 hb_direction_t direction, 1859 hb_position_t *x, 1860 hb_position_t *y) 1861 { 1862 return font->add_glyph_origin_for_direction (glyph, direction, x, y); 1863 } 1864 1865 /** 1866 * hb_font_subtract_glyph_origin_for_direction: 1867 * @font: #hb_font_t to work upon 1868 * @glyph: The glyph ID to query 1869 * @direction: The direction of the text segment 1870 * @x: (inout): Input = The original X coordinate 1871 * Output = The X coordinate minus the X-coordinate of the origin 1872 * @y: (inout): Input = The original Y coordinate 1873 * Output = The Y coordinate minus the Y-coordinate of the origin 1874 * 1875 * Subtracts the origin coordinates from an (X,Y) point coordinate, 1876 * in the specified glyph ID in the specified font. 1877 * 1878 * Calls the appropriate direction-specific variant (horizontal 1879 * or vertical) depending on the value of @direction. 1880 * 1881 * Since: 0.9.2 1882 **/ 1883 void 1884 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, 1885 hb_codepoint_t glyph, 1886 hb_direction_t direction, 1887 hb_position_t *x, 1888 hb_position_t *y) 1889 { 1890 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); 1891 } 1892 1893 /** 1894 * hb_font_get_glyph_kerning_for_direction: 1895 * @font: #hb_font_t to work upon 1896 * @first_glyph: The glyph ID of the first glyph in the glyph pair to query 1897 * @second_glyph: The glyph ID of the second glyph in the glyph pair to query 1898 * @direction: The direction of the text segment 1899 * @x: (out): The horizontal kerning-adjustment value retrieved 1900 * @y: (out): The vertical kerning-adjustment value retrieved 1901 * 1902 * Fetches the kerning-adjustment value for a glyph-pair in the specified font. 1903 * 1904 * Calls the appropriate direction-specific variant (horizontal 1905 * or vertical) depending on the value of @direction. 1906 * 1907 * Since: 0.9.2 1908 **/ 1909 void 1910 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, 1911 hb_codepoint_t first_glyph, 1912 hb_codepoint_t second_glyph, 1913 hb_direction_t direction, 1914 hb_position_t *x, 1915 hb_position_t *y) 1916 { 1917 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); 1918 } 1919 1920 /** 1921 * hb_font_get_glyph_extents_for_origin: 1922 * @font: #hb_font_t to work upon 1923 * @glyph: The glyph ID to query 1924 * @direction: The direction of the text segment 1925 * @extents: (out): The #hb_glyph_extents_t retrieved 1926 * 1927 * Fetches the #hb_glyph_extents_t data for a glyph ID 1928 * in the specified font, with respect to the origin in 1929 * a text segment in the specified direction. 1930 * 1931 * Calls the appropriate direction-specific variant (horizontal 1932 * or vertical) depending on the value of @direction. 1933 * 1934 * Return value: `true` if data found, `false` otherwise 1935 * 1936 * Since: 0.9.2 1937 **/ 1938 hb_bool_t 1939 hb_font_get_glyph_extents_for_origin (hb_font_t *font, 1940 hb_codepoint_t glyph, 1941 hb_direction_t direction, 1942 hb_glyph_extents_t *extents) 1943 { 1944 return font->get_glyph_extents_for_origin (glyph, direction, extents); 1945 } 1946 1947 /** 1948 * hb_font_get_glyph_contour_point_for_origin: 1949 * @font: #hb_font_t to work upon 1950 * @glyph: The glyph ID to query 1951 * @point_index: The contour-point index to query 1952 * @direction: The direction of the text segment 1953 * @x: (out): The X value retrieved for the contour point 1954 * @y: (out): The Y value retrieved for the contour point 1955 * 1956 * Fetches the (X,Y) coordinates of a specified contour-point index 1957 * in the specified glyph ID in the specified font, with respect 1958 * to the origin in a text segment in the specified direction. 1959 * 1960 * Calls the appropriate direction-specific variant (horizontal 1961 * or vertical) depending on the value of @direction. 1962 * 1963 * Return value: `true` if data found, `false` otherwise 1964 * 1965 * Since: 0.9.2 1966 **/ 1967 hb_bool_t 1968 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, 1969 hb_codepoint_t glyph, 1970 unsigned int point_index, 1971 hb_direction_t direction, 1972 hb_position_t *x, 1973 hb_position_t *y) 1974 { 1975 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); 1976 } 1977 1978 /** 1979 * hb_font_glyph_to_string: 1980 * @font: #hb_font_t to work upon 1981 * @glyph: The glyph ID to query 1982 * @s: (out) (array length=size): The string containing the glyph name 1983 * @size: Length of string @s 1984 * 1985 * Fetches the name of the specified glyph ID in @font and returns 1986 * it in string @s. 1987 * 1988 * If the glyph ID has no name in @font, a string of the form `gidDDD` is 1989 * generated, with `DDD` being the glyph ID. 1990 * 1991 * According to the OpenType specification, glyph names are limited to 63 1992 * characters and can only contain (a subset of) ASCII. 1993 * 1994 * Since: 0.9.2 1995 **/ 1996 void 1997 hb_font_glyph_to_string (hb_font_t *font, 1998 hb_codepoint_t glyph, 1999 char *s, 2000 unsigned int size) 2001 { 2002 font->glyph_to_string (glyph, s, size); 2003 } 2004 2005 /** 2006 * hb_font_glyph_from_string: 2007 * @font: #hb_font_t to work upon 2008 * @s: (array length=len) (element-type uint8_t): string to query 2009 * @len: The length of the string @s 2010 * @glyph: (out): The glyph ID corresponding to the string requested 2011 * 2012 * Fetches the glyph ID from @font that matches the specified string. 2013 * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically. 2014 * 2015 * <note>Note: @len == -1 means the string is null-terminated.</note> 2016 * 2017 * Return value: `true` if data found, `false` otherwise 2018 * 2019 * Since: 0.9.2 2020 **/ 2021 hb_bool_t 2022 hb_font_glyph_from_string (hb_font_t *font, 2023 const char *s, 2024 int len, 2025 hb_codepoint_t *glyph) 2026 { 2027 return font->glyph_from_string (s, len, glyph); 2028 } 2029 2030 2031 /* 2032 * hb_font_t 2033 */ 2034 2035 DEFINE_NULL_INSTANCE (hb_font_t) = 2036 { 2037 HB_OBJECT_HEADER_STATIC, 2038 2039 0, /* serial */ 2040 0, /* serial_coords */ 2041 2042 nullptr, /* parent */ 2043 const_cast<hb_face_t *> (&_hb_Null_hb_face_t), 2044 2045 1000, /* x_scale */ 2046 1000, /* y_scale */ 2047 false, /* is_synthetic */ 2048 0.f, /* x_embolden */ 2049 0.f, /* y_embolden */ 2050 true, /* embolden_in_place */ 2051 0, /* x_strength */ 2052 0, /* y_strength */ 2053 0.f, /* slant */ 2054 0.f, /* slant_xy; */ 2055 1.f, /* x_multf */ 2056 1.f, /* y_multf */ 2057 1<<16, /* x_mult */ 2058 1<<16, /* y_mult */ 2059 2060 0, /* x_ppem */ 2061 0, /* y_ppem */ 2062 0, /* ptem */ 2063 2064 HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */ 2065 false, /* has_nonzero_coords */ 2066 0, /* num_coords */ 2067 nullptr, /* coords */ 2068 nullptr, /* design_coords */ 2069 2070 const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), 2071 2072 /* Zero for the rest is fine. */ 2073 }; 2074 2075 2076 static hb_font_t * 2077 _hb_font_create (hb_face_t *face) 2078 { 2079 hb_font_t *font; 2080 2081 if (unlikely (!face)) 2082 face = hb_face_get_empty (); 2083 2084 if (!(font = hb_object_create<hb_font_t> ())) 2085 return hb_font_get_empty (); 2086 2087 hb_face_make_immutable (face); 2088 font->parent = hb_font_get_empty (); 2089 font->face = hb_face_reference (face); 2090 font->klass = hb_font_funcs_get_empty (); 2091 font->data.init0 (font); 2092 font->x_scale = font->y_scale = face->get_upem (); 2093 font->embolden_in_place = true; 2094 font->x_multf = font->y_multf = 1.f; 2095 font->x_mult = font->y_mult = 1 << 16; 2096 font->instance_index = HB_FONT_NO_VAR_NAMED_INSTANCE; 2097 2098 return font; 2099 } 2100 2101 /** 2102 * hb_font_create: 2103 * @face: a face. 2104 * 2105 * Constructs a new font object from the specified face. 2106 * 2107 * <note>Note: If @face's index value (as passed to hb_face_create() 2108 * has non-zero top 16-bits, those bits minus one are passed to 2109 * hb_font_set_var_named_instance(), effectively loading a named-instance 2110 * of a variable font, instead of the default-instance. This allows 2111 * specifying which named-instance to load by default when creating the 2112 * face.</note> 2113 * 2114 * Return value: (transfer full): The new font object 2115 * 2116 * Since: 0.9.2 2117 **/ 2118 hb_font_t * 2119 hb_font_create (hb_face_t *face) 2120 { 2121 hb_font_t *font = _hb_font_create (face); 2122 2123 hb_font_set_funcs_using (font, nullptr); 2124 2125 #ifndef HB_NO_VAR 2126 // Initialize variations. 2127 if (likely (face)) 2128 { 2129 if (face->index >> 16) 2130 hb_font_set_var_named_instance (font, (face->index >> 16) - 1); 2131 else 2132 hb_font_set_variations (font, nullptr, 0); 2133 } 2134 #endif 2135 2136 return font; 2137 } 2138 2139 static void 2140 _hb_font_adopt_var_coords (hb_font_t *font, 2141 int *coords, /* 2.14 normalized */ 2142 float *design_coords, 2143 unsigned int coords_length) 2144 { 2145 hb_free (font->coords); 2146 hb_free (font->design_coords); 2147 2148 font->coords = coords; 2149 font->design_coords = design_coords; 2150 font->num_coords = coords_length; 2151 font->has_nonzero_coords = hb_any (hb_array (coords, coords_length)); 2152 2153 font->changed (); 2154 font->serial_coords = font->serial; 2155 } 2156 2157 /** 2158 * hb_font_create_sub_font: 2159 * @parent: The parent font object 2160 * 2161 * Constructs a sub-font font object from the specified @parent font, 2162 * replicating the parent's properties. 2163 * 2164 * Return value: (transfer full): The new sub-font font object 2165 * 2166 * Since: 0.9.2 2167 **/ 2168 hb_font_t * 2169 hb_font_create_sub_font (hb_font_t *parent) 2170 { 2171 if (unlikely (!parent)) 2172 parent = hb_font_get_empty (); 2173 2174 hb_font_t *font = _hb_font_create (parent->face); 2175 2176 if (unlikely (hb_object_is_immutable (font))) 2177 return font; 2178 2179 font->parent = hb_font_reference (parent); 2180 2181 font->x_scale = parent->x_scale; 2182 font->y_scale = parent->y_scale; 2183 font->x_embolden = parent->x_embolden; 2184 font->y_embolden = parent->y_embolden; 2185 font->embolden_in_place = parent->embolden_in_place; 2186 font->slant = parent->slant; 2187 font->x_ppem = parent->x_ppem; 2188 font->y_ppem = parent->y_ppem; 2189 font->ptem = parent->ptem; 2190 2191 unsigned int num_coords = parent->num_coords; 2192 if (num_coords) 2193 { 2194 int *coords = (int *) hb_calloc (num_coords, sizeof (parent->coords[0])); 2195 float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0])); 2196 if (likely (coords && design_coords)) 2197 { 2198 hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); 2199 hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0])); 2200 _hb_font_adopt_var_coords (font, coords, design_coords, num_coords); 2201 } 2202 else 2203 { 2204 hb_free (coords); 2205 hb_free (design_coords); 2206 } 2207 } 2208 2209 font->changed (); 2210 font->serial_coords = font->serial; 2211 2212 return font; 2213 } 2214 2215 /** 2216 * hb_font_get_empty: 2217 * 2218 * Fetches the empty font object. 2219 * 2220 * Return value: (transfer full): The empty font object 2221 * 2222 * Since: 0.9.2 2223 **/ 2224 hb_font_t * 2225 hb_font_get_empty () 2226 { 2227 return const_cast<hb_font_t *> (&Null (hb_font_t)); 2228 } 2229 2230 /** 2231 * hb_font_reference: (skip) 2232 * @font: #hb_font_t to work upon 2233 * 2234 * Increases the reference count on the given font object. 2235 * 2236 * Return value: (transfer full): The @font object 2237 * 2238 * Since: 0.9.2 2239 **/ 2240 hb_font_t * 2241 hb_font_reference (hb_font_t *font) 2242 { 2243 return hb_object_reference (font); 2244 } 2245 2246 /** 2247 * hb_font_destroy: (skip) 2248 * @font: #hb_font_t to work upon 2249 * 2250 * Decreases the reference count on the given font object. When the 2251 * reference count reaches zero, the font is destroyed, 2252 * freeing all memory. 2253 * 2254 * Since: 0.9.2 2255 **/ 2256 void 2257 hb_font_destroy (hb_font_t *font) 2258 { 2259 if (!hb_object_destroy (font)) return; 2260 2261 font->data.fini (); 2262 2263 if (font->destroy) 2264 font->destroy (font->user_data); 2265 2266 hb_font_destroy (font->parent); 2267 hb_face_destroy (font->face); 2268 hb_font_funcs_destroy (font->klass); 2269 2270 hb_free (font->coords); 2271 hb_free (font->design_coords); 2272 2273 hb_free (font); 2274 } 2275 2276 /** 2277 * hb_font_set_user_data: (skip) 2278 * @font: #hb_font_t to work upon 2279 * @key: The user-data key 2280 * @data: A pointer to the user data 2281 * @destroy: (nullable): A callback to call when @data is not needed anymore 2282 * @replace: Whether to replace an existing data with the same key 2283 * 2284 * Attaches a user-data key/data pair to the specified font object. 2285 * 2286 * Return value: `true` if success, `false` otherwise 2287 * 2288 * Since: 0.9.2 2289 **/ 2290 hb_bool_t 2291 hb_font_set_user_data (hb_font_t *font, 2292 hb_user_data_key_t *key, 2293 void * data, 2294 hb_destroy_func_t destroy /* May be NULL. */, 2295 hb_bool_t replace) 2296 { 2297 if (!hb_object_is_immutable (font)) 2298 font->changed (); 2299 2300 return hb_object_set_user_data (font, key, data, destroy, replace); 2301 } 2302 2303 /** 2304 * hb_font_get_user_data: (skip) 2305 * @font: #hb_font_t to work upon 2306 * @key: The user-data key to query 2307 * 2308 * Fetches the user-data object associated with the specified key, 2309 * attached to the specified font object. 2310 * 2311 * Return value: (transfer none): Pointer to the user data 2312 * 2313 * Since: 0.9.2 2314 **/ 2315 void * 2316 hb_font_get_user_data (const hb_font_t *font, 2317 hb_user_data_key_t *key) 2318 { 2319 return hb_object_get_user_data (font, key); 2320 } 2321 2322 /** 2323 * hb_font_make_immutable: 2324 * @font: #hb_font_t to work upon 2325 * 2326 * Makes @font immutable. 2327 * 2328 * Since: 0.9.2 2329 **/ 2330 void 2331 hb_font_make_immutable (hb_font_t *font) 2332 { 2333 if (hb_object_is_immutable (font)) 2334 return; 2335 2336 if (font->parent) 2337 hb_font_make_immutable (font->parent); 2338 2339 hb_object_make_immutable (font); 2340 } 2341 2342 /** 2343 * hb_font_is_immutable: 2344 * @font: #hb_font_t to work upon 2345 * 2346 * Tests whether a font object is immutable. 2347 * 2348 * Return value: `true` if @font is immutable, `false` otherwise 2349 * 2350 * Since: 0.9.2 2351 **/ 2352 hb_bool_t 2353 hb_font_is_immutable (hb_font_t *font) 2354 { 2355 return hb_object_is_immutable (font); 2356 } 2357 2358 /** 2359 * hb_font_get_serial: 2360 * @font: #hb_font_t to work upon 2361 * 2362 * Returns the internal serial number of the font. The serial 2363 * number is increased every time a setting on the font is 2364 * changed, using a setter function. 2365 * 2366 * Return value: serial number 2367 * 2368 * Since: 4.4.0 2369 **/ 2370 unsigned int 2371 hb_font_get_serial (hb_font_t *font) 2372 { 2373 return font->serial.get_acquire (); 2374 } 2375 2376 /** 2377 * hb_font_changed: 2378 * @font: #hb_font_t to work upon 2379 * 2380 * Notifies the @font that underlying font data has changed. 2381 * This has the effect of increasing the serial as returned 2382 * by hb_font_get_serial(), which invalidates internal caches. 2383 * 2384 * Since: 4.4.0 2385 **/ 2386 void 2387 hb_font_changed (hb_font_t *font) 2388 { 2389 if (hb_object_is_immutable (font)) 2390 return; 2391 2392 font->changed (); 2393 } 2394 2395 /** 2396 * hb_font_set_parent: 2397 * @font: #hb_font_t to work upon 2398 * @parent: The parent font object to assign 2399 * 2400 * Sets the parent font of @font. 2401 * 2402 * Since: 1.0.5 2403 **/ 2404 void 2405 hb_font_set_parent (hb_font_t *font, 2406 hb_font_t *parent) 2407 { 2408 if (hb_object_is_immutable (font)) 2409 return; 2410 2411 if (parent == font->parent) 2412 return; 2413 2414 if (!parent) 2415 parent = hb_font_get_empty (); 2416 2417 hb_font_t *old = font->parent; 2418 2419 font->parent = hb_font_reference (parent); 2420 2421 hb_font_destroy (old); 2422 2423 font->changed (); 2424 } 2425 2426 /** 2427 * hb_font_get_parent: 2428 * @font: #hb_font_t to work upon 2429 * 2430 * Fetches the parent font of @font. 2431 * 2432 * Return value: (transfer none): The parent font object 2433 * 2434 * Since: 0.9.2 2435 **/ 2436 hb_font_t * 2437 hb_font_get_parent (hb_font_t *font) 2438 { 2439 return font->parent; 2440 } 2441 2442 /** 2443 * hb_font_set_face: 2444 * @font: #hb_font_t to work upon 2445 * @face: The #hb_face_t to assign 2446 * 2447 * Sets @face as the font-face value of @font. 2448 * 2449 * Since: 1.4.3 2450 **/ 2451 void 2452 hb_font_set_face (hb_font_t *font, 2453 hb_face_t *face) 2454 { 2455 if (hb_object_is_immutable (font)) 2456 return; 2457 2458 if (face == font->face) 2459 return; 2460 2461 if (unlikely (!face)) 2462 face = hb_face_get_empty (); 2463 2464 hb_face_t *old = font->face; 2465 2466 hb_face_make_immutable (face); 2467 font->face = hb_face_reference (face); 2468 font->changed (); 2469 2470 hb_face_destroy (old); 2471 2472 font->changed (); 2473 font->serial_coords = font->serial; 2474 } 2475 2476 /** 2477 * hb_font_get_face: 2478 * @font: #hb_font_t to work upon 2479 * 2480 * Fetches the face associated with the specified font object. 2481 * 2482 * Return value: (transfer none): The #hb_face_t value 2483 * 2484 * Since: 0.9.2 2485 **/ 2486 hb_face_t * 2487 hb_font_get_face (hb_font_t *font) 2488 { 2489 return font->face; 2490 } 2491 2492 2493 /** 2494 * hb_font_set_funcs: 2495 * @font: #hb_font_t to work upon 2496 * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure. 2497 * @font_data: Data to attach to @font 2498 * @destroy: (nullable): The function to call when @font_data is not needed anymore 2499 * 2500 * Replaces the font-functions structure attached to a font, updating 2501 * the font's user-data with @font-data and the @destroy callback. 2502 * 2503 * Since: 0.9.2 2504 **/ 2505 void 2506 hb_font_set_funcs (hb_font_t *font, 2507 hb_font_funcs_t *klass, 2508 void *font_data, 2509 hb_destroy_func_t destroy /* May be NULL. */) 2510 { 2511 if (hb_object_is_immutable (font)) 2512 { 2513 if (destroy) 2514 destroy (font_data); 2515 return; 2516 } 2517 2518 if (font->destroy) 2519 font->destroy (font->user_data); 2520 2521 if (!klass) 2522 klass = hb_font_funcs_get_empty (); 2523 2524 hb_font_funcs_reference (klass); 2525 hb_font_funcs_destroy (font->klass); 2526 font->klass = klass; 2527 font->user_data = font_data; 2528 font->destroy = destroy; 2529 2530 font->changed (); 2531 } 2532 2533 /** 2534 * hb_font_set_funcs_data: 2535 * @font: #hb_font_t to work upon 2536 * @font_data: (destroy destroy) (scope notified): Data to attach to @font 2537 * @destroy: (nullable): The function to call when @font_data is not needed anymore 2538 * 2539 * Replaces the user data attached to a font, updating the font's 2540 * @destroy callback. 2541 * 2542 * Since: 0.9.2 2543 **/ 2544 void 2545 hb_font_set_funcs_data (hb_font_t *font, 2546 void *font_data, 2547 hb_destroy_func_t destroy /* May be NULL. */) 2548 { 2549 /* Destroy user_data? */ 2550 if (hb_object_is_immutable (font)) 2551 { 2552 if (destroy) 2553 destroy (font_data); 2554 return; 2555 } 2556 2557 if (font->destroy) 2558 font->destroy (font->user_data); 2559 2560 font->user_data = font_data; 2561 font->destroy = destroy; 2562 2563 font->changed (); 2564 } 2565 2566 static const struct supported_font_funcs_t { 2567 char name[16]; 2568 void (*func) (hb_font_t *); 2569 } supported_font_funcs[] = 2570 { 2571 #ifndef HB_NO_OT_FONT 2572 {"ot", hb_ot_font_set_funcs}, 2573 #endif 2574 #ifdef HAVE_FREETYPE 2575 {"ft", hb_ft_font_set_funcs}, 2576 #endif 2577 #ifdef HAVE_FONTATIONS 2578 {"fontations",hb_fontations_font_set_funcs}, 2579 #endif 2580 #ifdef HAVE_CORETEXT 2581 {"coretext", hb_coretext_font_set_funcs}, 2582 #endif 2583 #ifdef HAVE_DIRECTWRITE 2584 {"directwrite",hb_directwrite_font_set_funcs}, 2585 #endif 2586 }; 2587 2588 static const char *get_default_funcs_name () 2589 { 2590 static hb_atomic_t<const char *> static_funcs_name; 2591 const char *name = static_funcs_name.get_acquire (); 2592 if (!name) 2593 { 2594 name = getenv ("HB_FONT_FUNCS"); 2595 if (!name) 2596 name = ""; 2597 if (!static_funcs_name.cmpexch (nullptr, name)) 2598 name = static_funcs_name.get_acquire (); 2599 } 2600 return name; 2601 } 2602 2603 /** 2604 * hb_font_set_funcs_using: 2605 * @font: #hb_font_t to work upon 2606 * @name: The name of the font-functions structure to use, or `NULL` 2607 * 2608 * Sets the font-functions structure to use for a font, based on the 2609 * specified name. 2610 * 2611 * If @name is `NULL` or the empty string, the default (first) functioning font-functions 2612 * are used. This default can be changed by setting the `HB_FONT_FUNCS` environment 2613 * variable to the name of the desired font-functions. 2614 * 2615 * Return value: `true` if the font-functions was found and set, `false` otherwise 2616 * 2617 * Since: 11.0.0 2618 **/ 2619 hb_bool_t 2620 hb_font_set_funcs_using (hb_font_t *font, 2621 const char *name) 2622 { 2623 if (unlikely (hb_object_is_immutable (font))) 2624 return false; 2625 2626 bool retry = false; 2627 2628 if (!name || !*name) 2629 { 2630 name = get_default_funcs_name (); 2631 retry = true; 2632 } 2633 if (name && !*name) name = nullptr; 2634 2635 retry: 2636 for (unsigned i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) 2637 if (!name || strcmp (supported_font_funcs[i].name, name) == 0) 2638 { 2639 supported_font_funcs[i].func (font); 2640 if (name || font->klass != hb_font_funcs_get_empty ()) 2641 return true; 2642 } 2643 2644 if (retry) 2645 { 2646 retry = false; 2647 name = nullptr; 2648 goto retry; 2649 } 2650 2651 return false; 2652 } 2653 2654 static inline void free_static_font_funcs_list (); 2655 2656 static const char * const nil_font_funcs_list[] = {nullptr}; 2657 2658 static struct hb_font_funcs_list_lazy_loader_t : hb_lazy_loader_t<const char *, 2659 hb_font_funcs_list_lazy_loader_t> 2660 { 2661 static const char ** create () 2662 { 2663 const char **font_funcs_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_font_funcs), sizeof (const char *)); 2664 if (unlikely (!font_funcs_list)) 2665 return nullptr; 2666 2667 unsigned i; 2668 for (i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) 2669 font_funcs_list[i] = supported_font_funcs[i].name; 2670 font_funcs_list[i] = nullptr; 2671 2672 hb_atexit (free_static_font_funcs_list); 2673 2674 return font_funcs_list; 2675 } 2676 static void destroy (const char **l) 2677 { hb_free (l); } 2678 static const char * const * get_null () 2679 { return nil_font_funcs_list; } 2680 } static_font_funcs_list; 2681 2682 static inline 2683 void free_static_font_funcs_list () 2684 { 2685 static_font_funcs_list.free_instance (); 2686 } 2687 2688 /** 2689 * hb_font_list_funcs: 2690 * 2691 * Retrieves the list of font functions supported by HarfBuzz. 2692 * 2693 * Return value: (transfer none) (array zero-terminated=1): a 2694 * `NULL`-terminated array of supported font functions 2695 * constant strings. The returned array is owned by HarfBuzz 2696 * and should not be modified or freed. 2697 * 2698 * Since: 11.0.0 2699 **/ 2700 const char ** 2701 hb_font_list_funcs () 2702 { 2703 return static_font_funcs_list.get_unconst (); 2704 } 2705 2706 /** 2707 * hb_font_set_scale: 2708 * @font: #hb_font_t to work upon 2709 * @x_scale: Horizontal scale value to assign 2710 * @y_scale: Vertical scale value to assign 2711 * 2712 * Sets the horizontal and vertical scale of a font. 2713 * 2714 * The font scale is a number related to, but not the same as, 2715 * font size. Typically the client establishes a scale factor 2716 * to be used between the two. For example, 64, or 256, which 2717 * would be the fractional-precision part of the font scale. 2718 * This is necessary because #hb_position_t values are integer 2719 * types and you need to leave room for fractional values 2720 * in there. 2721 * 2722 * For example, to set the font size to 20, with 64 2723 * levels of fractional precision you would call 2724 * `hb_font_set_scale(font, 20 * 64, 20 * 64)`. 2725 * 2726 * In the example above, even what font size 20 means is up to 2727 * you. It might be 20 pixels, or 20 points, or 20 millimeters. 2728 * HarfBuzz does not care about that. You can set the point 2729 * size of the font using hb_font_set_ptem(), and the pixel 2730 * size using hb_font_set_ppem(). 2731 * 2732 * The choice of scale is yours but needs to be consistent between 2733 * what you set here, and what you expect out of #hb_position_t 2734 * as well has draw / paint API output values. 2735 * 2736 * Fonts default to a scale equal to the UPEM value of their face. 2737 * A font with this setting is sometimes called an "unscaled" font. 2738 * 2739 * Since: 0.9.2 2740 **/ 2741 void 2742 hb_font_set_scale (hb_font_t *font, 2743 int x_scale, 2744 int y_scale) 2745 { 2746 if (hb_object_is_immutable (font)) 2747 return; 2748 2749 if (font->x_scale == x_scale && font->y_scale == y_scale) 2750 return; 2751 2752 font->x_scale = x_scale; 2753 font->y_scale = y_scale; 2754 2755 font->changed (); 2756 } 2757 2758 /** 2759 * hb_font_get_scale: 2760 * @font: #hb_font_t to work upon 2761 * @x_scale: (out): Horizontal scale value 2762 * @y_scale: (out): Vertical scale value 2763 * 2764 * Fetches the horizontal and vertical scale of a font. 2765 * 2766 * Since: 0.9.2 2767 **/ 2768 void 2769 hb_font_get_scale (hb_font_t *font, 2770 int *x_scale, 2771 int *y_scale) 2772 { 2773 if (x_scale) *x_scale = font->x_scale; 2774 if (y_scale) *y_scale = font->y_scale; 2775 } 2776 2777 /** 2778 * hb_font_set_ppem: 2779 * @font: #hb_font_t to work upon 2780 * @x_ppem: Horizontal ppem value to assign 2781 * @y_ppem: Vertical ppem value to assign 2782 * 2783 * Sets the horizontal and vertical pixels-per-em (PPEM) of a font. 2784 * 2785 * These values are used for pixel-size-specific adjustment to 2786 * shaping and draw results, though for the most part they are 2787 * unused and can be left unset. 2788 * 2789 * Since: 0.9.2 2790 **/ 2791 void 2792 hb_font_set_ppem (hb_font_t *font, 2793 unsigned int x_ppem, 2794 unsigned int y_ppem) 2795 { 2796 if (hb_object_is_immutable (font)) 2797 return; 2798 2799 if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) 2800 return; 2801 2802 font->x_ppem = x_ppem; 2803 font->y_ppem = y_ppem; 2804 2805 font->changed (); 2806 } 2807 2808 /** 2809 * hb_font_get_ppem: 2810 * @font: #hb_font_t to work upon 2811 * @x_ppem: (out): Horizontal ppem value 2812 * @y_ppem: (out): Vertical ppem value 2813 * 2814 * Fetches the horizontal and vertical points-per-em (ppem) of a font. 2815 * 2816 * Since: 0.9.2 2817 **/ 2818 void 2819 hb_font_get_ppem (hb_font_t *font, 2820 unsigned int *x_ppem, 2821 unsigned int *y_ppem) 2822 { 2823 if (x_ppem) *x_ppem = font->x_ppem; 2824 if (y_ppem) *y_ppem = font->y_ppem; 2825 } 2826 2827 /** 2828 * hb_font_set_ptem: 2829 * @font: #hb_font_t to work upon 2830 * @ptem: font size in points. 2831 * 2832 * Sets the "point size" of a font. Set to zero to unset. 2833 * Used in CoreText to implement optical sizing. 2834 * 2835 * <note>Note: There are 72 points in an inch.</note> 2836 * 2837 * Since: 1.6.0 2838 **/ 2839 void 2840 hb_font_set_ptem (hb_font_t *font, 2841 float ptem) 2842 { 2843 if (hb_object_is_immutable (font)) 2844 return; 2845 2846 if (font->ptem == ptem) 2847 return; 2848 2849 font->ptem = ptem; 2850 2851 font->changed (); 2852 } 2853 2854 /** 2855 * hb_font_get_ptem: 2856 * @font: #hb_font_t to work upon 2857 * 2858 * Fetches the "point size" of a font. Used in CoreText to 2859 * implement optical sizing. 2860 * 2861 * Return value: Point size. A value of zero means "not set." 2862 * 2863 * Since: 1.6.0 2864 **/ 2865 float 2866 hb_font_get_ptem (hb_font_t *font) 2867 { 2868 return font->ptem; 2869 } 2870 2871 /** 2872 * hb_font_is_synthetic: 2873 * @font: #hb_font_t to work upon 2874 * 2875 * Tests whether a font is synthetic. A synthetic font is one 2876 * that has either synthetic slant or synthetic bold set on it. 2877 * 2878 * Return value: `true` if the font is synthetic, `false` otherwise. 2879 * 2880 * Since: 11.2.0 2881 */ 2882 hb_bool_t 2883 hb_font_is_synthetic (hb_font_t *font) 2884 { 2885 return font->is_synthetic; 2886 } 2887 2888 /** 2889 * hb_font_set_synthetic_bold: 2890 * @font: #hb_font_t to work upon 2891 * @x_embolden: the amount to embolden horizontally 2892 * @y_embolden: the amount to embolden vertically 2893 * @in_place: whether to embolden glyphs in-place 2894 * 2895 * Sets the "synthetic boldness" of a font. 2896 * 2897 * Positive values for @x_embolden / @y_embolden make a font 2898 * bolder, negative values thinner. Typical values are in the 2899 * 0.01 to 0.05 range. The default value is zero. 2900 * 2901 * Synthetic boldness is applied by offsetting the contour 2902 * points of the glyph shape. 2903 * 2904 * Synthetic boldness is applied when rendering a glyph via 2905 * hb_font_draw_glyph_or_fail(). 2906 * 2907 * If @in_place is `false`, then glyph advance-widths are also 2908 * adjusted, otherwise they are not. The in-place mode is 2909 * useful for simulating [font grading](https://fonts.google.com/knowledge/glossary/grade). 2910 * 2911 * 2912 * Since: 7.0.0 2913 **/ 2914 void 2915 hb_font_set_synthetic_bold (hb_font_t *font, 2916 float x_embolden, 2917 float y_embolden, 2918 hb_bool_t in_place) 2919 { 2920 if (hb_object_is_immutable (font)) 2921 return; 2922 2923 if (font->x_embolden == x_embolden && 2924 font->y_embolden == y_embolden && 2925 font->embolden_in_place == (bool) in_place) 2926 return; 2927 2928 font->x_embolden = x_embolden; 2929 font->y_embolden = y_embolden; 2930 font->embolden_in_place = in_place; 2931 2932 font->changed (); 2933 } 2934 2935 /** 2936 * hb_font_get_synthetic_bold: 2937 * @font: #hb_font_t to work upon 2938 * @x_embolden: (out): return location for horizontal value 2939 * @y_embolden: (out): return location for vertical value 2940 * @in_place: (out): return location for in-place value 2941 * 2942 * Fetches the "synthetic boldness" parameters of a font. 2943 * 2944 * Since: 7.0.0 2945 **/ 2946 void 2947 hb_font_get_synthetic_bold (hb_font_t *font, 2948 float *x_embolden, 2949 float *y_embolden, 2950 hb_bool_t *in_place) 2951 { 2952 if (x_embolden) *x_embolden = font->x_embolden; 2953 if (y_embolden) *y_embolden = font->y_embolden; 2954 if (in_place) *in_place = font->embolden_in_place; 2955 } 2956 2957 /** 2958 * hb_font_set_synthetic_slant: 2959 * @font: #hb_font_t to work upon 2960 * @slant: synthetic slant value. 2961 * 2962 * Sets the "synthetic slant" of a font. By default is zero. 2963 * Synthetic slant is the graphical skew applied to the font 2964 * at rendering time. 2965 * 2966 * HarfBuzz needs to know this value to adjust shaping results, 2967 * metrics, and style values to match the slanted rendering. 2968 * 2969 * <note>Note: The glyph shape fetched via the hb_font_draw_glyph_or_fail() 2970 * function is slanted to reflect this value as well.</note> 2971 * 2972 * <note>Note: The slant value is a ratio. For example, a 2973 * 20% slant would be represented as a 0.2 value.</note> 2974 * 2975 * Since: 3.3.0 2976 **/ 2977 HB_EXTERN void 2978 hb_font_set_synthetic_slant (hb_font_t *font, float slant) 2979 { 2980 if (hb_object_is_immutable (font)) 2981 return; 2982 2983 if (font->slant == slant) 2984 return; 2985 2986 font->slant = slant; 2987 2988 font->changed (); 2989 } 2990 2991 /** 2992 * hb_font_get_synthetic_slant: 2993 * @font: #hb_font_t to work upon 2994 * 2995 * Fetches the "synthetic slant" of a font. 2996 * 2997 * Return value: Synthetic slant. By default is zero. 2998 * 2999 * Since: 3.3.0 3000 **/ 3001 HB_EXTERN float 3002 hb_font_get_synthetic_slant (hb_font_t *font) 3003 { 3004 return font->slant; 3005 } 3006 3007 #ifndef HB_NO_VAR 3008 /* 3009 * Variations 3010 */ 3011 3012 /** 3013 * hb_font_set_variations: 3014 * @font: #hb_font_t to work upon 3015 * @variations: (array length=variations_length): Array of variation settings to apply 3016 * @variations_length: Number of variations to apply 3017 * 3018 * Applies a list of font-variation settings to a font. 3019 * 3020 * Note that this overrides all existing variations set on @font. 3021 * Axes not included in @variations will be effectively set to their 3022 * default values. 3023 * 3024 * Since: 1.4.2 3025 */ 3026 void 3027 hb_font_set_variations (hb_font_t *font, 3028 const hb_variation_t *variations, 3029 unsigned int variations_length) 3030 { 3031 if (hb_object_is_immutable (font)) 3032 return; 3033 3034 const OT::fvar &fvar = *font->face->table.fvar; 3035 auto axes = fvar.get_axes (); 3036 const unsigned coords_length = axes.length; 3037 3038 int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; 3039 float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; 3040 3041 if (unlikely (coords_length && !(normalized && design_coords))) 3042 { 3043 hb_free (normalized); 3044 hb_free (design_coords); 3045 return; 3046 } 3047 3048 /* Initialize design coords. */ 3049 for (unsigned int i = 0; i < coords_length; i++) 3050 design_coords[i] = axes[i].get_default (); 3051 if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE) 3052 { 3053 unsigned count = coords_length; 3054 /* This may fail if index is out-of-range; 3055 * That's why we initialize design_coords from fvar above 3056 * unconditionally. */ 3057 hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index, 3058 &count, design_coords); 3059 } 3060 3061 for (unsigned int i = 0; i < variations_length; i++) 3062 { 3063 const auto tag = variations[i].tag; 3064 const auto v = variations[i].value; 3065 for (unsigned axis_index = 0; axis_index < coords_length; axis_index++) 3066 if (axes[axis_index].axisTag == tag) 3067 design_coords[axis_index] = v; 3068 } 3069 3070 hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); 3071 _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); 3072 } 3073 3074 /** 3075 * hb_font_set_variation: 3076 * @font: #hb_font_t to work upon 3077 * @tag: The #hb_tag_t tag of the variation-axis name 3078 * @value: The value of the variation axis 3079 * 3080 * Change the value of one variation axis on the font. 3081 * 3082 * Note: This function is expensive to be called repeatedly. 3083 * If you want to set multiple variation axes at the same time, 3084 * use hb_font_set_variations() instead. 3085 * 3086 * Since: 7.1.0 3087 */ 3088 void 3089 hb_font_set_variation (hb_font_t *font, 3090 hb_tag_t tag, 3091 float value) 3092 { 3093 if (hb_object_is_immutable (font)) 3094 return; 3095 3096 // TODO Share some of this code with set_variations() 3097 3098 const OT::fvar &fvar = *font->face->table.fvar; 3099 auto axes = fvar.get_axes (); 3100 const unsigned coords_length = axes.length; 3101 3102 int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; 3103 float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; 3104 3105 if (unlikely (coords_length && !(normalized && design_coords))) 3106 { 3107 hb_free (normalized); 3108 hb_free (design_coords); 3109 return; 3110 } 3111 3112 /* Initialize design coords. */ 3113 if (font->design_coords) 3114 { 3115 assert (coords_length == font->num_coords); 3116 for (unsigned int i = 0; i < coords_length; i++) 3117 design_coords[i] = font->design_coords[i]; 3118 } 3119 else 3120 { 3121 for (unsigned int i = 0; i < coords_length; i++) 3122 design_coords[i] = axes[i].get_default (); 3123 if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE) 3124 { 3125 unsigned count = coords_length; 3126 /* This may fail if index is out-of-range; 3127 * That's why we initialize design_coords from fvar above 3128 * unconditionally. */ 3129 hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index, 3130 &count, design_coords); 3131 } 3132 } 3133 3134 for (unsigned axis_index = 0; axis_index < coords_length; axis_index++) 3135 if (axes[axis_index].axisTag == tag) 3136 design_coords[axis_index] = value; 3137 3138 hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); 3139 _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); 3140 } 3141 3142 /** 3143 * hb_font_set_var_coords_design: 3144 * @font: #hb_font_t to work upon 3145 * @coords: (array length=coords_length): Array of variation coordinates to apply 3146 * @coords_length: Number of coordinates to apply 3147 * 3148 * Applies a list of variation coordinates (in design-space units) 3149 * to a font. 3150 * 3151 * Note that this overrides all existing variations set on @font. 3152 * Axes not included in @coords will be effectively set to their 3153 * default values. 3154 * 3155 * Since: 1.4.2 3156 */ 3157 void 3158 hb_font_set_var_coords_design (hb_font_t *font, 3159 const float *coords, 3160 unsigned int input_coords_length) 3161 { 3162 if (hb_object_is_immutable (font)) 3163 return; 3164 3165 const OT::fvar &fvar = *font->face->table.fvar; 3166 auto axes = fvar.get_axes (); 3167 const unsigned coords_length = axes.length; 3168 3169 input_coords_length = hb_min (input_coords_length, coords_length); 3170 int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; 3171 float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; 3172 3173 if (unlikely (coords_length && !(normalized && design_coords))) 3174 { 3175 hb_free (normalized); 3176 hb_free (design_coords); 3177 return; 3178 } 3179 3180 if (input_coords_length) 3181 hb_memcpy (design_coords, coords, input_coords_length * sizeof (font->design_coords[0])); 3182 // Fill in the rest with default values 3183 for (unsigned int i = input_coords_length; i < coords_length; i++) 3184 design_coords[i] = axes[i].get_default (); 3185 3186 hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); 3187 _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); 3188 } 3189 3190 /** 3191 * hb_font_set_var_named_instance: 3192 * @font: a font. 3193 * @instance_index: named instance index. 3194 * 3195 * Sets design coords of a font from a named-instance index. 3196 * 3197 * Since: 2.6.0 3198 */ 3199 void 3200 hb_font_set_var_named_instance (hb_font_t *font, 3201 unsigned int instance_index) 3202 { 3203 if (hb_object_is_immutable (font)) 3204 return; 3205 3206 if (font->instance_index == instance_index) 3207 return; 3208 3209 font->instance_index = instance_index; 3210 hb_font_set_variations (font, nullptr, 0); 3211 } 3212 3213 /** 3214 * hb_font_get_var_named_instance: 3215 * @font: a font. 3216 * 3217 * Returns the currently-set named-instance index of the font. 3218 * 3219 * Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE. 3220 * 3221 * Since: 7.0.0 3222 **/ 3223 unsigned int 3224 hb_font_get_var_named_instance (hb_font_t *font) 3225 { 3226 return font->instance_index; 3227 } 3228 3229 /** 3230 * hb_font_set_var_coords_normalized: 3231 * @font: #hb_font_t to work upon 3232 * @coords: (array length=coords_length): Array of variation coordinates to apply 3233 * @coords_length: Number of coordinates to apply 3234 * 3235 * Applies a list of variation coordinates (in normalized units) 3236 * to a font. 3237 * 3238 * Note that this overrides all existing variations set on @font. 3239 * Axes not included in @coords will be effectively set to their 3240 * default values. 3241 * 3242 * <note>Note: Coordinates should be normalized to 2.14.</note> 3243 * 3244 * Since: 1.4.2 3245 */ 3246 void 3247 hb_font_set_var_coords_normalized (hb_font_t *font, 3248 const int *coords, /* 2.14 normalized */ 3249 unsigned int input_coords_length) 3250 { 3251 if (hb_object_is_immutable (font)) 3252 return; 3253 3254 const OT::fvar &fvar = *font->face->table.fvar; 3255 auto axes = fvar.get_axes (); 3256 unsigned coords_length = axes.length; 3257 3258 input_coords_length = hb_min (input_coords_length, coords_length); 3259 int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; 3260 float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; 3261 3262 if (unlikely (coords_length && !(copy && design_coords))) 3263 { 3264 hb_free (copy); 3265 hb_free (design_coords); 3266 return; 3267 } 3268 3269 if (input_coords_length) 3270 hb_memcpy (copy, coords, input_coords_length * sizeof (coords[0])); 3271 3272 for (unsigned int i = 0; i < coords_length; ++i) 3273 design_coords[i] = NAN; 3274 3275 _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); 3276 } 3277 3278 /** 3279 * hb_font_get_var_coords_normalized: 3280 * @font: #hb_font_t to work upon 3281 * @length: (out): Number of coordinates retrieved 3282 * 3283 * Fetches the list of normalized variation coordinates currently 3284 * set on a font. 3285 * 3286 * <note>Note that if no variation coordinates are set, this function may 3287 * return %NULL.</note> 3288 * 3289 * Return value is valid as long as variation coordinates of the font 3290 * are not modified. 3291 * 3292 * Return value: coordinates array 3293 * 3294 * Since: 1.4.2 3295 */ 3296 const int * 3297 hb_font_get_var_coords_normalized (hb_font_t *font, 3298 unsigned int *length) 3299 { 3300 if (length) 3301 *length = font->num_coords; 3302 3303 return font->coords; 3304 } 3305 3306 /** 3307 * hb_font_get_var_coords_design: 3308 * @font: #hb_font_t to work upon 3309 * @length: (out): Number of coordinates retrieved 3310 * 3311 * Fetches the list of variation coordinates (in design-space units) currently 3312 * set on a font. 3313 * 3314 * <note>Note that if no variation coordinates are set, this function may 3315 * return %NULL.</note> 3316 * 3317 * <note>If variations have been set on the font using normalized coordinates 3318 * (i.e. via hb_font_set_var_coords_normalized()), the design coordinates will 3319 * have NaN (Not a Number) values.</note> 3320 * 3321 * Return value is valid as long as variation coordinates of the font 3322 * are not modified. 3323 * 3324 * Return value: coordinates array 3325 * 3326 * Since: 3.3.0 3327 */ 3328 const float * 3329 hb_font_get_var_coords_design (hb_font_t *font, 3330 unsigned int *length) 3331 { 3332 if (length) 3333 *length = font->num_coords; 3334 3335 return font->design_coords; 3336 } 3337 #endif 3338 3339 #ifndef HB_DISABLE_DEPRECATED 3340 /* 3341 * Deprecated get_glyph_func(): 3342 */ 3343 3344 struct hb_trampoline_closure_t 3345 { 3346 void *user_data; 3347 hb_destroy_func_t destroy; 3348 unsigned int ref_count; 3349 }; 3350 3351 template <typename FuncType> 3352 struct hb_trampoline_t 3353 { 3354 hb_trampoline_closure_t closure; /* Must be first. */ 3355 FuncType func; 3356 }; 3357 3358 template <typename FuncType> 3359 static hb_trampoline_t<FuncType> * 3360 trampoline_create (FuncType func, 3361 void *user_data, 3362 hb_destroy_func_t destroy) 3363 { 3364 typedef hb_trampoline_t<FuncType> trampoline_t; 3365 3366 trampoline_t *trampoline = (trampoline_t *) hb_calloc (1, sizeof (trampoline_t)); 3367 3368 if (unlikely (!trampoline)) 3369 return nullptr; 3370 3371 trampoline->closure.user_data = user_data; 3372 trampoline->closure.destroy = destroy; 3373 trampoline->closure.ref_count = 1; 3374 trampoline->func = func; 3375 3376 return trampoline; 3377 } 3378 3379 static void 3380 trampoline_reference (hb_trampoline_closure_t *closure) 3381 { 3382 closure->ref_count++; 3383 } 3384 3385 static void 3386 trampoline_destroy (void *user_data) 3387 { 3388 hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data; 3389 3390 if (--closure->ref_count) 3391 return; 3392 3393 if (closure->destroy) 3394 closure->destroy (closure->user_data); 3395 hb_free (closure); 3396 } 3397 3398 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t; 3399 3400 static hb_bool_t 3401 hb_font_get_nominal_glyph_trampoline (hb_font_t *font, 3402 void *font_data, 3403 hb_codepoint_t unicode, 3404 hb_codepoint_t *glyph, 3405 void *user_data) 3406 { 3407 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 3408 return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data); 3409 } 3410 3411 static hb_bool_t 3412 hb_font_get_variation_glyph_trampoline (hb_font_t *font, 3413 void *font_data, 3414 hb_codepoint_t unicode, 3415 hb_codepoint_t variation_selector, 3416 hb_codepoint_t *glyph, 3417 void *user_data) 3418 { 3419 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 3420 return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data); 3421 } 3422 3423 /** 3424 * hb_font_funcs_set_glyph_func: 3425 * @ffuncs: The font-functions structure 3426 * @func: (closure user_data) (destroy destroy) (scope notified): callback function 3427 * @user_data: data to pass to @func 3428 * @destroy: (nullable): function to call when @user_data is not needed anymore 3429 * 3430 * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and 3431 * hb_font_funcs_set_variation_glyph_func() instead. 3432 * 3433 * Since: 0.9.2 3434 * Deprecated: 1.2.3 3435 **/ 3436 void 3437 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, 3438 hb_font_get_glyph_func_t func, 3439 void *user_data, 3440 hb_destroy_func_t destroy /* May be NULL. */) 3441 { 3442 if (hb_object_is_immutable (ffuncs)) 3443 { 3444 if (destroy) 3445 destroy (user_data); 3446 return; 3447 } 3448 3449 hb_font_get_glyph_trampoline_t *trampoline; 3450 3451 trampoline = trampoline_create (func, user_data, destroy); 3452 if (unlikely (!trampoline)) 3453 { 3454 if (destroy) 3455 destroy (user_data); 3456 return; 3457 } 3458 3459 /* Since we pass it to two destroying functions. */ 3460 trampoline_reference (&trampoline->closure); 3461 3462 hb_font_funcs_set_nominal_glyph_func (ffuncs, 3463 hb_font_get_nominal_glyph_trampoline, 3464 trampoline, 3465 trampoline_destroy); 3466 3467 hb_font_funcs_set_variation_glyph_func (ffuncs, 3468 hb_font_get_variation_glyph_trampoline, 3469 trampoline, 3470 trampoline_destroy); 3471 } 3472 #endif 3473 3474 3475 #ifndef HB_DISABLE_DEPRECATED 3476 3477 struct hb_draw_glyph_closure_t 3478 { 3479 hb_font_draw_glyph_func_t func; 3480 void *user_data; 3481 hb_destroy_func_t destroy; 3482 }; 3483 static hb_bool_t 3484 hb_font_draw_glyph_trampoline (hb_font_t *font, 3485 void *font_data, 3486 hb_codepoint_t glyph, 3487 hb_draw_funcs_t *draw_funcs, 3488 void *draw_data, 3489 void *user_data) 3490 { 3491 hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data; 3492 closure->func (font, font_data, glyph, draw_funcs, draw_data, closure->user_data); 3493 return true; 3494 } 3495 static void 3496 hb_font_draw_glyph_closure_destroy (void *user_data) 3497 { 3498 hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data; 3499 3500 if (closure->destroy) 3501 closure->destroy (closure->user_data); 3502 hb_free (closure); 3503 } 3504 static void 3505 _hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, 3506 hb_font_draw_glyph_func_t func, 3507 void *user_data, 3508 hb_destroy_func_t destroy /* May be NULL. */) 3509 { 3510 if (hb_object_is_immutable (ffuncs)) 3511 { 3512 if (destroy) 3513 destroy (user_data); 3514 return; 3515 } 3516 hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) hb_calloc (1, sizeof (hb_draw_glyph_closure_t)); 3517 if (unlikely (!closure)) 3518 { 3519 if (destroy) 3520 destroy (user_data); 3521 return; 3522 } 3523 closure->func = func; 3524 closure->user_data = user_data; 3525 closure->destroy = destroy; 3526 3527 hb_font_funcs_set_draw_glyph_or_fail_func (ffuncs, 3528 hb_font_draw_glyph_trampoline, 3529 closure, 3530 hb_font_draw_glyph_closure_destroy); 3531 } 3532 void 3533 hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, 3534 hb_font_draw_glyph_func_t func, 3535 void *user_data, 3536 hb_destroy_func_t destroy /* May be NULL. */) 3537 { 3538 _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); 3539 } 3540 void 3541 hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, 3542 hb_font_get_glyph_shape_func_t func, 3543 void *user_data, 3544 hb_destroy_func_t destroy /* May be NULL. */) 3545 { 3546 _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); 3547 } 3548 3549 struct hb_paint_glyph_closure_t 3550 { 3551 hb_font_paint_glyph_func_t func; 3552 void *user_data; 3553 hb_destroy_func_t destroy; 3554 }; 3555 static hb_bool_t 3556 hb_font_paint_glyph_trampoline (hb_font_t *font, 3557 void *font_data, 3558 hb_codepoint_t glyph, 3559 hb_paint_funcs_t *paint_funcs, 3560 void *paint_data, 3561 unsigned int palette, 3562 hb_color_t foreground, 3563 void *user_data) 3564 { 3565 hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data; 3566 closure->func (font, font_data, glyph, paint_funcs, paint_data, palette, foreground, closure->user_data); 3567 return true; 3568 } 3569 static void 3570 hb_font_paint_glyph_closure_destroy (void *user_data) 3571 { 3572 hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data; 3573 3574 if (closure->destroy) 3575 closure->destroy (closure->user_data); 3576 hb_free (closure); 3577 } 3578 void 3579 hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, 3580 hb_font_paint_glyph_func_t func, 3581 void *user_data, 3582 hb_destroy_func_t destroy /* May be NULL. */) 3583 { 3584 if (hb_object_is_immutable (ffuncs)) 3585 { 3586 if (destroy) 3587 destroy (user_data); 3588 return; 3589 } 3590 hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) hb_calloc (1, sizeof (hb_paint_glyph_closure_t)); 3591 if (unlikely (!closure)) 3592 { 3593 if (destroy) 3594 destroy (user_data); 3595 return; 3596 } 3597 closure->func = func; 3598 closure->user_data = user_data; 3599 closure->destroy = destroy; 3600 3601 hb_font_funcs_set_paint_glyph_or_fail_func (ffuncs, 3602 hb_font_paint_glyph_trampoline, 3603 closure, 3604 hb_font_paint_glyph_closure_destroy); 3605 } 3606 #endif