1*2d1272b8SAndroid Build Coastguard Worker /* 2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2017 Google, 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 * Google Author(s): Behdad Esfahbod 25*2d1272b8SAndroid Build Coastguard Worker */ 26*2d1272b8SAndroid Build Coastguard Worker 27*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_OT_KERN_TABLE_HH 28*2d1272b8SAndroid Build Coastguard Worker #define HB_OT_KERN_TABLE_HH 29*2d1272b8SAndroid Build Coastguard Worker 30*2d1272b8SAndroid Build Coastguard Worker #include "hb-aat-layout-kerx-table.hh" 31*2d1272b8SAndroid Build Coastguard Worker 32*2d1272b8SAndroid Build Coastguard Worker 33*2d1272b8SAndroid Build Coastguard Worker /* 34*2d1272b8SAndroid Build Coastguard Worker * kern -- Kerning 35*2d1272b8SAndroid Build Coastguard Worker * https://docs.microsoft.com/en-us/typography/opentype/spec/kern 36*2d1272b8SAndroid Build Coastguard Worker * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html 37*2d1272b8SAndroid Build Coastguard Worker */ 38*2d1272b8SAndroid Build Coastguard Worker #define HB_OT_TAG_kern HB_TAG('k','e','r','n') 39*2d1272b8SAndroid Build Coastguard Worker 40*2d1272b8SAndroid Build Coastguard Worker 41*2d1272b8SAndroid Build Coastguard Worker namespace OT { 42*2d1272b8SAndroid Build Coastguard Worker 43*2d1272b8SAndroid Build Coastguard Worker 44*2d1272b8SAndroid Build Coastguard Worker template <typename KernSubTableHeader> 45*2d1272b8SAndroid Build Coastguard Worker struct KernSubTableFormat3 46*2d1272b8SAndroid Build Coastguard Worker { get_kerningOT::KernSubTableFormat347*2d1272b8SAndroid Build Coastguard Worker int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const 48*2d1272b8SAndroid Build Coastguard Worker { 49*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount); 50*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount); 51*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount); 52*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount); 53*2d1272b8SAndroid Build Coastguard Worker 54*2d1272b8SAndroid Build Coastguard Worker unsigned int leftC = leftClass[left]; 55*2d1272b8SAndroid Build Coastguard Worker unsigned int rightC = rightClass[right]; 56*2d1272b8SAndroid Build Coastguard Worker if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount)) 57*2d1272b8SAndroid Build Coastguard Worker return 0; 58*2d1272b8SAndroid Build Coastguard Worker unsigned int i = leftC * rightClassCount + rightC; 59*2d1272b8SAndroid Build Coastguard Worker return kernValue[kernIndex[i]]; 60*2d1272b8SAndroid Build Coastguard Worker } 61*2d1272b8SAndroid Build Coastguard Worker applyOT::KernSubTableFormat362*2d1272b8SAndroid Build Coastguard Worker bool apply (AAT::hb_aat_apply_context_t *c) const 63*2d1272b8SAndroid Build Coastguard Worker { 64*2d1272b8SAndroid Build Coastguard Worker TRACE_APPLY (this); 65*2d1272b8SAndroid Build Coastguard Worker 66*2d1272b8SAndroid Build Coastguard Worker if (!c->plan->requested_kerning) 67*2d1272b8SAndroid Build Coastguard Worker return false; 68*2d1272b8SAndroid Build Coastguard Worker 69*2d1272b8SAndroid Build Coastguard Worker if (header.coverage & header.Backwards) 70*2d1272b8SAndroid Build Coastguard Worker return false; 71*2d1272b8SAndroid Build Coastguard Worker 72*2d1272b8SAndroid Build Coastguard Worker hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream); 73*2d1272b8SAndroid Build Coastguard Worker machine.kern (c->font, c->buffer, c->plan->kern_mask); 74*2d1272b8SAndroid Build Coastguard Worker 75*2d1272b8SAndroid Build Coastguard Worker return_trace (true); 76*2d1272b8SAndroid Build Coastguard Worker } 77*2d1272b8SAndroid Build Coastguard Worker sanitizeOT::KernSubTableFormat378*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 79*2d1272b8SAndroid Build Coastguard Worker { 80*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 81*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this) && 82*2d1272b8SAndroid Build Coastguard Worker hb_barrier () && 83*2d1272b8SAndroid Build Coastguard Worker c->check_range (kernValueZ, 84*2d1272b8SAndroid Build Coastguard Worker kernValueCount * sizeof (FWORD) + 85*2d1272b8SAndroid Build Coastguard Worker glyphCount * 2 + 86*2d1272b8SAndroid Build Coastguard Worker leftClassCount * rightClassCount)); 87*2d1272b8SAndroid Build Coastguard Worker } 88*2d1272b8SAndroid Build Coastguard Worker 89*2d1272b8SAndroid Build Coastguard Worker template <typename set_t> collect_glyphsOT::KernSubTableFormat390*2d1272b8SAndroid Build Coastguard Worker void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const 91*2d1272b8SAndroid Build Coastguard Worker { 92*2d1272b8SAndroid Build Coastguard Worker set_t set; 93*2d1272b8SAndroid Build Coastguard Worker if (likely (glyphCount)) 94*2d1272b8SAndroid Build Coastguard Worker set.add_range (0, glyphCount - 1); 95*2d1272b8SAndroid Build Coastguard Worker left_set.union_ (set); 96*2d1272b8SAndroid Build Coastguard Worker right_set.union_ (set); 97*2d1272b8SAndroid Build Coastguard Worker } 98*2d1272b8SAndroid Build Coastguard Worker 99*2d1272b8SAndroid Build Coastguard Worker protected: 100*2d1272b8SAndroid Build Coastguard Worker KernSubTableHeader 101*2d1272b8SAndroid Build Coastguard Worker header; 102*2d1272b8SAndroid Build Coastguard Worker HBUINT16 glyphCount; /* The number of glyphs in this font. */ 103*2d1272b8SAndroid Build Coastguard Worker HBUINT8 kernValueCount; /* The number of kerning values. */ 104*2d1272b8SAndroid Build Coastguard Worker HBUINT8 leftClassCount; /* The number of left-hand classes. */ 105*2d1272b8SAndroid Build Coastguard Worker HBUINT8 rightClassCount;/* The number of right-hand classes. */ 106*2d1272b8SAndroid Build Coastguard Worker HBUINT8 flags; /* Set to zero (reserved for future use). */ 107*2d1272b8SAndroid Build Coastguard Worker UnsizedArrayOf<FWORD> 108*2d1272b8SAndroid Build Coastguard Worker kernValueZ; /* The kerning values. 109*2d1272b8SAndroid Build Coastguard Worker * Length kernValueCount. */ 110*2d1272b8SAndroid Build Coastguard Worker #if 0 111*2d1272b8SAndroid Build Coastguard Worker UnsizedArrayOf<HBUINT8> 112*2d1272b8SAndroid Build Coastguard Worker leftClass; /* The left-hand classes. 113*2d1272b8SAndroid Build Coastguard Worker * Length glyphCount. */ 114*2d1272b8SAndroid Build Coastguard Worker UnsizedArrayOf<HBUINT8> 115*2d1272b8SAndroid Build Coastguard Worker rightClass; /* The right-hand classes. 116*2d1272b8SAndroid Build Coastguard Worker * Length glyphCount. */ 117*2d1272b8SAndroid Build Coastguard Worker UnsizedArrayOf<HBUINT8>kernIndex; 118*2d1272b8SAndroid Build Coastguard Worker /* The indices into the kernValue array. 119*2d1272b8SAndroid Build Coastguard Worker * Length leftClassCount * rightClassCount */ 120*2d1272b8SAndroid Build Coastguard Worker #endif 121*2d1272b8SAndroid Build Coastguard Worker public: 122*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ); 123*2d1272b8SAndroid Build Coastguard Worker }; 124*2d1272b8SAndroid Build Coastguard Worker 125*2d1272b8SAndroid Build Coastguard Worker template <typename KernSubTableHeader> 126*2d1272b8SAndroid Build Coastguard Worker struct KernSubTable 127*2d1272b8SAndroid Build Coastguard Worker { get_sizeOT::KernSubTable128*2d1272b8SAndroid Build Coastguard Worker unsigned int get_size () const { return u.header.length; } get_typeOT::KernSubTable129*2d1272b8SAndroid Build Coastguard Worker unsigned int get_type () const { return u.header.format; } 130*2d1272b8SAndroid Build Coastguard Worker get_kerningOT::KernSubTable131*2d1272b8SAndroid Build Coastguard Worker int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const 132*2d1272b8SAndroid Build Coastguard Worker { 133*2d1272b8SAndroid Build Coastguard Worker switch (get_type ()) { 134*2d1272b8SAndroid Build Coastguard Worker /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */ 135*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return u.format0.get_kerning (left, right); 136*2d1272b8SAndroid Build Coastguard Worker default:return 0; 137*2d1272b8SAndroid Build Coastguard Worker } 138*2d1272b8SAndroid Build Coastguard Worker } 139*2d1272b8SAndroid Build Coastguard Worker 140*2d1272b8SAndroid Build Coastguard Worker template <typename context_t, typename ...Ts> dispatchOT::KernSubTable141*2d1272b8SAndroid Build Coastguard Worker typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const 142*2d1272b8SAndroid Build Coastguard Worker { 143*2d1272b8SAndroid Build Coastguard Worker unsigned int subtable_type = get_type (); 144*2d1272b8SAndroid Build Coastguard Worker TRACE_DISPATCH (this, subtable_type); 145*2d1272b8SAndroid Build Coastguard Worker switch (subtable_type) { 146*2d1272b8SAndroid Build Coastguard Worker case 0: return_trace (c->dispatch (u.format0)); 147*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 148*2d1272b8SAndroid Build Coastguard Worker case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); 149*2d1272b8SAndroid Build Coastguard Worker #endif 150*2d1272b8SAndroid Build Coastguard Worker case 2: return_trace (c->dispatch (u.format2)); 151*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 152*2d1272b8SAndroid Build Coastguard Worker case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); 153*2d1272b8SAndroid Build Coastguard Worker #endif 154*2d1272b8SAndroid Build Coastguard Worker default: return_trace (c->default_return_value ()); 155*2d1272b8SAndroid Build Coastguard Worker } 156*2d1272b8SAndroid Build Coastguard Worker } 157*2d1272b8SAndroid Build Coastguard Worker 158*2d1272b8SAndroid Build Coastguard Worker template <typename set_t> collect_glyphsOT::KernSubTable159*2d1272b8SAndroid Build Coastguard Worker void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const 160*2d1272b8SAndroid Build Coastguard Worker { 161*2d1272b8SAndroid Build Coastguard Worker unsigned int subtable_type = get_type (); 162*2d1272b8SAndroid Build Coastguard Worker switch (subtable_type) { 163*2d1272b8SAndroid Build Coastguard Worker case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; 164*2d1272b8SAndroid Build Coastguard Worker case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; 165*2d1272b8SAndroid Build Coastguard Worker case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; 166*2d1272b8SAndroid Build Coastguard Worker case 3: u.format3.collect_glyphs (left_set, right_set, num_glyphs); return; 167*2d1272b8SAndroid Build Coastguard Worker default: return; 168*2d1272b8SAndroid Build Coastguard Worker } 169*2d1272b8SAndroid Build Coastguard Worker } 170*2d1272b8SAndroid Build Coastguard Worker sanitizeOT::KernSubTable171*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 172*2d1272b8SAndroid Build Coastguard Worker { 173*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 174*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!(u.header.sanitize (c) && 175*2d1272b8SAndroid Build Coastguard Worker hb_barrier () && 176*2d1272b8SAndroid Build Coastguard Worker u.header.length >= u.header.min_size && 177*2d1272b8SAndroid Build Coastguard Worker c->check_range (this, u.header.length)))) return_trace (false); 178*2d1272b8SAndroid Build Coastguard Worker 179*2d1272b8SAndroid Build Coastguard Worker return_trace (dispatch (c)); 180*2d1272b8SAndroid Build Coastguard Worker } 181*2d1272b8SAndroid Build Coastguard Worker 182*2d1272b8SAndroid Build Coastguard Worker public: 183*2d1272b8SAndroid Build Coastguard Worker union { 184*2d1272b8SAndroid Build Coastguard Worker KernSubTableHeader header; 185*2d1272b8SAndroid Build Coastguard Worker AAT::KerxSubTableFormat0<KernSubTableHeader> format0; 186*2d1272b8SAndroid Build Coastguard Worker AAT::KerxSubTableFormat1<KernSubTableHeader> format1; 187*2d1272b8SAndroid Build Coastguard Worker AAT::KerxSubTableFormat2<KernSubTableHeader> format2; 188*2d1272b8SAndroid Build Coastguard Worker KernSubTableFormat3<KernSubTableHeader> format3; 189*2d1272b8SAndroid Build Coastguard Worker } u; 190*2d1272b8SAndroid Build Coastguard Worker public: 191*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_MIN (KernSubTableHeader::static_size); 192*2d1272b8SAndroid Build Coastguard Worker }; 193*2d1272b8SAndroid Build Coastguard Worker 194*2d1272b8SAndroid Build Coastguard Worker 195*2d1272b8SAndroid Build Coastguard Worker struct KernOTSubTableHeader 196*2d1272b8SAndroid Build Coastguard Worker { 197*2d1272b8SAndroid Build Coastguard Worker static constexpr bool apple = false; 198*2d1272b8SAndroid Build Coastguard Worker typedef AAT::ObsoleteTypes Types; 199*2d1272b8SAndroid Build Coastguard Worker tuple_countOT::KernOTSubTableHeader200*2d1272b8SAndroid Build Coastguard Worker unsigned tuple_count () const { return 0; } is_horizontalOT::KernOTSubTableHeader201*2d1272b8SAndroid Build Coastguard Worker bool is_horizontal () const { return (coverage & Horizontal); } 202*2d1272b8SAndroid Build Coastguard Worker 203*2d1272b8SAndroid Build Coastguard Worker enum Coverage 204*2d1272b8SAndroid Build Coastguard Worker { 205*2d1272b8SAndroid Build Coastguard Worker Horizontal = 0x01u, 206*2d1272b8SAndroid Build Coastguard Worker Minimum = 0x02u, 207*2d1272b8SAndroid Build Coastguard Worker CrossStream = 0x04u, 208*2d1272b8SAndroid Build Coastguard Worker Override = 0x08u, 209*2d1272b8SAndroid Build Coastguard Worker 210*2d1272b8SAndroid Build Coastguard Worker /* Not supported: */ 211*2d1272b8SAndroid Build Coastguard Worker Backwards = 0x00u, 212*2d1272b8SAndroid Build Coastguard Worker Variation = 0x00u, 213*2d1272b8SAndroid Build Coastguard Worker }; 214*2d1272b8SAndroid Build Coastguard Worker sanitizeOT::KernOTSubTableHeader215*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 216*2d1272b8SAndroid Build Coastguard Worker { 217*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 218*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this)); 219*2d1272b8SAndroid Build Coastguard Worker } 220*2d1272b8SAndroid Build Coastguard Worker 221*2d1272b8SAndroid Build Coastguard Worker public: 222*2d1272b8SAndroid Build Coastguard Worker HBUINT16 versionZ; /* Unused. */ 223*2d1272b8SAndroid Build Coastguard Worker HBUINT16 length; /* Length of the subtable (including this header). */ 224*2d1272b8SAndroid Build Coastguard Worker HBUINT8 format; /* Subtable format. */ 225*2d1272b8SAndroid Build Coastguard Worker HBUINT8 coverage; /* Coverage bits. */ 226*2d1272b8SAndroid Build Coastguard Worker public: 227*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (6); 228*2d1272b8SAndroid Build Coastguard Worker }; 229*2d1272b8SAndroid Build Coastguard Worker 230*2d1272b8SAndroid Build Coastguard Worker struct KernOT : AAT::KerxTable<KernOT> 231*2d1272b8SAndroid Build Coastguard Worker { 232*2d1272b8SAndroid Build Coastguard Worker friend struct AAT::KerxTable<KernOT>; 233*2d1272b8SAndroid Build Coastguard Worker 234*2d1272b8SAndroid Build Coastguard Worker static constexpr hb_tag_t tableTag = HB_OT_TAG_kern; 235*2d1272b8SAndroid Build Coastguard Worker static constexpr unsigned minVersion = 0u; 236*2d1272b8SAndroid Build Coastguard Worker 237*2d1272b8SAndroid Build Coastguard Worker typedef KernOTSubTableHeader SubTableHeader; 238*2d1272b8SAndroid Build Coastguard Worker typedef SubTableHeader::Types Types; 239*2d1272b8SAndroid Build Coastguard Worker typedef KernSubTable<SubTableHeader> SubTable; 240*2d1272b8SAndroid Build Coastguard Worker 241*2d1272b8SAndroid Build Coastguard Worker protected: 242*2d1272b8SAndroid Build Coastguard Worker HBUINT16 version; /* Version--0x0000u */ 243*2d1272b8SAndroid Build Coastguard Worker HBUINT16 tableCount; /* Number of subtables in the kerning table. */ 244*2d1272b8SAndroid Build Coastguard Worker SubTable firstSubTable; /* Subtables. */ 245*2d1272b8SAndroid Build Coastguard Worker public: 246*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_MIN (4); 247*2d1272b8SAndroid Build Coastguard Worker }; 248*2d1272b8SAndroid Build Coastguard Worker 249*2d1272b8SAndroid Build Coastguard Worker 250*2d1272b8SAndroid Build Coastguard Worker struct KernAATSubTableHeader 251*2d1272b8SAndroid Build Coastguard Worker { 252*2d1272b8SAndroid Build Coastguard Worker static constexpr bool apple = true; 253*2d1272b8SAndroid Build Coastguard Worker typedef AAT::ObsoleteTypes Types; 254*2d1272b8SAndroid Build Coastguard Worker tuple_countOT::KernAATSubTableHeader255*2d1272b8SAndroid Build Coastguard Worker unsigned tuple_count () const { return 0; } is_horizontalOT::KernAATSubTableHeader256*2d1272b8SAndroid Build Coastguard Worker bool is_horizontal () const { return !(coverage & Vertical); } 257*2d1272b8SAndroid Build Coastguard Worker 258*2d1272b8SAndroid Build Coastguard Worker enum Coverage 259*2d1272b8SAndroid Build Coastguard Worker { 260*2d1272b8SAndroid Build Coastguard Worker Vertical = 0x80u, 261*2d1272b8SAndroid Build Coastguard Worker CrossStream = 0x40u, 262*2d1272b8SAndroid Build Coastguard Worker Variation = 0x20u, 263*2d1272b8SAndroid Build Coastguard Worker 264*2d1272b8SAndroid Build Coastguard Worker /* Not supported: */ 265*2d1272b8SAndroid Build Coastguard Worker Backwards = 0x00u, 266*2d1272b8SAndroid Build Coastguard Worker }; 267*2d1272b8SAndroid Build Coastguard Worker sanitizeOT::KernAATSubTableHeader268*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 269*2d1272b8SAndroid Build Coastguard Worker { 270*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 271*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this)); 272*2d1272b8SAndroid Build Coastguard Worker } 273*2d1272b8SAndroid Build Coastguard Worker 274*2d1272b8SAndroid Build Coastguard Worker public: 275*2d1272b8SAndroid Build Coastguard Worker HBUINT32 length; /* Length of the subtable (including this header). */ 276*2d1272b8SAndroid Build Coastguard Worker HBUINT8 coverage; /* Coverage bits. */ 277*2d1272b8SAndroid Build Coastguard Worker HBUINT8 format; /* Subtable format. */ 278*2d1272b8SAndroid Build Coastguard Worker HBUINT16 tupleIndex; /* The tuple index (used for variations fonts). 279*2d1272b8SAndroid Build Coastguard Worker * This value specifies which tuple this subtable covers. 280*2d1272b8SAndroid Build Coastguard Worker * Note: We don't implement. */ 281*2d1272b8SAndroid Build Coastguard Worker public: 282*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (8); 283*2d1272b8SAndroid Build Coastguard Worker }; 284*2d1272b8SAndroid Build Coastguard Worker 285*2d1272b8SAndroid Build Coastguard Worker struct KernAAT : AAT::KerxTable<KernAAT> 286*2d1272b8SAndroid Build Coastguard Worker { 287*2d1272b8SAndroid Build Coastguard Worker friend struct AAT::KerxTable<KernAAT>; 288*2d1272b8SAndroid Build Coastguard Worker 289*2d1272b8SAndroid Build Coastguard Worker static constexpr hb_tag_t tableTag = HB_OT_TAG_kern; 290*2d1272b8SAndroid Build Coastguard Worker static constexpr unsigned minVersion = 0x00010000u; 291*2d1272b8SAndroid Build Coastguard Worker 292*2d1272b8SAndroid Build Coastguard Worker typedef KernAATSubTableHeader SubTableHeader; 293*2d1272b8SAndroid Build Coastguard Worker typedef SubTableHeader::Types Types; 294*2d1272b8SAndroid Build Coastguard Worker typedef KernSubTable<SubTableHeader> SubTable; 295*2d1272b8SAndroid Build Coastguard Worker 296*2d1272b8SAndroid Build Coastguard Worker protected: 297*2d1272b8SAndroid Build Coastguard Worker HBUINT32 version; /* Version--0x00010000u */ 298*2d1272b8SAndroid Build Coastguard Worker HBUINT32 tableCount; /* Number of subtables in the kerning table. */ 299*2d1272b8SAndroid Build Coastguard Worker SubTable firstSubTable; /* Subtables. */ 300*2d1272b8SAndroid Build Coastguard Worker public: 301*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_MIN (8); 302*2d1272b8SAndroid Build Coastguard Worker }; 303*2d1272b8SAndroid Build Coastguard Worker 304*2d1272b8SAndroid Build Coastguard Worker struct kern 305*2d1272b8SAndroid Build Coastguard Worker { 306*2d1272b8SAndroid Build Coastguard Worker static constexpr hb_tag_t tableTag = HB_OT_TAG_kern; 307*2d1272b8SAndroid Build Coastguard Worker has_dataOT::kern308*2d1272b8SAndroid Build Coastguard Worker bool has_data () const { return u.version32; } get_typeOT::kern309*2d1272b8SAndroid Build Coastguard Worker unsigned get_type () const { return u.major; } 310*2d1272b8SAndroid Build Coastguard Worker has_state_machineOT::kern311*2d1272b8SAndroid Build Coastguard Worker bool has_state_machine () const 312*2d1272b8SAndroid Build Coastguard Worker { 313*2d1272b8SAndroid Build Coastguard Worker switch (get_type ()) { 314*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return u.ot.has_state_machine (); 315*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 316*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.aat.has_state_machine (); 317*2d1272b8SAndroid Build Coastguard Worker #endif 318*2d1272b8SAndroid Build Coastguard Worker default:return false; 319*2d1272b8SAndroid Build Coastguard Worker } 320*2d1272b8SAndroid Build Coastguard Worker } 321*2d1272b8SAndroid Build Coastguard Worker has_cross_streamOT::kern322*2d1272b8SAndroid Build Coastguard Worker bool has_cross_stream () const 323*2d1272b8SAndroid Build Coastguard Worker { 324*2d1272b8SAndroid Build Coastguard Worker switch (get_type ()) { 325*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return u.ot.has_cross_stream (); 326*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 327*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.aat.has_cross_stream (); 328*2d1272b8SAndroid Build Coastguard Worker #endif 329*2d1272b8SAndroid Build Coastguard Worker default:return false; 330*2d1272b8SAndroid Build Coastguard Worker } 331*2d1272b8SAndroid Build Coastguard Worker } 332*2d1272b8SAndroid Build Coastguard Worker get_h_kerningOT::kern333*2d1272b8SAndroid Build Coastguard Worker int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const 334*2d1272b8SAndroid Build Coastguard Worker { 335*2d1272b8SAndroid Build Coastguard Worker switch (get_type ()) { 336*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return u.ot.get_h_kerning (left, right); 337*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 338*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.aat.get_h_kerning (left, right); 339*2d1272b8SAndroid Build Coastguard Worker #endif 340*2d1272b8SAndroid Build Coastguard Worker default:return 0; 341*2d1272b8SAndroid Build Coastguard Worker } 342*2d1272b8SAndroid Build Coastguard Worker } 343*2d1272b8SAndroid Build Coastguard Worker applyOT::kern344*2d1272b8SAndroid Build Coastguard Worker bool apply (AAT::hb_aat_apply_context_t *c, 345*2d1272b8SAndroid Build Coastguard Worker const AAT::kern_accelerator_data_t *accel_data = nullptr) const 346*2d1272b8SAndroid Build Coastguard Worker { return dispatch (c, accel_data); } 347*2d1272b8SAndroid Build Coastguard Worker 348*2d1272b8SAndroid Build Coastguard Worker template <typename context_t, typename ...Ts> dispatchOT::kern349*2d1272b8SAndroid Build Coastguard Worker typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const 350*2d1272b8SAndroid Build Coastguard Worker { 351*2d1272b8SAndroid Build Coastguard Worker unsigned int subtable_type = get_type (); 352*2d1272b8SAndroid Build Coastguard Worker TRACE_DISPATCH (this, subtable_type); 353*2d1272b8SAndroid Build Coastguard Worker switch (subtable_type) { 354*2d1272b8SAndroid Build Coastguard Worker case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...)); 355*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 356*2d1272b8SAndroid Build Coastguard Worker case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...)); 357*2d1272b8SAndroid Build Coastguard Worker #endif 358*2d1272b8SAndroid Build Coastguard Worker default: return_trace (c->default_return_value ()); 359*2d1272b8SAndroid Build Coastguard Worker } 360*2d1272b8SAndroid Build Coastguard Worker } 361*2d1272b8SAndroid Build Coastguard Worker sanitizeOT::kern362*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const 363*2d1272b8SAndroid Build Coastguard Worker { 364*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this); 365*2d1272b8SAndroid Build Coastguard Worker if (!u.version32.sanitize (c)) return_trace (false); 366*2d1272b8SAndroid Build Coastguard Worker hb_barrier (); 367*2d1272b8SAndroid Build Coastguard Worker return_trace (dispatch (c)); 368*2d1272b8SAndroid Build Coastguard Worker } 369*2d1272b8SAndroid Build Coastguard Worker create_accelerator_dataOT::kern370*2d1272b8SAndroid Build Coastguard Worker AAT::kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const 371*2d1272b8SAndroid Build Coastguard Worker { 372*2d1272b8SAndroid Build Coastguard Worker switch (get_type ()) { 373*2d1272b8SAndroid Build Coastguard Worker case 0: hb_barrier (); return u.ot.create_accelerator_data (num_glyphs); 374*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 375*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.aat.create_accelerator_data (num_glyphs); 376*2d1272b8SAndroid Build Coastguard Worker #endif 377*2d1272b8SAndroid Build Coastguard Worker default:return AAT::kern_accelerator_data_t (); 378*2d1272b8SAndroid Build Coastguard Worker } 379*2d1272b8SAndroid Build Coastguard Worker } 380*2d1272b8SAndroid Build Coastguard Worker 381*2d1272b8SAndroid Build Coastguard Worker struct accelerator_t 382*2d1272b8SAndroid Build Coastguard Worker { accelerator_tOT::kern::accelerator_t383*2d1272b8SAndroid Build Coastguard Worker accelerator_t (hb_face_t *face) 384*2d1272b8SAndroid Build Coastguard Worker { 385*2d1272b8SAndroid Build Coastguard Worker hb_sanitize_context_t sc; 386*2d1272b8SAndroid Build Coastguard Worker this->table = sc.reference_table<kern> (face); 387*2d1272b8SAndroid Build Coastguard Worker this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ()); 388*2d1272b8SAndroid Build Coastguard Worker } ~accelerator_tOT::kern::accelerator_t389*2d1272b8SAndroid Build Coastguard Worker ~accelerator_t () 390*2d1272b8SAndroid Build Coastguard Worker { 391*2d1272b8SAndroid Build Coastguard Worker this->table.destroy (); 392*2d1272b8SAndroid Build Coastguard Worker } 393*2d1272b8SAndroid Build Coastguard Worker get_blobOT::kern::accelerator_t394*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *get_blob () const { return table.get_blob (); } 395*2d1272b8SAndroid Build Coastguard Worker applyOT::kern::accelerator_t396*2d1272b8SAndroid Build Coastguard Worker bool apply (AAT::hb_aat_apply_context_t *c) const 397*2d1272b8SAndroid Build Coastguard Worker { 398*2d1272b8SAndroid Build Coastguard Worker return table->apply (c, &accel_data); 399*2d1272b8SAndroid Build Coastguard Worker } 400*2d1272b8SAndroid Build Coastguard Worker 401*2d1272b8SAndroid Build Coastguard Worker hb_blob_ptr_t<kern> table; 402*2d1272b8SAndroid Build Coastguard Worker AAT::kern_accelerator_data_t accel_data; 403*2d1272b8SAndroid Build Coastguard Worker }; 404*2d1272b8SAndroid Build Coastguard Worker 405*2d1272b8SAndroid Build Coastguard Worker protected: 406*2d1272b8SAndroid Build Coastguard Worker union { 407*2d1272b8SAndroid Build Coastguard Worker HBUINT32 version32; 408*2d1272b8SAndroid Build Coastguard Worker HBUINT16 major; 409*2d1272b8SAndroid Build Coastguard Worker KernOT ot; 410*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_NO_AAT_SHAPE 411*2d1272b8SAndroid Build Coastguard Worker KernAAT aat; 412*2d1272b8SAndroid Build Coastguard Worker #endif 413*2d1272b8SAndroid Build Coastguard Worker } u; 414*2d1272b8SAndroid Build Coastguard Worker public: 415*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_UNION (4, version32); 416*2d1272b8SAndroid Build Coastguard Worker }; 417*2d1272b8SAndroid Build Coastguard Worker 418*2d1272b8SAndroid Build Coastguard Worker struct kern_accelerator_t : kern::accelerator_t { kern_accelerator_tOT::kern_accelerator_t419*2d1272b8SAndroid Build Coastguard Worker kern_accelerator_t (hb_face_t *face) : kern::accelerator_t (face) {} 420*2d1272b8SAndroid Build Coastguard Worker }; 421*2d1272b8SAndroid Build Coastguard Worker 422*2d1272b8SAndroid Build Coastguard Worker } /* namespace OT */ 423*2d1272b8SAndroid Build Coastguard Worker 424*2d1272b8SAndroid Build Coastguard Worker 425*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_OT_KERN_TABLE_HH */ 426