[subset] Implement for ClassDef

This commit is contained in:
Behdad Esfahbod 2018-12-13 17:48:42 -05:00
parent 6e33a3955d
commit 705e2f5056
2 changed files with 84 additions and 4 deletions

View File

@ -1190,6 +1190,11 @@ struct Coverage
* Class Definition Table
*/
static inline void ClassDef_serialize (hb_serialize_context_t *c,
Supplier<GlyphID> &glyphs,
Supplier<HBUINT16> &klasses,
unsigned int num_glyphs);
struct ClassDefFormat1
{
friend struct ClassDef;
@ -1233,6 +1238,27 @@ struct ClassDefFormat1
return_trace (true);
}
inline bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_vector_t<GlyphID> glyphs;
hb_codepoint_t first_glyph = startGlyph;
unsigned int count = classValue.len;
glyphs.resize (count);
for (unsigned i = 0; i < count; i++)
glyphs[i].set (glyph_map[first_glyph + i]);
c->serializer->err (glyphs.in_error ());
Supplier<GlyphID> glyphs_supplier (glyphs);
Supplier<HBUINT16> klasses_supplier (classValue.as_array ());
ClassDef_serialize (c->serializer,
glyphs_supplier,
klasses_supplier,
glyphs.len);
return_trace (glyphs.len);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -1356,6 +1382,39 @@ struct ClassDefFormat2
return_trace (true);
}
inline bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset;
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_vector_t<GlyphID> glyphs;
hb_vector_t<GlyphID> klasses;
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
{
unsigned int value = rangeRecord[i].value;
if (!value) continue;
hb_codepoint_t start = rangeRecord[i].start;
hb_codepoint_t end = rangeRecord[i].end + 1;
for (hb_codepoint_t g = start; g < end; g++)
{
if (!glyphset.has (g)) continue;
glyphs.push ()->set (glyph_map[g]);
klasses.push ()->set (value);
}
}
c->serializer->err (glyphs.in_error () || klasses.in_error ());
Supplier<GlyphID> glyphs_supplier (glyphs);
Supplier<GlyphID> klasses_supplier (klasses);
ClassDef_serialize (c->serializer,
glyphs_supplier,
klasses_supplier,
glyphs.len);
return_trace (glyphs.len);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -1469,6 +1528,16 @@ struct ClassDef
}
}
inline bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
switch (u.format) {
case 1: return_trace (u.format1.subset (c));
case 2: return_trace (u.format2.subset (c));
default:return_trace (false);
}
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -1527,6 +1596,17 @@ struct ClassDef
DEFINE_SIZE_UNION (2, format);
};
static inline void ClassDef_serialize (hb_serialize_context_t *c,
Supplier<GlyphID> &glyphs,
Supplier<HBUINT16> &klasses,
unsigned int num_glyphs)
{
c->start_embed<ClassDef> ()->serialize (c,
glyphs,
klasses,
num_glyphs);
}
/*
* Item Variation Store

View File

@ -110,14 +110,14 @@ struct SingleSubstFormat1
inline bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset;
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_vector_t<GlyphID> from;
hb_vector_t<GlyphID> to;
hb_codepoint_t delta = deltaGlyphID;
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
{
if (!c->plan->glyphset->has (iter.get_glyph ()))
continue;
if (!glyphset.has (iter.get_glyph ())) continue;
from.push ()->set (glyph_map[iter.get_glyph ()]);
to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]);
}
@ -217,13 +217,13 @@ struct SingleSubstFormat2
inline bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset;
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_vector_t<GlyphID> from;
hb_vector_t<GlyphID> to;
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
{
if (!c->plan->glyphset->has (iter.get_glyph ()))
continue;
if (!glyphset.has (iter.get_glyph ())) continue;
from.push ()->set (glyph_map[iter.get_glyph ()]);
to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]);
}