[cff] Convert interpretation environment to use constructor

This commit is contained in:
Behdad Esfahbod 2022-05-10 16:33:37 -06:00
parent de053e2efb
commit bff78e6515
10 changed files with 58 additions and 78 deletions

View File

@ -351,13 +351,6 @@ using byte_str_array_t = hb_vector_t<hb_ubytes_t>;
template <typename ELEM, int LIMIT> template <typename ELEM, int LIMIT>
struct cff_stack_t struct cff_stack_t
{ {
void init ()
{
error = false;
count = 0;
}
void fini () {}
ELEM& operator [] (unsigned int i) ELEM& operator [] (unsigned int i)
{ {
if (unlikely (i >= count)) if (unlikely (i >= count))
@ -434,8 +427,8 @@ struct cff_stack_t
{ return hb_array_t<const ELEM> (elements).sub_array (start, length); } { return hb_array_t<const ELEM> (elements).sub_array (start, length); }
private: private:
bool error; bool error = false;
unsigned int count; unsigned int count = 0;
ELEM elements[LIMIT]; ELEM elements[LIMIT];
}; };
@ -561,14 +554,11 @@ struct parsed_values_t
template <typename ARG=number_t> template <typename ARG=number_t>
struct interp_env_t struct interp_env_t
{ {
void init (const hb_ubytes_t &str_) interp_env_t () {}
interp_env_t (const hb_ubytes_t &str_)
{ {
str_ref.reset (str_); str_ref.reset (str_);
argStack.init ();
error = false;
} }
void fini () { argStack.fini (); }
bool in_error () const bool in_error () const
{ return error || str_ref.in_error () || argStack.in_error (); } { return error || str_ref.in_error () || argStack.in_error (); }
@ -602,10 +592,10 @@ struct interp_env_t
arg_stack_t<ARG> arg_stack_t<ARG>
argStack; argStack;
protected: protected:
bool error; bool error = false;
}; };
typedef interp_env_t<> num_interp_env_t; using num_interp_env_t = interp_env_t<>;
template <typename ARG=number_t> template <typename ARG=number_t>
struct opset_t struct opset_t
@ -648,11 +638,8 @@ struct opset_t
template <typename ENV> template <typename ENV>
struct interpreter_t struct interpreter_t
{ {
~interpreter_t() { fini (); } interpreter_t (ENV& env_) : env (env_) {}
ENV& env;
void fini () { env.fini (); }
ENV env;
}; };
} /* namespace CFF */ } /* namespace CFF */

View File

