[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];
|
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; }
|
inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
|
||||||
|
|
||||||
const T *arrayZ;
|
const T *arrayZ;
|
||||||
|
|
|
@ -417,7 +417,7 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null>
|
||||||
template <typename Type, typename LenType=HBUINT16>
|
template <typename Type, typename LenType=HBUINT16>
|
||||||
struct ArrayOf
|
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;
|
unsigned int count = len;
|
||||||
if (unlikely (start_offset > count))
|
if (unlikely (start_offset > count))
|
||||||
|
|
|
@ -98,35 +98,27 @@ struct COLR
|
||||||
|
|
||||||
inline bool has_data (void) const { return numBaseGlyphs; }
|
inline bool has_data (void) const { return numBaseGlyphs; }
|
||||||
|
|
||||||
inline bool get_base_glyph_record (hb_codepoint_t glyph_id,
|
inline unsigned int get_glyph_layers (hb_codepoint_t glyph,
|
||||||
unsigned int *first_layer /* OUT */,
|
unsigned int start_offset,
|
||||||
unsigned int *num_layers /* OUT */) const
|
unsigned int *count, /* IN/OUT. May be NULL. */
|
||||||
|
hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const
|
||||||
{
|
{
|
||||||
const BaseGlyphRecord* record;
|
const BaseGlyphRecord &record = get_glyph_record (glyph);
|
||||||
record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs,
|
|
||||||
sizeof (BaseGlyphRecord), BaseGlyphRecord::cmp);
|
|
||||||
if (unlikely (!record))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (first_layer) *first_layer = record->firstLayerIdx;
|
hb_array_t<const LayerRecord> all_layers ((this+layersZ).arrayZ, numLayers);
|
||||||
if (num_layers) *num_layers = record->numLayers;
|
hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
|
||||||
return true;
|
record.numLayers);
|
||||||
}
|
if (count)
|
||||||
|
|
||||||
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<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;
|
layers[i].glyph = segment_layers.arrayZ[i].glyphId;
|
||||||
*color_index = 0xFFFF;
|
layers[i].color_index = segment_layers.arrayZ[i].colorIdx;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
const LayerRecord &layer = (this+layersZ)[record];
|
}
|
||||||
if (glyph_id) *glyph_id = layer.glyphId;
|
return glyph_layers.len;
|
||||||
if (color_index) *color_index = layer.colorIdx;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -137,6 +129,17 @@ struct COLR
|
||||||
(this+layersZ).sanitize (c, numLayers)));
|
(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:
|
protected:
|
||||||
HBUINT16 version; /* Table version number (starts at 0). */
|
HBUINT16 version; /* Table version number (starts at 0). */
|
||||||
HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */
|
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. */)
|
hb_ot_color_layer_t *layers /* OUT. May be NULL. */)
|
||||||
{
|
{
|
||||||
const OT::COLR& colr = _get_colr (face);
|
const OT::COLR& colr = _get_colr (face);
|
||||||
unsigned int num_results = 0;
|
return colr.get_glyph_layers (glyph, start_offset, count, layers);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue