1*2d1272b8SAndroid Build Coastguard Worker /* 2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2018 Adobe Inc. 3*2d1272b8SAndroid Build Coastguard Worker * 4*2d1272b8SAndroid Build Coastguard Worker * This is part of HarfBuzz, a text shaping library. 5*2d1272b8SAndroid Build Coastguard Worker * 6*2d1272b8SAndroid Build Coastguard Worker * Permission is hereby granted, without written agreement and without 7*2d1272b8SAndroid Build Coastguard Worker * license or royalty fees, to use, copy, modify, and distribute this 8*2d1272b8SAndroid Build Coastguard Worker * software and its documentation for any purpose, provided that the 9*2d1272b8SAndroid Build Coastguard Worker * above copyright notice and the following two paragraphs appear in 10*2d1272b8SAndroid Build Coastguard Worker * all copies of this software. 11*2d1272b8SAndroid Build Coastguard Worker * 12*2d1272b8SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13*2d1272b8SAndroid Build Coastguard Worker * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14*2d1272b8SAndroid Build Coastguard Worker * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15*2d1272b8SAndroid Build Coastguard Worker * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16*2d1272b8SAndroid Build Coastguard Worker * DAMAGE. 17*2d1272b8SAndroid Build Coastguard Worker * 18*2d1272b8SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19*2d1272b8SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20*2d1272b8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21*2d1272b8SAndroid Build Coastguard Worker * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22*2d1272b8SAndroid Build Coastguard Worker * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23*2d1272b8SAndroid Build Coastguard Worker * 24*2d1272b8SAndroid Build Coastguard Worker * Adobe Author(s): Michiharu Ariza 25*2d1272b8SAndroid Build Coastguard Worker */ 26*2d1272b8SAndroid Build Coastguard Worker 27*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_OT_CFF2_TABLE_HH 28*2d1272b8SAndroid Build Coastguard Worker #define HB_OT_CFF2_TABLE_HH 29*2d1272b8SAndroid Build Coastguard Worker 30*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-cff-common.hh" 31*2d1272b8SAndroid Build Coastguard Worker #include "hb-subset-cff-common.hh" 32*2d1272b8SAndroid Build Coastguard Worker #include "hb-draw.hh" 33*2d1272b8SAndroid Build Coastguard Worker #include "hb-paint.hh" 34*2d1272b8SAndroid Build Coastguard Worker 35*2d1272b8SAndroid Build Coastguard Worker namespace CFF { 36*2d1272b8SAndroid Build Coastguard Worker 37*2d1272b8SAndroid Build Coastguard Worker /* 38*2d1272b8SAndroid Build Coastguard Worker * CFF2 -- Compact Font Format (CFF) Version 2 39*2d1272b8SAndroid Build Coastguard Worker * https://docs.microsoft.com/en-us/typography/opentype/spec/cff2 40*2d1272b8SAndroid Build Coastguard Worker */ 41*2d1272b8SAndroid Build Coastguard Worker #define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2') 42*2d1272b8SAndroid Build Coastguard Worker 43*2d1272b8SAndroid Build Coastguard Worker typedef CFF2Index CFF2CharStrings; 44*2d1272b8SAndroid Build Coastguard Worker typedef Subrs<HBUINT32> CFF2Subrs; 45*2d1272b8SAndroid Build Coastguard Worker 46*2d1272b8SAndroid Build Coastguard Worker typedef FDSelect3_4<HBUINT32, HBUINT16> FDSelect4; 47*2d1272b8SAndroid Build Coastguard Worker typedef FDSelect3_4_Range<HBUINT32, HBUINT16> FDSelect4_Range; 48*2d1272b8SAndroid Build Coastguard Worker 49*2d1272b8SAndroid Build Coastguard Worker struct CFF2FDSelect 50*2d1272b8SAndroid Build Coastguard Worker { serializeCFF::CFF2FDSelect51*2d1272b8SAndroid Build Coastguard Worker bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs) 52*2d1272b8SAndroid Build Coastguard Worker { 53*2d1272b8SAndroid Build Coastguard Worker TRACE_SERIALIZE (this); 54*2d1272b8SAndroid Build Coastguard Worker unsigned int size = src.get_size (num_glyphs); 55*2d1272b8SAndroid Build Coastguard Worker CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size); 56*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!dest)) return_trace (false); 57*2d1272b8SAndroid Build Coastguard Worker hb_memcpy (dest, &src, size); 58*2d1272b8SAndroid Build Coastguard Worker return_trace (true); 59*2d1272b8SAndroid Build Coastguard Worker } 60*2d1272b8SAndroid Build Coastguard Worker get_sizeCFF::CFF2FDSelect61*2d1272b8SAndroid Build Coastguard Worker unsigned int get_size (unsigned int num_glyphs) const 62*2d1272b8SAndroid Build Coastguard Worker { 63*2d1272b8SAndroid Build Coastguard Worker switch (format) 64*2d1272b8SAndroid Build Coastguard Worker { 65*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return format.static_size + u.format0.get_size (num_glyphs); 66*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return format.static_size + u.format3.get_size (); 67*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return format.static_size + u.format4.get_size (); 68*2d1272b8SAndroid Build Coastguard Worker default:return 0; 69*2d1272b8SAndroid Build Coastguard Worker } 70*2d1272b8SAndroid Build Coastguard Worker } 71*2d1272b8SAndroid Build Coastguard Worker get_fdCFF::CFF2FDSelect72*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t get_fd (hb_codepoint_t glyph) const 73*2d1272b8SAndroid Build Coastguard Worker { 74*2d1272b8SAndroid Build Coastguard Worker if (this == &Null (CFF2FDSelect)) 75*2d1272b8SAndroid Build Coastguard Worker return 0; 76*2d1272b8SAndroid Build Coastguard Worker 77*2d1272b8SAndroid Build Coastguard Worker switch (format) 78*2d1272b8SAndroid Build Coastguard Worker { 79*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return u.format0.get_fd (glyph); 80*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return u.format3.get_fd (glyph); 81*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return u.format4.get_fd (glyph); 82*2d1272b8SAndroid Build Coastguard Worker default:return 0; 83*2d1272b8SAndroid Build Coastguard Worker } 84*2d1272b8SAndroid Build Coastguard Worker } 85*2d1272b8SAndroid Build Coastguard Worker sanitizeCFF::CFF2FDSelect86*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const 87*2d1272b8SAndroid Build Coastguard Worker { 88*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 89*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!c->check_struct (this))) 90*2d1272b8SAndroid Build Coastguard Worker return_trace (false); 91*2d1272b8SAndroid Build Coastguard Worker hb_barrier (); 92*2d1272b8SAndroid Build Coastguard Worker 93*2d1272b8SAndroid Build Coastguard Worker switch (format) 94*2d1272b8SAndroid Build Coastguard Worker { 95*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return_trace (u.format0.sanitize (c, fdcount)); 96*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return_trace (u.format3.sanitize (c, fdcount)); 97*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return_trace (u.format4.sanitize (c, fdcount)); 98*2d1272b8SAndroid Build Coastguard Worker default:return_trace (false); 99*2d1272b8SAndroid Build Coastguard Worker } 100*2d1272b8SAndroid Build Coastguard Worker } 101*2d1272b8SAndroid Build Coastguard Worker 102*2d1272b8SAndroid Build Coastguard Worker HBUINT8 format; 103*2d1272b8SAndroid Build Coastguard Worker union { 104*2d1272b8SAndroid Build Coastguard Worker FDSelect0 format0; 105*2d1272b8SAndroid Build Coastguard Worker FDSelect3 format3; 106*2d1272b8SAndroid Build Coastguard Worker FDSelect4 format4; 107*2d1272b8SAndroid Build Coastguard Worker } u; 108*2d1272b8SAndroid Build Coastguard Worker public: 109*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_MIN (2); 110*2d1272b8SAndroid Build Coastguard Worker }; 111*2d1272b8SAndroid Build Coastguard Worker 112*2d1272b8SAndroid Build Coastguard Worker struct CFF2ItemVariationStore 113*2d1272b8SAndroid Build Coastguard Worker { sanitizeCFF::CFF2ItemVariationStore114*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 115*2d1272b8SAndroid Build Coastguard Worker { 116*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 117*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this) && 118*2d1272b8SAndroid Build Coastguard Worker hb_barrier () && 119*2d1272b8SAndroid Build Coastguard Worker c->check_range (&varStore, size) && 120*2d1272b8SAndroid Build Coastguard Worker varStore.sanitize (c)); 121*2d1272b8SAndroid Build Coastguard Worker } 122*2d1272b8SAndroid Build Coastguard Worker serializeCFF::CFF2ItemVariationStore123*2d1272b8SAndroid Build Coastguard Worker bool serialize (hb_serialize_context_t *c, const CFF2ItemVariationStore *varStore) 124*2d1272b8SAndroid Build Coastguard Worker { 125*2d1272b8SAndroid Build Coastguard Worker TRACE_SERIALIZE (this); 126*2d1272b8SAndroid Build Coastguard Worker unsigned int size_ = varStore->get_size (); 127*2d1272b8SAndroid Build Coastguard Worker CFF2ItemVariationStore *dest = c->allocate_size<CFF2ItemVariationStore> (size_); 128*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!dest)) return_trace (false); 129*2d1272b8SAndroid Build Coastguard Worker hb_memcpy (dest, varStore, size_); 130*2d1272b8SAndroid Build Coastguard Worker return_trace (true); 131*2d1272b8SAndroid Build Coastguard Worker } 132*2d1272b8SAndroid Build Coastguard Worker get_sizeCFF::CFF2ItemVariationStore133*2d1272b8SAndroid Build Coastguard Worker unsigned int get_size () const { return HBUINT16::static_size + size; } 134*2d1272b8SAndroid Build Coastguard Worker 135*2d1272b8SAndroid Build Coastguard Worker HBUINT16 size; 136*2d1272b8SAndroid Build Coastguard Worker ItemVariationStore varStore; 137*2d1272b8SAndroid Build Coastguard Worker 138*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_MIN (2 + ItemVariationStore::min_size); 139*2d1272b8SAndroid Build Coastguard Worker }; 140*2d1272b8SAndroid Build Coastguard Worker 141*2d1272b8SAndroid Build Coastguard Worker struct cff2_top_dict_values_t : top_dict_values_t<> 142*2d1272b8SAndroid Build Coastguard Worker { initCFF::cff2_top_dict_values_t143*2d1272b8SAndroid Build Coastguard Worker void init () 144*2d1272b8SAndroid Build Coastguard Worker { 145*2d1272b8SAndroid Build Coastguard Worker top_dict_values_t<>::init (); 146*2d1272b8SAndroid Build Coastguard Worker vstoreOffset = 0; 147*2d1272b8SAndroid Build Coastguard Worker FDSelectOffset = 0; 148*2d1272b8SAndroid Build Coastguard Worker } finiCFF::cff2_top_dict_values_t149*2d1272b8SAndroid Build Coastguard Worker void fini () { top_dict_values_t<>::fini (); } 150*2d1272b8SAndroid Build Coastguard Worker 151*2d1272b8SAndroid Build Coastguard Worker int vstoreOffset; 152*2d1272b8SAndroid Build Coastguard Worker int FDSelectOffset; 153*2d1272b8SAndroid Build Coastguard Worker }; 154*2d1272b8SAndroid Build Coastguard Worker 155*2d1272b8SAndroid Build Coastguard Worker struct cff2_top_dict_opset_t : top_dict_opset_t<> 156*2d1272b8SAndroid Build Coastguard Worker { process_opCFF::cff2_top_dict_opset_t157*2d1272b8SAndroid Build Coastguard Worker static void process_op (op_code_t op, num_interp_env_t& env, cff2_top_dict_values_t& dictval) 158*2d1272b8SAndroid Build Coastguard Worker { 159*2d1272b8SAndroid Build Coastguard Worker switch (op) { 160*2d1272b8SAndroid Build Coastguard Worker case OpCode_FontMatrix: 161*2d1272b8SAndroid Build Coastguard Worker { 162*2d1272b8SAndroid Build Coastguard Worker dict_val_t val; 163*2d1272b8SAndroid Build Coastguard Worker val.init (); 164*2d1272b8SAndroid Build Coastguard Worker dictval.add_op (op, env.str_ref); 165*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 166*2d1272b8SAndroid Build Coastguard Worker } 167*2d1272b8SAndroid Build Coastguard Worker break; 168*2d1272b8SAndroid Build Coastguard Worker 169*2d1272b8SAndroid Build Coastguard Worker case OpCode_vstore: 170*2d1272b8SAndroid Build Coastguard Worker dictval.vstoreOffset = env.argStack.pop_int (); 171*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 172*2d1272b8SAndroid Build Coastguard Worker break; 173*2d1272b8SAndroid Build Coastguard Worker case OpCode_FDSelect: 174*2d1272b8SAndroid Build Coastguard Worker dictval.FDSelectOffset = env.argStack.pop_int (); 175*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 176*2d1272b8SAndroid Build Coastguard Worker break; 177*2d1272b8SAndroid Build Coastguard Worker 178*2d1272b8SAndroid Build Coastguard Worker default: 179*2d1272b8SAndroid Build Coastguard Worker SUPER::process_op (op, env, dictval); 180*2d1272b8SAndroid Build Coastguard Worker /* Record this operand below if stack is empty, otherwise done */ 181*2d1272b8SAndroid Build Coastguard Worker if (!env.argStack.is_empty ()) return; 182*2d1272b8SAndroid Build Coastguard Worker } 183*2d1272b8SAndroid Build Coastguard Worker 184*2d1272b8SAndroid Build Coastguard Worker if (unlikely (env.in_error ())) return; 185*2d1272b8SAndroid Build Coastguard Worker 186*2d1272b8SAndroid Build Coastguard Worker dictval.add_op (op, env.str_ref); 187*2d1272b8SAndroid Build Coastguard Worker } 188*2d1272b8SAndroid Build Coastguard Worker 189*2d1272b8SAndroid Build Coastguard Worker typedef top_dict_opset_t<> SUPER; 190*2d1272b8SAndroid Build Coastguard Worker }; 191*2d1272b8SAndroid Build Coastguard Worker 192*2d1272b8SAndroid Build Coastguard Worker struct cff2_font_dict_values_t : dict_values_t<op_str_t> 193*2d1272b8SAndroid Build Coastguard Worker { initCFF::cff2_font_dict_values_t194*2d1272b8SAndroid Build Coastguard Worker void init () 195*2d1272b8SAndroid Build Coastguard Worker { 196*2d1272b8SAndroid Build Coastguard Worker dict_values_t<op_str_t>::init (); 197*2d1272b8SAndroid Build Coastguard Worker privateDictInfo.init (); 198*2d1272b8SAndroid Build Coastguard Worker } finiCFF::cff2_font_dict_values_t199*2d1272b8SAndroid Build Coastguard Worker void fini () { dict_values_t<op_str_t>::fini (); } 200*2d1272b8SAndroid Build Coastguard Worker 201*2d1272b8SAndroid Build Coastguard Worker table_info_t privateDictInfo; 202*2d1272b8SAndroid Build Coastguard Worker }; 203*2d1272b8SAndroid Build Coastguard Worker 204*2d1272b8SAndroid Build Coastguard Worker struct cff2_font_dict_opset_t : dict_opset_t 205*2d1272b8SAndroid Build Coastguard Worker { process_opCFF::cff2_font_dict_opset_t206*2d1272b8SAndroid Build Coastguard Worker static void process_op (op_code_t op, num_interp_env_t& env, cff2_font_dict_values_t& dictval) 207*2d1272b8SAndroid Build Coastguard Worker { 208*2d1272b8SAndroid Build Coastguard Worker switch (op) { 209*2d1272b8SAndroid Build Coastguard Worker case OpCode_Private: 210*2d1272b8SAndroid Build Coastguard Worker dictval.privateDictInfo.offset = env.argStack.pop_uint (); 211*2d1272b8SAndroid Build Coastguard Worker dictval.privateDictInfo.size = env.argStack.pop_uint (); 212*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 213*2d1272b8SAndroid Build Coastguard Worker break; 214*2d1272b8SAndroid Build Coastguard Worker 215*2d1272b8SAndroid Build Coastguard Worker default: 216*2d1272b8SAndroid Build Coastguard Worker SUPER::process_op (op, env); 217*2d1272b8SAndroid Build Coastguard Worker if (!env.argStack.is_empty ()) 218*2d1272b8SAndroid Build Coastguard Worker return; 219*2d1272b8SAndroid Build Coastguard Worker } 220*2d1272b8SAndroid Build Coastguard Worker 221*2d1272b8SAndroid Build Coastguard Worker if (unlikely (env.in_error ())) return; 222*2d1272b8SAndroid Build Coastguard Worker 223*2d1272b8SAndroid Build Coastguard Worker dictval.add_op (op, env.str_ref); 224*2d1272b8SAndroid Build Coastguard Worker } 225*2d1272b8SAndroid Build Coastguard Worker 226*2d1272b8SAndroid Build Coastguard Worker private: 227*2d1272b8SAndroid Build Coastguard Worker typedef dict_opset_t SUPER; 228*2d1272b8SAndroid Build Coastguard Worker }; 229*2d1272b8SAndroid Build Coastguard Worker 230*2d1272b8SAndroid Build Coastguard Worker template <typename VAL> 231*2d1272b8SAndroid Build Coastguard Worker struct cff2_private_dict_values_base_t : dict_values_t<VAL> 232*2d1272b8SAndroid Build Coastguard Worker { initCFF::cff2_private_dict_values_base_t233*2d1272b8SAndroid Build Coastguard Worker void init () 234*2d1272b8SAndroid Build Coastguard Worker { 235*2d1272b8SAndroid Build Coastguard Worker dict_values_t<VAL>::init (); 236*2d1272b8SAndroid Build Coastguard Worker subrsOffset = 0; 237*2d1272b8SAndroid Build Coastguard Worker localSubrs = &Null (CFF2Subrs); 238*2d1272b8SAndroid Build Coastguard Worker ivs = 0; 239*2d1272b8SAndroid Build Coastguard Worker } finiCFF::cff2_private_dict_values_base_t240*2d1272b8SAndroid Build Coastguard Worker void fini () { dict_values_t<VAL>::fini (); } 241*2d1272b8SAndroid Build Coastguard Worker 242*2d1272b8SAndroid Build Coastguard Worker int subrsOffset; 243*2d1272b8SAndroid Build Coastguard Worker const CFF2Subrs *localSubrs; 244*2d1272b8SAndroid Build Coastguard Worker unsigned int ivs; 245*2d1272b8SAndroid Build Coastguard Worker }; 246*2d1272b8SAndroid Build Coastguard Worker 247*2d1272b8SAndroid Build Coastguard Worker typedef cff2_private_dict_values_base_t<op_str_t> cff2_private_dict_values_subset_t; 248*2d1272b8SAndroid Build Coastguard Worker typedef cff2_private_dict_values_base_t<num_dict_val_t> cff2_private_dict_values_t; 249*2d1272b8SAndroid Build Coastguard Worker 250*2d1272b8SAndroid Build Coastguard Worker struct cff2_priv_dict_interp_env_t : num_interp_env_t 251*2d1272b8SAndroid Build Coastguard Worker { cff2_priv_dict_interp_env_tCFF::cff2_priv_dict_interp_env_t252*2d1272b8SAndroid Build Coastguard Worker cff2_priv_dict_interp_env_t (const hb_ubytes_t &str) : 253*2d1272b8SAndroid Build Coastguard Worker num_interp_env_t (str) {} 254*2d1272b8SAndroid Build Coastguard Worker process_vsindexCFF::cff2_priv_dict_interp_env_t255*2d1272b8SAndroid Build Coastguard Worker void process_vsindex () 256*2d1272b8SAndroid Build Coastguard Worker { 257*2d1272b8SAndroid Build Coastguard Worker if (likely (!seen_vsindex)) 258*2d1272b8SAndroid Build Coastguard Worker { 259*2d1272b8SAndroid Build Coastguard Worker set_ivs (argStack.pop_uint ()); 260*2d1272b8SAndroid Build Coastguard Worker } 261*2d1272b8SAndroid Build Coastguard Worker seen_vsindex = true; 262*2d1272b8SAndroid Build Coastguard Worker } 263*2d1272b8SAndroid Build Coastguard Worker get_ivsCFF::cff2_priv_dict_interp_env_t264*2d1272b8SAndroid Build Coastguard Worker unsigned int get_ivs () const { return ivs; } set_ivsCFF::cff2_priv_dict_interp_env_t265*2d1272b8SAndroid Build Coastguard Worker void set_ivs (unsigned int ivs_) { ivs = ivs_; } 266*2d1272b8SAndroid Build Coastguard Worker 267*2d1272b8SAndroid Build Coastguard Worker protected: 268*2d1272b8SAndroid Build Coastguard Worker unsigned int ivs = 0; 269*2d1272b8SAndroid Build Coastguard Worker bool seen_vsindex = false; 270*2d1272b8SAndroid Build Coastguard Worker }; 271*2d1272b8SAndroid Build Coastguard Worker 272*2d1272b8SAndroid Build Coastguard Worker struct cff2_private_dict_opset_t : dict_opset_t 273*2d1272b8SAndroid Build Coastguard Worker { process_opCFF::cff2_private_dict_opset_t274*2d1272b8SAndroid Build Coastguard Worker static void process_op (op_code_t op, cff2_priv_dict_interp_env_t& env, cff2_private_dict_values_t& dictval) 275*2d1272b8SAndroid Build Coastguard Worker { 276*2d1272b8SAndroid Build Coastguard Worker num_dict_val_t val; 277*2d1272b8SAndroid Build Coastguard Worker val.init (); 278*2d1272b8SAndroid Build Coastguard Worker 279*2d1272b8SAndroid Build Coastguard Worker switch (op) { 280*2d1272b8SAndroid Build Coastguard Worker case OpCode_StdHW: 281*2d1272b8SAndroid Build Coastguard Worker case OpCode_StdVW: 282*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueScale: 283*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueShift: 284*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueFuzz: 285*2d1272b8SAndroid Build Coastguard Worker case OpCode_ExpansionFactor: 286*2d1272b8SAndroid Build Coastguard Worker case OpCode_LanguageGroup: 287*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueValues: 288*2d1272b8SAndroid Build Coastguard Worker case OpCode_OtherBlues: 289*2d1272b8SAndroid Build Coastguard Worker case OpCode_FamilyBlues: 290*2d1272b8SAndroid Build Coastguard Worker case OpCode_FamilyOtherBlues: 291*2d1272b8SAndroid Build Coastguard Worker case OpCode_StemSnapH: 292*2d1272b8SAndroid Build Coastguard Worker case OpCode_StemSnapV: 293*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 294*2d1272b8SAndroid Build Coastguard Worker break; 295*2d1272b8SAndroid Build Coastguard Worker case OpCode_Subrs: 296*2d1272b8SAndroid Build Coastguard Worker dictval.subrsOffset = env.argStack.pop_int (); 297*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 298*2d1272b8SAndroid Build Coastguard Worker break; 299*2d1272b8SAndroid Build Coastguard Worker case OpCode_vsindexdict: 300*2d1272b8SAndroid Build Coastguard Worker env.process_vsindex (); 301*2d1272b8SAndroid Build Coastguard Worker dictval.ivs = env.get_ivs (); 302*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 303*2d1272b8SAndroid Build Coastguard Worker break; 304*2d1272b8SAndroid Build Coastguard Worker case OpCode_blenddict: 305*2d1272b8SAndroid Build Coastguard Worker break; 306*2d1272b8SAndroid Build Coastguard Worker 307*2d1272b8SAndroid Build Coastguard Worker default: 308*2d1272b8SAndroid Build Coastguard Worker dict_opset_t::process_op (op, env); 309*2d1272b8SAndroid Build Coastguard Worker if (!env.argStack.is_empty ()) return; 310*2d1272b8SAndroid Build Coastguard Worker break; 311*2d1272b8SAndroid Build Coastguard Worker } 312*2d1272b8SAndroid Build Coastguard Worker 313*2d1272b8SAndroid Build Coastguard Worker if (unlikely (env.in_error ())) return; 314*2d1272b8SAndroid Build Coastguard Worker 315*2d1272b8SAndroid Build Coastguard Worker dictval.add_op (op, env.str_ref, val); 316*2d1272b8SAndroid Build Coastguard Worker } 317*2d1272b8SAndroid Build Coastguard Worker }; 318*2d1272b8SAndroid Build Coastguard Worker 319*2d1272b8SAndroid Build Coastguard Worker struct cff2_private_dict_opset_subset_t : dict_opset_t 320*2d1272b8SAndroid Build Coastguard Worker { process_opCFF::cff2_private_dict_opset_subset_t321*2d1272b8SAndroid Build Coastguard Worker static void process_op (op_code_t op, cff2_priv_dict_interp_env_t& env, cff2_private_dict_values_subset_t& dictval) 322*2d1272b8SAndroid Build Coastguard Worker { 323*2d1272b8SAndroid Build Coastguard Worker switch (op) { 324*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueValues: 325*2d1272b8SAndroid Build Coastguard Worker case OpCode_OtherBlues: 326*2d1272b8SAndroid Build Coastguard Worker case OpCode_FamilyBlues: 327*2d1272b8SAndroid Build Coastguard Worker case OpCode_FamilyOtherBlues: 328*2d1272b8SAndroid Build Coastguard Worker case OpCode_StdHW: 329*2d1272b8SAndroid Build Coastguard Worker case OpCode_StdVW: 330*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueScale: 331*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueShift: 332*2d1272b8SAndroid Build Coastguard Worker case OpCode_BlueFuzz: 333*2d1272b8SAndroid Build Coastguard Worker case OpCode_StemSnapH: 334*2d1272b8SAndroid Build Coastguard Worker case OpCode_StemSnapV: 335*2d1272b8SAndroid Build Coastguard Worker case OpCode_LanguageGroup: 336*2d1272b8SAndroid Build Coastguard Worker case OpCode_ExpansionFactor: 337*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 338*2d1272b8SAndroid Build Coastguard Worker break; 339*2d1272b8SAndroid Build Coastguard Worker 340*2d1272b8SAndroid Build Coastguard Worker case OpCode_blenddict: 341*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 342*2d1272b8SAndroid Build Coastguard Worker return; 343*2d1272b8SAndroid Build Coastguard Worker 344*2d1272b8SAndroid Build Coastguard Worker case OpCode_Subrs: 345*2d1272b8SAndroid Build Coastguard Worker dictval.subrsOffset = env.argStack.pop_int (); 346*2d1272b8SAndroid Build Coastguard Worker env.clear_args (); 347*2d1272b8SAndroid Build Coastguard Worker break; 348*2d1272b8SAndroid Build Coastguard Worker 349*2d1272b8SAndroid Build Coastguard Worker default: 350*2d1272b8SAndroid Build Coastguard Worker SUPER::process_op (op, env); 351*2d1272b8SAndroid Build Coastguard Worker if (!env.argStack.is_empty ()) return; 352*2d1272b8SAndroid Build Coastguard Worker break; 353*2d1272b8SAndroid Build Coastguard Worker } 354*2d1272b8SAndroid Build Coastguard Worker 355*2d1272b8SAndroid Build Coastguard Worker if (unlikely (env.in_error ())) return; 356*2d1272b8SAndroid Build Coastguard Worker 357*2d1272b8SAndroid Build Coastguard Worker dictval.add_op (op, env.str_ref); 358*2d1272b8SAndroid Build Coastguard Worker } 359*2d1272b8SAndroid Build Coastguard Worker 360*2d1272b8SAndroid Build Coastguard Worker private: 361*2d1272b8SAndroid Build Coastguard Worker typedef dict_opset_t SUPER; 362*2d1272b8SAndroid Build Coastguard Worker }; 363*2d1272b8SAndroid Build Coastguard Worker 364*2d1272b8SAndroid Build Coastguard Worker typedef dict_interpreter_t<cff2_top_dict_opset_t, cff2_top_dict_values_t> cff2_top_dict_interpreter_t; 365*2d1272b8SAndroid Build Coastguard Worker typedef dict_interpreter_t<cff2_font_dict_opset_t, cff2_font_dict_values_t> cff2_font_dict_interpreter_t; 366*2d1272b8SAndroid Build Coastguard Worker 367*2d1272b8SAndroid Build Coastguard Worker struct CFF2FDArray : FDArray<HBUINT32> 368*2d1272b8SAndroid Build Coastguard Worker { 369*2d1272b8SAndroid Build Coastguard Worker /* FDArray::serialize does not compile without this partial specialization */ 370*2d1272b8SAndroid Build Coastguard Worker template <typename ITER, typename OP_SERIALIZER> serializeCFF::CFF2FDArray371*2d1272b8SAndroid Build Coastguard Worker bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr) 372*2d1272b8SAndroid Build Coastguard Worker { return FDArray<HBUINT32>::serialize<cff2_font_dict_values_t, table_info_t> (c, it, opszr); } 373*2d1272b8SAndroid Build Coastguard Worker }; 374*2d1272b8SAndroid Build Coastguard Worker 375*2d1272b8SAndroid Build Coastguard Worker } /* namespace CFF */ 376*2d1272b8SAndroid Build Coastguard Worker 377*2d1272b8SAndroid Build Coastguard Worker namespace OT { 378*2d1272b8SAndroid Build Coastguard Worker 379*2d1272b8SAndroid Build Coastguard Worker using namespace CFF; 380*2d1272b8SAndroid Build Coastguard Worker 381*2d1272b8SAndroid Build Coastguard Worker struct cff2 382*2d1272b8SAndroid Build Coastguard Worker { 383*2d1272b8SAndroid Build Coastguard Worker static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF2; 384*2d1272b8SAndroid Build Coastguard Worker sanitizeOT::cff2385*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 386*2d1272b8SAndroid Build Coastguard Worker { 387*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 388*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this) && 389*2d1272b8SAndroid Build Coastguard Worker hb_barrier () && 390*2d1272b8SAndroid Build Coastguard Worker likely (version.major == 2)); 391*2d1272b8SAndroid Build Coastguard Worker } 392*2d1272b8SAndroid Build Coastguard Worker 393*2d1272b8SAndroid Build Coastguard Worker template <typename PRIVOPSET, typename PRIVDICTVAL> 394*2d1272b8SAndroid Build Coastguard Worker struct accelerator_templ_t 395*2d1272b8SAndroid Build Coastguard Worker { 396*2d1272b8SAndroid Build Coastguard Worker static constexpr hb_tag_t tableTag = cff2::tableTag; 397*2d1272b8SAndroid Build Coastguard Worker accelerator_templ_tOT::cff2::accelerator_templ_t398*2d1272b8SAndroid Build Coastguard Worker accelerator_templ_t (hb_face_t *face) 399*2d1272b8SAndroid Build Coastguard Worker { 400*2d1272b8SAndroid Build Coastguard Worker if (!face) return; 401*2d1272b8SAndroid Build Coastguard Worker 402*2d1272b8SAndroid Build Coastguard Worker topDict.init (); 403*2d1272b8SAndroid Build Coastguard Worker fontDicts.init (); 404*2d1272b8SAndroid Build Coastguard Worker privateDicts.init (); 405*2d1272b8SAndroid Build Coastguard Worker 406*2d1272b8SAndroid Build Coastguard Worker this->blob = sc.reference_table<cff2> (face); 407*2d1272b8SAndroid Build Coastguard Worker 408*2d1272b8SAndroid Build Coastguard Worker /* setup for run-time santization */ 409*2d1272b8SAndroid Build Coastguard Worker sc.init (this->blob); 410*2d1272b8SAndroid Build Coastguard Worker sc.start_processing (); 411*2d1272b8SAndroid Build Coastguard Worker 412*2d1272b8SAndroid Build Coastguard Worker const OT::cff2 *cff2 = this->blob->template as<OT::cff2> (); 413*2d1272b8SAndroid Build Coastguard Worker 414*2d1272b8SAndroid Build Coastguard Worker if (cff2 == &Null (OT::cff2)) 415*2d1272b8SAndroid Build Coastguard Worker goto fail; 416*2d1272b8SAndroid Build Coastguard Worker 417*2d1272b8SAndroid Build Coastguard Worker { /* parse top dict */ 418*2d1272b8SAndroid Build Coastguard Worker hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); 419*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!topDictStr.sanitize (&sc))) goto fail; 420*2d1272b8SAndroid Build Coastguard Worker hb_barrier (); 421*2d1272b8SAndroid Build Coastguard Worker num_interp_env_t env (topDictStr); 422*2d1272b8SAndroid Build Coastguard Worker cff2_top_dict_interpreter_t top_interp (env); 423*2d1272b8SAndroid Build Coastguard Worker topDict.init (); 424*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!top_interp.interpret (topDict))) goto fail; 425*2d1272b8SAndroid Build Coastguard Worker } 426*2d1272b8SAndroid Build Coastguard Worker 427*2d1272b8SAndroid Build Coastguard Worker globalSubrs = &StructAtOffsetOrNull<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize, sc); 428*2d1272b8SAndroid Build Coastguard Worker varStore = &StructAtOffsetOrNull<CFF2ItemVariationStore> (cff2, topDict.vstoreOffset, sc); 429*2d1272b8SAndroid Build Coastguard Worker charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset, sc); 430*2d1272b8SAndroid Build Coastguard Worker fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset, sc); 431*2d1272b8SAndroid Build Coastguard Worker fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset, sc, fdArray->count); 432*2d1272b8SAndroid Build Coastguard Worker 433*2d1272b8SAndroid Build Coastguard Worker if (charStrings == &Null (CFF2CharStrings) || 434*2d1272b8SAndroid Build Coastguard Worker globalSubrs == &Null (CFF2Subrs) || 435*2d1272b8SAndroid Build Coastguard Worker fdArray == &Null (CFF2FDArray)) 436*2d1272b8SAndroid Build Coastguard Worker goto fail; 437*2d1272b8SAndroid Build Coastguard Worker 438*2d1272b8SAndroid Build Coastguard Worker num_glyphs = charStrings->count; 439*2d1272b8SAndroid Build Coastguard Worker if (num_glyphs != sc.get_num_glyphs ()) 440*2d1272b8SAndroid Build Coastguard Worker goto fail; 441*2d1272b8SAndroid Build Coastguard Worker 442*2d1272b8SAndroid Build Coastguard Worker fdCount = fdArray->count; 443*2d1272b8SAndroid Build Coastguard Worker if (!privateDicts.resize (fdCount)) 444*2d1272b8SAndroid Build Coastguard Worker goto fail; 445*2d1272b8SAndroid Build Coastguard Worker 446*2d1272b8SAndroid Build Coastguard Worker /* parse font dicts and gather private dicts */ 447*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < fdCount; i++) 448*2d1272b8SAndroid Build Coastguard Worker { 449*2d1272b8SAndroid Build Coastguard Worker const hb_ubytes_t fontDictStr = (*fdArray)[i]; 450*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; 451*2d1272b8SAndroid Build Coastguard Worker hb_barrier (); 452*2d1272b8SAndroid Build Coastguard Worker cff2_font_dict_values_t *font; 453*2d1272b8SAndroid Build Coastguard Worker num_interp_env_t env (fontDictStr); 454*2d1272b8SAndroid Build Coastguard Worker cff2_font_dict_interpreter_t font_interp (env); 455*2d1272b8SAndroid Build Coastguard Worker font = fontDicts.push (); 456*2d1272b8SAndroid Build Coastguard Worker if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail; 457*2d1272b8SAndroid Build Coastguard Worker font->init (); 458*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!font_interp.interpret (*font))) goto fail; 459*2d1272b8SAndroid Build Coastguard Worker 460*2d1272b8SAndroid Build Coastguard Worker const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); 461*2d1272b8SAndroid Build Coastguard Worker if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; 462*2d1272b8SAndroid Build Coastguard Worker cff2_priv_dict_interp_env_t env2 (privDictStr); 463*2d1272b8SAndroid Build Coastguard Worker dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp (env2); 464*2d1272b8SAndroid Build Coastguard Worker privateDicts[i].init (); 465*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; 466*2d1272b8SAndroid Build Coastguard Worker 467*2d1272b8SAndroid Build Coastguard Worker privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset, sc); 468*2d1272b8SAndroid Build Coastguard Worker } 469*2d1272b8SAndroid Build Coastguard Worker 470*2d1272b8SAndroid Build Coastguard Worker return; 471*2d1272b8SAndroid Build Coastguard Worker 472*2d1272b8SAndroid Build Coastguard Worker fail: 473*2d1272b8SAndroid Build Coastguard Worker _fini (); 474*2d1272b8SAndroid Build Coastguard Worker } ~accelerator_templ_tOT::cff2::accelerator_templ_t475*2d1272b8SAndroid Build Coastguard Worker ~accelerator_templ_t () { _fini (); } _finiOT::cff2::accelerator_templ_t476*2d1272b8SAndroid Build Coastguard Worker void _fini () 477*2d1272b8SAndroid Build Coastguard Worker { 478*2d1272b8SAndroid Build Coastguard Worker sc.end_processing (); 479*2d1272b8SAndroid Build Coastguard Worker topDict.fini (); 480*2d1272b8SAndroid Build Coastguard Worker fontDicts.fini (); 481*2d1272b8SAndroid Build Coastguard Worker privateDicts.fini (); 482*2d1272b8SAndroid Build Coastguard Worker hb_blob_destroy (blob); 483*2d1272b8SAndroid Build Coastguard Worker blob = nullptr; 484*2d1272b8SAndroid Build Coastguard Worker } 485*2d1272b8SAndroid Build Coastguard Worker create_glyph_to_sid_mapOT::cff2::accelerator_templ_t486*2d1272b8SAndroid Build Coastguard Worker hb_vector_t<uint16_t> *create_glyph_to_sid_map () const 487*2d1272b8SAndroid Build Coastguard Worker { 488*2d1272b8SAndroid Build Coastguard Worker return nullptr; 489*2d1272b8SAndroid Build Coastguard Worker } 490*2d1272b8SAndroid Build Coastguard Worker get_blobOT::cff2::accelerator_templ_t491*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *get_blob () const { return blob; } 492*2d1272b8SAndroid Build Coastguard Worker is_validOT::cff2::accelerator_templ_t493*2d1272b8SAndroid Build Coastguard Worker bool is_valid () const { return blob; } 494*2d1272b8SAndroid Build Coastguard Worker 495*2d1272b8SAndroid Build Coastguard Worker protected: 496*2d1272b8SAndroid Build Coastguard Worker hb_sanitize_context_t sc; 497*2d1272b8SAndroid Build Coastguard Worker 498*2d1272b8SAndroid Build Coastguard Worker public: 499*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *blob = nullptr; 500*2d1272b8SAndroid Build Coastguard Worker cff2_top_dict_values_t topDict; 501*2d1272b8SAndroid Build Coastguard Worker const CFF2Subrs *globalSubrs = nullptr; 502*2d1272b8SAndroid Build Coastguard Worker const CFF2ItemVariationStore *varStore = nullptr; 503*2d1272b8SAndroid Build Coastguard Worker const CFF2CharStrings *charStrings = nullptr; 504*2d1272b8SAndroid Build Coastguard Worker const CFF2FDArray *fdArray = nullptr; 505*2d1272b8SAndroid Build Coastguard Worker const CFF2FDSelect *fdSelect = nullptr; 506*2d1272b8SAndroid Build Coastguard Worker unsigned int fdCount = 0; 507*2d1272b8SAndroid Build Coastguard Worker 508*2d1272b8SAndroid Build Coastguard Worker hb_vector_t<cff2_font_dict_values_t> fontDicts; 509*2d1272b8SAndroid Build Coastguard Worker hb_vector_t<PRIVDICTVAL> privateDicts; 510*2d1272b8SAndroid Build Coastguard Worker 511*2d1272b8SAndroid Build Coastguard Worker unsigned int num_glyphs = 0; 512*2d1272b8SAndroid Build Coastguard Worker }; 513*2d1272b8SAndroid Build Coastguard Worker 514*2d1272b8SAndroid Build Coastguard Worker struct accelerator_t : accelerator_templ_t<cff2_private_dict_opset_t, cff2_private_dict_values_t> 515*2d1272b8SAndroid Build Coastguard Worker { accelerator_tOT::cff2::accelerator_t516*2d1272b8SAndroid Build Coastguard Worker accelerator_t (hb_face_t *face) : accelerator_templ_t (face) {} 517*2d1272b8SAndroid Build Coastguard Worker 518*2d1272b8SAndroid Build Coastguard Worker HB_INTERNAL bool get_extents (hb_font_t *font, 519*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t glyph, 520*2d1272b8SAndroid Build Coastguard Worker hb_glyph_extents_t *extents) const; 521*2d1272b8SAndroid Build Coastguard Worker 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; 522*2d1272b8SAndroid Build Coastguard Worker HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; 523*2d1272b8SAndroid Build Coastguard Worker HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t<const int> coords) const; 524*2d1272b8SAndroid Build Coastguard Worker }; 525*2d1272b8SAndroid Build Coastguard Worker 526*2d1272b8SAndroid Build Coastguard Worker struct accelerator_subset_t : accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> 527*2d1272b8SAndroid Build Coastguard Worker { accelerator_subset_tOT::cff2::accelerator_subset_t528*2d1272b8SAndroid Build Coastguard Worker accelerator_subset_t (hb_face_t *face) : SUPER (face) {} ~accelerator_subset_tOT::cff2::accelerator_subset_t529*2d1272b8SAndroid Build Coastguard Worker ~accelerator_subset_t () 530*2d1272b8SAndroid Build Coastguard Worker { 531*2d1272b8SAndroid Build Coastguard Worker if (cff_accelerator) 532*2d1272b8SAndroid Build Coastguard Worker cff_subset_accelerator_t::destroy (cff_accelerator); 533*2d1272b8SAndroid Build Coastguard Worker } 534*2d1272b8SAndroid Build Coastguard Worker 535*2d1272b8SAndroid Build Coastguard Worker HB_INTERNAL bool subset (hb_subset_context_t *c) const; 536*2d1272b8SAndroid Build Coastguard Worker HB_INTERNAL bool serialize (hb_serialize_context_t *c, 537*2d1272b8SAndroid Build Coastguard Worker struct cff2_subset_plan &plan, 538*2d1272b8SAndroid Build Coastguard Worker hb_array_t<int> normalized_coords) const; 539*2d1272b8SAndroid Build Coastguard Worker 540*2d1272b8SAndroid Build Coastguard Worker mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr; 541*2d1272b8SAndroid Build Coastguard Worker 542*2d1272b8SAndroid Build Coastguard Worker typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> SUPER; 543*2d1272b8SAndroid Build Coastguard Worker }; 544*2d1272b8SAndroid Build Coastguard Worker 545*2d1272b8SAndroid Build Coastguard Worker public: 546*2d1272b8SAndroid Build Coastguard Worker FixedVersion<HBUINT8> version; /* Version of CFF2 table. set to 0x0200u */ 547*2d1272b8SAndroid Build Coastguard Worker NNOffsetTo<TopDict, HBUINT8> topDict; /* headerSize = Offset to Top DICT. */ 548*2d1272b8SAndroid Build Coastguard Worker HBUINT16 topDictSize; /* Top DICT size */ 549*2d1272b8SAndroid Build Coastguard Worker 550*2d1272b8SAndroid Build Coastguard Worker public: 551*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (5); 552*2d1272b8SAndroid Build Coastguard Worker }; 553*2d1272b8SAndroid Build Coastguard Worker 554*2d1272b8SAndroid Build Coastguard Worker struct cff2_accelerator_t : cff2::accelerator_t { cff2_accelerator_tOT::cff2_accelerator_t555*2d1272b8SAndroid Build Coastguard Worker cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {} 556*2d1272b8SAndroid Build Coastguard Worker }; 557*2d1272b8SAndroid Build Coastguard Worker 558*2d1272b8SAndroid Build Coastguard Worker struct cff2_subset_accelerator_t : cff2::accelerator_subset_t { cff2_subset_accelerator_tOT::cff2_subset_accelerator_t559*2d1272b8SAndroid Build Coastguard Worker cff2_subset_accelerator_t (hb_face_t *face) : cff2::accelerator_subset_t (face) {} 560*2d1272b8SAndroid Build Coastguard Worker }; 561*2d1272b8SAndroid Build Coastguard Worker 562*2d1272b8SAndroid Build Coastguard Worker } /* namespace OT */ 563*2d1272b8SAndroid Build Coastguard Worker 564*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_OT_CFF2_TABLE_HH */ 565