[instance] minor optimizations to glyf instancing

This commit is contained in:
Qunxin Liu 2022-09-20 13:14:26 -07:00 committed by Garret Rieger
parent d5fc4a73c0
commit e94fe2adf3
3 changed files with 38 additions and 23 deletions

View File

@ -150,7 +150,8 @@ struct Glyph
hb_bytes_t &dest_end /* OUT */)
{
contour_point_vector_t all_points, deltas;
get_points (font, glyf, all_points, &deltas, false, false);
if (!get_points (font, glyf, all_points, &deltas, false, false))
return false;
// .notdef, set type to empty so we only update metrics and don't compile bytes for
// it
@ -179,7 +180,12 @@ struct Glyph
break;
}
return compile_header_bytes (plan, all_points, dest_start);
if (!compile_header_bytes (plan, all_points, dest_start))
{
dest_end.fini ();
return false;
}
return true;
}
@ -247,8 +253,7 @@ struct Glyph
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
{
if (unlikely (!deltas->resize (points.length))) return false;
for (unsigned i = 0 ; i < points.length; i++)
deltas->arrayZ[i] = points.arrayZ[i];
deltas->copy_vector (points);
}
#ifndef HB_NO_VAR

View File

@ -271,31 +271,29 @@ struct SimpleGlyph
}
//convert absolute values to relative values
unsigned num_points = all_points.length - 4;
hb_vector_t<hb_pair_t<int, int>> deltas;
deltas.resize (num_points);
for (unsigned i = 0; i < num_points; i++)
{
deltas[i].first = i == 0 ? roundf (all_points[i].x) : roundf (all_points[i].x) - roundf (all_points[i-1].x);
deltas[i].second = i == 0 ? roundf (all_points[i].y) : roundf (all_points[i].y) - roundf (all_points[i-1].y);
}
hb_vector_t<uint8_t> flags, x_coords, y_coords;
flags.alloc (num_points);
x_coords.alloc (2*num_points);
y_coords.alloc (2*num_points);
if (unlikely (!flags.alloc (num_points))) return false;
if (unlikely (!x_coords.alloc (2*num_points))) return false;
if (unlikely (!y_coords.alloc (2*num_points))) return false;
uint8_t lastflag = 0, repeat = 0;
int prev_x = 0.f, prev_y = 0.f;
for (unsigned i = 0; i < num_points; i++)
{
uint8_t flag = all_points[i].flag;
flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
encode_coord (deltas[i].first, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
encode_coord (deltas[i].second, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
float cur_x = roundf (all_points[i].x);
float cur_y = roundf (all_points[i].y);
encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point
encode_flag (flag, repeat, lastflag, flags);
prev_x = cur_x;
prev_y = cur_y;
}
unsigned len_before_instrs = 2 * header.numberOfContours + 2;

View File

@ -75,7 +75,10 @@ struct glyf
_populate_subset_glyphs (c->plan, &glyphs);
if (!c->plan->pinned_at_default)
_compile_subset_glyphs_with_deltas (c->plan, &glyphs);
{
if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs))
return_trace (false);
}
auto padded_offsets =
+ hb_iter (glyphs)
@ -107,7 +110,7 @@ struct glyf
_populate_subset_glyphs (const hb_subset_plan_t *plan,
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
void
bool
_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
@ -404,15 +407,17 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
;
}
inline void
inline bool
glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
{
OT::glyf_accelerator_t glyf (plan->source);
hb_font_t *font = hb_font_create (plan->source);
if (unlikely (!font)) return false;
hb_vector_t<hb_variation_t> vars;
vars.alloc (plan->user_axes_location->get_population ());
if (unlikely (!vars.alloc (plan->user_axes_location->get_population ())))
return false;
for (auto _ : *plan->user_axes_location)
{
@ -424,9 +429,16 @@ glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
for (auto& subset_glyph : *glyphs)
const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf);
{
if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf))
{
hb_font_destroy (font);
return false;
}
}
hb_font_destroy (font);
return true;
}