Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-font.cc

Issue 2609123003: Roll HarfBuzz to 1.3.4 (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 13 matching lines...) Expand all
24 * Google Author(s): Behdad Esfahbod, Roozbeh Pournader 24 * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
25 */ 25 */
26 26
27 #include "hb-private.hh" 27 #include "hb-private.hh"
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-cbdt-table.hh"
34 #include "hb-ot-glyf-table.hh" 35 #include "hb-ot-glyf-table.hh"
35 #include "hb-ot-head-table.hh" 36 #include "hb-ot-head-table.hh"
36 #include "hb-ot-hhea-table.hh" 37 #include "hb-ot-hhea-table.hh"
37 #include "hb-ot-hmtx-table.hh" 38 #include "hb-ot-hmtx-table.hh"
38 #include "hb-ot-os2-table.hh" 39 #include "hb-ot-os2-table.hh"
39 //#include "hb-ot-post-table.hh" 40 //#include "hb-ot-post-table.hh"
40 41
41 42
42 struct hb_ot_face_metrics_accelerator_t 43 struct hb_ot_face_metrics_accelerator_t
43 { 44 {
44 unsigned int num_metrics; 45 unsigned int num_metrics;
45 unsigned int num_advances; 46 unsigned int num_advances;
46 unsigned int default_advance; 47 unsigned int default_advance;
47 unsigned short ascender; 48 unsigned short ascender;
48 unsigned short descender; 49 unsigned short descender;
49 unsigned short line_gap; 50 unsigned short line_gap;
51 bool has_font_extents;
50 52
51 const OT::_mtx *table; 53 const OT::_mtx *table;
52 hb_blob_t *blob; 54 hb_blob_t *blob;
53 55
54 inline void init (hb_face_t *face, 56 inline void init (hb_face_t *face,
55 hb_tag_t _hea_tag, 57 hb_tag_t _hea_tag,
56 hb_tag_t _mtx_tag, 58 hb_tag_t _mtx_tag,
57 » » hb_tag_t os2_tag) 59 » » hb_tag_t os2_tag,
60 » » unsigned int default_advance = 0)
58 { 61 {
59 this->default_advance = face->get_upem (); 62 this->default_advance = default_advance ? default_advance : face->get_upem ( );
60 63
61 bool got_font_extents = false; 64 bool got_font_extents = false;
62 if (os2_tag) 65 if (os2_tag)
63 { 66 {
64 hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_ta ble (os2_tag)); 67 hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_ta ble (os2_tag));
65 const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob); 68 const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob);
66 #define USE_TYPO_METRICS (1u<<7) 69 #define USE_TYPO_METRICS (1u<<7)
67 if (0 != (os2->fsSelection & USE_TYPO_METRICS)) 70 if (0 != (os2->fsSelection & USE_TYPO_METRICS))
68 { 71 {
69 this->ascender = os2->sTypoAscender; 72 this->ascender = os2->sTypoAscender;
70 this->descender = os2->sTypoDescender; 73 this->descender = os2->sTypoDescender;
71 this->line_gap = os2->sTypoLineGap; 74 this->line_gap = os2->sTypoLineGap;
72 got_font_extents = (this->ascender | this->descender) != 0; 75 got_font_extents = (this->ascender | this->descender) != 0;
73 } 76 }
74 hb_blob_destroy (os2_blob); 77 hb_blob_destroy (os2_blob);
75 } 78 }
76 79
77 hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_ta ble (_hea_tag)); 80 hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_ta ble (_hea_tag));
78 const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); 81 const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
79 this->num_advances = _hea->numberOfLongMetrics; 82 this->num_advances = _hea->numberOfLongMetrics;
80 if (!got_font_extents) 83 if (!got_font_extents)
81 { 84 {
82 this->ascender = _hea->ascender; 85 this->ascender = _hea->ascender;
83 this->descender = _hea->descender; 86 this->descender = _hea->descender;
84 this->line_gap = _hea->lineGap; 87 this->line_gap = _hea->lineGap;
88 got_font_extents = (this->ascender | this->descender) != 0;
85 } 89 }
86 hb_blob_destroy (_hea_blob); 90 hb_blob_destroy (_hea_blob);
87 91
92 this->has_font_extents = got_font_extents;
93
88 this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_ tag)); 94 this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_ tag));
89 95
90 /* Cap num_metrics() and num_advances() based on table length. */ 96 /* Cap num_metrics() and num_advances() based on table length. */
91 unsigned int len = hb_blob_get_length (this->blob); 97 unsigned int len = hb_blob_get_length (this->blob);
92 if (unlikely (this->num_advances * 4 > len)) 98 if (unlikely (this->num_advances * 4 > len))
93 this->num_advances = len / 4; 99 this->num_advances = len / 4;
94 this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; 100 this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2;
95 101
96 /* We MUST set num_metrics to zero if num_advances is zero. 102 /* We MUST set num_metrics to zero if num_advances is zero.
97 * Our get_advance() depends on that. */ 103 * Our get_advance() depends on that. */
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 201
196 extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); 202 extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
197 extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); 203 extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
198 extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x _bearing; 204 extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x _bearing;
199 extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y _bearing; 205 extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y _bearing;
200 206
201 return true; 207 return true;
202 } 208 }
203 }; 209 };
204 210
211 struct hb_ot_face_cbdt_accelerator_t
212 {
213 hb_blob_t *cblc_blob;
214 hb_blob_t *cbdt_blob;
215 const OT::CBLC *cblc;
216 const OT::CBDT *cbdt;
217
218 unsigned int cbdt_len;
219 float upem;
220
221 inline void init (hb_face_t *face)
222 {
223 upem = face->get_upem();
224
225 cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_ TAG_CBLC));
226 cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_ TAG_CBDT));
227 cbdt_len = hb_blob_get_length (cbdt_blob);
228
229 if (hb_blob_get_length (cblc_blob) == 0) {
230 cblc = NULL;
231 cbdt = NULL;
232 return; /* Not a bitmap font. */
233 }
234 cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob);
235 cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob);
236
237 }
238
239 inline void fini (void)
240 {
241 hb_blob_destroy (this->cblc_blob);
242 hb_blob_destroy (this->cbdt_blob);
243 }
244
245 inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) co nst
246 {
247 unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if availabl e. */
248
249 if (cblc == NULL)
250 return false; // Not a color bitmap font.
251
252 const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyp h, &x_ppem, &y_ppem);
253 if (subtable_record == NULL)
254 return false;
255
256 if (subtable_record->get_extents (extents))
257 return true;
258
259 unsigned int image_offset = 0, image_length = 0, image_format = 0;
260 if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, & image_format))
261 return false;
262
263 {
264 /* TODO Move the following into CBDT struct when adding more formats. */
265
266 if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_l ength))
267 return false;
268
269 switch (image_format)
270 {
271 case 17: {
272 if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size))
273 return false;
274
275 const OT::GlyphBitmapDataFormat17& glyphFormat17 =
276 OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image _offset);
277 glyphFormat17.glyphMetrics.get_extents (extents);
278 }
279 break;
280 default:
281 // TODO: Support other image formats.
282 return false;
283 }
284 }
285
286 /* Convert to the font units. */
287 extents->x_bearing *= upem / (float) x_ppem;
288 extents->y_bearing *= upem / (float) y_ppem;
289 extents->width *= upem / (float) x_ppem;
290 extents->height *= upem / (float) y_ppem;
291
292 return true;
293 }
294 };
295
205 typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, 296 typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
206 hb_codepoint_t codepoint, 297 hb_codepoint_t codepoint,
207 hb_codepoint_t *glyph); 298 hb_codepoint_t *glyph);
208 299
209 template <typename Type> 300 template <typename Type>
210 static inline bool get_glyph_from (const void *obj, 301 static inline bool get_glyph_from (const void *obj,
211 hb_codepoint_t codepoint, 302 hb_codepoint_t codepoint,
212 hb_codepoint_t *glyph) 303 hb_codepoint_t *glyph)
213 { 304 {
214 const Type *typed_obj = (const Type *) obj; 305 const Type *typed_obj = (const Type *) obj;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 hb_face_t *face; 458 hb_face_t *face;
368 T *instance; 459 T *instance;
369 }; 460 };
370 461
371 struct hb_ot_font_t 462 struct hb_ot_font_t
372 { 463 {
373 hb_ot_face_cmap_accelerator_t cmap; 464 hb_ot_face_cmap_accelerator_t cmap;
374 hb_ot_face_metrics_accelerator_t h_metrics; 465 hb_ot_face_metrics_accelerator_t h_metrics;
375 hb_ot_face_metrics_accelerator_t v_metrics; 466 hb_ot_face_metrics_accelerator_t v_metrics;
376 hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; 467 hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
468 hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
377 }; 469 };
378 470
379 471
380 static hb_ot_font_t * 472 static hb_ot_font_t *
381 _hb_ot_font_create (hb_face_t *face) 473 _hb_ot_font_create (hb_face_t *face)
382 { 474 {
383 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); 475 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
384 476
385 if (unlikely (!ot_font)) 477 if (unlikely (!ot_font))
386 return NULL; 478 return NULL;
387 479
388 ot_font->cmap.init (face); 480 ot_font->cmap.init (face);
389 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2); 481 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2);
390 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE); / * TODO Can we do this lazily? */ 482 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE,
483 » » » ot_font->h_metrics.ascender - ot_font->h_metrics.desc ender); /* TODO Can we do this lazily? */
391 ot_font->glyf.init (face); 484 ot_font->glyf.init (face);
485 ot_font->cbdt.init (face);
392 486
393 return ot_font; 487 return ot_font;
394 } 488 }
395 489
396 static void 490 static void
397 _hb_ot_font_destroy (hb_ot_font_t *ot_font) 491 _hb_ot_font_destroy (hb_ot_font_t *ot_font)
398 { 492 {
399 ot_font->cmap.fini (); 493 ot_font->cmap.fini ();
400 ot_font->h_metrics.fini (); 494 ot_font->h_metrics.fini ();
401 ot_font->v_metrics.fini (); 495 ot_font->v_metrics.fini ();
402 ot_font->glyf.fini (); 496 ot_font->glyf.fini ();
497 ot_font->cbdt.fini ();
403 498
404 free (ot_font); 499 free (ot_font);
405 } 500 }
406 501
407 502
408 static hb_bool_t 503 static hb_bool_t
409 hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, 504 hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
410 void *font_data, 505 void *font_data,
411 hb_codepoint_t unicode, 506 hb_codepoint_t unicode,
412 hb_codepoint_t *glyph, 507 hb_codepoint_t *glyph,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 546
452 static hb_bool_t 547 static hb_bool_t
453 hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, 548 hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
454 void *font_data, 549 void *font_data,
455 hb_codepoint_t glyph, 550 hb_codepoint_t glyph,
456 hb_glyph_extents_t *extents, 551 hb_glyph_extents_t *extents,
457 void *user_data HB_UNUSED) 552 void *user_data HB_UNUSED)
458 { 553 {
459 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; 554 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
460 bool ret = ot_font->glyf->get_extents (glyph, extents); 555 bool ret = ot_font->glyf->get_extents (glyph, extents);
556 if (!ret)
557 ret = ot_font->cbdt->get_extents (glyph, extents);
461 extents->x_bearing = font->em_scale_x (extents->x_bearing); 558 extents->x_bearing = font->em_scale_x (extents->x_bearing);
462 extents->y_bearing = font->em_scale_y (extents->y_bearing); 559 extents->y_bearing = font->em_scale_y (extents->y_bearing);
463 extents->width = font->em_scale_x (extents->width); 560 extents->width = font->em_scale_x (extents->width);
464 extents->height = font->em_scale_y (extents->height); 561 extents->height = font->em_scale_y (extents->height);
465 return ret; 562 return ret;
466 } 563 }
467 564
468 static hb_bool_t 565 static hb_bool_t
469 hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, 566 hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
470 void *font_data, 567 void *font_data,
471 hb_font_extents_t *metrics, 568 hb_font_extents_t *metrics,
472 void *user_data HB_UNUSED) 569 void *user_data HB_UNUSED)
473 { 570 {
474 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; 571 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
475 metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); 572 metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender);
476 metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); 573 metrics->descender = font->em_scale_y (ot_font->h_metrics.descender);
477 metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); 574 metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap);
478 return true; 575 return ot_font->h_metrics.has_font_extents;
479 } 576 }
480 577
481 static hb_bool_t 578 static hb_bool_t
482 hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, 579 hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
483 void *font_data, 580 void *font_data,
484 hb_font_extents_t *metrics, 581 hb_font_extents_t *metrics,
485 void *user_data HB_UNUSED) 582 void *user_data HB_UNUSED)
486 { 583 {
487 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; 584 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
488 metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender); 585 metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender);
489 metrics->descender = font->em_scale_x (ot_font->v_metrics.descender); 586 metrics->descender = font->em_scale_x (ot_font->v_metrics.descender);
490 metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap); 587 metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap);
491 return true; 588 return ot_font->v_metrics.has_font_extents;
492 } 589 }
493 590
494 static hb_font_funcs_t *static_ot_funcs = NULL; 591 static hb_font_funcs_t *static_ot_funcs = NULL;
495 592
496 #ifdef HB_USE_ATEXIT 593 #ifdef HB_USE_ATEXIT
497 static 594 static
498 void free_static_ot_funcs (void) 595 void free_static_ot_funcs (void)
499 { 596 {
500 hb_font_funcs_destroy (static_ot_funcs); 597 hb_font_funcs_destroy (static_ot_funcs);
501 } 598 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 { 649 {
553 hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); 650 hb_ot_font_t *ot_font = _hb_ot_font_create (font->face);
554 if (unlikely (!ot_font)) 651 if (unlikely (!ot_font))
555 return; 652 return;
556 653
557 hb_font_set_funcs (font, 654 hb_font_set_funcs (font,
558 _hb_ot_get_font_funcs (), 655 _hb_ot_get_font_funcs (),
559 ot_font, 656 ot_font,
560 (hb_destroy_func_t) _hb_ot_font_destroy); 657 (hb_destroy_func_t) _hb_ot_font_destroy);
561 } 658 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-cbdt-table.hh ('k') | third_party/harfbuzz-ng/src/hb-ot-layout.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698