| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007,2008,2009 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009 Red Hat, Inc. |
| 3 * Copyright © 2010,2012 Google, Inc. | 3 * Copyright © 2010,2012 Google, Inc. |
| 4 * | 4 * |
| 5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
| 6 * | 6 * |
| 7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
| 8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
| 9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
| 10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 { return lookupIndex[i]; } | 500 { return lookupIndex[i]; } |
| 501 inline unsigned int get_lookup_indexes (unsigned int start_index, | 501 inline unsigned int get_lookup_indexes (unsigned int start_index, |
| 502 unsigned int *lookup_count /* IN/OUT *
/, | 502 unsigned int *lookup_count /* IN/OUT *
/, |
| 503 unsigned int *lookup_tags /* OUT */) c
onst | 503 unsigned int *lookup_tags /* OUT */) c
onst |
| 504 { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } | 504 { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } |
| 505 | 505 |
| 506 inline const FeatureParams &get_feature_params (void) const | 506 inline const FeatureParams &get_feature_params (void) const |
| 507 { return this+featureParams; } | 507 { return this+featureParams; } |
| 508 | 508 |
| 509 inline bool sanitize (hb_sanitize_context_t *c, | 509 inline bool sanitize (hb_sanitize_context_t *c, |
| 510 » » » const Record<Feature>::sanitize_closure_t *closure) cons
t | 510 » » » const Record<Feature>::sanitize_closure_t *closure = NUL
L) const |
| 511 { | 511 { |
| 512 TRACE_SANITIZE (this); | 512 TRACE_SANITIZE (this); |
| 513 if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) | 513 if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) |
| 514 return_trace (false); | 514 return_trace (false); |
| 515 | 515 |
| 516 /* Some earlier versions of Adobe tools calculated the offset of the | 516 /* Some earlier versions of Adobe tools calculated the offset of the |
| 517 * FeatureParams subtable from the beginning of the FeatureList table! | 517 * FeatureParams subtable from the beginning of the FeatureList table! |
| 518 * | 518 * |
| 519 * If sanitizing "failed" for the FeatureParams subtable, try it with the | 519 * If sanitizing "failed" for the FeatureParams subtable, try it with the |
| 520 * alternative location. We would know sanitize "failed" if old value | 520 * alternative location. We would know sanitize "failed" if old value |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 for (unsigned int i = 0; i < count; i++) | 724 for (unsigned int i = 0; i < count; i++) |
| 725 glyphs->add (glyphArray[i]); | 725 glyphs->add (glyphArray[i]); |
| 726 } | 726 } |
| 727 | 727 |
| 728 public: | 728 public: |
| 729 /* Older compilers need this to be public. */ | 729 /* Older compilers need this to be public. */ |
| 730 struct Iter { | 730 struct Iter { |
| 731 inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; | 731 inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; |
| 732 inline bool more (void) { return i < c->glyphArray.len; } | 732 inline bool more (void) { return i < c->glyphArray.len; } |
| 733 inline void next (void) { i++; } | 733 inline void next (void) { i++; } |
| 734 inline uint16_t get_glyph (void) { return c->glyphArray[i]; } | 734 inline hb_codepoint_t get_glyph (void) { return c->glyphArray[i]; } |
| 735 inline uint16_t get_coverage (void) { return i; } | 735 inline unsigned int get_coverage (void) { return i; } |
| 736 | 736 |
| 737 private: | 737 private: |
| 738 const struct CoverageFormat1 *c; | 738 const struct CoverageFormat1 *c; |
| 739 unsigned int i; | 739 unsigned int i; |
| 740 }; | 740 }; |
| 741 private: | 741 private: |
| 742 | 742 |
| 743 protected: | 743 protected: |
| 744 USHORT coverageFormat; /* Format identifier--format = 1 */ | 744 USHORT coverageFormat; /* Format identifier--format = 1 */ |
| 745 SortedArrayOf<GlyphID> | 745 SortedArrayOf<GlyphID> |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 822 |
| 823 template <typename set_t> | 823 template <typename set_t> |
| 824 inline void add_coverage (set_t *glyphs) const { | 824 inline void add_coverage (set_t *glyphs) const { |
| 825 unsigned int count = rangeRecord.len; | 825 unsigned int count = rangeRecord.len; |
| 826 for (unsigned int i = 0; i < count; i++) | 826 for (unsigned int i = 0; i < count; i++) |
| 827 rangeRecord[i].add_coverage (glyphs); | 827 rangeRecord[i].add_coverage (glyphs); |
| 828 } | 828 } |
| 829 | 829 |
| 830 public: | 830 public: |
| 831 /* Older compilers need this to be public. */ | 831 /* Older compilers need this to be public. */ |
| 832 struct Iter { | 832 struct Iter |
| 833 inline void init (const CoverageFormat2 &c_) { | 833 { |
| 834 inline void init (const CoverageFormat2 &c_) |
| 835 { |
| 834 c = &c_; | 836 c = &c_; |
| 835 coverage = 0; | 837 coverage = 0; |
| 836 i = 0; | 838 i = 0; |
| 837 j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; | 839 j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; |
| 838 } | 840 } |
| 839 inline bool more (void) { return i < c->rangeRecord.len; } | 841 inline bool more (void) { return i < c->rangeRecord.len; } |
| 840 inline void next (void) { | 842 inline void next (void) |
| 841 coverage++; | 843 { |
| 842 if (j == c->rangeRecord[i].end) { | 844 if (j >= c->rangeRecord[i].end) |
| 845 { |
| 843 i++; | 846 i++; |
| 844 if (more ()) | 847 if (more ()) |
| 848 { |
| 845 j = c->rangeRecord[i].start; | 849 j = c->rangeRecord[i].start; |
| 850 coverage = c->rangeRecord[i].value; |
| 851 } |
| 846 return; | 852 return; |
| 847 } | 853 } |
| 854 coverage++; |
| 848 j++; | 855 j++; |
| 849 } | 856 } |
| 850 inline uint16_t get_glyph (void) { return j; } | 857 inline hb_codepoint_t get_glyph (void) { return j; } |
| 851 inline uint16_t get_coverage (void) { return coverage; } | 858 inline unsigned int get_coverage (void) { return coverage; } |
| 852 | 859 |
| 853 private: | 860 private: |
| 854 const struct CoverageFormat2 *c; | 861 const struct CoverageFormat2 *c; |
| 855 unsigned int i, j, coverage; | 862 unsigned int i, j, coverage; |
| 856 }; | 863 }; |
| 857 private: | 864 private: |
| 858 | 865 |
| 859 protected: | 866 protected: |
| 860 USHORT coverageFormat; /* Format identifier--format = 2 */ | 867 USHORT coverageFormat; /* Format identifier--format = 2 */ |
| 861 SortedArrayOf<RangeRecord> | 868 SortedArrayOf<RangeRecord> |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 default:return false; | 957 default:return false; |
| 951 } | 958 } |
| 952 } | 959 } |
| 953 inline void next (void) { | 960 inline void next (void) { |
| 954 switch (format) { | 961 switch (format) { |
| 955 case 1: u.format1.next (); break; | 962 case 1: u.format1.next (); break; |
| 956 case 2: u.format2.next (); break; | 963 case 2: u.format2.next (); break; |
| 957 default: break; | 964 default: break; |
| 958 } | 965 } |
| 959 } | 966 } |
| 960 inline uint16_t get_glyph (void) { | 967 inline hb_codepoint_t get_glyph (void) { |
| 961 switch (format) { | 968 switch (format) { |
| 962 case 1: return u.format1.get_glyph (); | 969 case 1: return u.format1.get_glyph (); |
| 963 case 2: return u.format2.get_glyph (); | 970 case 2: return u.format2.get_glyph (); |
| 964 default:return 0; | 971 default:return 0; |
| 965 } | 972 } |
| 966 } | 973 } |
| 967 inline uint16_t get_coverage (void) { | 974 inline unsigned int get_coverage (void) { |
| 968 switch (format) { | 975 switch (format) { |
| 969 case 1: return u.format1.get_coverage (); | 976 case 1: return u.format1.get_coverage (); |
| 970 case 2: return u.format2.get_coverage (); | 977 case 2: return u.format2.get_coverage (); |
| 971 default:return -1; | 978 default:return -1; |
| 972 } | 979 } |
| 973 } | 980 } |
| 974 | 981 |
| 975 private: | 982 private: |
| 976 unsigned int format; | 983 unsigned int format; |
| 977 union { | 984 union { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 USHORT format; /* Format identifier */ | 1162 USHORT format; /* Format identifier */ |
| 1156 ClassDefFormat1 format1; | 1163 ClassDefFormat1 format1; |
| 1157 ClassDefFormat2 format2; | 1164 ClassDefFormat2 format2; |
| 1158 } u; | 1165 } u; |
| 1159 public: | 1166 public: |
| 1160 DEFINE_SIZE_UNION (2, format); | 1167 DEFINE_SIZE_UNION (2, format); |
| 1161 }; | 1168 }; |
| 1162 | 1169 |
| 1163 | 1170 |
| 1164 /* | 1171 /* |
| 1172 * Item Variation Store |
| 1173 */ |
| 1174 |
| 1175 struct VarRegionAxis |
| 1176 { |
| 1177 inline float evaluate (int coord) const |
| 1178 { |
| 1179 int start = startCoord, peak = peakCoord, end = endCoord; |
| 1180 |
| 1181 /* TODO Move these to sanitize(). */ |
| 1182 if (unlikely (start > peak || peak > end)) |
| 1183 return 1.; |
| 1184 if (unlikely (start < 0 && end > 0 && peak != 0)) |
| 1185 return 1.; |
| 1186 |
| 1187 if (peak == 0 || coord == peak) |
| 1188 return 1.; |
| 1189 |
| 1190 if (coord <= start || end <= coord) |
| 1191 return 0.; |
| 1192 |
| 1193 /* Interpolate */ |
| 1194 if (coord < peak) |
| 1195 return float (coord - start) / (peak - start); |
| 1196 else |
| 1197 return float (end - coord) / (end - peak); |
| 1198 } |
| 1199 |
| 1200 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1201 { |
| 1202 TRACE_SANITIZE (this); |
| 1203 return_trace (c->check_struct (this)); |
| 1204 /* TODO Handle invalid start/peak/end configs, so we don't |
| 1205 * have to do that at runtime. */ |
| 1206 } |
| 1207 |
| 1208 public: |
| 1209 F2DOT14 startCoord; |
| 1210 F2DOT14 peakCoord; |
| 1211 F2DOT14 endCoord; |
| 1212 public: |
| 1213 DEFINE_SIZE_STATIC (6); |
| 1214 }; |
| 1215 |
| 1216 struct VarRegionList |
| 1217 { |
| 1218 inline float evaluate (unsigned int region_index, |
| 1219 int *coords, unsigned int coord_len) const |
| 1220 { |
| 1221 if (unlikely (region_index >= regionCount)) |
| 1222 return 0.; |
| 1223 |
| 1224 const VarRegionAxis *axes = axesZ + (region_index * axisCount); |
| 1225 |
| 1226 float v = 1.; |
| 1227 unsigned int count = MIN (coord_len, (unsigned int) axisCount); |
| 1228 for (unsigned int i = 0; i < count; i++) |
| 1229 { |
| 1230 float factor = axes[i].evaluate (coords[i]); |
| 1231 if (factor == 0.) |
| 1232 return 0.; |
| 1233 v *= factor; |
| 1234 } |
| 1235 return v; |
| 1236 } |
| 1237 |
| 1238 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1239 { |
| 1240 TRACE_SANITIZE (this); |
| 1241 return_trace (c->check_struct (this) && |
| 1242 c->check_array (axesZ, axesZ[0].static_size, |
| 1243 (unsigned int) axisCount * (unsigned int) regi
onCount)); |
| 1244 } |
| 1245 |
| 1246 protected: |
| 1247 USHORT axisCount; |
| 1248 USHORT regionCount; |
| 1249 VarRegionAxis axesZ[VAR]; |
| 1250 public: |
| 1251 DEFINE_SIZE_ARRAY (4, axesZ); |
| 1252 }; |
| 1253 |
| 1254 struct VarData |
| 1255 { |
| 1256 inline unsigned int get_row_size (void) const |
| 1257 { return shortCount + regionIndices.len; } |
| 1258 |
| 1259 inline unsigned int get_size (void) const |
| 1260 { return itemCount * get_row_size (); } |
| 1261 |
| 1262 inline float get_delta (unsigned int inner, |
| 1263 int *coords, unsigned int coord_count, |
| 1264 const VarRegionList ®ions) const |
| 1265 { |
| 1266 if (unlikely (inner >= itemCount)) |
| 1267 return 0.; |
| 1268 |
| 1269 unsigned int count = regionIndices.len; |
| 1270 unsigned int scount = shortCount; |
| 1271 |
| 1272 const BYTE *bytes = &StructAfter<BYTE> (regionIndices); |
| 1273 const BYTE *row = bytes + inner * (scount + count); |
| 1274 |
| 1275 float delta = 0.; |
| 1276 unsigned int i = 0; |
| 1277 |
| 1278 const SHORT *scursor = reinterpret_cast<const SHORT *> (row); |
| 1279 for (; i < scount; i++) |
| 1280 { |
| 1281 float scalar = regions.evaluate (regionIndices.array[i], coords, coord_coun
t); |
| 1282 delta += scalar * *scursor++; |
| 1283 } |
| 1284 const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor); |
| 1285 for (; i < count; i++) |
| 1286 { |
| 1287 float scalar = regions.evaluate (regionIndices.array[i], coords, coord_coun
t); |
| 1288 delta += scalar * *bcursor++; |
| 1289 } |
| 1290 |
| 1291 return delta; |
| 1292 } |
| 1293 |
| 1294 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1295 { |
| 1296 TRACE_SANITIZE (this); |
| 1297 return_trace (c->check_struct (this) && |
| 1298 regionIndices.sanitize(c) && |
| 1299 shortCount <= regionIndices.len && |
| 1300 c->check_array (&StructAfter<BYTE> (regionIndices), |
| 1301 get_row_size (), itemCount)); |
| 1302 } |
| 1303 |
| 1304 protected: |
| 1305 USHORT itemCount; |
| 1306 USHORT shortCount; |
| 1307 ArrayOf<USHORT> regionIndices; |
| 1308 BYTE bytesX[VAR]; |
| 1309 public: |
| 1310 DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); |
| 1311 }; |
| 1312 |
| 1313 struct VariationStore |
| 1314 { |
| 1315 inline float get_delta (unsigned int outer, unsigned int inner, |
| 1316 int *coords, unsigned int coord_count) const |
| 1317 { |
| 1318 if (unlikely (outer >= dataSets.len)) |
| 1319 return 0.; |
| 1320 |
| 1321 return (this+dataSets[outer]).get_delta (inner, |
| 1322 coords, coord_count, |
| 1323 this+regions); |
| 1324 } |
| 1325 |
| 1326 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1327 { |
| 1328 TRACE_SANITIZE (this); |
| 1329 return_trace (c->check_struct (this) && |
| 1330 format == 1 && |
| 1331 regions.sanitize (c, this) && |
| 1332 dataSets.sanitize (c, this)); |
| 1333 } |
| 1334 |
| 1335 protected: |
| 1336 USHORT format; |
| 1337 OffsetTo<VarRegionList, ULONG> regions; |
| 1338 OffsetArrayOf<VarData, ULONG> dataSets; |
| 1339 public: |
| 1340 DEFINE_SIZE_ARRAY (8, dataSets); |
| 1341 }; |
| 1342 |
| 1343 /* |
| 1344 * Feature Variations |
| 1345 */ |
| 1346 |
| 1347 struct ConditionFormat1 |
| 1348 { |
| 1349 friend struct Condition; |
| 1350 |
| 1351 private: |
| 1352 inline bool evaluate (const int *coords, unsigned int coord_len) const |
| 1353 { |
| 1354 int coord = axisIndex < coord_len ? coords[axisIndex] : 0; |
| 1355 return filterRangeMinValue <= coord && coord <= filterRangeMaxValue; |
| 1356 } |
| 1357 |
| 1358 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1359 { |
| 1360 TRACE_SANITIZE (this); |
| 1361 return_trace (c->check_struct (this)); |
| 1362 } |
| 1363 |
| 1364 protected: |
| 1365 USHORT format; /* Format identifier--format = 1 */ |
| 1366 USHORT axisIndex; |
| 1367 F2DOT14 filterRangeMinValue; |
| 1368 F2DOT14 filterRangeMaxValue; |
| 1369 public: |
| 1370 DEFINE_SIZE_STATIC (8); |
| 1371 }; |
| 1372 |
| 1373 struct Condition |
| 1374 { |
| 1375 inline bool evaluate (const int *coords, unsigned int coord_len) const |
| 1376 { |
| 1377 switch (u.format) { |
| 1378 case 1: return u.format1.evaluate (coords, coord_len); |
| 1379 default:return false; |
| 1380 } |
| 1381 } |
| 1382 |
| 1383 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1384 { |
| 1385 TRACE_SANITIZE (this); |
| 1386 if (!u.format.sanitize (c)) return_trace (false); |
| 1387 switch (u.format) { |
| 1388 case 1: return_trace (u.format1.sanitize (c)); |
| 1389 default:return_trace (true); |
| 1390 } |
| 1391 } |
| 1392 |
| 1393 protected: |
| 1394 union { |
| 1395 USHORT format; /* Format identifier */ |
| 1396 ConditionFormat1 format1; |
| 1397 } u; |
| 1398 public: |
| 1399 DEFINE_SIZE_UNION (2, format); |
| 1400 }; |
| 1401 |
| 1402 struct ConditionSet |
| 1403 { |
| 1404 inline bool evaluate (const int *coords, unsigned int coord_len) const |
| 1405 { |
| 1406 unsigned int count = conditions.len; |
| 1407 for (unsigned int i = 0; i < count; i++) |
| 1408 if (!(this+conditions.array[i]).evaluate (coords, coord_len)) |
| 1409 return false; |
| 1410 return true; |
| 1411 } |
| 1412 |
| 1413 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1414 { |
| 1415 TRACE_SANITIZE (this); |
| 1416 return_trace (conditions.sanitize (c, this)); |
| 1417 } |
| 1418 |
| 1419 protected: |
| 1420 OffsetArrayOf<Condition, ULONG> conditions; |
| 1421 public: |
| 1422 DEFINE_SIZE_ARRAY (2, conditions); |
| 1423 }; |
| 1424 |
| 1425 struct FeatureTableSubstitutionRecord |
| 1426 { |
| 1427 friend struct FeatureTableSubstitution; |
| 1428 |
| 1429 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 1430 { |
| 1431 TRACE_SANITIZE (this); |
| 1432 return_trace (c->check_struct (this) && feature.sanitize (c, base)); |
| 1433 } |
| 1434 |
| 1435 protected: |
| 1436 USHORT featureIndex; |
| 1437 OffsetTo<Feature, ULONG> feature; |
| 1438 public: |
| 1439 DEFINE_SIZE_STATIC (6); |
| 1440 }; |
| 1441 |
| 1442 struct FeatureTableSubstitution |
| 1443 { |
| 1444 inline const Feature *find_substitute (unsigned int feature_index) const |
| 1445 { |
| 1446 unsigned int count = substitutions.len; |
| 1447 for (unsigned int i = 0; i < count; i++) |
| 1448 { |
| 1449 const FeatureTableSubstitutionRecord &record = substitutions.array[i]; |
| 1450 if (record.featureIndex == feature_index) |
| 1451 return &(this+record.feature); |
| 1452 } |
| 1453 return NULL; |
| 1454 } |
| 1455 |
| 1456 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1457 { |
| 1458 TRACE_SANITIZE (this); |
| 1459 return_trace (version.sanitize (c) && |
| 1460 likely (version.major == 1) && |
| 1461 substitutions.sanitize (c, this)); |
| 1462 } |
| 1463 |
| 1464 protected: |
| 1465 FixedVersion<> version; /* Version--0x00010000u */ |
| 1466 ArrayOf<FeatureTableSubstitutionRecord> |
| 1467 substitutions; |
| 1468 public: |
| 1469 DEFINE_SIZE_ARRAY (6, substitutions); |
| 1470 }; |
| 1471 |
| 1472 struct FeatureVariationRecord |
| 1473 { |
| 1474 friend struct FeatureVariations; |
| 1475 |
| 1476 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 1477 { |
| 1478 TRACE_SANITIZE (this); |
| 1479 return_trace (conditions.sanitize (c, base) && |
| 1480 substitutions.sanitize (c, base)); |
| 1481 } |
| 1482 |
| 1483 protected: |
| 1484 OffsetTo<ConditionSet, ULONG> |
| 1485 conditions; |
| 1486 OffsetTo<FeatureTableSubstitution, ULONG> |
| 1487 substitutions; |
| 1488 public: |
| 1489 DEFINE_SIZE_STATIC (8); |
| 1490 }; |
| 1491 |
| 1492 struct FeatureVariations |
| 1493 { |
| 1494 static const unsigned int NOT_FOUND_INDEX = 0xFFFFFFFFu; |
| 1495 |
| 1496 inline bool find_index (const int *coords, unsigned int coord_len, |
| 1497 unsigned int *index) const |
| 1498 { |
| 1499 unsigned int count = varRecords.len; |
| 1500 for (unsigned int i = 0; i < count; i++) |
| 1501 { |
| 1502 const FeatureVariationRecord &record = varRecords.array[i]; |
| 1503 if ((this+record.conditions).evaluate (coords, coord_len)) |
| 1504 { |
| 1505 *index = i; |
| 1506 return true; |
| 1507 } |
| 1508 } |
| 1509 *index = NOT_FOUND_INDEX; |
| 1510 return false; |
| 1511 } |
| 1512 |
| 1513 inline const Feature *find_substitute (unsigned int variations_index, |
| 1514 unsigned int feature_index) const |
| 1515 { |
| 1516 const FeatureVariationRecord &record = varRecords[variations_index]; |
| 1517 return (this+record.substitutions).find_substitute (feature_index); |
| 1518 } |
| 1519 |
| 1520 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1521 { |
| 1522 TRACE_SANITIZE (this); |
| 1523 return_trace (version.sanitize (c) && |
| 1524 likely (version.major == 1) && |
| 1525 varRecords.sanitize (c, this)); |
| 1526 } |
| 1527 |
| 1528 protected: |
| 1529 FixedVersion<> version; /* Version--0x00010000u */ |
| 1530 ArrayOf<FeatureVariationRecord, ULONG> |
| 1531 varRecords; |
| 1532 public: |
| 1533 DEFINE_SIZE_ARRAY (8, varRecords); |
| 1534 }; |
| 1535 |
| 1536 |
| 1537 /* |
| 1165 * Device Tables | 1538 * Device Tables |
| 1166 */ | 1539 */ |
| 1167 | 1540 |
| 1168 struct Device | 1541 struct HintingDevice |
| 1169 { | 1542 { |
| 1543 friend struct Device; |
| 1544 |
| 1545 private: |
| 1170 | 1546 |
| 1171 inline hb_position_t get_x_delta (hb_font_t *font) const | 1547 inline hb_position_t get_x_delta (hb_font_t *font) const |
| 1172 { return get_delta (font->x_ppem, font->x_scale); } | 1548 { return get_delta (font->x_ppem, font->x_scale); } |
| 1173 | 1549 |
| 1174 inline hb_position_t get_y_delta (hb_font_t *font) const | 1550 inline hb_position_t get_y_delta (hb_font_t *font) const |
| 1175 { return get_delta (font->y_ppem, font->y_scale); } | 1551 { return get_delta (font->y_ppem, font->y_scale); } |
| 1176 | 1552 |
| 1177 inline unsigned int get_size (void) const | 1553 inline unsigned int get_size (void) const |
| 1178 { | 1554 { |
| 1179 unsigned int f = deltaFormat; | 1555 unsigned int f = deltaFormat; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2
, or 3 | 1604 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2
, or 3 |
| 1229 * 1 Signed 2-bit value, 8 values per
uint16 | 1605 * 1 Signed 2-bit value, 8 values per
uint16 |
| 1230 * 2 Signed 4-bit value, 4 values per
uint16 | 1606 * 2 Signed 4-bit value, 4 values per
uint16 |
| 1231 * 3 Signed 8-bit value, 2 values per
uint16 | 1607 * 3 Signed 8-bit value, 2 values per
uint16 |
| 1232 */ | 1608 */ |
| 1233 USHORT deltaValue[VAR]; /* Array of compressed data */ | 1609 USHORT deltaValue[VAR]; /* Array of compressed data */ |
| 1234 public: | 1610 public: |
| 1235 DEFINE_SIZE_ARRAY (6, deltaValue); | 1611 DEFINE_SIZE_ARRAY (6, deltaValue); |
| 1236 }; | 1612 }; |
| 1237 | 1613 |
| 1614 struct VariationDevice |
| 1615 { |
| 1616 friend struct Device; |
| 1617 |
| 1618 private: |
| 1619 |
| 1620 inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store
) const |
| 1621 { return font->em_scalef_x (get_delta (font, store)); } |
| 1622 |
| 1623 inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store
) const |
| 1624 { return font->em_scalef_y (get_delta (font, store)); } |
| 1625 |
| 1626 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1627 { |
| 1628 TRACE_SANITIZE (this); |
| 1629 return_trace (c->check_struct (this)); |
| 1630 } |
| 1631 |
| 1632 private: |
| 1633 |
| 1634 inline float get_delta (hb_font_t *font, const VariationStore &store) const |
| 1635 { |
| 1636 return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coor
ds); |
| 1637 } |
| 1638 |
| 1639 protected: |
| 1640 USHORT outerIndex; |
| 1641 USHORT innerIndex; |
| 1642 USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */ |
| 1643 public: |
| 1644 DEFINE_SIZE_STATIC (6); |
| 1645 }; |
| 1646 |
| 1647 struct DeviceHeader |
| 1648 { |
| 1649 protected: |
| 1650 USHORT reserved1; |
| 1651 USHORT reserved2; |
| 1652 public: |
| 1653 USHORT format; /* Format identifier */ |
| 1654 public: |
| 1655 DEFINE_SIZE_STATIC (6); |
| 1656 }; |
| 1657 |
| 1658 struct Device |
| 1659 { |
| 1660 inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store
=Null(VariationStore)) const |
| 1661 { |
| 1662 switch (u.b.format) |
| 1663 { |
| 1664 case 1: case 2: case 3: |
| 1665 return u.hinting.get_x_delta (font); |
| 1666 case 0x8000: |
| 1667 return u.variation.get_x_delta (font, store); |
| 1668 default: |
| 1669 return 0; |
| 1670 } |
| 1671 } |
| 1672 inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store
=Null(VariationStore)) const |
| 1673 { |
| 1674 switch (u.b.format) |
| 1675 { |
| 1676 case 1: case 2: case 3: |
| 1677 return u.hinting.get_y_delta (font); |
| 1678 case 0x8000: |
| 1679 return u.variation.get_y_delta (font, store); |
| 1680 default: |
| 1681 return 0; |
| 1682 } |
| 1683 } |
| 1684 |
| 1685 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1686 { |
| 1687 TRACE_SANITIZE (this); |
| 1688 if (!u.b.format.sanitize (c)) return_trace (false); |
| 1689 switch (u.b.format) { |
| 1690 case 1: case 2: case 3: |
| 1691 return_trace (u.hinting.sanitize (c)); |
| 1692 case 0x8000: |
| 1693 return_trace (u.variation.sanitize (c)); |
| 1694 default: |
| 1695 return_trace (true); |
| 1696 } |
| 1697 } |
| 1698 |
| 1699 protected: |
| 1700 union { |
| 1701 DeviceHeader b; |
| 1702 HintingDevice hinting; |
| 1703 VariationDevice variation; |
| 1704 } u; |
| 1705 public: |
| 1706 DEFINE_SIZE_UNION (6, b); |
| 1707 }; |
| 1708 |
| 1238 | 1709 |
| 1239 } /* namespace OT */ | 1710 } /* namespace OT */ |
| 1240 | 1711 |
| 1241 | 1712 |
| 1242 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ | 1713 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ |
| OLD | NEW |