summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc107
1 files changed, 102 insertions, 5 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
index 0b7e31b2d34..df01bc9fabb 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/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;