1 /* 2 * Copyright © 2021 Google, Inc. 3 * 4 * This is part of HarfBuzz, a text shaping library. 5 * 6 * Permission is hereby granted, without written agreement and without 7 * license or royalty fees, to use, copy, modify, and distribute this 8 * software and its documentation for any purpose, provided that the 9 * above copyright notice and the following two paragraphs appear in 10 * all copies of this software. 11 * 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * DAMAGE. 17 * 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 * 24 */ 25 26 #ifndef HB_OT_VAR_COMMON_HH 27 #define HB_OT_VAR_COMMON_HH 28 29 #include "hb-ot-layout-common.hh" 30 31 32 namespace OT { 33 34 struct DeltaSetIndexMapFormat0 35 { 36 friend struct DeltaSetIndexMap; 37 38 private: copyOT::DeltaSetIndexMapFormat039 DeltaSetIndexMapFormat0* copy (hb_serialize_context_t *c) const 40 { 41 TRACE_SERIALIZE (this); 42 auto *out = c->start_embed (this); 43 if (unlikely (!out)) return_trace (nullptr); 44 45 unsigned total_size = min_size + mapCount * get_width (); 46 HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); 47 if (unlikely (!p)) return_trace (nullptr); 48 49 memcpy (p, this, HBUINT8::static_size * total_size); 50 return_trace (out); 51 } 52 53 template <typename T> serializeOT::DeltaSetIndexMapFormat054 bool serialize (hb_serialize_context_t *c, const T &plan) 55 { 56 unsigned int width = plan.get_width (); 57 unsigned int inner_bit_count = plan.get_inner_bit_count (); 58 const hb_array_t<const uint32_t> output_map = plan.get_output_map (); 59 60 TRACE_SERIALIZE (this); 61 if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) 62 return_trace (false); 63 if (unlikely (!c->extend_min (this))) return_trace (false); 64 65 entryFormat = ((width-1)<<4)|(inner_bit_count-1); 66 mapCount = output_map.length; 67 HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length); 68 if (unlikely (!p)) return_trace (false); 69 for (unsigned int i = 0; i < output_map.length; i++) 70 { 71 unsigned int v = output_map[i]; 72 unsigned int outer = v >> 16; 73 unsigned int inner = v & 0xFFFF; 74 unsigned int u = (outer << inner_bit_count) | inner; 75 for (unsigned int w = width; w > 0;) 76 { 77 p[--w] = u; 78 u >>= 8; 79 } 80 p += width; 81 } 82 return_trace (true); 83 } 84 mapOT::DeltaSetIndexMapFormat085 uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ 86 { 87 /* If count is zero, pass value unchanged. This takes 88 * care of direct mapping for advance map. */ 89 if (!mapCount) 90 return v; 91 92 if (v >= mapCount) 93 v = mapCount - 1; 94 95 unsigned int u = 0; 96 { /* Fetch it. */ 97 unsigned int w = get_width (); 98 const HBUINT8 *p = mapDataZ.arrayZ + w * v; 99 for (; w; w--) 100 u = (u << 8) + *p++; 101 } 102 103 { /* Repack it. */ 104 unsigned int n = get_inner_bit_count (); 105 unsigned int outer = u >> n; 106 unsigned int inner = u & ((1 << n) - 1); 107 u = (outer<<16) | inner; 108 } 109 110 return u; 111 } 112 get_map_countOT::DeltaSetIndexMapFormat0113 unsigned get_map_count () const { return mapCount; } get_widthOT::DeltaSetIndexMapFormat0114 unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } get_inner_bit_countOT::DeltaSetIndexMapFormat0115 unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } 116 117 sanitizeOT::DeltaSetIndexMapFormat0118 bool sanitize (hb_sanitize_context_t *c) const 119 { 120 TRACE_SANITIZE (this); 121 return_trace (c->check_struct (this) && 122 c->check_range (mapDataZ.arrayZ, 123 mapCount, 124 get_width ())); 125 } 126 127 protected: 128 HBUINT8 format; /* Format identifier--format = 0 */ 129 HBUINT8 entryFormat; /* A packed field that describes the compressed 130 * representation of delta-set indices. */ 131 HBUINT16 mapCount; /* The number of mapping entries. */ 132 UnsizedArrayOf<HBUINT8> 133 mapDataZ; /* The delta-set index mapping data. */ 134 135 public: 136 DEFINE_SIZE_ARRAY (4, mapDataZ); 137 }; 138 139 struct DeltaSetIndexMapFormat1 140 { 141 friend struct DeltaSetIndexMap; 142 143 private: copyOT::DeltaSetIndexMapFormat1144 DeltaSetIndexMapFormat1* copy (hb_serialize_context_t *c) const 145 { 146 TRACE_SERIALIZE (this); 147 auto *out = c->start_embed (this); 148 if (unlikely (!out)) return_trace (nullptr); 149 150 unsigned total_size = min_size + mapCount * get_width (); 151 HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); 152 if (unlikely (!p)) return_trace (nullptr); 153 154 memcpy (p, this, HBUINT8::static_size * total_size); 155 return_trace (out); 156 } 157 get_map_countOT::DeltaSetIndexMapFormat1158 unsigned get_map_count () const { return mapCount; } get_widthOT::DeltaSetIndexMapFormat1159 unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } get_inner_bit_countOT::DeltaSetIndexMapFormat1160 unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } 161 sanitizeOT::DeltaSetIndexMapFormat1162 bool sanitize (hb_sanitize_context_t *c) const 163 { 164 TRACE_SANITIZE (this); 165 return_trace (c->check_struct (this) && 166 c->check_range (mapDataZ.arrayZ, 167 mapCount, 168 get_width ())); 169 } 170 171 protected: 172 HBUINT8 format; /* Format identifier--format = 1 */ 173 HBUINT8 entryFormat; /* A packed field that describes the compressed 174 * representation of delta-set indices. */ 175 HBUINT32 mapCount; /* The number of mapping entries. */ 176 UnsizedArrayOf<HBUINT8> 177 mapDataZ; /* The delta-set index mapping data. */ 178 179 public: 180 DEFINE_SIZE_ARRAY (6, mapDataZ); 181 }; 182 183 struct DeltaSetIndexMap 184 { 185 template <typename T> serializeOT::DeltaSetIndexMap186 bool serialize (hb_serialize_context_t *c, const T &plan) 187 { 188 TRACE_SERIALIZE (this); 189 switch (u.format) { 190 case 0: return_trace (u.format0.serialize (c, plan)); 191 default:return_trace (false); 192 } 193 } 194 mapOT::DeltaSetIndexMap195 uint32_t map (unsigned v) const 196 { 197 switch (u.format) { 198 case 0: return (u.format0.map (v)); 199 default:return v; 200 } 201 } 202 get_map_countOT::DeltaSetIndexMap203 unsigned get_map_count () const 204 { 205 switch (u.format) { 206 case 0: return u.format0.get_map_count (); 207 case 1: return u.format1.get_map_count (); 208 default:return 0; 209 } 210 } 211 get_widthOT::DeltaSetIndexMap212 unsigned get_width () const 213 { 214 switch (u.format) { 215 case 0: return u.format0.get_width (); 216 case 1: return u.format1.get_width (); 217 default:return 0; 218 } 219 } 220 get_inner_bit_countOT::DeltaSetIndexMap221 unsigned get_inner_bit_count () const 222 { 223 switch (u.format) { 224 case 0: return u.format0.get_inner_bit_count (); 225 case 1: return u.format1.get_inner_bit_count (); 226 default:return 0; 227 } 228 } 229 sanitizeOT::DeltaSetIndexMap230 bool sanitize (hb_sanitize_context_t *c) const 231 { 232 TRACE_SANITIZE (this); 233 if (!u.format.sanitize (c)) return_trace (false); 234 switch (u.format) { 235 case 0: return_trace (u.format0.sanitize (c)); 236 case 1: return_trace (u.format1.sanitize (c)); 237 default:return_trace (true); 238 } 239 } 240 copyOT::DeltaSetIndexMap241 DeltaSetIndexMap* copy (hb_serialize_context_t *c) const 242 { 243 TRACE_SERIALIZE (this); 244 switch (u.format) { 245 case 0: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format0.copy (c))); 246 case 1: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format1.copy (c))); 247 default:return_trace (nullptr); 248 } 249 } 250 251 protected: 252 union { 253 HBUINT8 format; /* Format identifier */ 254 DeltaSetIndexMapFormat0 format0; 255 DeltaSetIndexMapFormat1 format1; 256 } u; 257 public: 258 DEFINE_SIZE_UNION (1, format); 259 }; 260 261 } /* namespace OT */ 262 263 264 #endif /* HB_OT_VAR_COMMON_HH */ 265