diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh | 834 |
1 files changed, 527 insertions, 307 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh index ad206511c1..1bbd463841 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh @@ -27,17 +27,24 @@ #ifndef HB_OT_CFF1_TABLE_HH #define HB_OT_CFF1_TABLE_HH -#include "hb-ot-head-table.hh" #include "hb-ot-cff-common.hh" -#include "hb-subset-cff1.hh" +#include "hb-subset-cff-common.hh" +#include "hb-draw.hh" +#include "hb-paint.hh" + +#define HB_STRING_ARRAY_NAME cff1_std_strings +#define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh" +#include "hb-string-array.hh" +#undef HB_STRING_ARRAY_LIST +#undef HB_STRING_ARRAY_NAME namespace CFF { /* * CFF -- Compact Font Format (CFF) - * http://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf + * https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf */ -#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ') +#define HB_OT_TAG_CFF1 HB_TAG('C','F','F',' ') #define CFF_UNDEF_SID CFF_UNDEF_CODE @@ -45,11 +52,9 @@ enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 }; enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 }; typedef CFFIndex<HBUINT16> CFF1Index; -template <typename Type> struct CFF1IndexOf : CFFIndexOf<HBUINT16, Type> {}; typedef CFFIndex<HBUINT16> CFF1Index; typedef CFF1Index CFF1CharStrings; -typedef FDArray<HBUINT16> CFF1FDArray; typedef Subrs<HBUINT16> CFF1Subrs; struct CFF1FDSelect : FDSelect {}; @@ -104,6 +109,7 @@ struct Encoding1 { hb_codepoint_t get_code (hb_codepoint_t glyph) const { + /* TODO: Add cache like get_sid. */ assert (glyph > 0); glyph--; for (unsigned int i = 0; i < nRanges (); i++) @@ -167,11 +173,7 @@ struct Encoding bool serialize (hb_serialize_context_t *c, const Encoding &src) { TRACE_SERIALIZE (this); - unsigned int size = src.get_size (); - Encoding *dest = c->allocate_size<Encoding> (size); - if (unlikely (dest == nullptr)) return_trace (false); - memcpy (dest, &src, size); - return_trace (true); + return_trace (c->embed (src)); } /* serialize a subset Encoding */ @@ -182,14 +184,14 @@ struct Encoding const hb_vector_t<code_pair_t>& supp_codes) { TRACE_SERIALIZE (this); - Encoding *dest = c->extend_min (*this); - if (unlikely (dest == nullptr)) return_trace (false); + Encoding *dest = c->extend_min (this); + if (unlikely (!dest)) return_trace (false); dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0); switch (format) { case 0: { Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count); - if (unlikely (fmt0 == nullptr)) return_trace (false); + if (unlikely (!fmt0)) return_trace (false); fmt0->nCodes () = enc_count; unsigned int glyph = 0; for (unsigned int i = 0; i < code_ranges.length; i++) @@ -206,7 +208,7 @@ struct Encoding case 1: { Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length); - if (unlikely (fmt1 == nullptr)) return_trace (false); + if (unlikely (!fmt1)) return_trace (false); fmt1->nRanges () = code_ranges.length; for (unsigned int i = 0; i < code_ranges.length; i++) { @@ -223,7 +225,7 @@ struct Encoding if (supp_codes.length) { CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length); - if (unlikely (suppData == nullptr)) return_trace (false); + if (unlikely (!suppData)) return_trace (false); suppData->nSups () = supp_codes.length; for (unsigned int i = 0; i < supp_codes.length; i++) { @@ -235,23 +237,6 @@ struct Encoding return_trace (true); } - /* parallel to above: calculate the size of a subset Encoding */ - static unsigned int calculate_serialized_size (uint8_t format, - unsigned int enc_count, - unsigned int supp_count) - { - unsigned int size = min_size; - switch (format) - { - case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break; - case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break; - default:return 0; - } - if (supp_count > 0) - size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count; - return size; - } - unsigned int get_size () const { unsigned int size = min_size; @@ -290,6 +275,7 @@ struct Encoding TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (table_format ()) { @@ -323,21 +309,31 @@ struct Encoding }; /* Charset */ -struct Charset0 { - bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const +struct Charset0 +{ + bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && sids[num_glyphs - 1].sanitize (c)); + if (num_charset_entries) *num_charset_entries = num_glyphs; + return_trace (sids.sanitize (c, num_glyphs - 1)); } - hb_codepoint_t get_sid (hb_codepoint_t glyph) const + hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const { - if (glyph == 0) + if (unlikely (glyph >= num_glyphs)) return 0; + if (unlikely (glyph == 0)) return 0; else return sids[glyph - 1]; } + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const + { + mapping->resize (num_glyphs, false); + for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++) + mapping->arrayZ[gid] = {sids[gid - 1], gid}; + } + hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const { if (sid == 0) @@ -351,13 +347,13 @@ struct Charset0 { return 0; } - unsigned int get_size (unsigned int num_glyphs) const + static unsigned int get_size (unsigned int num_glyphs) { assert (num_glyphs > 0); - return HBUINT16::static_size * (num_glyphs - 1); + return UnsizedArrayOf<HBUINT16>::get_size (num_glyphs - 1); } - HBUINT16 sids[HB_VAR_ARRAY]; + UnsizedArrayOf<HBUINT16> sids; DEFINE_SIZE_ARRAY(0, sids); }; @@ -378,35 +374,78 @@ struct Charset_Range { template <typename TYPE> struct Charset1_2 { - bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const + bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); num_glyphs--; - for (unsigned int i = 0; num_glyphs > 0; i++) + unsigned i; + for (i = 0; num_glyphs > 0; i++) { - if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1))) + if (unlikely (!(ranges[i].sanitize (c) && + hb_barrier () && + (num_glyphs >= ranges[i].nLeft + 1)))) return_trace (false); num_glyphs -= (ranges[i].nLeft + 1); } + if (num_charset_entries) + *num_charset_entries = i; return_trace (true); } - hb_codepoint_t get_sid (hb_codepoint_t glyph) const + hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs, + code_pair_t *cache = nullptr) const { - if (glyph == 0) return 0; - glyph--; - for (unsigned int i = 0;; i++) + if (unlikely (glyph >= num_glyphs)) return 0; + unsigned i; + hb_codepoint_t start_glyph; + if (cache && likely (cache->glyph <= glyph)) { - if (glyph <= ranges[i].nLeft) - return (hb_codepoint_t)ranges[i].first + glyph; - glyph -= (ranges[i].nLeft + 1); + i = cache->code; + start_glyph = cache->glyph; + } + else + { + if (unlikely (glyph == 0)) return 0; + i = 0; + start_glyph = 1; + } + glyph -= start_glyph; + for (;; i++) + { + unsigned count = ranges[i].nLeft; + if (glyph <= count) + { + if (cache) + *cache = {i, start_glyph}; + return ranges[i].first + glyph; + } + count++; + start_glyph += count; + glyph -= count; } return 0; } + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const + { + mapping->resize (num_glyphs, false); + hb_codepoint_t gid = 1; + if (gid >= num_glyphs) + return; + for (unsigned i = 0;; i++) + { + hb_codepoint_t sid = ranges[i].first; + unsigned count = ranges[i].nLeft + 1; + unsigned last = gid + count; + for (unsigned j = 0; j < count; j++) + mapping->arrayZ[gid++] = {sid++, last - 1}; + + if (gid >= num_glyphs) + break; + } + } + hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const { if (sid == 0) return 0; @@ -414,7 +453,7 @@ struct Charset1_2 { for (unsigned int i = 0;; i++) { if (glyph >= num_glyphs) - return 0; + return 0; if ((ranges[i].first <= sid) && (sid <= ranges[i].first + ranges[i].nLeft)) return glyph + (sid - ranges[i].first); glyph += (ranges[i].nLeft + 1); @@ -425,21 +464,26 @@ struct Charset1_2 { unsigned int get_size (unsigned int num_glyphs) const { - unsigned int size = HBUINT8::static_size; - int glyph = (int)num_glyphs; + int glyph = (int) num_glyphs; + unsigned num_ranges = 0; assert (glyph > 0); glyph--; for (unsigned int i = 0; glyph > 0; i++) { glyph -= (ranges[i].nLeft + 1); - size += Charset_Range<TYPE>::static_size; + num_ranges++; } - return size; + return get_size_for_ranges (num_ranges); + } + + static unsigned int get_size_for_ranges (unsigned int num_ranges) + { + return UnsizedArrayOf<Charset_Range<TYPE> >::get_size (num_ranges); } - Charset_Range<TYPE> ranges[HB_VAR_ARRAY]; + UnsizedArrayOf<Charset_Range<TYPE>> ranges; DEFINE_SIZE_ARRAY (0, ranges); }; @@ -455,11 +499,7 @@ struct Charset bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs) { TRACE_SERIALIZE (this); - unsigned int size = src.get_size (num_glyphs); - Charset *dest = c->allocate_size<Charset> (size); - if (unlikely (dest == nullptr)) return_trace (false); - memcpy (dest, &src, size); - return_trace (true); + return_trace (c->embed ((const char *) &src, src.get_size (num_glyphs))); } /* serialize a subset Charset */ @@ -469,20 +509,20 @@ struct Charset const hb_vector_t<code_pair_t>& sid_ranges) { TRACE_SERIALIZE (this); - Charset *dest = c->extend_min (*this); - if (unlikely (dest == nullptr)) return_trace (false); + Charset *dest = c->extend_min (this); + if (unlikely (!dest)) return_trace (false); dest->format = format; switch (format) { case 0: { - Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1)); - if (unlikely (fmt0 == nullptr)) return_trace (false); + Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::get_size (num_glyphs), false); + if (unlikely (!fmt0)) return_trace (false); unsigned int glyph = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { - hb_codepoint_t sid = sid_ranges[i].code; - for (int left = (int)sid_ranges[i].glyph; left >= 0; left--) + hb_codepoint_t sid = sid_ranges.arrayZ[i].code; + for (int left = (int)sid_ranges.arrayZ[i].glyph; left >= 0; left--) fmt0->sids[glyph++] = sid++; } } @@ -490,29 +530,35 @@ struct Charset case 1: { - Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length); - if (unlikely (fmt1 == nullptr)) return_trace (false); + Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::get_size_for_ranges (sid_ranges.length), false); + if (unlikely (!fmt1)) return_trace (false); + hb_codepoint_t all_glyphs = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { - if (unlikely (!(sid_ranges[i].glyph <= 0xFF))) - return_trace (false); - fmt1->ranges[i].first = sid_ranges[i].code; - fmt1->ranges[i].nLeft = sid_ranges[i].glyph; + auto &_ = sid_ranges.arrayZ[i]; + all_glyphs |= _.glyph; + fmt1->ranges[i].first = _.code; + fmt1->ranges[i].nLeft = _.glyph; } + if (unlikely (!(all_glyphs <= 0xFF))) + return_trace (false); } break; case 2: { - Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length); - if (unlikely (fmt2 == nullptr)) return_trace (false); + Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::get_size_for_ranges (sid_ranges.length), false); + if (unlikely (!fmt2)) return_trace (false); + hb_codepoint_t all_glyphs = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { - if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF))) - return_trace (false); - fmt2->ranges[i].first = sid_ranges[i].code; - fmt2->ranges[i].nLeft = sid_ranges[i].glyph; + auto &_ = sid_ranges.arrayZ[i]; + all_glyphs |= _.glyph; + fmt2->ranges[i].first = _.code; + fmt2->ranges[i].nLeft = _.glyph; } + if (unlikely (!(all_glyphs <= 0xFFFF))) + return_trace (false); } break; @@ -520,38 +566,37 @@ struct Charset return_trace (true); } - /* parallel to above: calculate the size of a subset Charset */ - static unsigned int calculate_serialized_size (uint8_t format, - unsigned int count) + unsigned int get_size (unsigned int num_glyphs) const { switch (format) { - case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1); - case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count; - case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count; + case 0: return min_size + u.format0.get_size (num_glyphs); + case 1: return min_size + u.format1.get_size (num_glyphs); + case 2: return min_size + u.format2.get_size (num_glyphs); default:return 0; } } - unsigned int get_size (unsigned int num_glyphs) const + hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs, + code_pair_t *cache = nullptr) const { switch (format) { - case 0: return min_size + u.format0.get_size (num_glyphs); - case 1: return min_size + u.format1.get_size (num_glyphs); - case 2: return min_size + u.format2.get_size (num_glyphs); + case 0: return u.format0.get_sid (glyph, num_glyphs); + case 1: return u.format1.get_sid (glyph, num_glyphs, cache); + case 2: return u.format2.get_sid (glyph, num_glyphs, cache); default:return 0; } } - hb_codepoint_t get_sid (hb_codepoint_t glyph) const + void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { switch (format) { - case 0: return u.format0.get_sid (glyph); - case 1: return u.format1.get_sid (glyph); - case 2: return u.format2.get_sid (glyph); - default:return 0; + case 0: u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 1: u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return; + case 2: u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return; + default:return; } } @@ -566,17 +611,18 @@ struct Charset } } - bool sanitize (hb_sanitize_context_t *c) const + bool sanitize (hb_sanitize_context_t *c, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { - case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ())); - case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ())); - case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ())); + case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries)); + case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries)); default:return_trace (false); } } @@ -594,10 +640,10 @@ struct Charset struct CFF1StringIndex : CFF1Index { bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings, - unsigned int offSize_, const hb_inc_bimap_t &sidmap) + const hb_vector_t<unsigned> &sidmap) { TRACE_SERIALIZE (this); - if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0))) + if (unlikely ((strings.count == 0) || (sidmap.length == 0))) { if (unlikely (!c->extend_min (this->count))) return_trace (false); @@ -605,36 +651,16 @@ struct CFF1StringIndex : CFF1Index return_trace (true); } - byte_str_array_t bytesArray; - bytesArray.init (); - if (!bytesArray.resize (sidmap.get_population ())) - return_trace (false); - for (unsigned int i = 0; i < strings.count; i++) - { - hb_codepoint_t j = sidmap[i]; - if (j != CFF_UNDEF_CODE) - bytesArray[j] = strings[i]; - } + if (unlikely (sidmap.in_error ())) return_trace (false); - bool result = CFF1Index::serialize (c, offSize_, bytesArray); - bytesArray.fini (); - return_trace (result); - } - - /* in parallel to above */ - unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const - { - offSize_ = 0; - if ((count == 0) || (sidmap.get_population () == 0)) - return count.static_size; + // Save this in a vector since serialize() iterates it twice. + hb_vector_t<hb_ubytes_t> bytesArray (+ hb_iter (sidmap) + | hb_map (strings)); - unsigned int dataSize = 0; - for (unsigned int i = 0; i < count; i++) - if (sidmap[i] != CFF_UNDEF_CODE) - dataSize += length_at (i); + if (unlikely (bytesArray.in_error ())) return_trace (false); - offSize_ = calcOffSize(dataSize); - return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize); + bool result = CFF1Index::serialize (c, bytesArray); + return_trace (result); } }; @@ -642,6 +668,8 @@ struct cff1_top_dict_interp_env_t : num_interp_env_t { cff1_top_dict_interp_env_t () : 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 last_offset; @@ -735,10 +763,10 @@ struct cff1_top_dict_values_t : top_dict_values_t<cff1_top_dict_val_t> unsigned int ros_supplement; unsigned int cidCount; - unsigned int EncodingOffset; - unsigned int CharsetOffset; - unsigned int FDSelectOffset; - table_info_t privateDictInfo; + int EncodingOffset; + int CharsetOffset; + int FDSelectOffset; + table_info_t privateDictInfo; }; struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> @@ -753,6 +781,7 @@ struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> case OpCode_Notice: case OpCode_Copyright: case OpCode_FullName: + case OpCode_FontName: case OpCode_FamilyName: case OpCode_Weight: case OpCode_PostScript: @@ -792,30 +821,30 @@ struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> break; case OpCode_Encoding: - dictval.EncodingOffset = env.argStack.pop_uint (); + dictval.EncodingOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.EncodingOffset == 0)) return; break; case OpCode_charset: - dictval.CharsetOffset = env.argStack.pop_uint (); + dictval.CharsetOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.CharsetOffset == 0)) return; break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_Private: - dictval.privateDictInfo.offset = env.argStack.pop_uint (); + dictval.privateDictInfo.offset = env.argStack.pop_int (); dictval.privateDictInfo.size = env.argStack.pop_uint (); env.clear_args (); break; default: - env.last_offset = env.str_ref.offset; + env.last_offset = env.str_ref.get_offset (); top_dict_opset_t<cff1_top_dict_val_t>::process_op (op, env, dictval); /* Record this operand below if stack is empty, otherwise done */ if (!env.argStack.is_empty ()) return; @@ -880,22 +909,11 @@ struct cff1_private_dict_values_base_t : dict_values_t<VAL> { dict_values_t<VAL>::init (); subrsOffset = 0; - localSubrs = &Null(CFF1Subrs); + localSubrs = &Null (CFF1Subrs); } void fini () { dict_values_t<VAL>::fini (); } - unsigned int calculate_serialized_size () const - { - unsigned int size = 0; - for (unsigned int i = 0; i < dict_values_t<VAL>::get_count; i++) - if (dict_values_t<VAL>::get_value (i).op == OpCode_Subrs) - size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs); - else - size += dict_values_t<VAL>::get_value (i).str.length; - return size; - } - - unsigned int subrsOffset; + int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -916,8 +934,6 @@ struct cff1_private_dict_opset_t : dict_opset_t case OpCode_FamilyOtherBlues: case OpCode_StemSnapH: case OpCode_StemSnapV: - env.clear_args (); - break; case OpCode_StdHW: case OpCode_StdVW: case OpCode_BlueScale: @@ -929,11 +945,10 @@ struct cff1_private_dict_opset_t : dict_opset_t case OpCode_initialRandomSeed: case OpCode_defaultWidthX: case OpCode_nominalWidthX: - val.single_val = env.argStack.pop_num (); env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -949,7 +964,7 @@ struct cff1_private_dict_opset_t : dict_opset_t } }; -struct cff1_private_dict_opset_subset : dict_opset_t +struct cff1_private_dict_opset_subset_t : dict_opset_t { static void process_op (op_code_t op, num_interp_env_t& env, cff1_private_dict_values_subset_t& dictval) { @@ -975,7 +990,7 @@ struct cff1_private_dict_opset_subset : dict_opset_t break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -995,7 +1010,38 @@ typedef dict_interpreter_t<cff1_top_dict_opset_t, cff1_top_dict_values_t, cff1_t typedef dict_interpreter_t<cff1_font_dict_opset_t, cff1_font_dict_values_t> cff1_font_dict_interpreter_t; typedef CFF1Index CFF1NameIndex; -typedef CFF1IndexOf<TopDict> CFF1TopDictIndex; +typedef CFF1Index CFF1TopDictIndex; + +struct cff1_font_dict_values_mod_t +{ + cff1_font_dict_values_mod_t() { init (); } + + void init () { init ( &Null (cff1_font_dict_values_t), CFF_UNDEF_SID ); } + + void init (const cff1_font_dict_values_t *base_, + unsigned int fontName_) + { + base = base_; + fontName = fontName_; + privateDictInfo.init (); + } + + unsigned get_count () const { return base->get_count (); } + + const op_str_t &operator [] (unsigned int i) const { return (*base)[i]; } + + const cff1_font_dict_values_t *base; + table_info_t privateDictInfo; + unsigned int fontName; +}; + +struct CFF1FDArray : FDArray<HBUINT16> +{ + /* FDArray::serialize() requires this partial specialization to compile */ + template <typename ITER, typename OP_SERIALIZER> + bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr) + { return FDArray<HBUINT16>::serialize<cff1_font_dict_values_mod_t, cff1_font_dict_values_mod_t> (c, it, opszr); } +}; } /* namespace CFF */ @@ -1005,20 +1051,25 @@ using namespace CFF; struct cff1 { - static constexpr hb_tag_t tableTag = HB_OT_TAG_cff1; + static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF1; bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 1)); } template <typename PRIVOPSET, typename PRIVDICTVAL> struct accelerator_templ_t { - void init (hb_face_t *face) + static constexpr hb_tag_t tableTag = cff1::tableTag; + + accelerator_templ_t (hb_face_t *face) { + if (!face) return; + topDict.init (); fontDicts.init (); privateDicts.init (); @@ -1031,69 +1082,82 @@ struct cff1 const OT::cff1 *cff = this->blob->template as<OT::cff1> (); - if (cff == &Null(OT::cff1)) - { fini (); return; } + if (cff == &Null (OT::cff1)) + goto fail; nameIndex = &cff->nameIndex (cff); if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc)) - { fini (); return; } + goto fail; + hb_barrier (); - topDictIndex = &StructAtOffset<CFF1TopDictIndex> (nameIndex, nameIndex->get_size ()); - if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) - { fini (); return; } + topDictIndex = &StructAtOffsetOrNull<CFF1TopDictIndex> (nameIndex, nameIndex->get_size (), sc); + if (topDictIndex == &Null (CFF1TopDictIndex) || (topDictIndex->count == 0)) + goto fail; + hb_barrier (); { /* parse top dict */ - const byte_str_t topDictStr = (*topDictIndex)[0]; - if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; } - cff1_top_dict_interpreter_t top_interp; - top_interp.env.init (topDictStr); - topDict.init (); - if (unlikely (!top_interp.interpret (topDict))) { fini (); return; } + const hb_ubytes_t topDictStr = (*topDictIndex)[0]; + if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); + cff1_top_dict_interp_env_t env (topDictStr); + cff1_top_dict_interpreter_t top_interp (env); + if (unlikely (!top_interp.interpret (topDict))) goto fail; } if (is_predef_charset ()) - charset = &Null(Charset); + charset = &Null (Charset); else { - charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset); - if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc))) { fini (); return; } + charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset, sc, &num_charset_entries); + if (unlikely (charset == &Null (Charset))) goto fail; } fdCount = 1; if (is_CID ()) { - fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset); - if (unlikely ((fdArray == &Null(CFF1FDArray)) || !fdArray->sanitize (&sc) || - (fdSelect == &Null(CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) - { fini (); return; } + fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset, sc, fdArray->count); + if (unlikely (fdArray == &Null (CFF1FDArray) || + fdSelect == &Null (CFF1FDSelect))) + goto fail; fdCount = fdArray->count; } else { - fdArray = &Null(CFF1FDArray); - fdSelect = &Null(CFF1FDSelect); + fdArray = &Null (CFF1FDArray); + fdSelect = &Null (CFF1FDSelect); } - stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ()); - if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) - { fini (); return; } - - globalSubrs = &StructAtOffset<CFF1Subrs> (stringIndex, stringIndex->get_size ()); - if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) - { fini (); return; } + encoding = &Null (Encoding); + if (is_CID ()) + { + if (unlikely (charset == &Null (Charset))) goto fail; + } + else + { + if (!is_predef_encoding ()) + { + encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset, sc); + if (unlikely (encoding == &Null (Encoding))) goto fail; + } + } - charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset); + stringIndex = &StructAtOffsetOrNull<CFF1StringIndex> (topDictIndex, topDictIndex->get_size (), sc); + if (stringIndex == &Null (CFF1StringIndex)) + goto fail; - if ((charStrings == &Null(CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) - { fini (); return; } + globalSubrs = &StructAtOffsetOrNull<CFF1Subrs> (stringIndex, stringIndex->get_size (), sc); + charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset, sc); + if (charStrings == &Null (CFF1CharStrings)) + goto fail; num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) - { fini (); return; } + goto fail; - privateDicts.resize (fdCount); + if (unlikely (!privateDicts.resize (fdCount))) + goto fail; for (unsigned int i = 0; i < fdCount; i++) privateDicts[i].init (); @@ -1102,59 +1166,61 @@ struct cff1 { for (unsigned int i = 0; i < fdCount; i++) { - byte_str_t fontDictStr = (*fdArray)[i]; - if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; } - cff1_font_dict_values_t *font; - cff1_font_dict_interpreter_t font_interp; - font_interp.env.init (fontDictStr); + hb_ubytes_t fontDictStr = (*fdArray)[i]; + if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); + cff1_font_dict_values_t *font; + cff1_top_dict_interp_env_t env (fontDictStr); + cff1_font_dict_interpreter_t font_interp (env); font = fontDicts.push (); - if (unlikely (font == &Crap(cff1_font_dict_values_t))) { fini (); return; } + if (unlikely (fontDicts.in_error ())) goto fail; + font->init (); - if (unlikely (!font_interp.interpret (*font))) { fini (); return; } - PRIVDICTVAL *priv = &privateDicts[i]; - const byte_str_t privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } - dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp; - priv_interp.env.init (privDictStr); + if (unlikely (!font_interp.interpret (*font))) goto fail; + PRIVDICTVAL *priv = &privateDicts[i]; + const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + num_interp_env_t env2 (privDictStr); + dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2); priv->init (); - if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } + if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null(CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - { fini (); return; } + priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset, sc); } } else /* non-CID */ { - cff1_top_dict_values_t *font = &topDict; - PRIVDICTVAL *priv = &privateDicts[0]; + cff1_top_dict_values_t *font = &topDict; + PRIVDICTVAL *priv = &privateDicts[0]; - const byte_str_t privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; } - dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp; - priv_interp.env.init (privDictStr); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); + num_interp_env_t env (privDictStr); + dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env); priv->init (); - if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; } + if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null(CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - { fini (); return; } + priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset, sc); + hb_barrier (); } - } - 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; } - bool is_valid () const { return blob != nullptr; } + hb_blob_t *get_blob () const { return blob; } + + bool is_valid () const { return blob; } bool is_CID () const { return topDict.is_CID (); } bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; } @@ -1165,73 +1231,23 @@ struct cff1 if (unlikely (sid == CFF_UNDEF_SID)) return 0; - if (charset != &Null(Charset)) + if (charset != &Null (Charset)) return charset->get_glyph (sid, num_glyphs); else if ((topDict.CharsetOffset == ISOAdobeCharset) && (code <= 228 /*zcaron*/)) return sid; return 0; } - protected: - hb_blob_t *blob; - hb_sanitize_context_t sc; - - public: - const Charset *charset; - const CFF1NameIndex *nameIndex; - const CFF1TopDictIndex *topDictIndex; - const CFF1StringIndex *stringIndex; - const CFF1Subrs *globalSubrs; - const CFF1CharStrings *charStrings; - const CFF1FDArray *fdArray; - const CFF1FDSelect *fdSelect; - unsigned int fdCount; - - cff1_top_dict_values_t topDict; - hb_vector_t<cff1_font_dict_values_t> fontDicts; - hb_vector_t<PRIVDICTVAL> privateDicts; - - unsigned int num_glyphs; - }; - - struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> - { - HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; - }; - - struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> - { - void init (hb_face_t *face) - { - SUPER::init (face); - if (blob == nullptr) return; - - const OT::cff1 *cff = this->blob->as<OT::cff1> (); - encoding = &Null(Encoding); - if (is_CID ()) - { - if (unlikely (charset == &Null(Charset))) { fini (); return; } - } - else - { - if (!is_predef_encoding ()) - { - encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; } - } - } - } - bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; } - hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const + hb_codepoint_t glyph_to_code (hb_codepoint_t glyph, + code_pair_t *glyph_to_sid_cache = nullptr) const { - if (encoding != &Null(Encoding)) + if (encoding != &Null (Encoding)) return encoding->get_code (glyph); else { - hb_codepoint_t sid = glyph_to_sid (glyph); + hb_codepoint_t sid = glyph_to_sid (glyph, glyph_to_sid_cache); if (sid == 0) return 0; hb_codepoint_t code = 0; switch (topDict.EncodingOffset) @@ -1249,22 +1265,38 @@ struct cff1 } } - hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const + glyph_to_sid_map_t *create_glyph_to_sid_map () const + { + if (charset != &Null (Charset)) + { + auto *mapping = (glyph_to_sid_map_t *) hb_malloc (sizeof (glyph_to_sid_map_t)); + if (unlikely (!mapping)) return nullptr; + mapping = new (mapping) glyph_to_sid_map_t (); + mapping->push (code_pair_t {0, 1}); + charset->collect_glyph_to_sid_map (mapping, num_glyphs); + return mapping; + } + else + return nullptr; + } + + hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph, + code_pair_t *cache = nullptr) const { - if (charset != &Null(Charset)) - return charset->get_sid (glyph); + if (charset != &Null (Charset)) + return charset->get_sid (glyph, num_glyphs, cache); else { hb_codepoint_t sid = 0; switch (topDict.CharsetOffset) { - case ISOAdobeCharset: + case ISOAdobeCharset: if (glyph <= 228 /*zcaron*/) sid = glyph; break; - case ExpertCharset: + case ExpertCharset: sid = lookup_expert_charset_for_sid (glyph); break; - case ExpertSubsetCharset: + case ExpertSubsetCharset: sid = lookup_expert_subset_charset_for_sid (glyph); break; default: @@ -1274,47 +1306,235 @@ struct cff1 } } - const Encoding *encoding; + hb_codepoint_t sid_to_glyph (hb_codepoint_t sid) const + { + if (charset != &Null (Charset)) + return charset->get_glyph (sid, num_glyphs); + else + { + hb_codepoint_t glyph = 0; + switch (topDict.CharsetOffset) + { + case ISOAdobeCharset: + if (sid <= 228 /*zcaron*/) glyph = sid; + break; + case ExpertCharset: + glyph = lookup_expert_charset_for_glyph (sid); + break; + case ExpertSubsetCharset: + glyph = lookup_expert_subset_charset_for_glyph (sid); + break; + default: + break; + } + return glyph; + } + } + + protected: + hb_sanitize_context_t sc; + + public: + hb_blob_t *blob = nullptr; + const Encoding *encoding = nullptr; + const Charset *charset = nullptr; + const CFF1NameIndex *nameIndex = nullptr; + const CFF1TopDictIndex *topDictIndex = nullptr; + const CFF1StringIndex *stringIndex = nullptr; + const CFF1Subrs *globalSubrs = nullptr; + const CFF1CharStrings *charStrings = nullptr; + const CFF1FDArray *fdArray = nullptr; + const CFF1FDSelect *fdSelect = nullptr; + unsigned int fdCount = 0; + + cff1_top_dict_values_t topDict; + hb_vector_t<cff1_font_dict_values_t> + fontDicts; + hb_vector_t<PRIVDICTVAL> privateDicts; + + unsigned int num_glyphs = 0; + unsigned int num_charset_entries = 0; + }; + + struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> + { + accelerator_t (hb_face_t *face) : SUPER (face) + { + glyph_names.set_relaxed (nullptr); + + if (!is_valid ()) return; + if (is_CID ()) return; + } + ~accelerator_t () + { + hb_sorted_vector_t<gname_t> *names = glyph_names.get_relaxed (); + if (names) + { + names->fini (); + hb_free (names); + } + } + + bool get_glyph_name (hb_codepoint_t glyph, + char *buf, unsigned int buf_len) const + { + if (unlikely (glyph >= num_glyphs)) return false; + if (unlikely (!is_valid ())) return false; + if (is_CID()) return false; + if (unlikely (!buf_len)) return true; + hb_codepoint_t sid = glyph_to_sid (glyph); + const char *str; + size_t str_len; + if (sid < cff1_std_strings_length) + { + hb_bytes_t byte_str = cff1_std_strings (sid); + str = byte_str.arrayZ; + str_len = byte_str.length; + } + else + { + hb_ubytes_t ubyte_str = (*stringIndex)[sid - cff1_std_strings_length]; + str = (const char *)ubyte_str.arrayZ; + str_len = ubyte_str.length; + } + if (!str_len) return false; + unsigned int len = hb_min (buf_len - 1, str_len); + strncpy (buf, (const char*)str, len); + buf[len] = '\0'; + return true; + } + + bool get_glyph_from_name (const char *name, int len, + hb_codepoint_t *glyph) const + { + if (unlikely (!is_valid ())) return false; + if (is_CID()) return false; + if (len < 0) len = strlen (name); + if (unlikely (!len)) return false; + + retry: + hb_sorted_vector_t<gname_t> *names = glyph_names.get_acquire (); + if (unlikely (!names)) + { + names = (hb_sorted_vector_t<gname_t> *) hb_calloc (1, sizeof (hb_sorted_vector_t<gname_t>)); + if (likely (names)) + { + names->init (); + /* TODO */ + + /* fill glyph names */ + code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID}; + for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) + { + hb_codepoint_t sid = glyph_to_sid (gid, &glyph_to_sid_cache); + gname_t gname; + gname.sid = sid; + if (sid < cff1_std_strings_length) + gname.name = cff1_std_strings (sid); + else + { + hb_ubytes_t ustr = (*stringIndex)[sid - cff1_std_strings_length]; + gname.name = hb_bytes_t ((const char*) ustr.arrayZ, ustr.length); + } + if (unlikely (!gname.name.arrayZ)) + gname.name = hb_bytes_t ("", 0); /* To avoid nullptr. */ + names->push (gname); + } + names->qsort (); + } + if (unlikely (!glyph_names.cmpexch (nullptr, names))) + { + if (names) + { + names->fini (); + hb_free (names); + } + goto retry; + } + } + + gname_t key = { hb_bytes_t (name, len), 0 }; + const gname_t *gname = names ? names->bsearch (key) : nullptr; + if (!gname) return false; + hb_codepoint_t gid = sid_to_glyph (gname->sid); + if (!gid && gname->sid) return false; + *glyph = gid; + return true; + } + + HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; + 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; private: - typedef accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> SUPER; + struct gname_t + { + hb_bytes_t name; + uint16_t sid; + + static int cmp (const void *a_, const void *b_) + { + const gname_t *a = (const gname_t *)a_; + const gname_t *b = (const gname_t *)b_; + unsigned minlen = hb_min (a->name.length, b->name.length); + int ret = strncmp (a->name.arrayZ, b->name.arrayZ, minlen); + if (ret) return ret; + return a->name.length - b->name.length; + } + + int cmp (const gname_t &a) const { return cmp (&a, this); } + }; + + mutable hb_atomic_ptr_t<hb_sorted_vector_t<gname_t>> glyph_names; + + typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER; }; - bool subset (hb_subset_plan_t *plan) const + struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset_t, cff1_private_dict_values_subset_t> { - hb_blob_t *cff_prime = nullptr; - - bool success = true; - if (hb_subset_cff1 (plan, &cff_prime)) { - success = success && plan->add_table (HB_OT_TAG_cff1, cff_prime); - hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source); - success = success && head_blob && plan->add_table (HB_OT_TAG_head, head_blob); - hb_blob_destroy (head_blob); - } else { - success = false; + accelerator_subset_t (hb_face_t *face) : SUPER (face) {} + ~accelerator_subset_t () + { + if (cff_accelerator) + cff_subset_accelerator_t::destroy (cff_accelerator); } - hb_blob_destroy (cff_prime); - return success; - } + HB_INTERNAL bool subset (hb_subset_context_t *c) const; + HB_INTERNAL bool serialize (hb_serialize_context_t *c, + struct cff1_subset_plan &plan) const; + HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; + + mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr; + + typedef accelerator_templ_t<cff1_private_dict_opset_subset_t, cff1_private_dict_values_subset_t> SUPER; + }; protected: HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid); HB_INTERNAL static hb_codepoint_t lookup_expert_encoding_for_code (hb_codepoint_t sid); HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_sid (hb_codepoint_t glyph); HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph); + HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_glyph (hb_codepoint_t sid); + HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid); HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_sid (hb_codepoint_t code); public: FixedVersion<HBUINT8> version; /* Version of CFF table. set to 0x0100u */ - OffsetTo<CFF1NameIndex, HBUINT8> nameIndex; /* headerSize = Offset to Name INDEX. */ + NNOffsetTo<CFF1NameIndex, HBUINT8> nameIndex; /* headerSize = Offset to Name INDEX. */ HBUINT8 offSize; /* offset size (unused?) */ public: DEFINE_SIZE_STATIC (4); }; -struct cff1_accelerator_t : cff1::accelerator_t {}; +struct cff1_accelerator_t : cff1::accelerator_t { + cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {} +}; + +struct cff1_subset_accelerator_t : cff1::accelerator_subset_t { + cff1_subset_accelerator_t (hb_face_t *face) : cff1::accelerator_subset_t (face) {} +}; + } /* namespace OT */ #endif /* HB_OT_CFF1_TABLE_HH */ |