[subset/cff] Support instancing
This commit is contained in:
parent
5153218b41
commit
c632a164b9
|
@ -38,7 +38,8 @@ typedef biased_subrs_t<CFF1Subrs> cff1_biased_subrs_t;
|
||||||
struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
|
struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
|
||||||
{
|
{
|
||||||
template <typename ACC>
|
template <typename ACC>
|
||||||
cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd)
|
cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd,
|
||||||
|
const int *coords_=nullptr, unsigned int num_coords_=0)
|
||||||
: SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
|
: SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
|
||||||
{
|
{
|
||||||
processed_width = false;
|
processed_width = false;
|
||||||
|
|
|
@ -169,7 +169,9 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs>
|
||||||
const CFF2VariationStore *varStore;
|
const CFF2VariationStore *varStore;
|
||||||
unsigned int region_count;
|
unsigned int region_count;
|
||||||
unsigned int ivs;
|
unsigned int ivs;
|
||||||
|
public:
|
||||||
hb_vector_t<float> scalars;
|
hb_vector_t<float> scalars;
|
||||||
|
protected:
|
||||||
bool do_blend;
|
bool do_blend;
|
||||||
bool seen_vsindex_;
|
bool seen_vsindex_;
|
||||||
bool seen_blend;
|
bool seen_blend;
|
||||||
|
|
|
@ -223,6 +223,7 @@ struct flatten_param_t
|
||||||
{
|
{
|
||||||
str_buff_t &flatStr;
|
str_buff_t &flatStr;
|
||||||
bool drop_hints;
|
bool drop_hints;
|
||||||
|
const hb_subset_plan_t *plan;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ACC, typename ENV, typename OPSET, op_code_t endchar_op=OpCode_Invalid>
|
template <typename ACC, typename ENV, typename OPSET, op_code_t endchar_op=OpCode_Invalid>
|
||||||
|
@ -250,11 +251,15 @@ struct subr_flattener_t
|
||||||
unsigned int fd = acc.fdSelect->get_fd (glyph);
|
unsigned int fd = acc.fdSelect->get_fd (glyph);
|
||||||
if (unlikely (fd >= acc.fdCount))
|
if (unlikely (fd >= acc.fdCount))
|
||||||
return false;
|
return false;
|
||||||
ENV env (str, acc, fd);
|
|
||||||
|
|
||||||
|
ENV env (str, acc, fd,
|
||||||
|
plan->normalized_coords.arrayZ, plan->normalized_coords.length);
|
||||||
cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env);
|
cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env);
|
||||||
flatten_param_t param = {
|
flatten_param_t param = {
|
||||||
flat_charstrings.arrayZ[i],
|
flat_charstrings.arrayZ[i],
|
||||||
(bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
(bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING),
|
||||||
|
plan
|
||||||
};
|
};
|
||||||
if (unlikely (!interp.interpret (param)))
|
if (unlikely (!interp.interpret (param)))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -122,8 +122,43 @@ struct cff2_cs_opset_flatten_t : cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatte
|
||||||
SUPER::flush_args (env, param);
|
SUPER::flush_args (env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double instantiate_blends (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)
|
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->pinned_at_default)
|
||||||
|
{
|
||||||
|
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_real (instantiate_blends (arg1, env, param));
|
||||||
|
encoder.encode_num (arg1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* flatten the default values */
|
/* flatten the default values */
|
||||||
str_encoder_t encoder (param.flatStr);
|
str_encoder_t encoder (param.flatStr);
|
||||||
for (unsigned int j = 0; j < arg.numValues; j++)
|
for (unsigned int j = 0; j < arg.numValues; j++)
|
||||||
|
@ -240,7 +275,8 @@ struct cff2_subset_plan {
|
||||||
orig_fdcount = acc.fdArray->count;
|
orig_fdcount = acc.fdArray->count;
|
||||||
|
|
||||||
drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
|
drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
|
||||||
desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE;
|
desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE ||
|
||||||
|
!plan->pinned_at_default;
|
||||||
|
|
||||||
if (desubroutinize)
|
if (desubroutinize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -769,6 +769,7 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hb_array_t<const OT::AxisRecord> axes = face->table.fvar->get_axes ();
|
hb_array_t<const OT::AxisRecord> axes = face->table.fvar->get_axes ();
|
||||||
|
plan->normalized_coords.resize (axes.length);
|
||||||
|
|
||||||
bool has_avar = face->table.avar->has_data ();
|
bool has_avar = face->table.avar->has_data ();
|
||||||
const OT::SegmentMaps *seg_maps = nullptr;
|
const OT::SegmentMaps *seg_maps = nullptr;
|
||||||
|
@ -777,6 +778,7 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
|
||||||
|
|
||||||
bool axis_not_pinned = false;
|
bool axis_not_pinned = false;
|
||||||
unsigned old_axis_idx = 0, new_axis_idx = 0;
|
unsigned old_axis_idx = 0, new_axis_idx = 0;
|
||||||
|
unsigned int i;
|
||||||
for (const auto& axis : axes)
|
for (const auto& axis : axes)
|
||||||
{
|
{
|
||||||
hb_tag_t axis_tag = axis.get_axis_tag ();
|
hb_tag_t axis_tag = axis.get_axis_tag ();
|
||||||
|
@ -798,11 +800,15 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
|
||||||
plan->axes_location->set (axis_tag, normalized_v);
|
plan->axes_location->set (axis_tag, normalized_v);
|
||||||
if (normalized_v != 0)
|
if (normalized_v != 0)
|
||||||
plan->pinned_at_default = false;
|
plan->pinned_at_default = false;
|
||||||
|
|
||||||
|
plan->normalized_coords[i] = normalized_v;
|
||||||
}
|
}
|
||||||
if (has_avar)
|
if (has_avar)
|
||||||
seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
|
seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
|
||||||
|
|
||||||
old_axis_idx++;
|
old_axis_idx++;
|
||||||
|
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
plan->all_axes_pinned = !axis_not_pinned;
|
plan->all_axes_pinned = !axis_not_pinned;
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,6 +190,7 @@ struct hb_subset_plan_t
|
||||||
hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>>* sanitized_table_cache;
|
hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>>* sanitized_table_cache;
|
||||||
//normalized axes location map
|
//normalized axes location map
|
||||||
hb_hashmap_t<hb_tag_t, int> *axes_location;
|
hb_hashmap_t<hb_tag_t, int> *axes_location;
|
||||||
|
hb_vector_t<int> normalized_coords;
|
||||||
//user specified axes location map
|
//user specified axes location map
|
||||||
hb_hashmap_t<hb_tag_t, float> *user_axes_location;
|
hb_hashmap_t<hb_tag_t, float> *user_axes_location;
|
||||||
//retained old axis index -> new axis index mapping in fvar axis array
|
//retained old axis index -> new axis index mapping in fvar axis array
|
||||||
|
|
Loading…
Reference in New Issue