|
|
|
@ -397,7 +397,7 @@ struct cff2 |
|
|
|
|
template <typename PRIVOPSET, typename PRIVDICTVAL> |
|
|
|
|
struct accelerator_templ_t |
|
|
|
|
{ |
|
|
|
|
void Xinit (hb_face_t *face) |
|
|
|
|
accelerator_templ_t (hb_face_t *face) |
|
|
|
|
{ |
|
|
|
|
topDict.init (); |
|
|
|
|
fontDicts.init (); |
|
|
|
@ -412,15 +412,15 @@ struct cff2 |
|
|
|
|
const OT::cff2 *cff2 = this->blob->template as<OT::cff2> (); |
|
|
|
|
|
|
|
|
|
if (cff2 == &Null (OT::cff2)) |
|
|
|
|
{ Xfini (); return; } |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
{ /* parse top dict */ |
|
|
|
|
byte_str_t topDictStr (cff2 + cff2->topDict, cff2->topDictSize); |
|
|
|
|
if (unlikely (!topDictStr.sanitize (&sc))) { Xfini (); return; } |
|
|
|
|
if (unlikely (!topDictStr.sanitize (&sc))) goto fail; |
|
|
|
|
cff2_top_dict_interpreter_t top_interp; |
|
|
|
|
top_interp.env.init (topDictStr); |
|
|
|
|
topDict.init (); |
|
|
|
|
if (unlikely (!top_interp.interpret (topDict))) { Xfini (); return; } |
|
|
|
|
if (unlikely (!top_interp.interpret (topDict))) goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize); |
|
|
|
@ -434,44 +434,50 @@ struct cff2 |
|
|
|
|
(globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || |
|
|
|
|
(fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || |
|
|
|
|
(((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) |
|
|
|
|
{ Xfini (); return; } |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
num_glyphs = charStrings->count; |
|
|
|
|
if (num_glyphs != sc.get_num_glyphs ()) |
|
|
|
|
{ Xfini (); return; } |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
fdCount = fdArray->count; |
|
|
|
|
if (!privateDicts.resize (fdCount)) |
|
|
|
|
{ Xfini (); return; } |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
/* parse font dicts and gather private dicts */ |
|
|
|
|
for (unsigned int i = 0; i < fdCount; i++) |
|
|
|
|
{ |
|
|
|
|
const byte_str_t fontDictStr = (*fdArray)[i]; |
|
|
|
|
if (unlikely (!fontDictStr.sanitize (&sc))) { Xfini (); return; } |
|
|
|
|
if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; |
|
|
|
|
cff2_font_dict_values_t *font; |
|
|
|
|
cff2_font_dict_interpreter_t font_interp; |
|
|
|
|
font_interp.env.init (fontDictStr); |
|
|
|
|
font = fontDicts.push (); |
|
|
|
|
if (unlikely (font == &Crap (cff2_font_dict_values_t))) { Xfini (); return; } |
|
|
|
|
if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail; |
|
|
|
|
font->init (); |
|
|
|
|
if (unlikely (!font_interp.interpret (*font))) { Xfini (); return; } |
|
|
|
|
if (unlikely (!font_interp.interpret (*font))) goto fail; |
|
|
|
|
|
|
|
|
|
const byte_str_t privDictStr (StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset), font->privateDictInfo.size); |
|
|
|
|
if (unlikely (!privDictStr.sanitize (&sc))) { Xfini (); return; } |
|
|
|
|
if (unlikely (!privDictStr.sanitize (&sc))) goto fail; |
|
|
|
|
dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp; |
|
|
|
|
priv_interp.env.init(privDictStr); |
|
|
|
|
privateDicts[i].init (); |
|
|
|
|
if (unlikely (!priv_interp.interpret (privateDicts[i]))) { Xfini (); return; } |
|
|
|
|
if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; |
|
|
|
|
|
|
|
|
|
privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset); |
|
|
|
|
if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && |
|
|
|
|
unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) |
|
|
|
|
{ Xfini (); return; } |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Xfini () |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
fail: |
|
|
|
|
_fini (); |
|
|
|
|
} |
|
|
|
|
~accelerator_templ_t () { _fini (); } |
|
|
|
|
void _fini () |
|
|
|
|
{ |
|
|
|
|
sc.end_processing (); |
|
|
|
|
topDict.fini (); |
|
|
|
@ -504,6 +510,8 @@ struct cff2 |
|
|
|
|
|
|
|
|
|
struct accelerator_t : accelerator_templ_t<cff2_private_dict_opset_t, cff2_private_dict_values_t> |
|
|
|
|
{ |
|
|
|
|
accelerator_t (hb_face_t *face) : accelerator_templ_t (face) {} |
|
|
|
|
|
|
|
|
|
HB_INTERNAL bool get_extents (hb_font_t *font, |
|
|
|
|
hb_codepoint_t glyph, |
|
|
|
|
hb_glyph_extents_t *extents) const; |
|
|
|
@ -525,7 +533,10 @@ struct cff2 |
|
|
|
|
DEFINE_SIZE_STATIC (5); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct cff2_accelerator_t : cff2::accelerator_t {}; |
|
|
|
|
struct cff2_accelerator_t : cff2::accelerator_t { |
|
|
|
|
cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
} /* namespace OT */ |
|
|
|
|
|
|
|
|
|
#endif /* HB_OT_CFF2_TABLE_HH */ |
|
|
|
|