提交 49544eb8 编写于 作者: G Garret Rieger 提交者: Behdad Esfahbod

[subset] Refactor composite glyf iteration code into an Iterator outside of the accelerator.

上级 dc6d67df
...@@ -133,6 +133,58 @@ struct glyf ...@@ -133,6 +133,58 @@ struct glyf
return size; return size;
} }
struct Iterator
{
const char *glyph_start;
const char *glyph_end;
const CompositeGlyphHeader *current;
inline bool move_to_next ()
{
if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
{
const CompositeGlyphHeader *possible =
&StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
if (!in_range (possible))
return false;
current = possible;
return true;
}
return false;
}
inline bool in_range (const CompositeGlyphHeader *composite) const
{
return (const char *) composite >= glyph_start
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
&& ((const char *) composite + composite->get_size()) <= glyph_end;
}
};
static inline bool get_iterator (const char * glyph_data,
unsigned int length,
CompositeGlyphHeader::Iterator *iterator /* OUT */)
{
if (length < GlyphHeader::static_size)
return false; /* Empty glyph; zero extents. */
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
if (glyph_header.numberOfContours < 0)
{
const CompositeGlyphHeader *possible =
&StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
iterator->glyph_start = glyph_data;
iterator->glyph_end = (const char *) glyph_data + length;
if (!iterator->in_range (possible))
return false;
iterator->current = possible;
return true;
}
return false;
}
DEFINE_SIZE_MIN (4); DEFINE_SIZE_MIN (4);
}; };
...@@ -166,69 +218,21 @@ struct glyf ...@@ -166,69 +218,21 @@ struct glyf
hb_blob_destroy (glyf_blob); hb_blob_destroy (glyf_blob);
} }
inline bool in_table (const char *offset, unsigned int len) const
{
return (offset - (const char *) glyf_table + len) <= glyf_len;
}
inline bool in_table (const CompositeGlyphHeader *header) const
{
return in_table ((const char *) header, CompositeGlyphHeader::min_size)
&& in_table ((const char *) header, header->get_size());
}
inline bool in_glyph (const CompositeGlyphHeader *header,
unsigned int start_offset,
unsigned int end_offset) const
{
do
{
unsigned int offset_in_glyf = (const char *) header - (const char*) glyf_table;
if (offset_in_glyf < start_offset
|| offset_in_glyf + header->get_size() > end_offset)
return false;
} while (next_composite (&header));
return true;
}
/* /*
* Returns true if the referenced glyph is a valid glyph and a composite glyph. * Returns true if the referenced glyph is a valid glyph and a composite glyph.
* If true is returned a pointer to the composite glyph will be written into * If true is returned a pointer to the composite glyph will be written into
* composite. * composite.
*/ */
inline bool get_composite (hb_codepoint_t glyph, const CompositeGlyphHeader ** composite /* OUT */) const inline bool get_composite (hb_codepoint_t glyph,
CompositeGlyphHeader::Iterator *composite /* OUT */) const
{ {
unsigned int start_offset, end_offset; unsigned int start_offset, end_offset;
if (!get_offsets (glyph, &start_offset, &end_offset)) if (!get_offsets (glyph, &start_offset, &end_offset))
return false; /* glyph not found */ return false; /* glyph not found */
if (end_offset - start_offset < GlyphHeader::static_size) return CompositeGlyphHeader::get_iterator ((const char*) this->glyf_table + start_offset,
return false; /* Empty glyph; zero extents. */ end_offset - start_offset,
composite);
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
if (glyph_header.numberOfContours < 0) {
const CompositeGlyphHeader *possible = &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
if (!in_table (possible)
|| !in_glyph (possible, start_offset, end_offset))
return false;
*composite = possible;
return true;
}
return false;
}
inline bool next_composite (const CompositeGlyphHeader ** next /* IN/OUT */) const
{
if ((*next)->flags & CompositeGlyphHeader::MORE_COMPONENTS)
{
const CompositeGlyphHeader *possible = &StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (**next);
if (!in_table (possible))
return false;
*next = possible;
return true;
}
return false;
} }
inline bool get_offsets (hb_codepoint_t glyph, inline bool get_offsets (hb_codepoint_t glyph,
......
...@@ -106,13 +106,13 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf, ...@@ -106,13 +106,13 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
hb_set_add (gids_to_retain, gid); hb_set_add (gids_to_retain, gid);
const OT::glyf::CompositeGlyphHeader *composite; OT::glyf::CompositeGlyphHeader::Iterator composite;
if (glyf.get_composite (gid, &composite)) if (glyf.get_composite (gid, &composite))
{ {
do do
{ {
_add_gid_and_children (glyf, (hb_codepoint_t) composite->glyphIndex, gids_to_retain); _add_gid_and_children (glyf, (hb_codepoint_t) composite.current->glyphIndex, gids_to_retain);
} while (glyf.next_composite (&composite)); } while (composite.move_to_next());
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册