| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2011,2014 Google, Inc. | 2 * Copyright © 2011,2014 Google, Inc. |
| 3 * | 3 * |
| 4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
| 5 * | 5 * |
| 6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
| 7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
| 8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
| 9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
| 10 * all copies of this software. | 10 * all copies of this software. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 #include "hb-ot.h" | 29 #include "hb-ot.h" |
| 30 | 30 |
| 31 #include "hb-font-private.hh" | 31 #include "hb-font-private.hh" |
| 32 | 32 |
| 33 #include "hb-ot-cmap-table.hh" | 33 #include "hb-ot-cmap-table.hh" |
| 34 #include "hb-ot-glyf-table.hh" | 34 #include "hb-ot-glyf-table.hh" |
| 35 #include "hb-ot-head-table.hh" | 35 #include "hb-ot-head-table.hh" |
| 36 #include "hb-ot-hhea-table.hh" | 36 #include "hb-ot-hhea-table.hh" |
| 37 #include "hb-ot-hmtx-table.hh" | 37 #include "hb-ot-hmtx-table.hh" |
| 38 #include "hb-ot-os2-table.hh" |
| 38 | 39 |
| 39 | 40 |
| 40 struct hb_ot_face_metrics_accelerator_t | 41 struct hb_ot_face_metrics_accelerator_t |
| 41 { | 42 { |
| 42 unsigned int num_metrics; | 43 unsigned int num_metrics; |
| 43 unsigned int num_advances; | 44 unsigned int num_advances; |
| 44 unsigned int default_advance; | 45 unsigned int default_advance; |
| 46 unsigned short ascender; |
| 47 unsigned short descender; |
| 48 unsigned short line_gap; |
| 49 |
| 45 const OT::_mtx *table; | 50 const OT::_mtx *table; |
| 46 hb_blob_t *blob; | 51 hb_blob_t *blob; |
| 47 | 52 |
| 48 inline void init (hb_face_t *face, | 53 inline void init (hb_face_t *face, |
| 49 » » hb_tag_t _hea_tag, hb_tag_t _mtx_tag) | 54 » » hb_tag_t _hea_tag, |
| 55 » » hb_tag_t _mtx_tag, |
| 56 » » hb_tag_t os2_tag) |
| 50 { | 57 { |
| 51 this->default_advance = face->get_upem (); | 58 this->default_advance = face->get_upem (); |
| 52 | 59 |
| 60 bool got_font_extents = false; |
| 61 if (os2_tag) |
| 62 { |
| 63 hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_ta
ble (os2_tag)); |
| 64 const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob); |
| 65 #define USE_TYPO_METRICS (1u<<7) |
| 66 if (0 != (os2->fsSelection & USE_TYPO_METRICS)) |
| 67 { |
| 68 this->ascender = os2->sTypoAscender; |
| 69 this->descender = os2->sTypoDescender; |
| 70 this->line_gap = os2->sTypoLineGap; |
| 71 got_font_extents = (this->ascender | this->descender) != 0; |
| 72 } |
| 73 hb_blob_destroy (os2_blob); |
| 74 } |
| 75 |
| 53 hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_ta
ble (_hea_tag)); | 76 hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_ta
ble (_hea_tag)); |
| 54 const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); | 77 const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); |
| 55 this->num_advances = _hea->numberOfLongMetrics; | 78 this->num_advances = _hea->numberOfLongMetrics; |
| 79 if (!got_font_extents) |
| 80 { |
| 81 this->ascender = _hea->ascender; |
| 82 this->descender = _hea->descender; |
| 83 this->line_gap = _hea->lineGap; |
| 84 } |
| 56 hb_blob_destroy (_hea_blob); | 85 hb_blob_destroy (_hea_blob); |
| 57 | 86 |
| 58 this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_
tag)); | 87 this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_
tag)); |
| 59 | 88 |
| 60 /* Cap num_metrics() and num_advances() based on table length. */ | 89 /* Cap num_metrics() and num_advances() based on table length. */ |
| 61 unsigned int len = hb_blob_get_length (this->blob); | 90 unsigned int len = hb_blob_get_length (this->blob); |
| 62 if (unlikely (this->num_advances * 4 > len)) | 91 if (unlikely (this->num_advances * 4 > len)) |
| 63 this->num_advances = len / 4; | 92 this->num_advances = len / 4; |
| 64 this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; | 93 this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; |
| 65 | 94 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 274 |
| 246 static hb_ot_font_t * | 275 static hb_ot_font_t * |
| 247 _hb_ot_font_create (hb_face_t *face) | 276 _hb_ot_font_create (hb_face_t *face) |
| 248 { | 277 { |
| 249 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); | 278 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); |
| 250 | 279 |
| 251 if (unlikely (!ot_font)) | 280 if (unlikely (!ot_font)) |
| 252 return NULL; | 281 return NULL; |
| 253 | 282 |
| 254 ot_font->cmap.init (face); | 283 ot_font->cmap.init (face); |
| 255 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx); | 284 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2); |
| 256 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx); /* TODO Can we
do this lazily? */ | 285 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE); /
* TODO Can we do this lazily? */ |
| 257 ot_font->glyf.init (face); | 286 ot_font->glyf.init (face); |
| 258 | 287 |
| 259 return ot_font; | 288 return ot_font; |
| 260 } | 289 } |
| 261 | 290 |
| 262 static void | 291 static void |
| 263 _hb_ot_font_destroy (hb_ot_font_t *ot_font) | 292 _hb_ot_font_destroy (hb_ot_font_t *ot_font) |
| 264 { | 293 { |
| 265 ot_font->cmap.fini (); | 294 ot_font->cmap.fini (); |
| 266 ot_font->h_metrics.fini (); | 295 ot_font->h_metrics.fini (); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 { | 342 { |
| 314 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | 343 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
| 315 bool ret = ot_font->glyf.get_extents (glyph, extents); | 344 bool ret = ot_font->glyf.get_extents (glyph, extents); |
| 316 extents->x_bearing = font->em_scale_x (extents->x_bearing); | 345 extents->x_bearing = font->em_scale_x (extents->x_bearing); |
| 317 extents->y_bearing = font->em_scale_y (extents->y_bearing); | 346 extents->y_bearing = font->em_scale_y (extents->y_bearing); |
| 318 extents->width = font->em_scale_x (extents->width); | 347 extents->width = font->em_scale_x (extents->width); |
| 319 extents->height = font->em_scale_y (extents->height); | 348 extents->height = font->em_scale_y (extents->height); |
| 320 return ret; | 349 return ret; |
| 321 } | 350 } |
| 322 | 351 |
| 352 static hb_bool_t |
| 353 hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, |
| 354 void *font_data, |
| 355 hb_font_extents_t *metrics, |
| 356 void *user_data HB_UNUSED) |
| 357 { |
| 358 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
| 359 metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); |
| 360 metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); |
| 361 metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); |
| 362 return true; |
| 363 } |
| 364 |
| 365 static hb_bool_t |
| 366 hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, |
| 367 void *font_data, |
| 368 hb_font_extents_t *metrics, |
| 369 void *user_data HB_UNUSED) |
| 370 { |
| 371 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
| 372 metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender); |
| 373 metrics->descender = font->em_scale_x (ot_font->v_metrics.descender); |
| 374 metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap); |
| 375 return true; |
| 376 } |
| 323 | 377 |
| 324 static hb_font_funcs_t *static_ot_funcs = NULL; | 378 static hb_font_funcs_t *static_ot_funcs = NULL; |
| 325 | 379 |
| 326 #ifdef HB_USE_ATEXIT | 380 #ifdef HB_USE_ATEXIT |
| 327 static | 381 static |
| 328 void free_static_ot_funcs (void) | 382 void free_static_ot_funcs (void) |
| 329 { | 383 { |
| 330 hb_font_funcs_destroy (static_ot_funcs); | 384 hb_font_funcs_destroy (static_ot_funcs); |
| 331 } | 385 } |
| 332 #endif | 386 #endif |
| 333 | 387 |
| 334 static hb_font_funcs_t * | 388 static hb_font_funcs_t * |
| 335 _hb_ot_get_font_funcs (void) | 389 _hb_ot_get_font_funcs (void) |
| 336 { | 390 { |
| 337 retry: | 391 retry: |
| 338 hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_fun
cs); | 392 hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_fun
cs); |
| 339 | 393 |
| 340 if (unlikely (!funcs)) | 394 if (unlikely (!funcs)) |
| 341 { | 395 { |
| 342 funcs = hb_font_funcs_create (); | 396 funcs = hb_font_funcs_create (); |
| 343 | 397 |
| 398 hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL
, NULL); |
| 399 hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL
, NULL); |
| 344 hb_font_funcs_set_glyph_func (funcs, hb_ot_get_glyph, NULL, NULL); | 400 hb_font_funcs_set_glyph_func (funcs, hb_ot_get_glyph, NULL, NULL); |
| 345 hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NU
LL, NULL); | 401 hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NU
LL, NULL); |
| 346 hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NU
LL, NULL); | 402 hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NU
LL, NULL); |
| 347 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NU
LL, NULL); | 403 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NU
LL, NULL); |
| 348 //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NU
LL, NULL); | 404 //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NU
LL, NULL); |
| 349 //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning,
NULL, NULL); TODO | 405 //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning,
NULL, NULL); TODO |
| 350 //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning,
NULL, NULL); | 406 //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning,
NULL, NULL); |
| 351 hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL,
NULL); | 407 hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL,
NULL); |
| 352 //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour
_point, NULL, NULL); TODO | 408 //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour
_point, NULL, NULL); TODO |
| 353 //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL
); TODO | 409 //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL
); TODO |
| 354 //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name,
NULL, NULL); TODO | 410 //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name,
NULL, NULL); TODO |
| 355 | 411 |
| 356 hb_font_funcs_make_immutable (funcs); | 412 hb_font_funcs_make_immutable (funcs); |
| 357 | 413 |
| 358 if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { | 414 if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { |
| 359 hb_font_funcs_destroy (funcs); | 415 hb_font_funcs_destroy (funcs); |
| 360 goto retry; | 416 goto retry; |
| 361 } | 417 } |
| 362 | 418 |
| 363 #ifdef HB_USE_ATEXIT | 419 #ifdef HB_USE_ATEXIT |
| 364 atexit (free_static_ot_funcs); /* First person registers atexit() callback.
*/ | 420 atexit (free_static_ot_funcs); /* First person registers atexit() callback.
*/ |
| 365 #endif | 421 #endif |
| 366 }; | 422 }; |
| 367 | 423 |
| 368 return funcs; | 424 return funcs; |
| 369 } | 425 } |
| 370 | 426 |
| 371 | 427 |
| 372 /** | 428 /** |
| 429 * hb_ot_font_set_funcs: |
| 430 * |
| 373 * Since: 0.9.28 | 431 * Since: 0.9.28 |
| 374 **/ | 432 **/ |
| 375 void | 433 void |
| 376 hb_ot_font_set_funcs (hb_font_t *font) | 434 hb_ot_font_set_funcs (hb_font_t *font) |
| 377 { | 435 { |
| 378 hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); | 436 hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); |
| 379 if (unlikely (!ot_font)) | 437 if (unlikely (!ot_font)) |
| 380 return; | 438 return; |
| 381 | 439 |
| 382 hb_font_set_funcs (font, | 440 hb_font_set_funcs (font, |
| 383 _hb_ot_get_font_funcs (), | 441 _hb_ot_get_font_funcs (), |
| 384 ot_font, | 442 ot_font, |
| 385 (hb_destroy_func_t) _hb_ot_font_destroy); | 443 (hb_destroy_func_t) _hb_ot_font_destroy); |
| 386 } | 444 } |
| OLD | NEW |