From 3bf91bd2690cda34a7687ed5465dc4bb0672f2b6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Oct 2018 12:40:38 -0700 Subject: [PATCH] [color] Rewrite colr access COLR table has one function: return layers for a glyph, and we expose exactly that, so should just wire it through. Also use sub_array() for verifiable safety. Also, BaseGlyphRecord's null object is enough. We don't need to special-case the not-found. --- src/hb-dsalgs.hh | 11 ++++++++ src/hb-open-type.hh | 2 +- src/hb-ot-color-colr-table.hh | 53 ++++++++++++++++++----------------- src/hb-ot-color.cc | 19 +------------ 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index eb15c089e..7e1b7eb1b 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -521,6 +521,17 @@ struct hb_array_t return arrayZ[i]; } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + { + unsigned int count = len; + if (unlikely (start_offset > count)) + count = 0; + else + count -= start_offset; + count = MIN (count, seg_count); + return hb_array_t (arrayZ + start_offset, count); + } + inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } const T *arrayZ; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 08e72064a..be0d8b016 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -417,7 +417,7 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf template struct ArrayOf { - const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const + inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const { unsigned int count = len; if (unlikely (start_offset > count)) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index acad25720..7c5c35d8c 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -98,35 +98,27 @@ struct COLR inline bool has_data (void) const { return numBaseGlyphs; } - inline bool get_base_glyph_record (hb_codepoint_t glyph_id, - unsigned int *first_layer /* OUT */, - unsigned int *num_layers /* OUT */) const + inline unsigned int get_glyph_layers (hb_codepoint_t glyph, + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const { - const BaseGlyphRecord* record; - record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs, - sizeof (BaseGlyphRecord), BaseGlyphRecord::cmp); - if (unlikely (!record)) - return false; + const BaseGlyphRecord &record = get_glyph_record (glyph); - if (first_layer) *first_layer = record->firstLayerIdx; - if (num_layers) *num_layers = record->numLayers; - return true; - } - - inline bool get_layer_record (unsigned int record, - hb_codepoint_t *glyph_id /* OUT */, - unsigned int *color_index /* OUT */) const - { - if (unlikely (record >= numLayers)) + hb_array_t all_layers ((this+layersZ).arrayZ, numLayers); + hb_array_t glyph_layers = all_layers.sub_array (record.firstLayerIdx, + record.numLayers); + if (count) { - *glyph_id = 0; - *color_index = 0xFFFF; - return false; + hb_array_t segment_layers = glyph_layers.sub_array (start_offset, *count); + *count = segment_layers.len; + for (unsigned int i = 0; i < segment_layers.len; i++) + { + layers[i].glyph = segment_layers.arrayZ[i].glyphId; + layers[i].color_index = segment_layers.arrayZ[i].colorIdx; + } } - const LayerRecord &layer = (this+layersZ)[record]; - if (glyph_id) *glyph_id = layer.glyphId; - if (color_index) *color_index = layer.colorIdx; - return true; + return glyph_layers.len; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -137,6 +129,17 @@ struct COLR (this+layersZ).sanitize (c, numLayers))); } + private: + inline const BaseGlyphRecord &get_glyph_record (hb_codepoint_t glyph_id) const + { + const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph_id, + &(this+baseGlyphsZ), + numBaseGlyphs, + sizeof (BaseGlyphRecord), + BaseGlyphRecord::cmp); + return rec ? *rec : Null(BaseGlyphRecord); + } + protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 2672d0a31..08d98a924 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -263,22 +263,5 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, hb_ot_color_layer_t *layers /* OUT. May be NULL. */) { const OT::COLR& colr = _get_colr (face); - unsigned int num_results = 0; - unsigned int start_layer_index, num_layers = 0; - if (colr.get_base_glyph_record (glyph, &start_layer_index, &num_layers)) - { - if (count) - { - unsigned int layer_count = MIN(*count, num_layers - start_offset); - for (unsigned int i = 0; i < layer_count; i++) - { - if (colr.get_layer_record (start_layer_index + start_offset + i, - &layers[num_results].glyph, &layers[num_results].color_index)) - ++num_results; - } - } - } - - if (likely (count)) *count = num_results; - return num_layers; + return colr.get_glyph_layers (glyph, start_offset, count, layers); }