fix composite glyf extents

This commit is contained in:
Michiharu Ariza 2019-03-17 22:49:18 -07:00
parent 597ad4df0c
commit b6cc838888
2 changed files with 29 additions and 13 deletions

View File

@ -487,14 +487,15 @@ struct glyf
/* Note: Recursively calls itself. Who's checking recursively nested composite glyph BTW? */ /* Note: Recursively calls itself. Who's checking recursively nested composite glyph BTW? */
bool get_var_metrics (hb_codepoint_t glyph, bool get_var_metrics (hb_codepoint_t glyph,
const int *coords, unsigned int coord_count, const int *coords, unsigned int coord_count,
hb_vector_t<contour_point_t> &phantoms /* OUT */) const hb_array_t<contour_point_t> phantoms /* OUT */) const
{ {
hb_vector_t<contour_point_t> points; hb_vector_t<contour_point_t> points;
hb_vector_t<unsigned int> end_points; hb_vector_t<unsigned int> end_points;
if (unlikely (!get_contour_points (glyph, points, end_points, true/*phantom_only*/))) return false; if (unlikely (!get_contour_points (glyph, points, end_points, true/*phantom_only*/))) return false;
hb_array_t<contour_point_t> phantoms_array = points.sub_array (points.length-PHANTOM_COUNT, PHANTOM_COUNT); hb_array_t<contour_point_t> phantoms_array = points.sub_array (points.length-PHANTOM_COUNT, PHANTOM_COUNT);
init_phantom_points (glyph, phantoms_array); init_phantom_points (glyph, phantoms_array);
if (unlikely (!gvar_accel.apply_deltas_to_points (glyph, coords, coord_count, points.as_array (), end_points.as_array ()))) return false; if (unlikely (!gvar_accel.apply_deltas_to_points (glyph, coords, coord_count,
points.as_array (), end_points.as_array ()))) return false;
for (unsigned int i = 0; i < PHANTOM_COUNT; i++) for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
phantoms[i] = points[points.length - PHANTOM_COUNT + i]; phantoms[i] = points[points.length - PHANTOM_COUNT + i];
@ -505,7 +506,8 @@ struct glyf
{ {
if (composite.current->flags & CompositeGlyphHeader::USE_MY_METRICS) if (composite.current->flags & CompositeGlyphHeader::USE_MY_METRICS)
{ {
if (unlikely (!get_var_metrics (composite.current->glyphIndex, coords, coord_count, phantoms))) return false; if (unlikely (!get_var_metrics (composite.current->glyphIndex, coords, coord_count,
phantoms.sub_array (0, 2)))) return false;
for (unsigned int j = 0; j < phantoms.length; j++) for (unsigned int j = 0; j < phantoms.length; j++)
composite.current->transform_point (phantoms[j].x, phantoms[j].y); composite.current->transform_point (phantoms[j].x, phantoms[j].y);
} }
@ -525,6 +527,8 @@ struct glyf
max.y = MAX (max.y, p.y); max.y = MAX (max.y, p.y);
} }
void offset (const contour_point_t &p) { min.offset (p); max.offset (p); }
void merge (const contour_bounds_t &b) void merge (const contour_bounds_t &b)
{ {
if (empty ()) { *this = b; return; } if (empty ()) { *this = b; return; }
@ -550,24 +554,33 @@ struct glyf
init_phantom_points (glyph, phantoms_array); init_phantom_points (glyph, phantoms_array);
if (unlikely (!gvar_accel.apply_deltas_to_points (glyph, coords, coord_count, points.as_array (), end_points.as_array ()))) return false; if (unlikely (!gvar_accel.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; CompositeGlyphHeader::Iterator composite;
if (!get_composite (glyph, &composite)) if (!get_composite (glyph, &composite))
{ {
/* simple glyph */ /* simple glyph */
for (unsigned int i = 0; i + PHANTOM_COUNT < points.length; i++) for (unsigned int i = 0; i + PHANTOM_COUNT < points.length; i++)
bounds.add (points[i]); /* TODO: need to check ON_CURVE or flatten? */ bounds.add (points[i]); /* TODO: need to check ON_CURVE or flatten? */
return true;
} }
else
{
/* composite glyph */ /* composite glyph */
do do
{ {
contour_bounds_t comp_bounds; contour_bounds_t comp_bounds;
if (unlikely (!get_bounds_var (composite.current->glyphIndex, coords, coord_count, comp_bounds))) return false; if (unlikely (!get_bounds_var (composite.current->glyphIndex, coords, coord_count, comp_bounds))) return false;
/* Apply offset & scaling */
composite.current->transform_point (comp_bounds.min.x, comp_bounds.min.y); composite.current->transform_point (comp_bounds.min.x, comp_bounds.min.y);
composite.current->transform_point (comp_bounds.max.x, comp_bounds.max.y); composite.current->transform_point (comp_bounds.max.x, comp_bounds.max.y);
/* Apply offset adjustments from gvar */
comp_bounds.offset (points[comp_index]);
bounds.merge (comp_bounds); bounds.merge (comp_bounds);
comp_index++;
} while (composite.move_to_next()); } while (composite.move_to_next());
}
/* Shift bounds by the updated left side bearing (vertically too?) */ /* Shift bounds by the updated left side bearing (vertically too?) */
{ {
@ -779,7 +792,7 @@ struct glyf
hb_vector_t<contour_point_t> phantoms; hb_vector_t<contour_point_t> phantoms;
phantoms.resize (PHANTOM_COUNT); phantoms.resize (PHANTOM_COUNT);
if (unlikely (!get_var_metrics (glyph, coords, coord_count, phantoms))) return advance; if (unlikely (!get_var_metrics (glyph, coords, coord_count, phantoms.as_array ()))) return advance;
if (vertical) if (vertical)
return -(phantoms[PHANTOM_BOTTOM].y - phantoms[PHANTOM_TOP].y); // is this sign correct? return -(phantoms[PHANTOM_BOTTOM].y - phantoms[PHANTOM_TOP].y); // is this sign correct?

View File

@ -44,6 +44,9 @@ namespace OT {
struct contour_point_t struct contour_point_t
{ {
void init () { flag = 0; x = y = 0.0f; } void init () { flag = 0; x = y = 0.0f; }
void offset (const contour_point_t &p) { x += p.x; y += p.y; }
uint8_t flag; uint8_t flag;
float x, y; float x, y;
}; };