@ -112,10 +112,9 @@ struct point_t
template <typename ARG, typename SUBRS> template <typename ARG, typename SUBRS>
struct cs_interp_env_t : interp_env_t<ARG> struct cs_interp_env_t : interp_env_t<ARG>
{ {
void init (const hb_ubytes_t &str, const SUBRS *globalSubrs_, const SUBRS *localSubrs_) cs_interp_env_t (const hb_ubytes_t &str, const SUBRS *globalSubrs_, const SUBRS *localSubrs_) :
interp_env_t<ARG> (str)
{ {
interp_env_t<ARG>::init (str);
context.init (str, CSType_CharString); context.init (str, CSType_CharString);
seen_moveto = true; seen_moveto = true;
seen_hintmask = false; seen_hintmask = false;
@ -123,15 +122,11 @@ struct cs_interp_env_t : interp_env_t<ARG>
vstem_count = 0; vstem_count = 0;
hintmask_size = 0; hintmask_size = 0;
pt.set_int (0, 0); pt.set_int (0, 0);
callStack.init ();
globalSubrs.init (globalSubrs_); globalSubrs.init (globalSubrs_);
localSubrs.init (localSubrs_); localSubrs.init (localSubrs_);
} }
void fini () ~cs_interp_env_t ()
{ {
interp_env_t<ARG>::fini ();
callStack.fini ();
globalSubrs.fini (); globalSubrs.fini ();
localSubrs.fini (); localSubrs.fini ();
} }
@ -880,6 +875,8 @@ struct path_procs_t
template <typename ENV, typename OPSET, typename PARAM> template <typename ENV, typename OPSET, typename PARAM>
struct cs_interpreter_t : interpreter_t<ENV> struct cs_interpreter_t : interpreter_t<ENV>
{ {
cs_interpreter_t (ENV& env_) : interpreter_t<ENV> (env_) {}
bool interpret (PARAM& param) bool interpret (PARAM& param)
{ {
SUPER::env.set_endchar (false); SUPER::env.set_endchar (false);

View File

@ -179,6 +179,8 @@ struct top_dict_opset_t : dict_opset_t
template <typename OPSET, typename PARAM, typename ENV=num_interp_env_t> template <typename OPSET, typename PARAM, typename ENV=num_interp_env_t>
struct dict_interpreter_t : interpreter_t<ENV> struct dict_interpreter_t : interpreter_t<ENV>
{ {
dict_interpreter_t (ENV& env_) : interpreter_t<ENV> (env_) {}
bool interpret (PARAM& param) bool interpret (PARAM& param)
{ {
param.init (); param.init ();

View File

@ -38,17 +38,15 @@ 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>
void init (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)
: SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
{ {
SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
processed_width = false; processed_width = false;
has_width = false; has_width = false;
arg_start = 0; arg_start = 0;
in_seac = false; in_seac = false;
} }
void fini () { SUPER::fini (); }
void set_width (bool has_width_) void set_width (bool has_width_)
{ {
if (likely (!processed_width && (SUPER::argStack.get_count () > 0))) if (likely (!processed_width && (SUPER::argStack.get_count () > 0)))
@ -154,7 +152,7 @@ struct cff1_cs_opset_t : cs_opset_t<number_t, OPSET, cff1_cs_interp_env_t, PARAM
}; };
template <typename OPSET, typename PARAM> template <typename OPSET, typename PARAM>
struct cff1_cs_interpreter_t : cs_interpreter_t<cff1_cs_interp_env_t, OPSET, PARAM> {}; using cff1_cs_interpreter_t = cs_interpreter_t<cff1_cs_interp_env_t, OPSET, PARAM>;
} /* namespace CFF */ } /* namespace CFF */

View File

@ -68,11 +68,10 @@ template <typename ELEM>
struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs> struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs>
{ {
template <typename ACC> template <typename ACC>
void init (const hb_ubytes_t &str, ACC &acc, unsigned int fd, cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd,
const int *coords_=nullptr, unsigned int num_coords_=0) const int *coords_=nullptr, unsigned int num_coords_=0)
: SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
{ {
SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
coords = coords_; coords = coords_;
num_coords = num_coords_; num_coords = num_coords_;
varStore = acc.varStore; varStore = acc.varStore;
@ -269,7 +268,7 @@ struct cff2_cs_opset_t : cs_opset_t<ELEM, OPSET, cff2_cs_interp_env_t<ELEM>, PAR
}; };
template <typename OPSET, typename PARAM, typename ELEM> template <typename OPSET, typename PARAM, typename ELEM>
struct cff2_cs_interpreter_t : cs_interpreter_t<cff2_cs_interp_env_t<ELEM>, OPSET, PARAM> {}; using cff2_cs_interpreter_t = cs_interpreter_t<cff2_cs_interp_env_t<ELEM>, OPSET, PARAM>;
} /* namespace CFF */ } /* namespace CFF */

View File

@ -393,10 +393,10 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false; if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
unsigned int fd = cff->fdSelect->get_fd (glyph); unsigned int fd = cff->fdSelect->get_fd (glyph);
cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp;
const hb_ubytes_t str = (*cff->charStrings)[glyph]; const hb_ubytes_t str = (*cff->charStrings)[glyph];
interp.env.init (str, *cff, fd); cff1_cs_interp_env_t env (str, *cff, fd);
interp.env.set_in_seac (in_seac); env.set_in_seac (in_seac);
cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp (env);
cff1_extents_param_t param (cff); cff1_extents_param_t param (cff);
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;
bounds = param.bounds; bounds = param.bounds;
@ -538,10 +538,10 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false; if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
unsigned int fd = cff->fdSelect->get_fd (glyph); unsigned int fd = cff->fdSelect->get_fd (glyph);
cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp;
const hb_ubytes_t str = (*cff->charStrings)[glyph]; const hb_ubytes_t str = (*cff->charStrings)[glyph];
interp.env.init (str, *cff, fd); cff1_cs_interp_env_t env (str, *cff, fd);
interp.env.set_in_seac (in_seac); env.set_in_seac (in_seac);
cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp (env);
cff1_path_param_t param (cff, font, draw_session, delta); cff1_path_param_t param (cff, font, draw_session, delta);
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;
@ -590,9 +590,9 @@ bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_code
if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false; if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
unsigned int fd = fdSelect->get_fd (glyph); unsigned int fd = fdSelect->get_fd (glyph);
cff1_cs_interpreter_t<cff1_cs_opset_seac_t, get_seac_param_t> interp;
const hb_ubytes_t str = (*charStrings)[glyph]; const hb_ubytes_t str = (*charStrings)[glyph];
interp.env.init (str, *this, fd); cff1_cs_interp_env_t env (str, *this, fd);
cff1_cs_interpreter_t<cff1_cs_opset_seac_t, get_seac_param_t> interp (env);
get_seac_param_t param (this); get_seac_param_t param (this);
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;

View File

@ -602,6 +602,8 @@ struct cff1_top_dict_interp_env_t : num_interp_env_t
{ {
cff1_top_dict_interp_env_t () cff1_top_dict_interp_env_t ()
: num_interp_env_t(), prev_offset(0), last_offset(0) {} : num_interp_env_t(), prev_offset(0), last_offset(0) {}
cff1_top_dict_interp_env_t (const hb_ubytes_t &bytes)
: num_interp_env_t(bytes), prev_offset(0), last_offset(0) {}
unsigned int prev_offset; unsigned int prev_offset;
unsigned int last_offset; unsigned int last_offset;
@ -1026,9 +1028,8 @@ struct cff1
{ /* parse top dict */ { /* parse top dict */
const hb_ubytes_t topDictStr = (*topDictIndex)[0]; const hb_ubytes_t topDictStr = (*topDictIndex)[0];
if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; } if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
cff1_top_dict_interpreter_t top_interp; cff1_top_dict_interp_env_t env (topDictStr);
top_interp.env.init (topDictStr); cff1_top_dict_interpreter_t top_interp (env);
topDict.init ();
if (unlikely (!top_interp.interpret (topDict))) { fini (); return; } if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
} }
@ -1101,8 +1102,8 @@ struct cff1
hb_ubytes_t fontDictStr = (*fdArray)[i]; hb_ubytes_t fontDictStr = (*fdArray)[i];
if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; } if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
cff1_font_dict_values_t *font; cff1_font_dict_values_t *font;
cff1_font_dict_interpreter_t font_interp; cff1_top_dict_interp_env_t env (fontDictStr);
font_interp.env.init (fontDictStr); cff1_font_dict_interpreter_t font_interp (env);
font = fontDicts.push (); font = fontDicts.push ();
if (unlikely (font == &Crap (cff1_font_dict_values_t))) { fini (); return; } if (unlikely (font == &Crap (cff1_font_dict_values_t))) { fini (); return; }
font->init (); font->init ();
@ -1110,8 +1111,8 @@ struct cff1
PRIVDICTVAL *priv = &privateDicts[i]; PRIVDICTVAL *priv = &privateDicts[i];
const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp; num_interp_env_t env2 (privDictStr);
priv_interp.env.init (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2);
priv->init (); priv->init ();
if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
@ -1128,8 +1129,8 @@ struct cff1
const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp; num_interp_env_t env (privDictStr);
priv_interp.env.init (privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env);
priv->init (); priv->init ();
if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }

View File

@ -111,9 +111,9 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false; if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
unsigned int fd = fdSelect->get_fd (glyph); unsigned int fd = fdSelect->get_fd (glyph);
cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t, number_t> interp;
const hb_ubytes_t str = (*charStrings)[glyph]; const hb_ubytes_t str = (*charStrings)[glyph];
interp.env.init (str, *this, fd, font->coords, font->num_coords); cff2_cs_interp_env_t<number_t> env (str, *this, fd, font->coords, font->num_coords);
cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t, number_t> interp (env);
cff2_extents_param_t param; cff2_extents_param_t param;
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;
@ -200,9 +200,9 @@ bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, h
if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false; if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
unsigned int fd = fdSelect->get_fd (glyph); unsigned int fd = fdSelect->get_fd (glyph);
cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t, number_t> interp;
const hb_ubytes_t str = (*charStrings)[glyph]; const hb_ubytes_t str = (*charStrings)[glyph];
interp.env.init (str, *this, fd, font->coords, font->num_coords); cff2_cs_interp_env_t<number_t> env (str, *this, fd, font->coords, font->num_coords);
cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t, number_t> interp (env);
cff2_path_param_t param (font, draw_session); cff2_path_param_t param (font, draw_session);
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;
return true; return true;

View File

@ -247,12 +247,8 @@ typedef cff2_private_dict_values_base_t<num_dict_val_t> cff2_private_dict_values
struct cff2_priv_dict_interp_env_t : num_interp_env_t struct cff2_priv_dict_interp_env_t : num_interp_env_t
{ {
void init (const hb_ubytes_t &str) cff2_priv_dict_interp_env_t (const hb_ubytes_t &str) :
{ num_interp_env_t (str) {}
num_interp_env_t::init (str);
ivs = 0;
seen_vsindex = false;
}
void process_vsindex () void process_vsindex ()
{ {
@ -267,8 +263,8 @@ struct cff2_priv_dict_interp_env_t : num_interp_env_t
void set_ivs (unsigned int ivs_) { ivs = ivs_; } void set_ivs (unsigned int ivs_) { ivs = ivs_; }
protected: protected:
unsigned int ivs; unsigned int ivs = 0;
bool seen_vsindex; bool seen_vsindex = false;
}; };
struct cff2_private_dict_opset_t : dict_opset_t struct cff2_private_dict_opset_t : dict_opset_t
@ -417,8 +413,8 @@ struct cff2
{ /* parse top dict */ { /* parse top dict */
hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize);
if (unlikely (!topDictStr.sanitize (&sc))) goto fail; if (unlikely (!topDictStr.sanitize (&sc))) goto fail;
cff2_top_dict_interpreter_t top_interp; num_interp_env_t env (topDictStr);
top_interp.env.init (topDictStr); cff2_top_dict_interpreter_t top_interp (env);
topDict.init (); topDict.init ();
if (unlikely (!top_interp.interpret (topDict))) goto fail; if (unlikely (!top_interp.interpret (topDict))) goto fail;
} }
@ -450,8 +446,8 @@ struct cff2
const hb_ubytes_t fontDictStr = (*fdArray)[i]; const hb_ubytes_t fontDictStr = (*fdArray)[i];
if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail;
cff2_font_dict_values_t *font; cff2_font_dict_values_t *font;
cff2_font_dict_interpreter_t font_interp; num_interp_env_t env (fontDictStr);
font_interp.env.init (fontDictStr); cff2_font_dict_interpreter_t font_interp (env);
font = fontDicts.push (); font = fontDicts.push ();
if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail; if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail;
font->init (); font->init ();
@ -459,8 +455,8 @@ struct cff2
const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
if (unlikely (!privDictStr.sanitize (&sc))) goto fail; if (unlikely (!privDictStr.sanitize (&sc))) goto fail;
dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp; cff2_priv_dict_interp_env_t env2 (privDictStr);
priv_interp.env.init(privDictStr); dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp (env2);
privateDicts[i].init (); privateDicts[i].init ();
if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail;

View File

@ -257,8 +257,8 @@ 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;
cs_interpreter_t<ENV, OPSET, flatten_param_t> interp; ENV env (str, acc, fd);
interp.env.init (str, acc, fd); cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env);
flatten_param_t param = { flatten_param_t param = {
flat_charstrings[i], flat_charstrings[i],
(bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) (bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
@ -566,8 +566,8 @@ struct subr_subsetter_t
if (unlikely (fd >= acc.fdCount)) if (unlikely (fd >= acc.fdCount))
return false; return false;
cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp; ENV env (str, acc, fd);
interp.env.init (str, acc, fd); cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env);
subr_subset_param_t param (&parsed_charstrings[i], subr_subset_param_t param (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_global_subrs,