Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/harfbuzz/src/OT/glyf/VarCompositeGlyph.hh @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 #ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH | |
| 2 #define OT_GLYF_VARCOMPOSITEGLYPH_HH | |
| 3 | |
| 4 | |
| 5 #include "../../hb-open-type.hh" | |
| 6 #include "coord-setter.hh" | |
| 7 | |
| 8 | |
| 9 namespace OT { | |
| 10 namespace glyf_impl { | |
| 11 | |
| 12 | |
| 13 struct VarCompositeGlyphRecord | |
| 14 { | |
| 15 protected: | |
| 16 enum var_composite_glyph_flag_t | |
| 17 { | |
| 18 USE_MY_METRICS = 0x0001, | |
| 19 AXIS_INDICES_ARE_SHORT = 0x0002, | |
| 20 UNIFORM_SCALE = 0x0004, | |
| 21 HAVE_TRANSLATE_X = 0x0008, | |
| 22 HAVE_TRANSLATE_Y = 0x0010, | |
| 23 HAVE_ROTATION = 0x0020, | |
| 24 HAVE_SCALE_X = 0x0040, | |
| 25 HAVE_SCALE_Y = 0x0080, | |
| 26 HAVE_SKEW_X = 0x0100, | |
| 27 HAVE_SKEW_Y = 0x0200, | |
| 28 HAVE_TCENTER_X = 0x0400, | |
| 29 HAVE_TCENTER_Y = 0x0800, | |
| 30 GID_IS_24 = 0x1000, | |
| 31 AXES_HAVE_VARIATION = 0x2000, | |
| 32 }; | |
| 33 | |
| 34 public: | |
| 35 | |
| 36 unsigned int get_size () const | |
| 37 { | |
| 38 unsigned int size = min_size; | |
| 39 | |
| 40 unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3; | |
| 41 size += numAxes * axis_width; | |
| 42 | |
| 43 // gid | |
| 44 size += 2; | |
| 45 if (flags & GID_IS_24) size += 1; | |
| 46 | |
| 47 if (flags & HAVE_TRANSLATE_X) size += 2; | |
| 48 if (flags & HAVE_TRANSLATE_Y) size += 2; | |
| 49 if (flags & HAVE_ROTATION) size += 2; | |
| 50 if (flags & HAVE_SCALE_X) size += 2; | |
| 51 if (flags & HAVE_SCALE_Y) size += 2; | |
| 52 if (flags & HAVE_SKEW_X) size += 2; | |
| 53 if (flags & HAVE_SKEW_Y) size += 2; | |
| 54 if (flags & HAVE_TCENTER_X) size += 2; | |
| 55 if (flags & HAVE_TCENTER_Y) size += 2; | |
| 56 | |
| 57 return size; | |
| 58 } | |
| 59 | |
| 60 bool has_more () const { return true; } | |
| 61 | |
| 62 bool is_use_my_metrics () const { return flags & USE_MY_METRICS; } | |
| 63 | |
| 64 hb_codepoint_t get_gid () const | |
| 65 { | |
| 66 if (flags & GID_IS_24) | |
| 67 return StructAfter<const HBGlyphID24> (numAxes); | |
| 68 else | |
| 69 return StructAfter<const HBGlyphID16> (numAxes); | |
| 70 } | |
| 71 | |
| 72 unsigned get_numAxes () const | |
| 73 { | |
| 74 return numAxes; | |
| 75 } | |
| 76 | |
| 77 unsigned get_num_points () const | |
| 78 { | |
| 79 unsigned num = 0; | |
| 80 if (flags & AXES_HAVE_VARIATION) num += numAxes; | |
| 81 if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++; | |
| 82 if (flags & HAVE_ROTATION) num++; | |
| 83 if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++; | |
| 84 if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++; | |
| 85 if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++; | |
| 86 return num; | |
| 87 } | |
| 88 | |
| 89 void transform_points (hb_array_t<contour_point_t> record_points, | |
| 90 contour_point_vector_t &points) const | |
| 91 { | |
| 92 float matrix[4]; | |
| 93 contour_point_t trans; | |
| 94 | |
| 95 get_transformation_from_points (record_points, matrix, trans); | |
| 96 | |
| 97 points.transform (matrix); | |
| 98 points.translate (trans); | |
| 99 } | |
| 100 | |
| 101 static inline void transform (float (&matrix)[4], contour_point_t &trans, | |
| 102 float (other)[6]) | |
| 103 { | |
| 104 // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268 | |
| 105 float xx1 = other[0]; | |
| 106 float xy1 = other[1]; | |
| 107 float yx1 = other[2]; | |
| 108 float yy1 = other[3]; | |
| 109 float dx1 = other[4]; | |
| 110 float dy1 = other[5]; | |
| 111 float xx2 = matrix[0]; | |
| 112 float xy2 = matrix[1]; | |
| 113 float yx2 = matrix[2]; | |
| 114 float yy2 = matrix[3]; | |
| 115 float dx2 = trans.x; | |
| 116 float dy2 = trans.y; | |
| 117 | |
| 118 matrix[0] = xx1*xx2 + xy1*yx2; | |
| 119 matrix[1] = xx1*xy2 + xy1*yy2; | |
| 120 matrix[2] = yx1*xx2 + yy1*yx2; | |
| 121 matrix[3] = yx1*xy2 + yy1*yy2; | |
| 122 trans.x = xx2*dx1 + yx2*dy1 + dx2; | |
| 123 trans.y = xy2*dx1 + yy2*dy1 + dy2; | |
| 124 } | |
| 125 | |
| 126 static void translate (float (&matrix)[4], contour_point_t &trans, | |
| 127 float translateX, float translateY) | |
| 128 { | |
| 129 // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213 | |
| 130 float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY}; | |
| 131 transform (matrix, trans, other); | |
| 132 } | |
| 133 | |
| 134 static void scale (float (&matrix)[4], contour_point_t &trans, | |
| 135 float scaleX, float scaleY) | |
| 136 { | |
| 137 // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224 | |
| 138 float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f}; | |
| 139 transform (matrix, trans, other); | |
| 140 } | |
| 141 | |
| 142 static void rotate (float (&matrix)[4], contour_point_t &trans, | |
| 143 float rotation) | |
| 144 { | |
| 145 // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 | |
| 146 rotation = rotation * float (M_PI); | |
| 147 float c = cosf (rotation); | |
| 148 float s = sinf (rotation); | |
| 149 float other[6] = {c, s, -s, c, 0.f, 0.f}; | |
| 150 transform (matrix, trans, other); | |
| 151 } | |
| 152 | |
| 153 static void skew (float (&matrix)[4], contour_point_t &trans, | |
| 154 float skewX, float skewY) | |
| 155 { | |
| 156 // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 | |
| 157 skewX = skewX * float (M_PI); | |
| 158 skewY = skewY * float (M_PI); | |
| 159 float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f}; | |
| 160 transform (matrix, trans, other); | |
| 161 } | |
| 162 | |
| 163 bool get_points (contour_point_vector_t &points) const | |
| 164 { | |
| 165 float translateX = 0.f; | |
| 166 float translateY = 0.f; | |
| 167 float rotation = 0.f; | |
| 168 float scaleX = 1.f * (1 << 12); | |
| 169 float scaleY = 1.f * (1 << 12); | |
| 170 float skewX = 0.f; | |
| 171 float skewY = 0.f; | |
| 172 float tCenterX = 0.f; | |
| 173 float tCenterY = 0.f; | |
| 174 | |
| 175 if (unlikely (!points.resize (points.length + get_num_points ()))) return false; | |
| 176 | |
| 177 unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; | |
| 178 unsigned axes_size = numAxes * axis_width; | |
| 179 | |
| 180 const F2DOT14 *q = (const F2DOT14 *) (axes_size + | |
| 181 (flags & GID_IS_24 ? 3 : 2) + | |
| 182 &StructAfter<const HBUINT8> (numAxes)); | |
| 183 | |
| 184 hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - get_num_points ()); | |
| 185 | |
| 186 unsigned count = numAxes; | |
| 187 if (flags & AXES_HAVE_VARIATION) | |
| 188 { | |
| 189 for (unsigned i = 0; i < count; i++) | |
| 190 rec_points[i].x = *q++; | |
| 191 rec_points += count; | |
| 192 } | |
| 193 else | |
| 194 q += count; | |
| 195 | |
| 196 const HBUINT16 *p = (const HBUINT16 *) q; | |
| 197 | |
| 198 if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++; | |
| 199 if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++; | |
| 200 if (flags & HAVE_ROTATION) rotation = * (const F2DOT14 *) p++; | |
| 201 if (flags & HAVE_SCALE_X) scaleX = * (const F4DOT12 *) p++; | |
| 202 if (flags & HAVE_SCALE_Y) scaleY = * (const F4DOT12 *) p++; | |
| 203 if (flags & HAVE_SKEW_X) skewX = * (const F2DOT14 *) p++; | |
| 204 if (flags & HAVE_SKEW_Y) skewY = * (const F2DOT14 *) p++; | |
| 205 if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++; | |
| 206 if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++; | |
| 207 | |
| 208 if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y)) | |
| 209 scaleY = scaleX; | |
| 210 | |
| 211 if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) | |
| 212 { | |
| 213 rec_points[0].x = translateX; | |
| 214 rec_points[0].y = translateY; | |
| 215 rec_points++; | |
| 216 } | |
| 217 if (flags & HAVE_ROTATION) | |
| 218 { | |
| 219 rec_points[0].x = rotation; | |
| 220 rec_points++; | |
| 221 } | |
| 222 if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) | |
| 223 { | |
| 224 rec_points[0].x = scaleX; | |
| 225 rec_points[0].y = scaleY; | |
| 226 rec_points++; | |
| 227 } | |
| 228 if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) | |
| 229 { | |
| 230 rec_points[0].x = skewX; | |
| 231 rec_points[0].y = skewY; | |
| 232 rec_points++; | |
| 233 } | |
| 234 if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) | |
| 235 { | |
| 236 rec_points[0].x = tCenterX; | |
| 237 rec_points[0].y = tCenterY; | |
| 238 rec_points++; | |
| 239 } | |
| 240 assert (!rec_points); | |
| 241 | |
| 242 return true; | |
| 243 } | |
| 244 | |
| 245 void get_transformation_from_points (hb_array_t<contour_point_t> rec_points, | |
| 246 float (&matrix)[4], contour_point_t &trans) const | |
| 247 { | |
| 248 if (flags & AXES_HAVE_VARIATION) | |
| 249 rec_points += numAxes; | |
| 250 | |
| 251 matrix[0] = matrix[3] = 1.f; | |
| 252 matrix[1] = matrix[2] = 0.f; | |
| 253 trans.init (0.f, 0.f); | |
| 254 | |
| 255 float translateX = 0.f; | |
| 256 float translateY = 0.f; | |
| 257 float rotation = 0.f; | |
| 258 float scaleX = 1.f; | |
| 259 float scaleY = 1.f; | |
| 260 float skewX = 0.f; | |
| 261 float skewY = 0.f; | |
| 262 float tCenterX = 0.f; | |
| 263 float tCenterY = 0.f; | |
| 264 | |
| 265 if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) | |
| 266 { | |
| 267 translateX = rec_points[0].x; | |
| 268 translateY = rec_points[0].y; | |
| 269 rec_points++; | |
| 270 } | |
| 271 if (flags & HAVE_ROTATION) | |
| 272 { | |
| 273 rotation = rec_points[0].x / (1 << 14); | |
| 274 rec_points++; | |
| 275 } | |
| 276 if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) | |
| 277 { | |
| 278 scaleX = rec_points[0].x / (1 << 12); | |
| 279 scaleY = rec_points[0].y / (1 << 12); | |
| 280 rec_points++; | |
| 281 } | |
| 282 if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) | |
| 283 { | |
| 284 skewX = rec_points[0].x / (1 << 14); | |
| 285 skewY = rec_points[0].y / (1 << 14); | |
| 286 rec_points++; | |
| 287 } | |
| 288 if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) | |
| 289 { | |
| 290 tCenterX = rec_points[0].x; | |
| 291 tCenterY = rec_points[0].y; | |
| 292 rec_points++; | |
| 293 } | |
| 294 assert (!rec_points); | |
| 295 | |
| 296 translate (matrix, trans, translateX + tCenterX, translateY + tCenterY); | |
| 297 rotate (matrix, trans, rotation); | |
| 298 scale (matrix, trans, scaleX, scaleY); | |
| 299 skew (matrix, trans, -skewX, skewY); | |
| 300 translate (matrix, trans, -tCenterX, -tCenterY); | |
| 301 } | |
| 302 | |
| 303 void set_variations (coord_setter_t &setter, | |
| 304 hb_array_t<contour_point_t> rec_points) const | |
| 305 { | |
| 306 bool have_variations = flags & AXES_HAVE_VARIATION; | |
| 307 unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; | |
| 308 | |
| 309 const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); | |
| 310 const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); | |
| 311 | |
| 312 const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes))); | |
| 313 | |
| 314 unsigned count = numAxes; | |
| 315 for (unsigned i = 0; i < count; i++) | |
| 316 { | |
| 317 unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++; | |
| 318 | |
| 319 signed v = have_variations ? rec_points[i].x : *a++; | |
| 320 | |
| 321 v += setter[axis_index]; | |
| 322 v = hb_clamp (v, -(1<<14), (1<<14)); | |
| 323 setter[axis_index] = v; | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 protected: | |
| 328 HBUINT16 flags; | |
| 329 HBUINT8 numAxes; | |
| 330 public: | |
| 331 DEFINE_SIZE_MIN (3); | |
| 332 }; | |
| 333 | |
| 334 using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>; | |
| 335 | |
| 336 struct VarCompositeGlyph | |
| 337 { | |
| 338 const GlyphHeader &header; | |
| 339 hb_bytes_t bytes; | |
| 340 VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) : | |
| 341 header (header_), bytes (bytes_) {} | |
| 342 | |
| 343 var_composite_iter_t iter () const | |
| 344 { return var_composite_iter_t (bytes, &StructAfter<VarCompositeGlyphRecord, GlyphHeader> (header)); } | |
| 345 | |
| 346 }; | |
| 347 | |
| 348 | |
| 349 } /* namespace glyf_impl */ | |
| 350 } /* namespace OT */ | |
| 351 | |
| 352 | |
| 353 #endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */ |
