[glyf] Rewrite composite iterator to new iterators convention
This commit is contained in:
parent
b7684fa9f4
commit
8378ab96e2
|
@ -213,19 +213,11 @@ struct glyf
|
|||
_fix_component_gids (const hb_subset_plan_t *plan,
|
||||
hb_bytes_t glyph)
|
||||
{
|
||||
OT::glyf::CompositeGlyphHeader::Iterator iterator;
|
||||
if (OT::glyf::CompositeGlyphHeader::get_iterator (&glyph,
|
||||
glyph.length,
|
||||
&iterator))
|
||||
for (auto &item : OT::glyf::get_composite_iterator (glyph))
|
||||
{
|
||||
do
|
||||
{
|
||||
hb_codepoint_t new_gid;
|
||||
if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
|
||||
&new_gid))
|
||||
continue;
|
||||
((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex = new_gid;
|
||||
} while (iterator.move_to_next ());
|
||||
hb_codepoint_t new_gid;
|
||||
if (plan->new_gid_for_old_gid (item.glyphIndex, &new_gid))
|
||||
((OT::glyf::CompositeGlyphHeader *) &item)->glyphIndex = new_gid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,18 +238,15 @@ struct glyf
|
|||
if (!glyph_header.is_composite_glyph ()) return true; // only for composites
|
||||
|
||||
/* remove WE_HAVE_INSTRUCTIONS from flags in dest */
|
||||
OT::glyf::CompositeGlyphHeader::Iterator composite_it;
|
||||
if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (&glyph, glyph.length,
|
||||
&composite_it)))
|
||||
return false;
|
||||
const OT::glyf::CompositeGlyphHeader *composite_header;
|
||||
do
|
||||
{
|
||||
composite_header = composite_it.current;
|
||||
OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&composite_header->flags);
|
||||
*flags = (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS;
|
||||
} while (composite_it.move_to_next ());
|
||||
return true;
|
||||
return
|
||||
+ OT::glyf::get_composite_iterator (glyph)
|
||||
| hb_reduce ([] (bool _, const OT::glyf::CompositeGlyphHeader &item)
|
||||
{
|
||||
OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&item.flags);
|
||||
*flags = (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS;
|
||||
return true;
|
||||
}, false)
|
||||
;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -431,60 +420,49 @@ struct glyf
|
|||
}
|
||||
|
||||
public:
|
||||
// TODO rewrite using new iterator framework if possible
|
||||
struct Iterator
|
||||
{
|
||||
const char *glyph_start;
|
||||
const char *glyph_end;
|
||||
const CompositeGlyphHeader *current;
|
||||
|
||||
bool move_to_next ()
|
||||
{
|
||||
if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
|
||||
{
|
||||
const CompositeGlyphHeader *possible =
|
||||
&StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
|
||||
if (unlikely (!in_range (possible))) return false;
|
||||
current = possible;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 bool get_iterator (const char * glyph_data,
|
||||
unsigned int length,
|
||||
CompositeGlyphHeader::Iterator *iterator /* OUT */)
|
||||
{
|
||||
const GlyphHeader &glyph_header = *hb_bytes_t (glyph_data, length).as<GlyphHeader> ();
|
||||
if (!glyph_header.has_data ()) return false; /* Empty glyph; zero extents. */
|
||||
|
||||
if (glyph_header.is_composite_glyph ())
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphHeader &>
|
||||
{
|
||||
typedef const CompositeGlyphHeader *__item_t__;
|
||||
composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : glyph (glyph_), current (current_)
|
||||
{ if (!in_range (current)) current = nullptr; }
|
||||
composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {}
|
||||
|
||||
const CompositeGlyphHeader &__item__ () const { return *current; }
|
||||
bool __more__ () const { return current; }
|
||||
void __next__ ()
|
||||
{
|
||||
if (!(current->flags & CompositeGlyphHeader::MORE_COMPONENTS)) { current = nullptr; return; }
|
||||
|
||||
const CompositeGlyphHeader *possible = &StructAfter<CompositeGlyphHeader,
|
||||
CompositeGlyphHeader> (*current);
|
||||
if (!in_range (possible)) { current = nullptr; return; }
|
||||
current = possible;
|
||||
}
|
||||
bool operator != (const composite_iter_t& o) const
|
||||
{ return glyph != o.glyph || current != o.current; }
|
||||
|
||||
bool in_range (const CompositeGlyphHeader *composite) const
|
||||
{
|
||||
return glyph.sub_array ((const char *) composite - (const char *) &glyph,
|
||||
CompositeGlyphHeader::min_size).as<CompositeGlyphHeader> () != &Null (CompositeGlyphHeader);
|
||||
}
|
||||
|
||||
private:
|
||||
hb_bytes_t glyph;
|
||||
__item_t__ current;
|
||||
};
|
||||
|
||||
static composite_iter_t get_composite_iterator (hb_bytes_t glyph)
|
||||
{
|
||||
const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
|
||||
if (!glyph_header.is_composite_glyph ()) return composite_iter_t ();
|
||||
|
||||
return composite_iter_t (glyph, &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header));
|
||||
}
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face_)
|
||||
|
@ -512,24 +490,18 @@ struct glyf
|
|||
glyf_table.destroy ();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* composite.
|
||||
*/
|
||||
bool get_composite (hb_codepoint_t glyph,
|
||||
CompositeGlyphHeader::Iterator *composite /* OUT */) const
|
||||
composite_iter_t get_composite_iter (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (unlikely (!num_glyphs))
|
||||
return false;
|
||||
return composite_iter_t ();
|
||||
|
||||
unsigned int start_offset, end_offset;
|
||||
if (!get_offsets (glyph, &start_offset, &end_offset))
|
||||
return false; /* glyph not found */
|
||||
return composite_iter_t (); /* glyph not found */
|
||||
|
||||
return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset,
|
||||
end_offset - start_offset,
|
||||
composite);
|
||||
hb_bytes_t bytes ((const char *) this->glyf_table + start_offset,
|
||||
end_offset - start_offset);
|
||||
return get_composite_iterator (bytes);
|
||||
}
|
||||
|
||||
enum simple_glyph_flag_t
|
||||
|
@ -643,36 +615,28 @@ struct glyf
|
|||
return true;
|
||||
}
|
||||
|
||||
CompositeGlyphHeader::Iterator composite;
|
||||
if (get_composite (glyph, &composite))
|
||||
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
|
||||
if (glyph_header.is_composite_glyph ())
|
||||
{
|
||||
hb_bytes_t bytes ((const char *) this->glyf_table + start_offset,
|
||||
end_offset - start_offset);
|
||||
/* For a composite glyph, add one pseudo point for each component */
|
||||
do { num_points++; } while (composite.move_to_next());
|
||||
num_points += hb_len (get_composite_iterator (bytes));
|
||||
points_.resize (num_points + PHANTOM_COUNT);
|
||||
for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
|
||||
return true;
|
||||
}
|
||||
|
||||
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
|
||||
int num_contours = glyph_header.numberOfContours;
|
||||
const HBUINT16 *end_pts = &StructAfter<HBUINT16, GlyphHeader> (glyph_header);
|
||||
|
||||
range_checker_t checker (glyf_table, start_offset, end_offset);
|
||||
num_points = 0;
|
||||
int num_contours = glyph_header.numberOfContours;
|
||||
if (glyph_header.is_simple_glyph ())
|
||||
{
|
||||
if (unlikely (!checker.in_range (&end_pts[num_contours + 1]))) return false;
|
||||
num_points = end_pts[glyph_header.numberOfContours - 1] + 1;
|
||||
}
|
||||
else if (glyph_header.is_composite_glyph ())
|
||||
{
|
||||
CompositeGlyphHeader::Iterator composite;
|
||||
if (unlikely (!get_composite (glyph, &composite))) return false;
|
||||
do
|
||||
{
|
||||
num_points++;
|
||||
} while (composite.move_to_next());
|
||||
}
|
||||
|
||||
points_.resize (num_points + PHANTOM_COUNT);
|
||||
for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
|
||||
|
@ -685,7 +649,7 @@ struct glyf
|
|||
end_points_[i] = end_pts[i];
|
||||
|
||||
/* Skip instructions */
|
||||
const HBUINT8 *p = &StructAtOffset<HBUINT8> (&end_pts[num_contours+1],
|
||||
const HBUINT8 *p = &StructAtOffset<HBUINT8> (&end_pts[num_contours + 1],
|
||||
end_pts[num_contours]);
|
||||
|
||||
/* Read flags */
|
||||
|
@ -744,40 +708,45 @@ struct glyf
|
|||
if (unlikely (!face->table.gvar->apply_deltas_to_points (glyph, coords, coord_count, points.as_array (), end_points.as_array ()))) return false;
|
||||
|
||||
unsigned int comp_index = 0;
|
||||
CompositeGlyphHeader::Iterator composite;
|
||||
if (!get_composite (glyph, &composite))
|
||||
unsigned int start_offset, end_offset;
|
||||
if (unlikely (!get_offsets (glyph, &start_offset, &end_offset))) return false;
|
||||
hb_bytes_t bytes ((const char *) this->glyf_table + start_offset,
|
||||
end_offset - start_offset);
|
||||
const GlyphHeader &glyph_header = *bytes.as<GlyphHeader> ();
|
||||
if (glyph_header.is_simple_glyph ())
|
||||
{
|
||||
/* simple glyph */
|
||||
all_points.extend (points.as_array ());
|
||||
}
|
||||
else
|
||||
else if (glyph_header.is_composite_glyph ())
|
||||
{
|
||||
/* composite glyph */
|
||||
do
|
||||
for (auto &item : get_composite_iterator (bytes))
|
||||
{
|
||||
contour_point_vector_t comp_points;
|
||||
if (unlikely (!get_points_var (composite.current->glyphIndex, coords, coord_count,
|
||||
if (unlikely (!get_points_var (item.glyphIndex, coords, coord_count,
|
||||
comp_points, depth))
|
||||
|| comp_points.length < PHANTOM_COUNT) return false;
|
||||
|| comp_points.length < PHANTOM_COUNT)
|
||||
return false;
|
||||
|
||||
/* Copy phantom points from component if USE_MY_METRICS flag set */
|
||||
if (composite.current->flags & CompositeGlyphHeader::USE_MY_METRICS)
|
||||
if (item.flags & CompositeGlyphHeader::USE_MY_METRICS)
|
||||
for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
|
||||
phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
|
||||
|
||||
/* Apply component transformation & translation */
|
||||
composite.current->transform_points (comp_points);
|
||||
item.transform_points (comp_points);
|
||||
|
||||
/* Apply translatation from gvar */
|
||||
comp_points.translate (points[comp_index]);
|
||||
|
||||
if (composite.current->is_anchored ())
|
||||
if (item.is_anchored ())
|
||||
{
|
||||
unsigned int p1, p2;
|
||||
composite.current->get_anchor_points (p1, p2);
|
||||
item.get_anchor_points (p1, p2);
|
||||
if (likely (p1 < all_points.length && p2 < comp_points.length))
|
||||
{
|
||||
contour_point_t delta;
|
||||
contour_point_t delta;
|
||||
delta.init (all_points[p1].x - comp_points[p2].x,
|
||||
all_points[p1].y - comp_points[p2].y);
|
||||
|
||||
|
@ -788,10 +757,11 @@ struct glyf
|
|||
all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
|
||||
|
||||
comp_index++;
|
||||
} while (composite.move_to_next());
|
||||
}
|
||||
|
||||
all_points.extend (phantoms);
|
||||
}
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -975,15 +945,10 @@ struct glyf
|
|||
unsigned int start = glyph.length;
|
||||
unsigned int end = glyph.length;
|
||||
unsigned int glyph_offset = &glyph - glyf_table;
|
||||
CompositeGlyphHeader::Iterator composite_it;
|
||||
if (unlikely (!CompositeGlyphHeader::get_iterator (&glyph, glyph.length,
|
||||
&composite_it)))
|
||||
return false;
|
||||
const CompositeGlyphHeader *last;
|
||||
do
|
||||
{
|
||||
last = composite_it.current;
|
||||
} while (composite_it.move_to_next ());
|
||||
const CompositeGlyphHeader *last = nullptr;
|
||||
for (auto &item : get_composite_iterator (glyph))
|
||||
last = &item;
|
||||
if (unlikely (!last)) return false;
|
||||
|
||||
if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
|
||||
start = ((char *) last - (char *) glyf_table->dataZ.arrayZ)
|
||||
|
|
|
@ -45,14 +45,8 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
|
|||
|
||||
hb_set_add (gids_to_retain, gid);
|
||||
|
||||
OT::glyf::CompositeGlyphHeader::Iterator composite;
|
||||
if (glyf.get_composite (gid, &composite))
|
||||
{
|
||||
do
|
||||
{
|
||||
_add_gid_and_children (glyf, (hb_codepoint_t) composite.current->glyphIndex, gids_to_retain);
|
||||
} while (composite.move_to_next());
|
||||
}
|
||||
for (auto &item : glyf.get_composite_iter (gid))
|
||||
_add_gid_and_children (glyf, item.glyphIndex, gids_to_retain);
|
||||
}
|
||||
|
||||
#ifndef HB_NO_SUBSET_CFF
|
||||
|
|
Loading…
Reference in New Issue