summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh
diff options
context:
space:
mode:
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.hh199
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 */