[subset-cff2] Faster instancing

Instantiate blends during parsing. Dedups code as well.
This commit is contained in:
Behdad Esfahbod 2023-01-06 11:39:13 -07:00
parent 3757baab2c
commit 4867e0b192
2 changed files with 8 additions and 41 deletions

View File

@ -163,15 +163,14 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs>
return v;
}
protected:
public:
const int *coords;
unsigned int num_coords;
protected:
const CFF2VariationStore *varStore;
unsigned int region_count;
unsigned int ivs;
public:
hb_vector_t<float> scalars;
protected:
bool do_blend;
bool seen_vsindex_;
bool seen_blend;
@ -224,7 +223,10 @@ struct cff2_cs_opset_t : cs_opset_t<ELEM, OPSET, cff2_cs_interp_env_t<ELEM>, PAR
const hb_array_t<const ELEM> blends,
unsigned n, unsigned i)
{
arg.set_blends (n, i, blends);
if (env.num_coords)
arg.set_int (round (arg.to_real () + env.blend_deltas (blends)));
else
arg.set_blends (n, i, blends);
}
template <typename T = ELEM,
hb_enable_if (!hb_is_same (T, blend_arg_t))>
@ -233,7 +235,7 @@ struct cff2_cs_opset_t : cs_opset_t<ELEM, OPSET, cff2_cs_interp_env_t<ELEM>, PAR
const hb_array_t<const ELEM> blends,
unsigned n, unsigned i)
{
arg.set_real (arg.to_real () + env.blend_deltas (blends));
arg.set_int (round (arg.to_real () + env.blend_deltas (blends)));
}
static void process_blend (cff2_cs_interp_env_t<ELEM> &env, PARAM& param)

View File

@ -122,43 +122,8 @@ struct cff2_cs_opset_flatten_t : cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatte
SUPER::flush_args (env, param);
}
static double instantiate_blend (const blend_arg_t &arg, cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
{
double v = arg.to_real ();
auto &scalars = env.scalars;
auto &deltas = arg.deltas;
if (scalars.length != deltas.length)
return v;
unsigned count = scalars.length;
for (unsigned i = 0; i < count; i++)
v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real ();
return v;
}
static void flatten_blends (const blend_arg_t &arg, unsigned int i, cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
{
if (param.plan->normalized_coords)
{
str_encoder_t encoder (param.flatStr);
for (unsigned int j = 0; j < arg.numValues; j++)
{
blend_arg_t arg1 = env.argStack[i + j];
if (unlikely (!((arg1.blending () && (arg.numValues == arg1.numValues) && (arg1.valueIndex == j) &&
(arg1.deltas.length == env.get_region_count ())))))
{
env.set_error ();
return;
}
arg1.set_int (round (instantiate_blend (arg1, env, param)));
encoder.encode_num (arg1);
}
return;
}
/* flatten the default values */
str_encoder_t encoder (param.flatStr);
for (unsigned int j = 0; j < arg.numValues; j++)
@ -276,7 +241,7 @@ struct cff2_subset_plan {
drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE ||
plan->normalized_coords;
plan->normalized_coords; // For instancing we need this path
if (desubroutinize)
{