diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh | 120 |
1 files changed, 98 insertions, 22 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh index dc7aa8469a..88d3850b6e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh @@ -28,6 +28,7 @@ #define HB_OT_GLYF_TABLE_HH #include "hb-open-type-private.hh" +#include "hb-ot-head-table.hh" namespace OT { @@ -42,6 +43,8 @@ namespace OT { struct loca { + friend struct glyf; + static const hb_tag_t tableTag = HB_OT_TAG_loca; inline bool sanitize (hb_sanitize_context_t *c) const @@ -50,12 +53,9 @@ struct loca return_trace (true); } - public: - union { - USHORT shortsZ[VAR]; /* Location offset divided by 2. */ - ULONG longsZ[VAR]; /* Location offset. */ - } u; - DEFINE_SIZE_ARRAY (0, u.longsZ); + protected: + UINT8 dataX[VAR]; /* Location data. */ + DEFINE_SIZE_ARRAY (0, dataX); }; @@ -78,26 +78,102 @@ struct glyf return_trace (true); } - public: - BYTE dataX[VAR]; /* Glyphs data. */ + struct GlyphHeader + { + INT16 numberOfContours; /* If the number of contours is + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ + FWORD xMin; /* Minimum x for coordinate data. */ + FWORD yMin; /* Minimum y for coordinate data. */ + FWORD xMax; /* Maximum x for coordinate data. */ + FWORD yMax; /* Maximum y for coordinate data. */ + + DEFINE_SIZE_STATIC (10); + }; + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + hb_blob_t *head_blob = Sanitizer<head>::sanitize (face->reference_table (HB_OT_TAG_head)); + const head *head_table = Sanitizer<head>::lock_instance (head_blob); + if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + { + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + hb_blob_destroy (head_blob); + return; + } + short_offset = 0 == head_table->indexToLocFormat; + hb_blob_destroy (head_blob); + + loca_blob = Sanitizer<loca>::sanitize (face->reference_table (HB_OT_TAG_loca)); + loca_table = Sanitizer<loca>::lock_instance (loca_blob); + glyf_blob = Sanitizer<glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf)); + glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob); + + num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1; + glyf_len = hb_blob_get_length (glyf_blob); + } + + inline void fini (void) + { + hb_blob_destroy (loca_blob); + hb_blob_destroy (glyf_blob); + } + + inline bool get_extents (hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (glyph >= num_glyphs)) + return false; + + unsigned int start_offset, end_offset; + if (short_offset) + { + const UINT16 *offsets = (const UINT16 *) loca_table->dataX; + start_offset = 2 * offsets[glyph]; + end_offset = 2 * offsets[glyph + 1]; + } + else + { + const UINT32 *offsets = (const UINT32 *) loca_table->dataX; + start_offset = offsets[glyph]; + end_offset = offsets[glyph + 1]; + } + + if (start_offset > end_offset || end_offset > glyf_len) + return false; + + if (end_offset - start_offset < GlyphHeader::static_size) + return true; /* Empty glyph; zero extents. */ + + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset); + + extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); + extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); + extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; + extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; + + return true; + } + + private: + bool short_offset; + unsigned int num_glyphs; + const loca *loca_table; + const glyf *glyf_table; + hb_blob_t *loca_blob; + hb_blob_t *glyf_blob; + unsigned int glyf_len; + }; + + protected: + UINT8 dataX[VAR]; /* Glyphs data. */ DEFINE_SIZE_ARRAY (0, dataX); }; -struct glyfGlyphHeader -{ - SHORT numberOfContours; /* If the number of contours is - * greater than or equal to zero, - * this is a simple glyph; if negative, - * this is a composite glyph. */ - FWORD xMin; /* Minimum x for coordinate data. */ - FWORD yMin; /* Minimum y for coordinate data. */ - FWORD xMax; /* Maximum x for coordinate data. */ - FWORD yMax; /* Maximum y for coordinate data. */ - - DEFINE_SIZE_STATIC (10); -}; - } /* namespace OT */ |