Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/harfbuzz/src/hb-ot-font.cc @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * Copyright © 2011,2014 Google, Inc. | |
| 3 * | |
| 4 * This is part of HarfBuzz, a text shaping library. | |
| 5 * | |
| 6 * Permission is hereby granted, without written agreement and without | |
| 7 * license or royalty fees, to use, copy, modify, and distribute this | |
| 8 * software and its documentation for any purpose, provided that the | |
| 9 * above copyright notice and the following two paragraphs appear in | |
| 10 * all copies of this software. | |
| 11 * | |
| 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | |
| 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | |
| 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | |
| 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |
| 16 * DAMAGE. | |
| 17 * | |
| 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | |
| 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
| 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO | |
| 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
| 23 * | |
| 24 * Google Author(s): Behdad Esfahbod, Roozbeh Pournader | |
| 25 */ | |
| 26 | |
| 27 #include "hb.hh" | |
| 28 | |
| 29 #ifndef HB_NO_OT_FONT | |
| 30 | |
| 31 #include "hb-ot.h" | |
| 32 | |
| 33 #include "hb-cache.hh" | |
| 34 #include "hb-font.hh" | |
| 35 #include "hb-machinery.hh" | |
| 36 #include "hb-ot-face.hh" | |
| 37 | |
| 38 #include "hb-ot-cmap-table.hh" | |
| 39 #include "hb-ot-glyf-table.hh" | |
| 40 #include "hb-ot-cff1-table.hh" | |
| 41 #include "hb-ot-cff2-table.hh" | |
| 42 #include "hb-ot-hmtx-table.hh" | |
| 43 #include "hb-ot-post-table.hh" | |
| 44 #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. | |
| 45 #include "hb-ot-vorg-table.hh" | |
| 46 #include "hb-ot-color-cbdt-table.hh" | |
| 47 #include "hb-ot-color-sbix-table.hh" | |
| 48 #include "hb-ot-color-colr-table.hh" | |
| 49 | |
| 50 | |
| 51 /** | |
| 52 * SECTION:hb-ot-font | |
| 53 * @title: hb-ot-font | |
| 54 * @short_description: OpenType font implementation | |
| 55 * @include: hb-ot.h | |
| 56 * | |
| 57 * Functions for using OpenType fonts with hb_shape(). Note that fonts returned | |
| 58 * by hb_font_create() default to using these functions, so most clients would | |
| 59 * never need to call these functions directly. | |
| 60 **/ | |
| 61 | |
| 62 using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>; | |
| 63 | |
| 64 struct hb_ot_font_t | |
| 65 { | |
| 66 const hb_ot_face_t *ot_face; | |
| 67 | |
| 68 /* h_advance caching */ | |
| 69 mutable hb_atomic_int_t cached_coords_serial; | |
| 70 mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache; | |
| 71 }; | |
| 72 | |
| 73 static hb_ot_font_t * | |
| 74 _hb_ot_font_create (hb_font_t *font) | |
| 75 { | |
| 76 hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t)); | |
| 77 if (unlikely (!ot_font)) | |
| 78 return nullptr; | |
| 79 | |
| 80 ot_font->ot_face = &font->face->table; | |
| 81 | |
| 82 return ot_font; | |
| 83 } | |
| 84 | |
| 85 static void | |
| 86 _hb_ot_font_destroy (void *font_data) | |
| 87 { | |
| 88 hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data; | |
| 89 | |
| 90 auto *cache = ot_font->advance_cache.get_relaxed (); | |
| 91 if (cache) | |
| 92 { | |
| 93 cache->fini (); | |
| 94 hb_free (cache); | |
| 95 } | |
| 96 | |
| 97 hb_free (ot_font); | |
| 98 } | |
| 99 | |
| 100 static hb_bool_t | |
| 101 hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, | |
| 102 void *font_data, | |
| 103 hb_codepoint_t unicode, | |
| 104 hb_codepoint_t *glyph, | |
| 105 void *user_data HB_UNUSED) | |
| 106 { | |
| 107 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 108 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 109 return ot_face->cmap->get_nominal_glyph (unicode, glyph); | |
| 110 } | |
| 111 | |
| 112 static unsigned int | |
| 113 hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, | |
| 114 void *font_data, | |
| 115 unsigned int count, | |
| 116 const hb_codepoint_t *first_unicode, | |
| 117 unsigned int unicode_stride, | |
| 118 hb_codepoint_t *first_glyph, | |
| 119 unsigned int glyph_stride, | |
| 120 void *user_data HB_UNUSED) | |
| 121 { | |
| 122 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 123 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 124 return ot_face->cmap->get_nominal_glyphs (count, | |
| 125 first_unicode, unicode_stride, | |
| 126 first_glyph, glyph_stride); | |
| 127 } | |
| 128 | |
| 129 static hb_bool_t | |
| 130 hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, | |
| 131 void *font_data, | |
| 132 hb_codepoint_t unicode, | |
| 133 hb_codepoint_t variation_selector, | |
| 134 hb_codepoint_t *glyph, | |
| 135 void *user_data HB_UNUSED) | |
| 136 { | |
| 137 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 138 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 139 return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph); | |
| 140 } | |
| 141 | |
| 142 static void | |
| 143 hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, | |
| 144 unsigned count, | |
| 145 const hb_codepoint_t *first_glyph, | |
| 146 unsigned glyph_stride, | |
| 147 hb_position_t *first_advance, | |
| 148 unsigned advance_stride, | |
| 149 void *user_data HB_UNUSED) | |
| 150 { | |
| 151 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 152 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 153 const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; | |
| 154 | |
| 155 #ifndef HB_NO_VAR | |
| 156 const OT::HVAR &HVAR = *hmtx.var_table; | |
| 157 const OT::VariationStore &varStore = &HVAR + HVAR.varStore; | |
| 158 OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; | |
| 159 | |
| 160 bool use_cache = font->num_coords; | |
| 161 #else | |
| 162 OT::VariationStore::cache_t *varStore_cache = nullptr; | |
| 163 bool use_cache = false; | |
| 164 #endif | |
| 165 | |
| 166 hb_ot_font_advance_cache_t *cache = nullptr; | |
| 167 if (use_cache) | |
| 168 { | |
| 169 retry: | |
| 170 cache = ot_font->advance_cache.get_acquire (); | |
| 171 if (unlikely (!cache)) | |
| 172 { | |
| 173 cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); | |
| 174 if (unlikely (!cache)) | |
| 175 { | |
| 176 use_cache = false; | |
| 177 goto out; | |
| 178 } | |
| 179 | |
| 180 cache->init (); | |
| 181 if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache))) | |
| 182 { | |
| 183 hb_free (cache); | |
| 184 goto retry; | |
| 185 } | |
| 186 ot_font->cached_coords_serial.set_release (font->serial_coords); | |
| 187 } | |
| 188 } | |
| 189 out: | |
| 190 | |
| 191 if (!use_cache) | |
| 192 { | |
| 193 for (unsigned int i = 0; i < count; i++) | |
| 194 { | |
| 195 *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); | |
| 196 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); | |
| 197 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); | |
| 198 } | |
| 199 } | |
| 200 else | |
| 201 { /* Use cache. */ | |
| 202 if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords) | |
| 203 { | |
| 204 ot_font->advance_cache->init (); | |
| 205 ot_font->cached_coords_serial.set_release (font->serial_coords); | |
| 206 } | |
| 207 | |
| 208 for (unsigned int i = 0; i < count; i++) | |
| 209 { | |
| 210 hb_position_t v; | |
| 211 unsigned cv; | |
| 212 if (ot_font->advance_cache->get (*first_glyph, &cv)) | |
| 213 v = cv; | |
| 214 else | |
| 215 { | |
| 216 v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); | |
| 217 ot_font->advance_cache->set (*first_glyph, v); | |
| 218 } | |
| 219 *first_advance = font->em_scale_x (v); | |
| 220 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); | |
| 221 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 #ifndef HB_NO_VAR | |
| 226 OT::VariationStore::destroy_cache (varStore_cache); | |
| 227 #endif | |
| 228 } | |
| 229 | |
| 230 #ifndef HB_NO_VERTICAL | |
| 231 static void | |
| 232 hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, | |
| 233 unsigned count, | |
| 234 const hb_codepoint_t *first_glyph, | |
| 235 unsigned glyph_stride, | |
| 236 hb_position_t *first_advance, | |
| 237 unsigned advance_stride, | |
| 238 void *user_data HB_UNUSED) | |
| 239 { | |
| 240 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 241 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 242 const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; | |
| 243 | |
| 244 if (vmtx.has_data ()) | |
| 245 { | |
| 246 #ifndef HB_NO_VAR | |
| 247 const OT::VVAR &VVAR = *vmtx.var_table; | |
| 248 const OT::VariationStore &varStore = &VVAR + VVAR.varStore; | |
| 249 OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; | |
| 250 #else | |
| 251 OT::VariationStore::cache_t *varStore_cache = nullptr; | |
| 252 #endif | |
| 253 | |
| 254 for (unsigned int i = 0; i < count; i++) | |
| 255 { | |
| 256 *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); | |
| 257 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); | |
| 258 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); | |
| 259 } | |
| 260 | |
| 261 #ifndef HB_NO_VAR | |
| 262 OT::VariationStore::destroy_cache (varStore_cache); | |
| 263 #endif | |
| 264 } | |
| 265 else | |
| 266 { | |
| 267 hb_font_extents_t font_extents; | |
| 268 font->get_h_extents_with_fallback (&font_extents); | |
| 269 hb_position_t advance = -(font_extents.ascender - font_extents.descender); | |
| 270 | |
| 271 for (unsigned int i = 0; i < count; i++) | |
| 272 { | |
| 273 *first_advance = advance; | |
| 274 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); | |
| 275 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); | |
| 276 } | |
| 277 } | |
| 278 } | |
| 279 #endif | |
| 280 | |
| 281 #ifndef HB_NO_VERTICAL | |
| 282 static hb_bool_t | |
| 283 hb_ot_get_glyph_v_origin (hb_font_t *font, | |
| 284 void *font_data, | |
| 285 hb_codepoint_t glyph, | |
| 286 hb_position_t *x, | |
| 287 hb_position_t *y, | |
| 288 void *user_data HB_UNUSED) | |
| 289 { | |
| 290 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 291 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 292 | |
| 293 *x = font->get_glyph_h_advance (glyph) / 2; | |
| 294 | |
| 295 const OT::VORG &VORG = *ot_face->VORG; | |
| 296 if (VORG.has_data ()) | |
| 297 { | |
| 298 float delta = 0; | |
| 299 | |
| 300 #ifndef HB_NO_VAR | |
| 301 const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; | |
| 302 const OT::VVAR &VVAR = *vmtx.var_table; | |
| 303 if (font->num_coords) | |
| 304 VVAR.get_vorg_delta_unscaled (glyph, | |
| 305 font->coords, font->num_coords, | |
| 306 &delta); | |
| 307 #endif | |
| 308 | |
| 309 *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); | |
| 310 return true; | |
| 311 } | |
| 312 | |
| 313 hb_glyph_extents_t extents = {0}; | |
| 314 if (ot_face->glyf->get_extents (font, glyph, &extents)) | |
| 315 { | |
| 316 const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; | |
| 317 int tsb = 0; | |
| 318 if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) | |
| 319 { | |
| 320 *y = extents.y_bearing + font->em_scale_y (tsb); | |
| 321 return true; | |
| 322 } | |
| 323 | |
| 324 hb_font_extents_t font_extents; | |
| 325 font->get_h_extents_with_fallback (&font_extents); | |
| 326 hb_position_t advance = font_extents.ascender - font_extents.descender; | |
| 327 int diff = advance - -extents.height; | |
| 328 *y = extents.y_bearing + (diff >> 1); | |
| 329 return true; | |
| 330 } | |
| 331 | |
| 332 hb_font_extents_t font_extents; | |
| 333 font->get_h_extents_with_fallback (&font_extents); | |
| 334 *y = font_extents.ascender; | |
| 335 | |
| 336 return true; | |
| 337 } | |
| 338 #endif | |
| 339 | |
| 340 static hb_bool_t | |
| 341 hb_ot_get_glyph_extents (hb_font_t *font, | |
| 342 void *font_data, | |
| 343 hb_codepoint_t glyph, | |
| 344 hb_glyph_extents_t *extents, | |
| 345 void *user_data HB_UNUSED) | |
| 346 { | |
| 347 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 348 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 349 | |
| 350 #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) | |
| 351 if (ot_face->sbix->get_extents (font, glyph, extents)) return true; | |
| 352 if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; | |
| 353 #endif | |
| 354 #if !defined(HB_NO_COLOR) | |
| 355 if (ot_face->COLR->get_extents (font, glyph, extents)) return true; | |
| 356 #endif | |
| 357 if (ot_face->glyf->get_extents (font, glyph, extents)) return true; | |
| 358 #ifndef HB_NO_OT_FONT_CFF | |
| 359 if (ot_face->cff1->get_extents (font, glyph, extents)) return true; | |
| 360 if (ot_face->cff2->get_extents (font, glyph, extents)) return true; | |
| 361 #endif | |
| 362 | |
| 363 return false; | |
| 364 } | |
| 365 | |
| 366 #ifndef HB_NO_OT_FONT_GLYPH_NAMES | |
| 367 static hb_bool_t | |
| 368 hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, | |
| 369 void *font_data, | |
| 370 hb_codepoint_t glyph, | |
| 371 char *name, unsigned int size, | |
| 372 void *user_data HB_UNUSED) | |
| 373 { | |
| 374 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 375 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 376 | |
| 377 if (ot_face->post->get_glyph_name (glyph, name, size)) return true; | |
| 378 #ifndef HB_NO_OT_FONT_CFF | |
| 379 if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true; | |
| 380 #endif | |
| 381 return false; | |
| 382 } | |
| 383 static hb_bool_t | |
| 384 hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, | |
| 385 void *font_data, | |
| 386 const char *name, int len, | |
| 387 hb_codepoint_t *glyph, | |
| 388 void *user_data HB_UNUSED) | |
| 389 { | |
| 390 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | |
| 391 const hb_ot_face_t *ot_face = ot_font->ot_face; | |
| 392 | |
| 393 if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true; | |
| 394 #ifndef HB_NO_OT_FONT_CFF | |
| 395 if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true; | |
| 396 #endif | |
| 397 return false; | |
| 398 } | |
| 399 #endif | |
| 400 | |
| 401 static hb_bool_t | |
| 402 hb_ot_get_font_h_extents (hb_font_t *font, | |
| 403 void *font_data HB_UNUSED, | |
| 404 hb_font_extents_t *metrics, | |
| 405 void *user_data HB_UNUSED) | |
| 406 { | |
| 407 return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && | |
| 408 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && | |
| 409 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); | |
| 410 } | |
| 411 | |
| 412 #ifndef HB_NO_VERTICAL | |
| 413 static hb_bool_t | |
| 414 hb_ot_get_font_v_extents (hb_font_t *font, | |
| 415 void *font_data HB_UNUSED, | |
| 416 hb_font_extents_t *metrics, | |
| 417 void *user_data HB_UNUSED) | |
| 418 { | |
| 419 return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_ASCENDER, &metrics->ascender) && | |
| 420 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) && | |
| 421 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap); | |
| 422 } | |
| 423 #endif | |
| 424 | |
| 425 #ifndef HB_NO_DRAW | |
| 426 static void | |
| 427 hb_ot_get_glyph_shape (hb_font_t *font, | |
| 428 void *font_data HB_UNUSED, | |
| 429 hb_codepoint_t glyph, | |
| 430 hb_draw_funcs_t *draw_funcs, void *draw_data, | |
| 431 void *user_data) | |
| 432 { | |
| 433 hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); | |
| 434 if (font->face->table.glyf->get_path (font, glyph, draw_session)) return; | |
| 435 #ifndef HB_NO_CFF | |
| 436 if (font->face->table.cff1->get_path (font, glyph, draw_session)) return; | |
| 437 if (font->face->table.cff2->get_path (font, glyph, draw_session)) return; | |
| 438 #endif | |
| 439 } | |
| 440 #endif | |
| 441 | |
| 442 static inline void free_static_ot_funcs (); | |
| 443 | |
| 444 static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t> | |
| 445 { | |
| 446 static hb_font_funcs_t *create () | |
| 447 { | |
| 448 hb_font_funcs_t *funcs = hb_font_funcs_create (); | |
| 449 | |
| 450 hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); | |
| 451 hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr); | |
| 452 hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); | |
| 453 | |
| 454 hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); | |
| 455 hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); | |
| 456 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); | |
| 457 | |
| 458 #ifndef HB_NO_VERTICAL | |
| 459 hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); | |
| 460 hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); | |
| 461 hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); | |
| 462 #endif | |
| 463 | |
| 464 #ifndef HB_NO_DRAW | |
| 465 hb_font_funcs_set_glyph_shape_func (funcs, hb_ot_get_glyph_shape, nullptr, nullptr); | |
| 466 #endif | |
| 467 | |
| 468 hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); | |
| 469 //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); | |
| 470 | |
| 471 #ifndef HB_NO_OT_FONT_GLYPH_NAMES | |
| 472 hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); | |
| 473 hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); | |
| 474 #endif | |
| 475 | |
| 476 hb_font_funcs_make_immutable (funcs); | |
| 477 | |
| 478 hb_atexit (free_static_ot_funcs); | |
| 479 | |
| 480 return funcs; | |
| 481 } | |
| 482 } static_ot_funcs; | |
| 483 | |
| 484 static inline | |
| 485 void free_static_ot_funcs () | |
| 486 { | |
| 487 static_ot_funcs.free_instance (); | |
| 488 } | |
| 489 | |
| 490 static hb_font_funcs_t * | |
| 491 _hb_ot_get_font_funcs () | |
| 492 { | |
| 493 return static_ot_funcs.get_unconst (); | |
| 494 } | |
| 495 | |
| 496 | |
| 497 /** | |
| 498 * hb_ot_font_set_funcs: | |
| 499 * @font: #hb_font_t to work upon | |
| 500 * | |
| 501 * Sets the font functions to use when working with @font. | |
| 502 * | |
| 503 * Since: 0.9.28 | |
| 504 **/ | |
| 505 void | |
| 506 hb_ot_font_set_funcs (hb_font_t *font) | |
| 507 { | |
| 508 hb_ot_font_t *ot_font = _hb_ot_font_create (font); | |
| 509 if (unlikely (!ot_font)) | |
| 510 return; | |
| 511 | |
| 512 hb_font_set_funcs (font, | |
| 513 _hb_ot_get_font_funcs (), | |
| 514 ot_font, | |
| 515 _hb_ot_font_destroy); | |
| 516 } | |
| 517 | |
| 518 #ifndef HB_NO_VAR | |
| 519 bool | |
| 520 _glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, | |
| 521 int *lsb) | |
| 522 { | |
| 523 return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); | |
| 524 } | |
| 525 | |
| 526 unsigned | |
| 527 _glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) | |
| 528 { | |
| 529 return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); | |
| 530 } | |
| 531 #endif | |
| 532 | |
| 533 | |
| 534 #endif |
