diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh | 199 |
1 files changed, 116 insertions, 83 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh index 829217feaa..4b3bdc9315 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh @@ -28,8 +28,9 @@ #define HB_OT_CFF2_TABLE_HH #include "hb-ot-cff-common.hh" -#include "hb-subset-cff2.hh" +#include "hb-subset-cff-common.hh" #include "hb-draw.hh" +#include "hb-paint.hh" namespace CFF { @@ -37,10 +38,9 @@ namespace CFF { * CFF2 -- Compact Font Format (CFF) Version 2 * https://docs.microsoft.com/en-us/typography/opentype/spec/cff2 */ -#define HB_OT_TAG_cff2 HB_TAG('C','F','F','2') +#define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2') typedef CFFIndex<HBUINT32> CFF2Index; -template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {}; typedef CFF2Index CFF2CharStrings; typedef Subrs<HBUINT32> CFF2Subrs; @@ -56,7 +56,7 @@ struct CFF2FDSelect unsigned int size = src.get_size (num_glyphs); CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size); if (unlikely (!dest)) return_trace (false); - memcpy (dest, &src, size); + hb_memcpy (dest, &src, size); return_trace (true); } @@ -90,6 +90,7 @@ struct CFF2FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { @@ -110,30 +111,33 @@ struct CFF2FDSelect DEFINE_SIZE_MIN (2); }; -struct CFF2VariationStore +struct CFF2ItemVariationStore { bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this)) && c->check_range (&varStore, size) && varStore.sanitize (c)); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (&varStore, size) && + varStore.sanitize (c)); } - bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) + bool serialize (hb_serialize_context_t *c, const CFF2ItemVariationStore *varStore) { TRACE_SERIALIZE (this); unsigned int size_ = varStore->get_size (); - CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_); + CFF2ItemVariationStore *dest = c->allocate_size<CFF2ItemVariationStore> (size_); if (unlikely (!dest)) return_trace (false); - memcpy (dest, varStore, size_); + hb_memcpy (dest, varStore, size_); return_trace (true); } unsigned int get_size () const { return HBUINT16::static_size + size; } HBUINT16 size; - VariationStore varStore; + ItemVariationStore varStore; - DEFINE_SIZE_MIN (2 + VariationStore::min_size); + DEFINE_SIZE_MIN (2 + ItemVariationStore::min_size); }; struct cff2_top_dict_values_t : top_dict_values_t<> @@ -146,8 +150,8 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int vstoreOffset; - unsigned int FDSelectOffset; + int vstoreOffset; + int FDSelectOffset; }; struct cff2_top_dict_opset_t : top_dict_opset_t<> @@ -165,11 +169,11 @@ struct cff2_top_dict_opset_t : top_dict_opset_t<> break; case OpCode_vstore: - dictval.vstoreOffset = env.argStack.pop_uint (); + dictval.vstoreOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -237,7 +241,7 @@ struct cff2_private_dict_values_base_t : dict_values_t<VAL> } void fini () { dict_values_t<VAL>::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; }; @@ -247,12 +251,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 { - void init (const byte_str_t &str) - { - num_interp_env_t::init (str); - ivs = 0; - seen_vsindex = false; - } + cff2_priv_dict_interp_env_t (const hb_ubytes_t &str) : + num_interp_env_t (str) {} void process_vsindex () { @@ -267,8 +267,8 @@ struct cff2_priv_dict_interp_env_t : num_interp_env_t void set_ivs (unsigned int ivs_) { ivs = ivs_; } protected: - unsigned int ivs; - bool seen_vsindex; + unsigned int ivs = 0; + bool seen_vsindex = false; }; struct cff2_private_dict_opset_t : dict_opset_t @@ -286,9 +286,6 @@ struct cff2_private_dict_opset_t : dict_opset_t case OpCode_BlueFuzz: case OpCode_ExpansionFactor: case OpCode_LanguageGroup: - val.single_val = env.argStack.pop_num (); - env.clear_args (); - break; case OpCode_BlueValues: case OpCode_OtherBlues: case OpCode_FamilyBlues: @@ -298,7 +295,7 @@ struct cff2_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_vsindexdict: @@ -347,7 +344,7 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t return; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -385,20 +382,25 @@ using namespace CFF; struct cff2 { - static constexpr hb_tag_t tableTag = HB_OT_TAG_cff2; + static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF2; bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2)); } template <typename PRIVOPSET, typename PRIVDICTVAL> struct accelerator_templ_t { - void init (hb_face_t *face) + static constexpr hb_tag_t tableTag = cff2::tableTag; + + accelerator_templ_t (hb_face_t *face) { + if (!face) return; + topDict.init (); fontDicts.init (); privateDicts.init (); @@ -412,109 +414,133 @@ struct cff2 const OT::cff2 *cff2 = this->blob->template as<OT::cff2> (); if (cff2 == &Null (OT::cff2)) - { fini (); return; } + goto fail; { /* parse top dict */ - byte_str_t topDictStr (cff2 + cff2->topDict, cff2->topDictSize); - if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; } - cff2_top_dict_interpreter_t top_interp; - top_interp.env.init (topDictStr); + hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); + if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); + num_interp_env_t env (topDictStr); + cff2_top_dict_interpreter_t top_interp (env); topDict.init (); - if (unlikely (!top_interp.interpret (topDict))) { fini (); return; } + if (unlikely (!top_interp.interpret (topDict))) goto fail; } - globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize); - varStore = &StructAtOffsetOrNull<CFF2VariationStore> (cff2, topDict.vstoreOffset); - charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset); - fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset); + globalSubrs = &StructAtOffsetOrNull<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize, sc); + varStore = &StructAtOffsetOrNull<CFF2ItemVariationStore> (cff2, topDict.vstoreOffset, sc); + charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset, sc); + fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset, sc, fdArray->count); - if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) || - (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || - (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || - (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || - (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) - { fini (); return; } + if (charStrings == &Null (CFF2CharStrings) || + globalSubrs == &Null (CFF2Subrs) || + fdArray == &Null (CFF2FDArray)) + goto fail; num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) - { fini (); return; } + goto fail; fdCount = fdArray->count; if (!privateDicts.resize (fdCount)) - { fini (); 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))) { fini (); return; } + const hb_ubytes_t fontDictStr = (*fdArray)[i]; + if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_font_dict_values_t *font; - cff2_font_dict_interpreter_t font_interp; - font_interp.env.init (fontDictStr); + num_interp_env_t env (fontDictStr); + cff2_font_dict_interpreter_t font_interp (env); font = fontDicts.push (); - if (unlikely (font == &Crap (cff2_font_dict_values_t))) { fini (); return; } + if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail; font->init (); - if (unlikely (!font_interp.interpret (*font))) { fini (); 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))) { fini (); return; } - dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp; - priv_interp.env.init(privDictStr); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + cff2_priv_dict_interp_env_t env2 (privDictStr); + dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp (env2); privateDicts[i].init (); - if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); 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))) - { fini (); return; } + privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset, sc); } - } - void fini () + return; + + fail: + _fini (); + } + ~accelerator_templ_t () { _fini (); } + void _fini () { sc.end_processing (); topDict.fini (); - fontDicts.fini_deep (); - privateDicts.fini_deep (); + fontDicts.fini (); + privateDicts.fini (); hb_blob_destroy (blob); blob = nullptr; } + hb_vector_t<uint16_t> *create_glyph_to_sid_map () const + { + return nullptr; + } + + hb_blob_t *get_blob () const { return blob; } + bool is_valid () const { return blob; } protected: - hb_blob_t *blob; hb_sanitize_context_t sc; public: + hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; - const CFF2Subrs *globalSubrs; - const CFF2VariationStore *varStore; - const CFF2CharStrings *charStrings; - const CFF2FDArray *fdArray; - const CFF2FDSelect *fdSelect; - unsigned int fdCount; + const CFF2Subrs *globalSubrs = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; + const CFF2CharStrings *charStrings = nullptr; + const CFF2FDArray *fdArray = nullptr; + const CFF2FDSelect *fdSelect = nullptr; + unsigned int fdCount = 0; hb_vector_t<cff2_font_dict_values_t> fontDicts; hb_vector_t<PRIVDICTVAL> privateDicts; - unsigned int num_glyphs; + unsigned int num_glyphs = 0; }; 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; -#ifdef HB_EXPERIMENTAL_API - HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const; -#endif + HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; + HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; }; - typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t; + struct accelerator_subset_t : accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> + { + accelerator_subset_t (hb_face_t *face) : SUPER (face) {} + ~accelerator_subset_t () + { + if (cff_accelerator) + cff_subset_accelerator_t::destroy (cff_accelerator); + } + + HB_INTERNAL bool subset (hb_subset_context_t *c) const; + HB_INTERNAL bool serialize (hb_serialize_context_t *c, + struct cff2_subset_plan &plan, + hb_array_t<int> normalized_coords) const; - bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); } + mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr; + + typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> SUPER; + }; public: FixedVersion<HBUINT8> version; /* Version of CFF2 table. set to 0x0200u */ @@ -525,7 +551,14 @@ 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) {} +}; + +struct cff2_subset_accelerator_t : cff2::accelerator_subset_t { + cff2_subset_accelerator_t (hb_face_t *face) : cff2::accelerator_subset_t (face) {} +}; + } /* namespace OT */ #endif /* HB_OT_CFF2_TABLE_HH */ |