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 |