| 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 28 matching lines...) Expand all Loading... |
| 39 | 39 |
| 40 struct hb_ot_face_metrics_accelerator_t | 40 struct hb_ot_face_metrics_accelerator_t |
| 41 { | 41 { |
| 42 unsigned int num_metrics; | 42 unsigned int num_metrics; |
| 43 unsigned int num_advances; | 43 unsigned int num_advances; |
| 44 unsigned int default_advance; | 44 unsigned int default_advance; |
| 45 const OT::_mtx *table; | 45 const OT::_mtx *table; |
| 46 hb_blob_t *blob; | 46 hb_blob_t *blob; |
| 47 | 47 |
| 48 inline void init (hb_face_t *face, | 48 inline void init (hb_face_t *face, |
| 49 » » hb_tag_t _hea_tag, hb_tag_t _mtx_tag, | 49 » » hb_tag_t _hea_tag, hb_tag_t _mtx_tag) |
| 50 » » unsigned int default_advance_) | |
| 51 { | 50 { |
| 52 this->default_advance = default_advance_; | 51 this->default_advance = face->get_upem (); |
| 53 this->num_metrics = face->get_num_glyphs (); | |
| 54 | 52 |
| 55 hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_ta
ble (_hea_tag)); | 53 hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_ta
ble (_hea_tag)); |
| 56 const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); | 54 const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); |
| 57 this->num_advances = _hea->numberOfLongMetrics; | 55 this->num_advances = _hea->numberOfLongMetrics; |
| 58 hb_blob_destroy (_hea_blob); | 56 hb_blob_destroy (_hea_blob); |
| 59 | 57 |
| 60 this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_
tag)); | 58 this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_
tag)); |
| 61 if (unlikely (!this->num_advances || | 59 |
| 62 » » 2 * (this->num_advances + this->num_metrics) > hb_blob_get_len
gth (this->blob))) | 60 /* Cap num_metrics() and num_advances() based on table length. */ |
| 61 unsigned int len = hb_blob_get_length (this->blob); |
| 62 if (unlikely (this->num_advances * 4 > len)) |
| 63 this->num_advances = len / 4; |
| 64 this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; |
| 65 |
| 66 /* We MUST set num_metrics to zero if num_advances is zero. |
| 67 * Our get_advance() depends on that. */ |
| 68 if (unlikely (!this->num_advances)) |
| 63 { | 69 { |
| 64 this->num_metrics = this->num_advances = 0; | 70 this->num_metrics = this->num_advances = 0; |
| 65 hb_blob_destroy (this->blob); | 71 hb_blob_destroy (this->blob); |
| 66 this->blob = hb_blob_get_empty (); | 72 this->blob = hb_blob_get_empty (); |
| 67 } | 73 } |
| 68 this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob); | 74 this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob); |
| 69 } | 75 } |
| 70 | 76 |
| 71 inline void fini (void) | 77 inline void fini (void) |
| 72 { | 78 { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 | 244 |
| 239 | 245 |
| 240 static hb_ot_font_t * | 246 static hb_ot_font_t * |
| 241 _hb_ot_font_create (hb_face_t *face) | 247 _hb_ot_font_create (hb_face_t *face) |
| 242 { | 248 { |
| 243 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); | 249 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); |
| 244 | 250 |
| 245 if (unlikely (!ot_font)) | 251 if (unlikely (!ot_font)) |
| 246 return NULL; | 252 return NULL; |
| 247 | 253 |
| 248 unsigned int upem = face->get_upem (); | |
| 249 | |
| 250 ot_font->cmap.init (face); | 254 ot_font->cmap.init (face); |
| 251 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1); | 255 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx); |
| 252 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO
Can we do this lazily? */ | 256 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx); /* TODO Can we
do this lazily? */ |
| 253 ot_font->glyf.init (face); | 257 ot_font->glyf.init (face); |
| 254 | 258 |
| 255 return ot_font; | 259 return ot_font; |
| 256 } | 260 } |
| 257 | 261 |
| 258 static void | 262 static void |
| 259 _hb_ot_font_destroy (hb_ot_font_t *ot_font) | 263 _hb_ot_font_destroy (hb_ot_font_t *ot_font) |
| 260 { | 264 { |
| 261 ot_font->cmap.fini (); | 265 ot_font->cmap.fini (); |
| 262 ot_font->h_metrics.fini (); | 266 ot_font->h_metrics.fini (); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, | 298 hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, |
| 295 void *font_data, | 299 void *font_data, |
| 296 hb_codepoint_t glyph, | 300 hb_codepoint_t glyph, |
| 297 void *user_data HB_UNUSED) | 301 void *user_data HB_UNUSED) |
| 298 { | 302 { |
| 299 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | 303 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
| 300 return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); | 304 return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); |
| 301 } | 305 } |
| 302 | 306 |
| 303 static hb_bool_t | 307 static hb_bool_t |
| 304 hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED, | |
| 305 void *font_data HB_UNUSED, | |
| 306 hb_codepoint_t glyph HB_UNUSED, | |
| 307 hb_position_t *x HB_UNUSED, | |
| 308 hb_position_t *y HB_UNUSED, | |
| 309 void *user_data HB_UNUSED) | |
| 310 { | |
| 311 /* We always work in the horizontal coordinates. */ | |
| 312 return true; | |
| 313 } | |
| 314 | |
| 315 static hb_bool_t | |
| 316 hb_ot_get_glyph_v_origin (hb_font_t *font HB_UNUSED, | |
| 317 void *font_data, | |
| 318 hb_codepoint_t glyph, | |
| 319 hb_position_t *x, | |
| 320 hb_position_t *y, | |
| 321 void *user_data HB_UNUSED) | |
| 322 { | |
| 323 /* TODO */ | |
| 324 return false; | |
| 325 } | |
| 326 | |
| 327 static hb_position_t | |
| 328 hb_ot_get_glyph_h_kerning (hb_font_t *font, | |
| 329 void *font_data, | |
| 330 hb_codepoint_t left_glyph, | |
| 331 hb_codepoint_t right_glyph, | |
| 332 void *user_data HB_UNUSED) | |
| 333 { | |
| 334 /* TODO */ | |
| 335 return 0; | |
| 336 } | |
| 337 | |
| 338 static hb_position_t | |
| 339 hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, | |
| 340 void *font_data HB_UNUSED, | |
| 341 hb_codepoint_t top_glyph HB_UNUSED, | |
| 342 hb_codepoint_t bottom_glyph HB_UNUSED, | |
| 343 void *user_data HB_UNUSED) | |
| 344 { | |
| 345 /* OpenType doesn't have vertical-kerning other than GPOS. */ | |
| 346 return 0; | |
| 347 } | |
| 348 | |
| 349 static hb_bool_t | |
| 350 hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, | 308 hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, |
| 351 void *font_data, | 309 void *font_data, |
| 352 hb_codepoint_t glyph, | 310 hb_codepoint_t glyph, |
| 353 hb_glyph_extents_t *extents, | 311 hb_glyph_extents_t *extents, |
| 354 void *user_data HB_UNUSED) | 312 void *user_data HB_UNUSED) |
| 355 { | 313 { |
| 356 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; | 314 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
| 357 bool ret = ot_font->glyf.get_extents (glyph, extents); | 315 bool ret = ot_font->glyf.get_extents (glyph, extents); |
| 358 extents->x_bearing = font->em_scale_x (extents->x_bearing); | 316 extents->x_bearing = font->em_scale_x (extents->x_bearing); |
| 359 extents->y_bearing = font->em_scale_y (extents->y_bearing); | 317 extents->y_bearing = font->em_scale_y (extents->y_bearing); |
| 360 extents->width = font->em_scale_x (extents->width); | 318 extents->width = font->em_scale_x (extents->width); |
| 361 extents->height = font->em_scale_y (extents->height); | 319 extents->height = font->em_scale_y (extents->height); |
| 362 return ret; | 320 return ret; |
| 363 } | 321 } |
| 364 | 322 |
| 365 static hb_bool_t | 323 |
| 366 hb_ot_get_glyph_contour_point (hb_font_t *font HB_UNUSED, | 324 static hb_font_funcs_t *static_ot_funcs = NULL; |
| 367 » » » void *font_data, | 325 |
| 368 » » » hb_codepoint_t glyph, | 326 #ifdef HB_USE_ATEXIT |
| 369 » » » unsigned int point_index, | 327 static |
| 370 » » » hb_position_t *x, | 328 void free_static_ot_funcs (void) |
| 371 » » » hb_position_t *y, | |
| 372 » » » void *user_data HB_UNUSED) | |
| 373 { | 329 { |
| 374 /* TODO */ | 330 hb_font_funcs_destroy (static_ot_funcs); |
| 375 return false; | |
| 376 } | 331 } |
| 377 | 332 #endif |
| 378 static hb_bool_t | |
| 379 hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, | |
| 380 » » void *font_data, | |
| 381 » » hb_codepoint_t glyph, | |
| 382 » » char *name, unsigned int size, | |
| 383 » » void *user_data HB_UNUSED) | |
| 384 { | |
| 385 /* TODO */ | |
| 386 return false; | |
| 387 } | |
| 388 | |
| 389 static hb_bool_t | |
| 390 hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, | |
| 391 » » » void *font_data, | |
| 392 » » » const char *name, int len, /* -1 means nul-terminated
*/ | |
| 393 » » » hb_codepoint_t *glyph, | |
| 394 » » » void *user_data HB_UNUSED) | |
| 395 { | |
| 396 /* TODO */ | |
| 397 return false; | |
| 398 } | |
| 399 | |
| 400 | 333 |
| 401 static hb_font_funcs_t * | 334 static hb_font_funcs_t * |
| 402 _hb_ot_get_font_funcs (void) | 335 _hb_ot_get_font_funcs (void) |
| 403 { | 336 { |
| 404 static const hb_font_funcs_t ot_ffuncs = { | 337 retry: |
| 405 HB_OBJECT_HEADER_STATIC, | 338 hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_fun
cs); |
| 406 | 339 |
| 407 true, /* immutable */ | 340 if (unlikely (!funcs)) |
| 341 { |
| 342 funcs = hb_font_funcs_create (); |
| 408 | 343 |
| 409 { | 344 hb_font_funcs_set_glyph_func (funcs, hb_ot_get_glyph, NULL, NULL); |
| 410 #define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name, | 345 hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NU
LL, NULL); |
| 411 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 346 hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NU
LL, NULL); |
| 412 #undef HB_FONT_FUNC_IMPLEMENT | 347 //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); |
| 349 //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); |
| 351 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 |
| 353 //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 |
| 355 |
| 356 hb_font_funcs_make_immutable (funcs); |
| 357 |
| 358 if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { |
| 359 hb_font_funcs_destroy (funcs); |
| 360 goto retry; |
| 413 } | 361 } |
| 362 |
| 363 #ifdef HB_USE_ATEXIT |
| 364 atexit (free_static_ot_funcs); /* First person registers atexit() callback.
*/ |
| 365 #endif |
| 414 }; | 366 }; |
| 415 | 367 |
| 416 return const_cast<hb_font_funcs_t *> (&ot_ffuncs); | 368 return funcs; |
| 417 } | 369 } |
| 418 | 370 |
| 419 | 371 |
| 420 /** | 372 /** |
| 421 * Since: 0.9.28 | 373 * Since: 0.9.28 |
| 422 **/ | 374 **/ |
| 423 void | 375 void |
| 424 hb_ot_font_set_funcs (hb_font_t *font) | 376 hb_ot_font_set_funcs (hb_font_t *font) |
| 425 { | 377 { |
| 426 hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); | 378 hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); |
| 427 if (unlikely (!ot_font)) | 379 if (unlikely (!ot_font)) |
| 428 return; | 380 return; |
| 429 | 381 |
| 430 hb_font_set_funcs (font, | 382 hb_font_set_funcs (font, |
| 431 _hb_ot_get_font_funcs (), | 383 _hb_ot_get_font_funcs (), |
| 432 ot_font, | 384 ot_font, |
| 433 (hb_destroy_func_t) _hb_ot_font_destroy); | 385 (hb_destroy_func_t) _hb_ot_font_destroy); |
| 434 } | 386 } |
| OLD | NEW |