| Index: third_party/harfbuzz-ng/src/hb-ot-font.cc
|
| diff --git a/third_party/harfbuzz-ng/src/hb-ot-font.cc b/third_party/harfbuzz-ng/src/hb-ot-font.cc
|
| index 0b7e31b2d3459c2ac72298f151c2f215b438500d..df01bc9fabbc4ab0c4e912cf135d4890e8f03bdc 100644
|
| --- a/third_party/harfbuzz-ng/src/hb-ot-font.cc
|
| +++ b/third_party/harfbuzz-ng/src/hb-ot-font.cc
|
| @@ -31,6 +31,7 @@
|
| #include "hb-font-private.hh"
|
|
|
| #include "hb-ot-cmap-table.hh"
|
| +#include "hb-ot-cbdt-table.hh"
|
| #include "hb-ot-glyf-table.hh"
|
| #include "hb-ot-head-table.hh"
|
| #include "hb-ot-hhea-table.hh"
|
| @@ -47,6 +48,7 @@ struct hb_ot_face_metrics_accelerator_t
|
| unsigned short ascender;
|
| unsigned short descender;
|
| unsigned short line_gap;
|
| + bool has_font_extents;
|
|
|
| const OT::_mtx *table;
|
| hb_blob_t *blob;
|
| @@ -54,9 +56,10 @@ struct hb_ot_face_metrics_accelerator_t
|
| inline void init (hb_face_t *face,
|
| hb_tag_t _hea_tag,
|
| hb_tag_t _mtx_tag,
|
| - hb_tag_t os2_tag)
|
| + hb_tag_t os2_tag,
|
| + unsigned int default_advance = 0)
|
| {
|
| - this->default_advance = face->get_upem ();
|
| + this->default_advance = default_advance ? default_advance : face->get_upem ();
|
|
|
| bool got_font_extents = false;
|
| if (os2_tag)
|
| @@ -82,9 +85,12 @@ struct hb_ot_face_metrics_accelerator_t
|
| this->ascender = _hea->ascender;
|
| this->descender = _hea->descender;
|
| this->line_gap = _hea->lineGap;
|
| + got_font_extents = (this->ascender | this->descender) != 0;
|
| }
|
| hb_blob_destroy (_hea_blob);
|
|
|
| + this->has_font_extents = got_font_extents;
|
| +
|
| this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag));
|
|
|
| /* Cap num_metrics() and num_advances() based on table length. */
|
| @@ -202,6 +208,91 @@ struct hb_ot_face_glyf_accelerator_t
|
| }
|
| };
|
|
|
| +struct hb_ot_face_cbdt_accelerator_t
|
| +{
|
| + hb_blob_t *cblc_blob;
|
| + hb_blob_t *cbdt_blob;
|
| + const OT::CBLC *cblc;
|
| + const OT::CBDT *cbdt;
|
| +
|
| + unsigned int cbdt_len;
|
| + float upem;
|
| +
|
| + inline void init (hb_face_t *face)
|
| + {
|
| + upem = face->get_upem();
|
| +
|
| + cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC));
|
| + cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
|
| + cbdt_len = hb_blob_get_length (cbdt_blob);
|
| +
|
| + if (hb_blob_get_length (cblc_blob) == 0) {
|
| + cblc = NULL;
|
| + cbdt = NULL;
|
| + return; /* Not a bitmap font. */
|
| + }
|
| + cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob);
|
| + cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob);
|
| +
|
| + }
|
| +
|
| + inline void fini (void)
|
| + {
|
| + hb_blob_destroy (this->cblc_blob);
|
| + hb_blob_destroy (this->cbdt_blob);
|
| + }
|
| +
|
| + inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
|
| + {
|
| + unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */
|
| +
|
| + if (cblc == NULL)
|
| + return false; // Not a color bitmap font.
|
| +
|
| + const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
|
| + if (subtable_record == NULL)
|
| + return false;
|
| +
|
| + if (subtable_record->get_extents (extents))
|
| + return true;
|
| +
|
| + unsigned int image_offset = 0, image_length = 0, image_format = 0;
|
| + if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
|
| + return false;
|
| +
|
| + {
|
| + /* TODO Move the following into CBDT struct when adding more formats. */
|
| +
|
| + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
|
| + return false;
|
| +
|
| + switch (image_format)
|
| + {
|
| + case 17: {
|
| + if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size))
|
| + return false;
|
| +
|
| + const OT::GlyphBitmapDataFormat17& glyphFormat17 =
|
| + OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset);
|
| + glyphFormat17.glyphMetrics.get_extents (extents);
|
| + }
|
| + break;
|
| + default:
|
| + // TODO: Support other image formats.
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + /* Convert to the font units. */
|
| + extents->x_bearing *= upem / (float) x_ppem;
|
| + extents->y_bearing *= upem / (float) y_ppem;
|
| + extents->width *= upem / (float) x_ppem;
|
| + extents->height *= upem / (float) y_ppem;
|
| +
|
| + return true;
|
| + }
|
| +};
|
| +
|
| typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
|
| hb_codepoint_t codepoint,
|
| hb_codepoint_t *glyph);
|
| @@ -374,6 +465,7 @@ struct hb_ot_font_t
|
| hb_ot_face_metrics_accelerator_t h_metrics;
|
| hb_ot_face_metrics_accelerator_t v_metrics;
|
| hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
|
| + hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
|
| };
|
|
|
|
|
| @@ -387,8 +479,10 @@ _hb_ot_font_create (hb_face_t *face)
|
|
|
| ot_font->cmap.init (face);
|
| ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2);
|
| - ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE); /* TODO Can we do this lazily? */
|
| + ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE,
|
| + ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
|
| ot_font->glyf.init (face);
|
| + ot_font->cbdt.init (face);
|
|
|
| return ot_font;
|
| }
|
| @@ -400,6 +494,7 @@ _hb_ot_font_destroy (hb_ot_font_t *ot_font)
|
| ot_font->h_metrics.fini ();
|
| ot_font->v_metrics.fini ();
|
| ot_font->glyf.fini ();
|
| + ot_font->cbdt.fini ();
|
|
|
| free (ot_font);
|
| }
|
| @@ -458,6 +553,8 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
|
| {
|
| const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
| bool ret = ot_font->glyf->get_extents (glyph, extents);
|
| + if (!ret)
|
| + ret = ot_font->cbdt->get_extents (glyph, extents);
|
| extents->x_bearing = font->em_scale_x (extents->x_bearing);
|
| extents->y_bearing = font->em_scale_y (extents->y_bearing);
|
| extents->width = font->em_scale_x (extents->width);
|
| @@ -475,7 +572,7 @@ hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
|
| metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender);
|
| metrics->descender = font->em_scale_y (ot_font->h_metrics.descender);
|
| metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap);
|
| - return true;
|
| + return ot_font->h_metrics.has_font_extents;
|
| }
|
|
|
| static hb_bool_t
|
| @@ -488,7 +585,7 @@ hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
|
| metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender);
|
| metrics->descender = font->em_scale_x (ot_font->v_metrics.descender);
|
| metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap);
|
| - return true;
|
| + return ot_font->v_metrics.has_font_extents;
|
| }
|
|
|
| static hb_font_funcs_t *static_ot_funcs = NULL;
|
|
|