| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 1998-2004 David Turner and Werner Lemberg | 2 * Copyright © 1998-2004 David Turner and Werner Lemberg |
| 3 * Copyright © 2006 Behdad Esfahbod | 3 * Copyright © 2006 Behdad Esfahbod |
| 4 * Copyright © 2007,2008,2009 Red Hat, Inc. | 4 * Copyright © 2007,2008,2009 Red Hat, Inc. |
| 5 * Copyright © 2012,2013 Google, Inc. | 5 * Copyright © 2012,2013 Google, Inc. |
| 6 * | 6 * |
| 7 * This is part of HarfBuzz, a text shaping library. | 7 * This is part of HarfBuzz, a text shaping library. |
| 8 * | 8 * |
| 9 * Permission is hereby granted, without written agreement and without | 9 * Permission is hereby granted, without written agreement and without |
| 10 * license or royalty fees, to use, copy, modify, and distribute this | 10 * license or royalty fees, to use, copy, modify, and distribute this |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 * Google Author(s): Behdad Esfahbod | 28 * Google Author(s): Behdad Esfahbod |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "hb-open-type-private.hh" | 31 #include "hb-open-type-private.hh" |
| 32 #include "hb-ot-layout-private.hh" | 32 #include "hb-ot-layout-private.hh" |
| 33 | 33 |
| 34 #include "hb-ot-layout-gdef-table.hh" | 34 #include "hb-ot-layout-gdef-table.hh" |
| 35 #include "hb-ot-layout-gsub-table.hh" | 35 #include "hb-ot-layout-gsub-table.hh" |
| 36 #include "hb-ot-layout-gpos-table.hh" | 36 #include "hb-ot-layout-gpos-table.hh" |
| 37 #include "hb-ot-layout-jstf-table.hh" | 37 #include "hb-ot-layout-jstf-table.hh" |
| 38 #include "hb-ot-layout-math-table.hh" | |
| 39 | 38 |
| 40 #include "hb-ot-map-private.hh" | 39 #include "hb-ot-map-private.hh" |
| 41 | 40 |
| 42 #include <stdlib.h> | 41 #include <stdlib.h> |
| 43 #include <string.h> | 42 #include <string.h> |
| 44 | 43 |
| 45 | 44 |
| 46 HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) | 45 HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) |
| 47 | 46 |
| 48 hb_ot_layout_t * | 47 hb_ot_layout_t * |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 { | 197 { |
| 199 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB
); | 198 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB
); |
| 200 return *hb_ot_layout_from_face (face)->gsub; | 199 return *hb_ot_layout_from_face (face)->gsub; |
| 201 } | 200 } |
| 202 static inline const OT::GPOS& | 201 static inline const OT::GPOS& |
| 203 _get_gpos (hb_face_t *face) | 202 _get_gpos (hb_face_t *face) |
| 204 { | 203 { |
| 205 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS
); | 204 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS
); |
| 206 return *hb_ot_layout_from_face (face)->gpos; | 205 return *hb_ot_layout_from_face (face)->gpos; |
| 207 } | 206 } |
| 208 static inline const OT::MATH& | |
| 209 _get_math (hb_face_t *face) | |
| 210 { | |
| 211 if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH
); | |
| 212 | |
| 213 hb_ot_layout_t * layout = hb_ot_layout_from_face (face); | |
| 214 | |
| 215 retry: | |
| 216 const OT::MATH *math = (const OT::MATH *) hb_atomic_ptr_get (&layout->math); | |
| 217 | |
| 218 if (unlikely (!math)) | |
| 219 { | |
| 220 hb_blob_t *blob = OT::Sanitizer<OT::MATH>::sanitize (face->reference_table (
HB_OT_TAG_MATH)); | |
| 221 math = OT::Sanitizer<OT::MATH>::lock_instance (blob); | |
| 222 if (!hb_atomic_ptr_cmpexch (&layout->math, NULL, math)) | |
| 223 { | |
| 224 hb_blob_destroy (blob); | |
| 225 goto retry; | |
| 226 } | |
| 227 layout->math_blob = blob; | |
| 228 } | |
| 229 | |
| 230 return *math; | |
| 231 } | |
| 232 | |
| 233 | 207 |
| 234 /* | 208 /* |
| 235 * GDEF | 209 * GDEF |
| 236 */ | 210 */ |
| 237 | 211 |
| 238 hb_bool_t | 212 hb_bool_t |
| 239 hb_ot_layout_has_glyph_classes (hb_face_t *face) | 213 hb_ot_layout_has_glyph_classes (hb_face_t *face) |
| 240 { | 214 { |
| 241 return _get_gdef (face).has_glyph_classes (); | 215 return _get_gdef (face).has_glyph_classes (); |
| 242 } | 216 } |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 * Since: 0.9.7 | 549 * Since: 0.9.7 |
| 576 **/ | 550 **/ |
| 577 unsigned int | 551 unsigned int |
| 578 hb_ot_layout_feature_get_lookups (hb_face_t *face, | 552 hb_ot_layout_feature_get_lookups (hb_face_t *face, |
| 579 hb_tag_t table_tag, | 553 hb_tag_t table_tag, |
| 580 unsigned int feature_index, | 554 unsigned int feature_index, |
| 581 unsigned int start_offset, | 555 unsigned int start_offset, |
| 582 unsigned int *lookup_count /* IN/OUT */, | 556 unsigned int *lookup_count /* IN/OUT */, |
| 583 unsigned int *lookup_indexes /* OUT */) | 557 unsigned int *lookup_indexes /* OUT */) |
| 584 { | 558 { |
| 585 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); | 559 return hb_ot_layout_feature_with_variations_get_lookups (face, |
| 586 const OT::Feature &f = g.get_feature (feature_index); | 560 » » » » » » » table_tag, |
| 587 | 561 » » » » » » » feature_index, |
| 588 return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); | 562 » » » » » » » HB_OT_LAYOUT_NO_VARIA
TIONS_INDEX, |
| 563 » » » » » » » start_offset, |
| 564 » » » » » » » lookup_count, |
| 565 » » » » » » » lookup_indexes); |
| 589 } | 566 } |
| 590 | 567 |
| 591 /** | 568 /** |
| 592 * hb_ot_layout_table_get_lookup_count: | 569 * hb_ot_layout_table_get_lookup_count: |
| 593 * | 570 * |
| 594 * Since: 0.9.22 | 571 * Since: 0.9.22 |
| 595 **/ | 572 **/ |
| 596 unsigned int | 573 unsigned int |
| 597 hb_ot_layout_table_get_lookup_count (hb_face_t *face, | 574 hb_ot_layout_table_get_lookup_count (hb_face_t *face, |
| 598 hb_tag_t table_tag) | 575 hb_tag_t table_tag) |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 case HB_OT_TAG_GPOS: | 806 case HB_OT_TAG_GPOS: |
| 830 { | 807 { |
| 831 const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (
lookup_index); | 808 const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (
lookup_index); |
| 832 l.collect_glyphs (&c); | 809 l.collect_glyphs (&c); |
| 833 return; | 810 return; |
| 834 } | 811 } |
| 835 } | 812 } |
| 836 } | 813 } |
| 837 | 814 |
| 838 | 815 |
| 816 /* Variations support */ |
| 817 |
| 818 hb_bool_t |
| 819 hb_ot_layout_table_find_feature_variations (hb_face_t *face, |
| 820 hb_tag_t table_tag, |
| 821 const int *coords, |
| 822 unsigned int num_coords, |
| 823 unsigned int *variations_index /* ou
t */) |
| 824 { |
| 825 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); |
| 826 |
| 827 return g.find_variations_index (coords, num_coords, variations_index); |
| 828 } |
| 829 |
| 830 unsigned int |
| 831 hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, |
| 832 hb_tag_t table_tag, |
| 833 unsigned int feature_index, |
| 834 unsigned int variations_index
, |
| 835 unsigned int start_offset, |
| 836 unsigned int *lookup_count /*
IN/OUT */, |
| 837 unsigned int *lookup_indexes /
* OUT */) |
| 838 { |
| 839 ASSERT_STATIC (OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIA
TIONS_INDEX); |
| 840 const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); |
| 841 |
| 842 const OT::Feature &f = g.get_feature_variation (feature_index, variations_inde
x); |
| 843 |
| 844 return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); |
| 845 } |
| 846 |
| 847 |
| 839 /* | 848 /* |
| 840 * OT::GSUB | 849 * OT::GSUB |
| 841 */ | 850 */ |
| 842 | 851 |
| 843 hb_bool_t | 852 hb_bool_t |
| 844 hb_ot_layout_has_substitution (hb_face_t *face) | 853 hb_ot_layout_has_substitution (hb_face_t *face) |
| 845 { | 854 { |
| 846 return &_get_gsub (face) != &OT::Null(OT::GSUB); | 855 return &_get_gsub (face) != &OT::Null(OT::GSUB); |
| 847 } | 856 } |
| 848 | 857 |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 apply (proxy, plan, font, buffer); | 1222 apply (proxy, plan, font, buffer); |
| 1214 } | 1223 } |
| 1215 | 1224 |
| 1216 HB_INTERNAL void | 1225 HB_INTERNAL void |
| 1217 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, | 1226 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, |
| 1218 const OT::SubstLookup &lookup, | 1227 const OT::SubstLookup &lookup, |
| 1219 const hb_ot_layout_lookup_accelerator_t &accel) | 1228 const hb_ot_layout_lookup_accelerator_t &accel) |
| 1220 { | 1229 { |
| 1221 apply_string<GSUBProxy> (c, lookup, accel); | 1230 apply_string<GSUBProxy> (c, lookup, accel); |
| 1222 } | 1231 } |
| 1223 | |
| 1224 | |
| 1225 /* | |
| 1226 * MATH | |
| 1227 */ | |
| 1228 /* TODO Move this to hb-ot-math.cc and separate it from hb_ot_layout_t. */ | |
| 1229 | |
| 1230 /** | |
| 1231 * hb_ot_math_has_data: | |
| 1232 * @face: #hb_face_t to test | |
| 1233 * | |
| 1234 * This function allows to verify the presence of an OpenType MATH table on the | |
| 1235 * face. If so, such a table will be loaded into memory and sanitized. You can | |
| 1236 * then safely call other functions for math layout and shaping. | |
| 1237 * | |
| 1238 * Return value: #TRUE if face has a MATH table and #FALSE otherwise | |
| 1239 * | |
| 1240 * Since: 1.3.3 | |
| 1241 **/ | |
| 1242 hb_bool_t | |
| 1243 hb_ot_math_has_data (hb_face_t *face) | |
| 1244 { | |
| 1245 return &_get_math (face) != &OT::Null(OT::MATH); | |
| 1246 } | |
| 1247 | |
| 1248 /** | |
| 1249 * hb_ot_math_get_constant: | |
| 1250 * @font: #hb_font_t from which to retrieve the value | |
| 1251 * @constant: #hb_ot_math_constant_t the constant to retrieve | |
| 1252 * | |
| 1253 * This function returns the requested math constants as a #hb_position_t. | |
| 1254 * If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, | |
| 1255 * HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or | |
| 1256 * HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is | |
| 1257 * actually an integer between 0 and 100 representing that percentage. | |
| 1258 * | |
| 1259 * Return value: the requested constant or 0 | |
| 1260 * | |
| 1261 * Since: 1.3.3 | |
| 1262 **/ | |
| 1263 hb_position_t | |
| 1264 hb_ot_math_get_constant (hb_font_t *font, | |
| 1265 hb_ot_math_constant_t constant) | |
| 1266 { | |
| 1267 const OT::MATH &math = _get_math (font->face); | |
| 1268 return math.get_constant(constant, font); | |
| 1269 } | |
| 1270 | |
| 1271 /** | |
| 1272 * hb_ot_math_get_glyph_italics_correction: | |
| 1273 * @font: #hb_font_t from which to retrieve the value | |
| 1274 * @glyph: glyph index from which to retrieve the value | |
| 1275 * | |
| 1276 * Return value: the italics correction of the glyph or 0 | |
| 1277 * | |
| 1278 * Since: 1.3.3 | |
| 1279 **/ | |
| 1280 hb_position_t | |
| 1281 hb_ot_math_get_glyph_italics_correction (hb_font_t *font, | |
| 1282 hb_codepoint_t glyph) | |
| 1283 { | |
| 1284 const OT::MATH &math = _get_math (font->face); | |
| 1285 return math.get_math_glyph_info().get_italics_correction (glyph, font); | |
| 1286 } | |
| 1287 | |
| 1288 /** | |
| 1289 * hb_ot_math_get_glyph_top_accent_attachment: | |
| 1290 * @font: #hb_font_t from which to retrieve the value | |
| 1291 * @glyph: glyph index from which to retrieve the value | |
| 1292 * | |
| 1293 * Return value: the top accent attachment of the glyph or 0 | |
| 1294 * | |
| 1295 * Since: 1.3.3 | |
| 1296 **/ | |
| 1297 hb_position_t | |
| 1298 hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, | |
| 1299 hb_codepoint_t glyph) | |
| 1300 { | |
| 1301 const OT::MATH &math = _get_math (font->face); | |
| 1302 return math.get_math_glyph_info().get_top_accent_attachment (glyph, font); | |
| 1303 } | |
| 1304 | |
| 1305 /** | |
| 1306 * hb_ot_math_is_glyph_extended_shape: | |
| 1307 * @font: a #hb_font_t to test | |
| 1308 * @glyph: a glyph index to test | |
| 1309 * | |
| 1310 * Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise | |
| 1311 * | |
| 1312 * Since: 1.3.3 | |
| 1313 **/ | |
| 1314 hb_bool_t | |
| 1315 hb_ot_math_is_glyph_extended_shape (hb_face_t *face, | |
| 1316 hb_codepoint_t glyph) | |
| 1317 { | |
| 1318 const OT::MATH &math = _get_math (face); | |
| 1319 return math.get_math_glyph_info().is_extended_shape (glyph); | |
| 1320 } | |
| 1321 | |
| 1322 /** | |
| 1323 * hb_ot_math_get_glyph_kerning: | |
| 1324 * @font: #hb_font_t from which to retrieve the value | |
| 1325 * @glyph: glyph index from which to retrieve the value | |
| 1326 * @kern: the #hb_ot_math_kern_t from which to retrieve the value | |
| 1327 * @correction_height: the correction height to use to determine the kerning. | |
| 1328 * | |
| 1329 * This function tries to retrieve the MathKern table for the specified font, | |
| 1330 * glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the | |
| 1331 * MathKern table to find one value that is greater or equal to specified | |
| 1332 * correction_height. If one is found the corresponding value from the list of | |
| 1333 * kerns is returned and otherwise the last kern value is returned. | |
| 1334 * | |
| 1335 * Return value: requested kerning or 0 | |
| 1336 * | |
| 1337 * Since: 1.3.3 | |
| 1338 **/ | |
| 1339 hb_position_t | |
| 1340 hb_ot_math_get_glyph_kerning (hb_font_t *font, | |
| 1341 hb_codepoint_t glyph, | |
| 1342 hb_ot_math_kern_t kern, | |
| 1343 hb_position_t correction_height) | |
| 1344 { | |
| 1345 const OT::MATH &math = _get_math (font->face); | |
| 1346 return math.get_math_glyph_info().get_kerning (glyph, kern, correction_height,
font); | |
| 1347 } | |
| 1348 | |
| 1349 /** | |
| 1350 * hb_ot_math_get_glyph_variants: | |
| 1351 * @font: #hb_font_t from which to retrieve the values | |
| 1352 * @glyph: index of the glyph to stretch | |
| 1353 * @direction: direction of the stretching | |
| 1354 * @start_offset: offset of the first variant to retrieve | |
| 1355 * @variants_count: maximum number of variants to retrieve after start_offset | |
| 1356 * (IN) and actual number of variants retrieved (OUT) | |
| 1357 * @variants: array of size at least @variants_count to store the result | |
| 1358 * | |
| 1359 * This function tries to retrieve the MathGlyphConstruction for the specified | |
| 1360 * font, glyph and direction. Note that only the value of | |
| 1361 * #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list | |
| 1362 * of size variants as an array of hb_ot_math_glyph_variant_t structs. | |
| 1363 * | |
| 1364 * Return value: the total number of size variants available or 0 | |
| 1365 * | |
| 1366 * Since: 1.3.3 | |
| 1367 **/ | |
| 1368 unsigned int | |
| 1369 hb_ot_math_get_glyph_variants (hb_font_t *font, | |
| 1370 hb_codepoint_t glyph, | |
| 1371 hb_direction_t direction, | |
| 1372 unsigned int start_offset, | |
| 1373 unsigned int *variants_count, /* IN/OUT */ | |
| 1374 hb_ot_math_glyph_variant_t *variants /* OUT */) | |
| 1375 { | |
| 1376 const OT::MATH &math = _get_math (font->face); | |
| 1377 return math.get_math_variants().get_glyph_variants (glyph, direction, font, | |
| 1378 start_offset, | |
| 1379 variants_count, | |
| 1380 variants); | |
| 1381 } | |
| 1382 | |
| 1383 /** | |
| 1384 * hb_ot_math_get_min_connector_overlap: | |
| 1385 * @font: #hb_font_t from which to retrieve the value | |
| 1386 * @direction: direction of the stretching | |
| 1387 * | |
| 1388 * This function tries to retrieve the MathVariants table for the specified | |
| 1389 * font and returns the minimum overlap of connecting glyphs to draw a glyph | |
| 1390 * assembly in the specified direction. Note that only the value of | |
| 1391 * #HB_DIRECTION_IS_HORIZONTAL is considered. | |
| 1392 * | |
| 1393 * Return value: requested min connector overlap or 0 | |
| 1394 * | |
| 1395 * Since: 1.3.3 | |
| 1396 **/ | |
| 1397 hb_position_t | |
| 1398 hb_ot_math_get_min_connector_overlap (hb_font_t *font, | |
| 1399 hb_direction_t direction) | |
| 1400 { | |
| 1401 const OT::MATH &math = _get_math (font->face); | |
| 1402 return math.get_math_variants().get_min_connector_overlap (direction, font); | |
| 1403 } | |
| 1404 | |
| 1405 /** | |
| 1406 * hb_ot_math_get_glyph_assembly: | |
| 1407 * @font: #hb_font_t from which to retrieve the values | |
| 1408 * @glyph: index of the glyph to stretch | |
| 1409 * @direction: direction of the stretching | |
| 1410 * @start_offset: offset of the first glyph part to retrieve | |
| 1411 * @parts_count: maximum number of glyph parts to retrieve after start_offset | |
| 1412 * (IN) and actual number of parts retrieved (OUT) | |
| 1413 * @parts: array of size at least @parts_count to store the result | |
| 1414 * @italics_correction: italic correction of the glyph assembly | |
| 1415 * | |
| 1416 * This function tries to retrieve the GlyphAssembly for the specified font, | |
| 1417 * glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL | |
| 1418 * is considered. It provides the information necessary to draw the glyph | |
| 1419 * assembly as an array of #hb_ot_math_glyph_part_t. | |
| 1420 * | |
| 1421 * Return value: the total number of parts in the glyph assembly | |
| 1422 * | |
| 1423 * Since: 1.3.3 | |
| 1424 **/ | |
| 1425 unsigned int | |
| 1426 hb_ot_math_get_glyph_assembly (hb_font_t *font, | |
| 1427 hb_codepoint_t glyph, | |
| 1428 hb_direction_t direction, | |
| 1429 unsigned int start_offset, | |
| 1430 unsigned int *parts_count, /* IN/OUT */ | |
| 1431 hb_ot_math_glyph_part_t *parts, /* OUT */ | |
| 1432 hb_position_t *italics_correction /* OUT */) | |
| 1433 { | |
| 1434 const OT::MATH &math = _get_math (font->face); | |
| 1435 return math.get_math_variants().get_glyph_parts (glyph, direction, font, | |
| 1436 start_offset, | |
| 1437 parts_count, | |
| 1438 parts, | |
| 1439 italics_correction); | |
| 1440 } | |
| OLD | NEW |