[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.
This commit is contained in:
parent
1de17bdb80
commit
3bf91bd269
|
@ -521,6 +521,17 @@ struct hb_array_t
|
|||
return arrayZ[i];
|
||||
}
|
||||
|
||||
inline hb_array_t<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<T> (arrayZ + start_offset, count);
|
||||
}
|
||||
|
||||
inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
|
||||
|
||||
const T *arrayZ;
|
||||
|
|
|
@ -417,7 +417,7 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null>
|
|||
template <typename Type, typename LenType=HBUINT16>
|
||||
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))
|
||||
|
|
|
@ -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
|
||||
hb_array_t<const LayerRecord> all_layers ((this+layersZ).arrayZ, numLayers);
|
||||
hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
|
||||
record.numLayers);
|
||||
if (count)
|
||||
{
|
||||
if (unlikely (record >= numLayers))
|
||||
hb_array_t<const LayerRecord> segment_layers = glyph_layers.sub_array (start_offset, *count);
|
||||
*count = segment_layers.len;
|
||||
for (unsigned int i = 0; i < segment_layers.len; i++)
|
||||
{
|
||||
*glyph_id = 0;
|
||||
*color_index = 0xFFFF;
|
||||
return false;
|
||||
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. */
|
||||
|
|
|
@ -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<unsigned int>(*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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue