[glyf] Push consumer machine one more level further
This commit is contained in:
parent
11f5f7c59c
commit
0f2c2d989b
|
@ -899,8 +899,10 @@ struct glyf
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_points (hb_font_t *font, hb_codepoint_t gid, contour_point_vector_t &all_points) const
|
template<typename T>
|
||||||
|
bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const
|
||||||
{
|
{
|
||||||
|
contour_point_vector_t all_points;
|
||||||
if (unlikely (!_get_points (gid, font->coords, font->num_coords, all_points) ||
|
if (unlikely (!_get_points (gid, font->coords, font->num_coords, all_points) ||
|
||||||
all_points.length < PHANTOM_COUNT)) return false;
|
all_points.length < PHANTOM_COUNT)) return false;
|
||||||
|
|
||||||
|
@ -910,36 +912,39 @@ struct glyf
|
||||||
contour_point_t delta;
|
contour_point_t delta;
|
||||||
delta.init (-all_points[all_points.length - PHANTOM_COUNT + PHANTOM_LEFT].x, 0.f);
|
delta.init (-all_points[all_points.length - PHANTOM_COUNT + PHANTOM_LEFT].x, 0.f);
|
||||||
if (delta.x) all_points.translate (delta);
|
if (delta.x) all_points.translate (delta);
|
||||||
|
|
||||||
|
for (unsigned point_index = 0; point_index + 4 < all_points.length; ++point_index)
|
||||||
|
consumer.consume_point (all_points[point_index]);
|
||||||
|
consumer.points_end ();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < PHANTOM_COUNT; ++i)
|
||||||
|
consumer.consume_phantom (all_points[all_points.length - PHANTOM_COUNT + i], i);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HB_NO_VAR
|
#ifndef HB_NO_VAR
|
||||||
bool get_var_extents_and_phantoms (hb_font_t *font, hb_codepoint_t gid,
|
struct extents_bounds_aggregator_t
|
||||||
hb_glyph_extents_t *extents /* OUT */,
|
|
||||||
contour_point_vector_t *phantoms /* OUT */) const
|
|
||||||
{
|
{
|
||||||
contour_point_vector_t all_points;
|
hb_font_t *font;
|
||||||
if (unlikely (!get_points (font, gid, all_points))) return false;
|
hb_glyph_extents_t *extents;
|
||||||
if (extents)
|
contour_point_vector_t *phantoms;
|
||||||
|
contour_bounds_t bounds;
|
||||||
|
|
||||||
|
extents_bounds_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_vector_t *phantoms_)
|
||||||
{
|
{
|
||||||
contour_bounds_t bounds;
|
font = font_;
|
||||||
for (unsigned int i = 0; i + PHANTOM_COUNT < all_points.length; i++)
|
extents = extents_;
|
||||||
bounds.add (all_points[i]);
|
phantoms = phantoms_;
|
||||||
bounds.get_extents (font, extents);
|
if (extents) bounds = contour_bounds_t ();
|
||||||
}
|
}
|
||||||
if (phantoms)
|
|
||||||
for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
|
|
||||||
(*phantoms)[i] = all_points[all_points.length - PHANTOM_COUNT + i];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get_var_metrics (hb_font_t *font, hb_codepoint_t gid,
|
void consume_point (const contour_point_t &point) { if (extents) bounds.add (point); }
|
||||||
contour_point_vector_t &phantoms) const
|
void points_end () { if (extents) bounds.get_extents (font, extents); }
|
||||||
{ return get_var_extents_and_phantoms (font, gid, nullptr, &phantoms); }
|
|
||||||
|
|
||||||
bool get_extents_var (hb_font_t *font, hb_codepoint_t gid,
|
void consume_phantom (const contour_point_t &point, unsigned i)
|
||||||
hb_glyph_extents_t *extents) const
|
{ if (phantoms) (*phantoms)[i] = point; }
|
||||||
{ return get_var_extents_and_phantoms (font, gid, extents, nullptr); }
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -952,7 +957,7 @@ struct glyf
|
||||||
phantoms.resize (PHANTOM_COUNT);
|
phantoms.resize (PHANTOM_COUNT);
|
||||||
|
|
||||||
if (likely (font->num_coords == face->table.gvar->get_axis_count ()))
|
if (likely (font->num_coords == face->table.gvar->get_axis_count ()))
|
||||||
success = get_var_metrics (font, gid, phantoms);
|
success = get_points (font, gid, extents_bounds_aggregator_t (font, nullptr, &phantoms));
|
||||||
|
|
||||||
if (unlikely (!success))
|
if (unlikely (!success))
|
||||||
return is_vertical ? face->table.vmtx->get_advance (gid) : face->table.hmtx->get_advance (gid);
|
return is_vertical ? face->table.vmtx->get_advance (gid) : face->table.hmtx->get_advance (gid);
|
||||||
|
@ -969,7 +974,7 @@ struct glyf
|
||||||
contour_point_vector_t phantoms;
|
contour_point_vector_t phantoms;
|
||||||
phantoms.resize (PHANTOM_COUNT);
|
phantoms.resize (PHANTOM_COUNT);
|
||||||
|
|
||||||
if (unlikely (!get_var_extents_and_phantoms (font, gid, &extents, &phantoms)))
|
if (unlikely (!get_points (font, gid, extents_bounds_aggregator_t (font, &extents, &phantoms))))
|
||||||
return is_vertical ? face->table.vmtx->get_side_bearing (gid) : face->table.hmtx->get_side_bearing (gid);
|
return is_vertical ? face->table.vmtx->get_side_bearing (gid) : face->table.hmtx->get_side_bearing (gid);
|
||||||
|
|
||||||
return is_vertical ? ceil (phantoms[PHANTOM_TOP].y) - extents.y_bearing : floor (phantoms[PHANTOM_LEFT].x);
|
return is_vertical ? ceil (phantoms[PHANTOM_TOP].y) - extents.y_bearing : floor (phantoms[PHANTOM_LEFT].x);
|
||||||
|
@ -982,7 +987,7 @@ struct glyf
|
||||||
unsigned int coord_count;
|
unsigned int coord_count;
|
||||||
const int *coords = hb_font_get_var_coords_normalized (font, &coord_count);
|
const int *coords = hb_font_get_var_coords_normalized (font, &coord_count);
|
||||||
if (coords && coord_count > 0 && coord_count == face->table.gvar->get_axis_count ())
|
if (coords && coord_count > 0 && coord_count == face->table.gvar->get_axis_count ())
|
||||||
return get_extents_var (font, gid, extents);
|
return get_points (font, gid, extents_bounds_aggregator_t (font, extents, nullptr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (unlikely (gid >= num_glyphs)) return false;
|
if (unlikely (gid >= num_glyphs)) return false;
|
||||||
|
@ -1095,7 +1100,7 @@ struct glyf
|
||||||
}
|
}
|
||||||
|
|
||||||
/* based on https://github.com/RazrFalcon/ttf-parser/blob/master/src/glyf.rs#L292 */
|
/* based on https://github.com/RazrFalcon/ttf-parser/blob/master/src/glyf.rs#L292 */
|
||||||
void consume_point (contour_point_t &point)
|
void consume_point (const contour_point_t &point)
|
||||||
{
|
{
|
||||||
/* Skip empty contours */
|
/* Skip empty contours */
|
||||||
if (unlikely (point.is_end_point && first_oncurve.is_null && first_offcurve.is_null))
|
if (unlikely (point.is_end_point && first_oncurve.is_null && first_offcurve.is_null))
|
||||||
|
@ -1199,19 +1204,15 @@ struct glyf
|
||||||
funcs->close_path (user_data);
|
funcs->close_path (user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void points_end () {}
|
||||||
|
|
||||||
|
void consume_phantom (const contour_point_t &point HB_UNUSED, unsigned i HB_UNUSED) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_path (hb_font_t *font, hb_codepoint_t gid,
|
get_path (hb_font_t *font, hb_codepoint_t gid,
|
||||||
const hb_draw_funcs_t *funcs, void *user_data) const
|
const hb_draw_funcs_t *funcs, void *user_data) const
|
||||||
{
|
{ return get_points (font, gid, path_builder_t (font, funcs, user_data)); }
|
||||||
path_builder_t builder (font, funcs, user_data);
|
|
||||||
contour_point_vector_t all_points;
|
|
||||||
if (unlikely (!get_points (font, gid, all_points))) return false;
|
|
||||||
for (unsigned point_index = 0; point_index < all_points.length - 4; ++point_index)
|
|
||||||
builder.consume_point (all_points[point_index]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool short_offset;
|
bool short_offset;
|
||||||
|
|
Loading…
Reference in New Issue