diff options
| author | Po Lu | 2023-03-27 16:42:52 +0800 |
|---|---|---|
| committer | Po Lu | 2023-03-27 16:42:52 +0800 |
| commit | dd4924ca90a8ada26bb10e5df4557ae32c0d6403 (patch) | |
| tree | 52b741e15c4074033746e44daaab26998a114618 /src | |
| parent | 18b34e9ca01deff8e0bde4b1e53293f27712a149 (diff) | |
| download | emacs-dd4924ca90a8ada26bb10e5df4557ae32c0d6403.tar.gz emacs-dd4924ca90a8ada26bb10e5df4557ae32c0d6403.zip | |
Update Android port
* configure.ac (HAVE_OTF_GET_VARIATION_GLYPHS): Check for
`hb_font_set_var_named_instance'.
* src/sfnt.c (main): Update tests.
* src/sfntfont-android.c (Fandroid_enumerate_fonts): Blacklist
bad font.
* src/sfntfont.c (struct sfnt_font_tables, struct sfnt_font_desc)
(sfnt_decode_instance_name, sfnt_weight_descriptions)
(sfnt_enum_font_1, sfntfont_list_1, sfntfont_desc_to_entity)
(sfntfont_list, struct sfntfont_get_glyph_outline_dcontext)
(sfntfont_get_glyph, sfntfont_get_glyph_outline)
(struct sfnt_font_info, sfnt_close_tables, sfnt_open_tables)
(sfntfont_open, sfntfont_measure_pcm, sfntfont_close)
(sfntfont_draw, sfntfont_begin_hb_font, syms_of_sfntfont)
(mark_sfntfont): Handle variable fonts correctly.
Diffstat (limited to 'src')
| -rw-r--r-- | src/sfnt.c | 4 | ||||
| -rw-r--r-- | src/sfntfont-android.c | 7 | ||||
| -rw-r--r-- | src/sfntfont.c | 405 |
3 files changed, 367 insertions, 49 deletions
diff --git a/src/sfnt.c b/src/sfnt.c index 9a1094a1ca9..99649698557 100644 --- a/src/sfnt.c +++ b/src/sfnt.c | |||
| @@ -18922,8 +18922,8 @@ main (int argc, char **argv) | |||
| 18922 | return 1; | 18922 | return 1; |
| 18923 | } | 18923 | } |
| 18924 | 18924 | ||
| 18925 | #define FANCY_PPEM 15 | 18925 | #define FANCY_PPEM 40 |
| 18926 | #define EASY_PPEM 15 | 18926 | #define EASY_PPEM 40 |
| 18927 | 18927 | ||
| 18928 | interpreter = NULL; | 18928 | interpreter = NULL; |
| 18929 | head = sfnt_read_head_table (fd, font); | 18929 | head = sfnt_read_head_table (fd, font); |
diff --git a/src/sfntfont-android.c b/src/sfntfont-android.c index 37f43465097..5e4c8fc6c9f 100644 --- a/src/sfntfont-android.c +++ b/src/sfntfont-android.c | |||
| @@ -713,8 +713,11 @@ loaded before character sets are made available. */) | |||
| 713 | /* If it contains (not ends with!) with .ttf or .ttc, then | 713 | /* If it contains (not ends with!) with .ttf or .ttc, then |
| 714 | enumerate it. */ | 714 | enumerate it. */ |
| 715 | 715 | ||
| 716 | if (strstr (dirent->d_name, ".ttf") | 716 | if ((strstr (dirent->d_name, ".ttf") |
| 717 | || strstr (dirent->d_name, ".ttc")) | 717 | || strstr (dirent->d_name, ".ttc")) |
| 718 | /* Ignore the non-variable Roboto font. */ | ||
| 719 | && (i != 0 || strcmp (dirent->d_name, | ||
| 720 | "RobotoStatic-Regular.ttf"))) | ||
| 718 | { | 721 | { |
| 719 | sprintf (name, "%s/%s", system_font_directories[i], | 722 | sprintf (name, "%s/%s", system_font_directories[i], |
| 720 | dirent->d_name); | 723 | dirent->d_name); |
diff --git a/src/sfntfont.c b/src/sfntfont.c index 346e145082a..808c8b7c629 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c | |||
| @@ -69,6 +69,10 @@ struct sfnt_font_tables | |||
| 69 | struct sfnt_prep_table *prep; | 69 | struct sfnt_prep_table *prep; |
| 70 | struct sfnt_fpgm_table *fpgm; | 70 | struct sfnt_fpgm_table *fpgm; |
| 71 | struct sfnt_cvt_table *cvt; | 71 | struct sfnt_cvt_table *cvt; |
| 72 | struct sfnt_fvar_table *fvar; | ||
| 73 | struct sfnt_avar_table *avar; | ||
| 74 | struct sfnt_gvar_table *gvar; | ||
| 75 | struct sfnt_cvar_table *cvar; | ||
| 72 | 76 | ||
| 73 | /* The selected character map. */ | 77 | /* The selected character map. */ |
| 74 | struct sfnt_cmap_encoding_subtable_data *cmap_data; | 78 | struct sfnt_cmap_encoding_subtable_data *cmap_data; |
| @@ -118,6 +122,11 @@ struct sfnt_font_desc | |||
| 118 | /* Font registry that this font supports. */ | 122 | /* Font registry that this font supports. */ |
| 119 | Lisp_Object registry; | 123 | Lisp_Object registry; |
| 120 | 124 | ||
| 125 | /* Vector of instances. Each element is another of the instance's | ||
| 126 | `style', `adstyle', and numeric width, weight, and slant. May be | ||
| 127 | nil. */ | ||
| 128 | Lisp_Object instances; | ||
| 129 | |||
| 121 | /* Numeric width, weight, slant and spacing. */ | 130 | /* Numeric width, weight, slant and spacing. */ |
| 122 | int width, weight, slant, spacing; | 131 | int width, weight, slant, spacing; |
| 123 | 132 | ||
| @@ -360,6 +369,29 @@ sfnt_decode_foundry_name (struct sfnt_name_table *name) | |||
| 360 | designer_rec.length); | 369 | designer_rec.length); |
| 361 | } | 370 | } |
| 362 | 371 | ||
| 372 | /* Decode the name of the specified font INSTANCE using the given NAME | ||
| 373 | table. Return the name of that instance, or nil upon failure. */ | ||
| 374 | |||
| 375 | static Lisp_Object | ||
| 376 | sfnt_decode_instance_name (struct sfnt_instance *instance, | ||
| 377 | struct sfnt_name_table *name) | ||
| 378 | { | ||
| 379 | struct sfnt_name_record name_rec; | ||
| 380 | unsigned char *name_data; | ||
| 381 | |||
| 382 | name_data = sfnt_find_name (name, instance->name_id, | ||
| 383 | &name_rec); | ||
| 384 | |||
| 385 | if (!name_data) | ||
| 386 | return Qnil; | ||
| 387 | |||
| 388 | return sfnt_decode_font_string (name_data, | ||
| 389 | name_rec.platform_id, | ||
| 390 | name_rec.platform_specific_id, | ||
| 391 | name_rec.language_id, | ||
| 392 | name_rec.length); | ||
| 393 | } | ||
| 394 | |||
| 363 | struct sfnt_style_desc | 395 | struct sfnt_style_desc |
| 364 | { | 396 | { |
| 365 | /* The C string to match against. */ | 397 | /* The C string to match against. */ |
| @@ -375,6 +407,7 @@ static struct sfnt_style_desc sfnt_weight_descriptions[] = | |||
| 375 | { "thin", 0, }, | 407 | { "thin", 0, }, |
| 376 | { "extralight", 40, }, | 408 | { "extralight", 40, }, |
| 377 | { "ultralight", 40, }, | 409 | { "ultralight", 40, }, |
| 410 | { "light", 50, }, | ||
| 378 | { "demilight", 55, }, | 411 | { "demilight", 55, }, |
| 379 | { "semilight", 55, }, | 412 | { "semilight", 55, }, |
| 380 | { "book", 75, }, | 413 | { "book", 75, }, |
| @@ -809,7 +842,10 @@ sfnt_enum_font_1 (int fd, const char *file, | |||
| 809 | struct sfnt_name_table *name; | 842 | struct sfnt_name_table *name; |
| 810 | struct sfnt_meta_table *meta; | 843 | struct sfnt_meta_table *meta; |
| 811 | struct sfnt_maxp_table *maxp; | 844 | struct sfnt_maxp_table *maxp; |
| 812 | Lisp_Object family, style; | 845 | struct sfnt_fvar_table *fvar; |
| 846 | struct sfnt_font_desc temp; | ||
| 847 | Lisp_Object family, style, instance, style1; | ||
| 848 | int i; | ||
| 813 | 849 | ||
| 814 | /* Create the font desc and copy in the file name. */ | 850 | /* Create the font desc and copy in the file name. */ |
| 815 | desc = xzalloc (sizeof *desc + strlen (file) + 1); | 851 | desc = xzalloc (sizeof *desc + strlen (file) + 1); |
| @@ -842,6 +878,10 @@ sfnt_enum_font_1 (int fd, const char *file, | |||
| 842 | if (sfnt_decode_family_style (name, &family, &style)) | 878 | if (sfnt_decode_family_style (name, &family, &style)) |
| 843 | goto bail4; | 879 | goto bail4; |
| 844 | 880 | ||
| 881 | /* See if this is a distortable/variable/multiple master font (all | ||
| 882 | three terms mean the same time.) */ | ||
| 883 | fvar = sfnt_read_fvar_table (fd, subtables); | ||
| 884 | |||
| 845 | /* Set the family. */ | 885 | /* Set the family. */ |
| 846 | desc->family = family; | 886 | desc->family = family; |
| 847 | desc->designer = sfnt_decode_foundry_name (name); | 887 | desc->designer = sfnt_decode_foundry_name (name); |
| @@ -877,6 +917,43 @@ sfnt_enum_font_1 (int fd, const char *file, | |||
| 877 | /* Figure out what registry this font is likely to support. */ | 917 | /* Figure out what registry this font is likely to support. */ |
| 878 | sfnt_grok_registry (fd, desc, subtables); | 918 | sfnt_grok_registry (fd, desc, subtables); |
| 879 | 919 | ||
| 920 | if (fvar && fvar->instance_count) | ||
| 921 | { | ||
| 922 | /* If there is an fvar table with instances, then this is a font | ||
| 923 | which defines different axes along which the points in each | ||
| 924 | glyph can be changed. | ||
| 925 | |||
| 926 | Instead of enumerating the font itself, enumerate each | ||
| 927 | instance within, which specifies how to configure each axis | ||
| 928 | to achieve a specified style. */ | ||
| 929 | |||
| 930 | desc->instances = make_vector (fvar->instance_count, Qnil); | ||
| 931 | |||
| 932 | for (i = 0; i < fvar->instance_count; ++i) | ||
| 933 | { | ||
| 934 | style1 = sfnt_decode_instance_name (&fvar->instance[i], | ||
| 935 | name); | ||
| 936 | |||
| 937 | if (!style1) | ||
| 938 | continue; | ||
| 939 | |||
| 940 | /* Now parse the style. */ | ||
| 941 | temp.adstyle = Qnil; | ||
| 942 | sfnt_parse_style (style1, &temp); | ||
| 943 | |||
| 944 | /* Set each field of the vector. */ | ||
| 945 | instance = make_vector (5, Qnil); | ||
| 946 | ASET (instance, 0, style1); | ||
| 947 | ASET (instance, 1, temp.adstyle); | ||
| 948 | ASET (instance, 2, make_fixnum (temp.width)); | ||
| 949 | ASET (instance, 3, make_fixnum (temp.weight)); | ||
| 950 | ASET (instance, 4, make_fixnum (temp.slant)); | ||
| 951 | |||
| 952 | /* Place the vector in desc->instances. */ | ||
| 953 | ASET (desc->instances, i, instance); | ||
| 954 | } | ||
| 955 | } | ||
| 956 | |||
| 880 | /* Set the style, link the desc onto system_fonts and return. */ | 957 | /* Set the style, link the desc onto system_fonts and return. */ |
| 881 | desc->style = style; | 958 | desc->style = style; |
| 882 | desc->next = system_fonts; | 959 | desc->next = system_fonts; |
| @@ -898,6 +975,7 @@ sfnt_enum_font_1 (int fd, const char *file, | |||
| 898 | next = &prev->next; | 975 | next = &prev->next; |
| 899 | } | 976 | } |
| 900 | 977 | ||
| 978 | xfree (fvar); | ||
| 901 | xfree (meta); | 979 | xfree (meta); |
| 902 | xfree (maxp); | 980 | xfree (maxp); |
| 903 | xfree (name); | 981 | xfree (name); |
| @@ -1346,15 +1424,23 @@ sfntfont_registries_compatible_p (Lisp_Object a, Lisp_Object b) | |||
| 1346 | } | 1424 | } |
| 1347 | 1425 | ||
| 1348 | /* Return whether or not the font description DESC satisfactorily | 1426 | /* Return whether or not the font description DESC satisfactorily |
| 1349 | matches the font specification FONT_SPEC. */ | 1427 | matches the font specification FONT_SPEC. |
| 1350 | 1428 | ||
| 1351 | static bool | 1429 | Value is 0 if there is no match, -1 if there is a match against |
| 1352 | sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec) | 1430 | DESC itself, and the number of matching instances if the style |
| 1431 | matches one or more instances defined in in DESC. Return the index | ||
| 1432 | of each matching instance in INSTANCES; it should be SIZE big. */ | ||
| 1433 | |||
| 1434 | static int | ||
| 1435 | sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec, | ||
| 1436 | int *instances, int size) | ||
| 1353 | { | 1437 | { |
| 1354 | Lisp_Object tem, extra, tail; | 1438 | Lisp_Object tem, extra, tail; |
| 1355 | struct sfnt_cmap_encoding_subtable_data *cmap; | 1439 | struct sfnt_cmap_encoding_subtable_data *cmap; |
| 1356 | size_t i; | 1440 | size_t i; |
| 1357 | struct sfnt_cmap_encoding_subtable subtable; | 1441 | struct sfnt_cmap_encoding_subtable subtable; |
| 1442 | int instance, num_instance; | ||
| 1443 | Lisp_Object item; | ||
| 1358 | 1444 | ||
| 1359 | /* cmap and subtable are caches for sfntfont_lookup_char. */ | 1445 | /* cmap and subtable are caches for sfntfont_lookup_char. */ |
| 1360 | 1446 | ||
| @@ -1388,7 +1474,9 @@ sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec) | |||
| 1388 | 1474 | ||
| 1389 | if (!NILP (tem) && NILP (Fstring_equal (SYMBOL_NAME (tem), | 1475 | if (!NILP (tem) && NILP (Fstring_equal (SYMBOL_NAME (tem), |
| 1390 | desc->family))) | 1476 | desc->family))) |
| 1391 | return false; | 1477 | return 0; |
| 1478 | |||
| 1479 | instance = -1; | ||
| 1392 | 1480 | ||
| 1393 | /* If a registry is set and wrong, then reject the font desc | 1481 | /* If a registry is set and wrong, then reject the font desc |
| 1394 | immediately. This detects 50% of mismatches from fontset.c. | 1482 | immediately. This detects 50% of mismatches from fontset.c. |
| @@ -1399,33 +1487,82 @@ sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec) | |||
| 1399 | tem = AREF (spec, FONT_REGISTRY_INDEX); | 1487 | tem = AREF (spec, FONT_REGISTRY_INDEX); |
| 1400 | if (!NILP (tem) && !NILP (desc->registry) | 1488 | if (!NILP (tem) && !NILP (desc->registry) |
| 1401 | && !sfntfont_registries_compatible_p (tem, desc->registry)) | 1489 | && !sfntfont_registries_compatible_p (tem, desc->registry)) |
| 1402 | return false; | 1490 | return 0; |
| 1403 | 1491 | ||
| 1404 | /* Check that the adstyle specified matches. */ | 1492 | /* Check the style. If DESC is a fixed font, just check once. |
| 1493 | Otherwise, check each instance. */ | ||
| 1405 | 1494 | ||
| 1406 | tem = AREF (spec, FONT_ADSTYLE_INDEX); | 1495 | if (NILP (desc->instances)) |
| 1407 | if (!NILP (tem) && NILP (Fequal (tem, desc->adstyle))) | 1496 | { |
| 1408 | return false; | 1497 | tem = AREF (spec, FONT_ADSTYLE_INDEX); |
| 1498 | if (!NILP (tem) && NILP (Fequal (tem, desc->adstyle))) | ||
| 1499 | return 0; | ||
| 1409 | 1500 | ||
| 1410 | /* Check the style. */ | 1501 | if (FONT_WIDTH_NUMERIC (spec) != -1 |
| 1502 | && FONT_WIDTH_NUMERIC (spec) != desc->width) | ||
| 1503 | return 0; | ||
| 1411 | 1504 | ||
| 1412 | if (FONT_WIDTH_NUMERIC (spec) != -1 | 1505 | if (FONT_WEIGHT_NUMERIC (spec) != -1 |
| 1413 | && FONT_WIDTH_NUMERIC (spec) != desc->width) | 1506 | && FONT_WEIGHT_NUMERIC (spec) != desc->weight) |
| 1414 | return false; | 1507 | return 0; |
| 1415 | 1508 | ||
| 1416 | if (FONT_WEIGHT_NUMERIC (spec) != -1 | 1509 | if (FONT_SLANT_NUMERIC (spec) != -1 |
| 1417 | && FONT_WEIGHT_NUMERIC (spec) != desc->weight) | 1510 | && FONT_SLANT_NUMERIC (spec) != desc->slant) |
| 1418 | return false; | 1511 | return 0; |
| 1512 | } | ||
| 1513 | else | ||
| 1514 | { | ||
| 1515 | num_instance = 0; | ||
| 1419 | 1516 | ||
| 1420 | if (FONT_SLANT_NUMERIC (spec) != -1 | 1517 | /* Find the indices of instances in this distortable font which |
| 1421 | && FONT_SLANT_NUMERIC (spec) != desc->slant) | 1518 | match the given font spec. */ |
| 1422 | return false; | 1519 | |
| 1520 | for (i = 0; i < ASIZE (desc->instances); ++i) | ||
| 1521 | { | ||
| 1522 | item = AREF (desc->instances, i); | ||
| 1523 | |||
| 1524 | if (NILP (item)) | ||
| 1525 | continue; | ||
| 1526 | |||
| 1527 | /* Check that the adstyle specified matches. */ | ||
| 1528 | |||
| 1529 | tem = AREF (spec, FONT_ADSTYLE_INDEX); | ||
| 1530 | if (!NILP (tem) && NILP (Fequal (tem, AREF (item, 1)))) | ||
| 1531 | continue; | ||
| 1532 | |||
| 1533 | /* Check the style. */ | ||
| 1534 | |||
| 1535 | if (FONT_WIDTH_NUMERIC (spec) != -1 | ||
| 1536 | && (FONT_WIDTH_NUMERIC (spec) | ||
| 1537 | != XFIXNUM (AREF (item, 2)))) | ||
| 1538 | continue; | ||
| 1539 | |||
| 1540 | if (FONT_WEIGHT_NUMERIC (spec) != -1 | ||
| 1541 | && (FONT_WEIGHT_NUMERIC (spec) | ||
| 1542 | != XFIXNUM (AREF (item, 3)))) | ||
| 1543 | continue; | ||
| 1544 | |||
| 1545 | if (FONT_SLANT_NUMERIC (spec) != -1 | ||
| 1546 | && (FONT_SLANT_NUMERIC (spec) | ||
| 1547 | != XFIXNUM (AREF (item, 4)))) | ||
| 1548 | continue; | ||
| 1549 | |||
| 1550 | if (num_instance == size) | ||
| 1551 | break; | ||
| 1552 | |||
| 1553 | /* A matching instance has been found. Set its index, then | ||
| 1554 | go back to the rest of the font matching. */ | ||
| 1555 | instances[num_instance++] = i; | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | instance = num_instance; | ||
| 1559 | } | ||
| 1423 | 1560 | ||
| 1424 | /* Handle extras. */ | 1561 | /* Handle extras. */ |
| 1425 | extra = AREF (spec, FONT_EXTRA_INDEX); | 1562 | extra = AREF (spec, FONT_EXTRA_INDEX); |
| 1426 | 1563 | ||
| 1427 | if (NILP (extra)) | 1564 | if (NILP (extra)) |
| 1428 | return true; | 1565 | return instance; |
| 1429 | 1566 | ||
| 1430 | tem = assq_no_quit (QCscript, extra); | 1567 | tem = assq_no_quit (QCscript, extra); |
| 1431 | cmap = NULL; | 1568 | cmap = NULL; |
| @@ -1490,12 +1627,12 @@ sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec) | |||
| 1490 | desc->subtable = subtable; | 1627 | desc->subtable = subtable; |
| 1491 | 1628 | ||
| 1492 | xfree (cmap); | 1629 | xfree (cmap); |
| 1493 | return true; | 1630 | return instance; |
| 1494 | 1631 | ||
| 1495 | fail: | 1632 | fail: |
| 1496 | /* The cmap might've been read in and require deallocation. */ | 1633 | /* The cmap might've been read in and require deallocation. */ |
| 1497 | xfree (cmap); | 1634 | xfree (cmap); |
| 1498 | return false; | 1635 | return 0; |
| 1499 | } | 1636 | } |
| 1500 | 1637 | ||
| 1501 | /* Type of font entities and font objects created. */ | 1638 | /* Type of font entities and font objects created. */ |
| @@ -1546,12 +1683,14 @@ sfntfont_registry_for_desc (struct sfnt_font_desc *desc) | |||
| 1546 | } | 1683 | } |
| 1547 | 1684 | ||
| 1548 | /* Return a font-entity that represents the font descriptor (unopened | 1685 | /* Return a font-entity that represents the font descriptor (unopened |
| 1549 | font) DESC. */ | 1686 | font) DESC. If INSTANCE is more than or equal to 1, then it is the |
| 1687 | index of the instance in DESC that should be opened plus 1; in that | ||
| 1688 | case, DESC must be a distortable font. */ | ||
| 1550 | 1689 | ||
| 1551 | static Lisp_Object | 1690 | static Lisp_Object |
| 1552 | sfntfont_desc_to_entity (struct sfnt_font_desc *desc) | 1691 | sfntfont_desc_to_entity (struct sfnt_font_desc *desc, int instance) |
| 1553 | { | 1692 | { |
| 1554 | Lisp_Object entity; | 1693 | Lisp_Object entity, vector; |
| 1555 | 1694 | ||
| 1556 | entity = font_make_entity (); | 1695 | entity = font_make_entity (); |
| 1557 | 1696 | ||
| @@ -1572,19 +1711,40 @@ sfntfont_desc_to_entity (struct sfnt_font_desc *desc) | |||
| 1572 | ASET (entity, FONT_SPACING_INDEX, | 1711 | ASET (entity, FONT_SPACING_INDEX, |
| 1573 | make_fixnum (desc->spacing)); | 1712 | make_fixnum (desc->spacing)); |
| 1574 | 1713 | ||
| 1575 | FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, | 1714 | if (instance >= 1) |
| 1576 | make_fixnum (desc->width)); | 1715 | { |
| 1577 | FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, | 1716 | if (NILP (desc->instances) |
| 1578 | make_fixnum (desc->weight)); | 1717 | || instance > ASIZE (desc->instances)) |
| 1579 | FONT_SET_STYLE (entity, FONT_SLANT_INDEX, | 1718 | emacs_abort (); |
| 1580 | make_fixnum (desc->slant)); | ||
| 1581 | 1719 | ||
| 1582 | ASET (entity, FONT_ADSTYLE_INDEX, Qnil); | 1720 | vector = AREF (desc->instances, instance - 1); |
| 1721 | FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, | ||
| 1722 | AREF (vector, 2)); | ||
| 1723 | FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, | ||
| 1724 | AREF (vector, 3)); | ||
| 1725 | FONT_SET_STYLE (entity, FONT_SLANT_INDEX, | ||
| 1726 | AREF (vector, 4)); | ||
| 1727 | ASET (entity, FONT_ADSTYLE_INDEX, AREF (vector, 1)); | ||
| 1728 | } | ||
| 1729 | else | ||
| 1730 | { | ||
| 1731 | FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, | ||
| 1732 | make_fixnum (desc->width)); | ||
| 1733 | FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, | ||
| 1734 | make_fixnum (desc->weight)); | ||
| 1735 | FONT_SET_STYLE (entity, FONT_SLANT_INDEX, | ||
| 1736 | make_fixnum (desc->slant)); | ||
| 1737 | ASET (entity, FONT_ADSTYLE_INDEX, desc->adstyle); | ||
| 1738 | } | ||
| 1583 | 1739 | ||
| 1584 | /* Set FONT_EXTRA_INDEX to a pointer to the font description. Font | 1740 | /* Set FONT_EXTRA_INDEX to a pointer to the font description. Font |
| 1585 | descriptions are never supposed to be freed. */ | 1741 | descriptions are never supposed to be freed. */ |
| 1742 | |||
| 1586 | ASET (entity, FONT_EXTRA_INDEX, | 1743 | ASET (entity, FONT_EXTRA_INDEX, |
| 1587 | list1 (Fcons (Qfont_entity, make_mint_ptr (desc)))); | 1744 | (instance >= 1 |
| 1745 | ? list2 (Fcons (Qfont_entity, make_mint_ptr (desc)), | ||
| 1746 | Fcons (Qfont_instance, make_fixnum (instance - 1))) | ||
| 1747 | : list1 (Fcons (Qfont_entity, make_mint_ptr (desc))))); | ||
| 1588 | 1748 | ||
| 1589 | return entity; | 1749 | return entity; |
| 1590 | } | 1750 | } |
| @@ -1597,6 +1757,7 @@ sfntfont_list (struct frame *f, Lisp_Object font_spec) | |||
| 1597 | { | 1757 | { |
| 1598 | Lisp_Object matching, tem; | 1758 | Lisp_Object matching, tem; |
| 1599 | struct sfnt_font_desc *desc; | 1759 | struct sfnt_font_desc *desc; |
| 1760 | int i, rc, instances[100]; | ||
| 1600 | 1761 | ||
| 1601 | matching = Qnil; | 1762 | matching = Qnil; |
| 1602 | 1763 | ||
| @@ -1612,10 +1773,24 @@ sfntfont_list (struct frame *f, Lisp_Object font_spec) | |||
| 1612 | } | 1773 | } |
| 1613 | 1774 | ||
| 1614 | /* Loop through known system fonts and add them one-by-one. */ | 1775 | /* Loop through known system fonts and add them one-by-one. */ |
| 1776 | |||
| 1615 | for (desc = system_fonts; desc; desc = desc->next) | 1777 | for (desc = system_fonts; desc; desc = desc->next) |
| 1616 | { | 1778 | { |
| 1617 | if (sfntfont_list_1 (desc, font_spec)) | 1779 | rc = sfntfont_list_1 (desc, font_spec, instances, |
| 1618 | matching = Fcons (sfntfont_desc_to_entity (desc), matching); | 1780 | ARRAYELTS (instances)); |
| 1781 | |||
| 1782 | if (rc < 0) | ||
| 1783 | matching = Fcons (sfntfont_desc_to_entity (desc, 0), | ||
| 1784 | matching); | ||
| 1785 | else if (rc) | ||
| 1786 | { | ||
| 1787 | /* Add each matching instance. */ | ||
| 1788 | |||
| 1789 | for (i = 0; i < rc; ++i) | ||
| 1790 | matching = Fcons (sfntfont_desc_to_entity (desc, | ||
| 1791 | instances[i] + 1), | ||
| 1792 | matching); | ||
| 1793 | } | ||
| 1619 | } | 1794 | } |
| 1620 | 1795 | ||
| 1621 | unblock_input (); | 1796 | unblock_input (); |
| @@ -1688,23 +1863,45 @@ struct sfntfont_get_glyph_outline_dcontext | |||
| 1688 | 1863 | ||
| 1689 | /* glyf table. */ | 1864 | /* glyf table. */ |
| 1690 | struct sfnt_glyf_table *glyf; | 1865 | struct sfnt_glyf_table *glyf; |
| 1866 | |||
| 1867 | /* Variation settings, or NULL. */ | ||
| 1868 | struct sfnt_blend *blend; | ||
| 1691 | }; | 1869 | }; |
| 1692 | 1870 | ||
| 1693 | /* Return the glyph identified by GLYPH from the glyf and loca table | 1871 | /* Return the glyph identified by GLYPH_ID from the glyf and loca |
| 1694 | specified in DCONTEXT. Set *NEED_FREE to true. */ | 1872 | table specified in DCONTEXT. Set *NEED_FREE to true. */ |
| 1695 | 1873 | ||
| 1696 | static struct sfnt_glyph * | 1874 | static struct sfnt_glyph * |
| 1697 | sfntfont_get_glyph (sfnt_glyph glyph, void *dcontext, | 1875 | sfntfont_get_glyph (sfnt_glyph glyph_id, void *dcontext, |
| 1698 | bool *need_free) | 1876 | bool *need_free) |
| 1699 | { | 1877 | { |
| 1700 | struct sfntfont_get_glyph_outline_dcontext *tables; | 1878 | struct sfntfont_get_glyph_outline_dcontext *tables; |
| 1879 | struct sfnt_glyph *glyph; | ||
| 1880 | struct sfnt_metrics_distortion distortion; | ||
| 1701 | 1881 | ||
| 1702 | tables = dcontext; | 1882 | tables = dcontext; |
| 1703 | *need_free = true; | 1883 | *need_free = true; |
| 1704 | 1884 | ||
| 1705 | return sfnt_read_glyph (glyph, tables->glyf, | 1885 | glyph = sfnt_read_glyph (glyph_id, tables->glyf, |
| 1706 | tables->loca_short, | 1886 | tables->loca_short, |
| 1707 | tables->loca_long); | 1887 | tables->loca_long); |
| 1888 | |||
| 1889 | if (!tables->blend || !glyph) | ||
| 1890 | return glyph; | ||
| 1891 | |||
| 1892 | if ((glyph->simple | ||
| 1893 | && sfnt_vary_simple_glyph (tables->blend, glyph_id, | ||
| 1894 | glyph, &distortion)) | ||
| 1895 | || (!glyph->simple | ||
| 1896 | && sfnt_vary_compound_glyph (tables->blend, glyph_id, | ||
| 1897 | glyph, &distortion))) | ||
| 1898 | { | ||
| 1899 | sfnt_free_glyph (glyph); | ||
| 1900 | return NULL; | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | /* Note that the distortion is not relevant for compound glyphs. */ | ||
| 1904 | return glyph; | ||
| 1708 | } | 1905 | } |
| 1709 | 1906 | ||
| 1710 | /* Free the glyph identified by GLYPH. */ | 1907 | /* Free the glyph identified by GLYPH. */ |
| @@ -1734,6 +1931,8 @@ sfntfont_dereference_outline (struct sfnt_glyph_outline *outline) | |||
| 1734 | HEAD. Keep *CACHE_SIZE updated with the number of elements in the | 1931 | HEAD. Keep *CACHE_SIZE updated with the number of elements in the |
| 1735 | cache. | 1932 | cache. |
| 1736 | 1933 | ||
| 1934 | Distort the glyph using BLEND if INDEX is not -1. | ||
| 1935 | |||
| 1737 | Use the offset information in the long or short loca tables | 1936 | Use the offset information in the long or short loca tables |
| 1738 | LOCA_LONG and LOCA_SHORT, whichever is set. | 1937 | LOCA_LONG and LOCA_SHORT, whichever is set. |
| 1739 | 1938 | ||
| @@ -1754,6 +1953,8 @@ static struct sfnt_glyph_outline * | |||
| 1754 | sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | 1953 | sfntfont_get_glyph_outline (sfnt_glyph glyph_code, |
| 1755 | struct sfnt_outline_cache *cache, | 1954 | struct sfnt_outline_cache *cache, |
| 1756 | sfnt_fixed scale, int *cache_size, | 1955 | sfnt_fixed scale, int *cache_size, |
| 1956 | struct sfnt_blend *blend, | ||
| 1957 | int index, | ||
| 1757 | struct sfnt_glyf_table *glyf, | 1958 | struct sfnt_glyf_table *glyf, |
| 1758 | struct sfnt_head_table *head, | 1959 | struct sfnt_head_table *head, |
| 1759 | struct sfnt_hmtx_table *hmtx, | 1960 | struct sfnt_hmtx_table *hmtx, |
| @@ -1772,8 +1973,10 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1772 | struct sfnt_instructed_outline *value; | 1973 | struct sfnt_instructed_outline *value; |
| 1773 | const char *error; | 1974 | const char *error; |
| 1774 | struct sfnt_glyph_metrics temp; | 1975 | struct sfnt_glyph_metrics temp; |
| 1976 | struct sfnt_metrics_distortion distortion; | ||
| 1775 | 1977 | ||
| 1776 | start = cache->next; | 1978 | start = cache->next; |
| 1979 | distortion.advance = 0; | ||
| 1777 | 1980 | ||
| 1778 | /* See if the outline is already cached. */ | 1981 | /* See if the outline is already cached. */ |
| 1779 | for (; start != cache; start = start->next) | 1982 | for (; start != cache; start = start->next) |
| @@ -1806,6 +2009,30 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1806 | if (!glyph) | 2009 | if (!glyph) |
| 1807 | return NULL; | 2010 | return NULL; |
| 1808 | 2011 | ||
| 2012 | /* Distort the glyph if necessary. */ | ||
| 2013 | |||
| 2014 | if (index != -1) | ||
| 2015 | { | ||
| 2016 | if (glyph->simple) | ||
| 2017 | { | ||
| 2018 | if (sfnt_vary_simple_glyph (blend, glyph_code, | ||
| 2019 | glyph, &distortion)) | ||
| 2020 | { | ||
| 2021 | sfnt_free_glyph (glyph); | ||
| 2022 | return NULL; | ||
| 2023 | } | ||
| 2024 | } | ||
| 2025 | else if (!glyph->simple) | ||
| 2026 | { | ||
| 2027 | if (sfnt_vary_compound_glyph (blend, glyph_code, | ||
| 2028 | glyph, &distortion)) | ||
| 2029 | { | ||
| 2030 | sfnt_free_glyph (glyph); | ||
| 2031 | return NULL; | ||
| 2032 | } | ||
| 2033 | } | ||
| 2034 | } | ||
| 2035 | |||
| 1809 | /* Try to instruct the glyph if INTERPRETER is specified. */ | 2036 | /* Try to instruct the glyph if INTERPRETER is specified. */ |
| 1810 | 2037 | ||
| 1811 | outline = NULL; | 2038 | outline = NULL; |
| @@ -1813,6 +2040,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1813 | dcontext.loca_long = loca_long; | 2040 | dcontext.loca_long = loca_long; |
| 1814 | dcontext.loca_short = loca_short; | 2041 | dcontext.loca_short = loca_short; |
| 1815 | dcontext.glyf = glyf; | 2042 | dcontext.glyf = glyf; |
| 2043 | dcontext.blend = (index != -1 ? blend : NULL); | ||
| 1816 | 2044 | ||
| 1817 | /* Now load the glyph's unscaled metrics into TEMP. */ | 2045 | /* Now load the glyph's unscaled metrics into TEMP. */ |
| 1818 | 2046 | ||
| @@ -1820,6 +2048,9 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1820 | head, maxp)) | 2048 | head, maxp)) |
| 1821 | goto fail; | 2049 | goto fail; |
| 1822 | 2050 | ||
| 2051 | /* Add the advance width distortion. */ | ||
| 2052 | temp.advance += distortion.advance; | ||
| 2053 | |||
| 1823 | if (interpreter) | 2054 | if (interpreter) |
| 1824 | { | 2055 | { |
| 1825 | if (glyph->simple) | 2056 | if (glyph->simple) |
| @@ -1878,6 +2109,13 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1878 | if (!outline) | 2109 | if (!outline) |
| 1879 | return NULL; | 2110 | return NULL; |
| 1880 | 2111 | ||
| 2112 | if (index != -1) | ||
| 2113 | /* Finally, adjust the left side bearing of the glyph metrics by | ||
| 2114 | the origin point of the outline, should a distortion have been | ||
| 2115 | applied. The left side bearing is the distance from the origin | ||
| 2116 | point to the left most point on the X axis. */ | ||
| 2117 | temp.lbearing = outline->xmin - outline->origin; | ||
| 2118 | |||
| 1881 | start = xmalloc (sizeof *start); | 2119 | start = xmalloc (sizeof *start); |
| 1882 | start->glyph = glyph_code; | 2120 | start->glyph = glyph_code; |
| 1883 | start->outline = outline; | 2121 | start->outline = outline; |
| @@ -2125,6 +2363,13 @@ struct sfnt_font_info | |||
| 2125 | /* Factor used to convert from em space to pixel space. */ | 2363 | /* Factor used to convert from em space to pixel space. */ |
| 2126 | sfnt_fixed scale; | 2364 | sfnt_fixed scale; |
| 2127 | 2365 | ||
| 2366 | /* The blend (configuration of this multiple master font). */ | ||
| 2367 | struct sfnt_blend blend; | ||
| 2368 | |||
| 2369 | /* The index of the named instance used to initialize BLEND. | ||
| 2370 | -1 if BLEND is not initialized. */ | ||
| 2371 | int instance; | ||
| 2372 | |||
| 2128 | #ifdef HAVE_MMAP | 2373 | #ifdef HAVE_MMAP |
| 2129 | /* Whether or not the glyph table has been mmapped. */ | 2374 | /* Whether or not the glyph table has been mmapped. */ |
| 2130 | bool glyf_table_mapped; | 2375 | bool glyf_table_mapped; |
| @@ -2358,6 +2603,10 @@ sfnt_close_tables (struct sfnt_font_tables *tables) | |||
| 2358 | xfree (tables->prep); | 2603 | xfree (tables->prep); |
| 2359 | xfree (tables->fpgm); | 2604 | xfree (tables->fpgm); |
| 2360 | xfree (tables->cvt); | 2605 | xfree (tables->cvt); |
| 2606 | xfree (tables->fvar); | ||
| 2607 | xfree (tables->avar); | ||
| 2608 | xfree (tables->gvar); | ||
| 2609 | xfree (tables->cvar); | ||
| 2361 | xfree (tables->cmap_data); | 2610 | xfree (tables->cmap_data); |
| 2362 | 2611 | ||
| 2363 | if (tables->uvs) | 2612 | if (tables->uvs) |
| @@ -2524,6 +2773,15 @@ sfnt_open_tables (struct sfnt_font_desc *desc) | |||
| 2524 | tables->fpgm = sfnt_read_fpgm_table (fd, subtable); | 2773 | tables->fpgm = sfnt_read_fpgm_table (fd, subtable); |
| 2525 | tables->cvt = sfnt_read_cvt_table (fd, subtable); | 2774 | tables->cvt = sfnt_read_cvt_table (fd, subtable); |
| 2526 | 2775 | ||
| 2776 | /* Read distortion related tables. These might not be present. */ | ||
| 2777 | tables->fvar = sfnt_read_fvar_table (fd, subtable); | ||
| 2778 | tables->avar = sfnt_read_avar_table (fd, subtable); | ||
| 2779 | tables->gvar = sfnt_read_gvar_table (fd, subtable); | ||
| 2780 | |||
| 2781 | if (tables->cvt && tables->fvar) | ||
| 2782 | tables->cvar = sfnt_read_cvar_table (fd, subtable, tables->fvar, | ||
| 2783 | tables->cvt); | ||
| 2784 | |||
| 2527 | return tables; | 2785 | return tables; |
| 2528 | 2786 | ||
| 2529 | bail5: | 2787 | bail5: |
| @@ -2614,9 +2872,10 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 2614 | struct sfnt_font_desc *desc; | 2872 | struct sfnt_font_desc *desc; |
| 2615 | Lisp_Object font_object; | 2873 | Lisp_Object font_object; |
| 2616 | struct charset *charset; | 2874 | struct charset *charset; |
| 2617 | int point_size; | 2875 | int point_size, instance, i; |
| 2618 | Display_Info *dpyinfo; | 2876 | Display_Info *dpyinfo; |
| 2619 | struct sfnt_font_tables *tables; | 2877 | struct sfnt_font_tables *tables; |
| 2878 | Lisp_Object tem; | ||
| 2620 | 2879 | ||
| 2621 | if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0) | 2880 | if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0) |
| 2622 | pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)); | 2881 | pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)); |
| @@ -2633,10 +2892,18 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 2633 | 2892 | ||
| 2634 | /* Now find the font description corresponding to FONT_ENTITY. */ | 2893 | /* Now find the font description corresponding to FONT_ENTITY. */ |
| 2635 | 2894 | ||
| 2636 | if (NILP (AREF (font_entity, FONT_EXTRA_INDEX))) | 2895 | tem = AREF (font_entity, FONT_EXTRA_INDEX); |
| 2896 | if (NILP (tem)) | ||
| 2637 | return Qnil; | 2897 | return Qnil; |
| 2638 | 2898 | ||
| 2639 | desc = xmint_pointer (XCDR (XCAR (AREF (font_entity, FONT_EXTRA_INDEX)))); | 2899 | desc = xmint_pointer (XCDR (XCAR (tem))); |
| 2900 | |||
| 2901 | /* Finally, see if a specific instance is associated with | ||
| 2902 | FONT_ENTITY. */ | ||
| 2903 | |||
| 2904 | instance = -1; | ||
| 2905 | if (!NILP (XCDR (tem))) | ||
| 2906 | instance = XFIXNUM (XCDR (XCAR (XCDR (tem)))); | ||
| 2640 | 2907 | ||
| 2641 | /* Build the font object. */ | 2908 | /* Build the font object. */ |
| 2642 | font_object = font_make_object (VECSIZE (struct sfnt_font_info), | 2909 | font_object = font_make_object (VECSIZE (struct sfnt_font_info), |
| @@ -2669,6 +2936,8 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 2669 | font_info->raster_cache_size = 0; | 2936 | font_info->raster_cache_size = 0; |
| 2670 | font_info->interpreter = NULL; | 2937 | font_info->interpreter = NULL; |
| 2671 | font_info->scale = 0; | 2938 | font_info->scale = 0; |
| 2939 | font_info->instance = -1; | ||
| 2940 | font_info->blend.coords = NULL; | ||
| 2672 | #ifdef HAVE_MMAP | 2941 | #ifdef HAVE_MMAP |
| 2673 | font_info->glyf_table_mapped = false; | 2942 | font_info->glyf_table_mapped = false; |
| 2674 | #endif /* HAVE_MMAP */ | 2943 | #endif /* HAVE_MMAP */ |
| @@ -2784,6 +3053,34 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 2784 | / 2)); | 3053 | / 2)); |
| 2785 | sfntfont_setup_interpreter (font_info, point_size); | 3054 | sfntfont_setup_interpreter (font_info, point_size); |
| 2786 | 3055 | ||
| 3056 | /* If an instance was specified and the font is distortable, set up | ||
| 3057 | the blend. */ | ||
| 3058 | |||
| 3059 | if (instance != -1 | ||
| 3060 | && desc->tables->fvar && desc->tables->gvar | ||
| 3061 | /* Make sure the instance is within range. */ | ||
| 3062 | && instance < desc->tables->fvar->instance_count) | ||
| 3063 | { | ||
| 3064 | sfnt_init_blend (&font_info->blend, desc->tables->fvar, | ||
| 3065 | desc->tables->gvar, desc->tables->avar, | ||
| 3066 | desc->tables->cvar); | ||
| 3067 | |||
| 3068 | /* Copy over the coordinates. */ | ||
| 3069 | for (i = 0; i < desc->tables->fvar->axis_count; ++i) | ||
| 3070 | font_info->blend.coords[i] | ||
| 3071 | = desc->tables->fvar->instance[instance].coords[i]; | ||
| 3072 | |||
| 3073 | sfnt_normalize_blend (&font_info->blend); | ||
| 3074 | |||
| 3075 | /* If an interpreter was specified, distort it now. */ | ||
| 3076 | |||
| 3077 | if (font_info->interpreter) | ||
| 3078 | sfnt_vary_interpreter (font_info->interpreter, | ||
| 3079 | &font_info->blend); | ||
| 3080 | |||
| 3081 | font_info->instance = instance; | ||
| 3082 | } | ||
| 3083 | |||
| 2787 | #ifdef HAVE_HARFBUZZ | 3084 | #ifdef HAVE_HARFBUZZ |
| 2788 | /* HarfBuzz will potentially read font tables after the font has | 3085 | /* HarfBuzz will potentially read font tables after the font has |
| 2789 | been opened by Emacs. Keep the font open, and record its offset | 3086 | been opened by Emacs. Keep the font open, and record its offset |
| @@ -2855,6 +3152,8 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, | |||
| 2855 | outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache, | 3152 | outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache, |
| 2856 | font->scale, | 3153 | font->scale, |
| 2857 | &font->outline_cache_size, | 3154 | &font->outline_cache_size, |
| 3155 | &font->blend, | ||
| 3156 | font->instance, | ||
| 2858 | font->glyf, font->head, | 3157 | font->glyf, font->head, |
| 2859 | font->hmtx, font->hhea, | 3158 | font->hmtx, font->hhea, |
| 2860 | font->maxp, | 3159 | font->maxp, |
| @@ -2960,6 +3259,11 @@ sfntfont_close (struct font *font) | |||
| 2960 | info->interpreter = NULL; | 3259 | info->interpreter = NULL; |
| 2961 | info->uvs = NULL; | 3260 | info->uvs = NULL; |
| 2962 | 3261 | ||
| 3262 | /* Deinitialize the blend. */ | ||
| 3263 | if (info->instance != -1 && info->blend.coords) | ||
| 3264 | sfnt_free_blend (&info->blend); | ||
| 3265 | info->instance = -1; | ||
| 3266 | |||
| 2963 | #ifdef HAVE_MMAP | 3267 | #ifdef HAVE_MMAP |
| 2964 | 3268 | ||
| 2965 | /* Unlink INFO. */ | 3269 | /* Unlink INFO. */ |
| @@ -3035,6 +3339,8 @@ sfntfont_draw (struct glyph_string *s, int from, int to, | |||
| 3035 | &info->outline_cache, | 3339 | &info->outline_cache, |
| 3036 | info->scale, | 3340 | info->scale, |
| 3037 | &info->outline_cache_size, | 3341 | &info->outline_cache_size, |
| 3342 | &info->blend, | ||
| 3343 | info->instance, | ||
| 3038 | info->glyf, info->head, | 3344 | info->glyf, info->head, |
| 3039 | info->hmtx, info->hhea, | 3345 | info->hmtx, info->hhea, |
| 3040 | info->maxp, | 3346 | info->maxp, |
| @@ -3362,6 +3668,13 @@ sfntfont_begin_hb_font (struct font *font, double *position_unit) | |||
| 3362 | hb_font_set_scale (info->hb_font, factor * 64, factor * 64); | 3668 | hb_font_set_scale (info->hb_font, factor * 64, factor * 64); |
| 3363 | hb_font_set_ppem (info->hb_font, factor, factor); | 3669 | hb_font_set_ppem (info->hb_font, factor, factor); |
| 3364 | 3670 | ||
| 3671 | #ifdef HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE | ||
| 3672 | /* Set the instance if this is a distortable font. */ | ||
| 3673 | if (info->instance != -1) | ||
| 3674 | hb_font_set_var_named_instance (info->hb_font, | ||
| 3675 | info->instance); | ||
| 3676 | #endif /* HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE */ | ||
| 3677 | |||
| 3365 | /* This is needed for HarfBuzz before 2.0.0; it is the default | 3678 | /* This is needed for HarfBuzz before 2.0.0; it is the default |
| 3366 | in later versions. */ | 3679 | in later versions. */ |
| 3367 | hb_ot_font_set_funcs (info->hb_font); | 3680 | hb_ot_font_set_funcs (info->hb_font); |
| @@ -3396,6 +3709,7 @@ syms_of_sfntfont (void) | |||
| 3396 | DEFSYM (Qzh, "zh"); | 3709 | DEFSYM (Qzh, "zh"); |
| 3397 | DEFSYM (Qja, "ja"); | 3710 | DEFSYM (Qja, "ja"); |
| 3398 | DEFSYM (Qko, "ko"); | 3711 | DEFSYM (Qko, "ko"); |
| 3712 | DEFSYM (Qfont_instance, "font-instance"); | ||
| 3399 | 3713 | ||
| 3400 | /* Char-table purpose. */ | 3714 | /* Char-table purpose. */ |
| 3401 | DEFSYM (Qfont_lookup_cache, "font-lookup-cache"); | 3715 | DEFSYM (Qfont_lookup_cache, "font-lookup-cache"); |
| @@ -3427,6 +3741,7 @@ mark_sfntfont (void) | |||
| 3427 | mark_object (desc->family); | 3741 | mark_object (desc->family); |
| 3428 | mark_object (desc->style); | 3742 | mark_object (desc->style); |
| 3429 | mark_object (desc->adstyle); | 3743 | mark_object (desc->adstyle); |
| 3744 | mark_object (desc->instances); | ||
| 3430 | mark_object (desc->languages); | 3745 | mark_object (desc->languages); |
| 3431 | mark_object (desc->registry); | 3746 | mark_object (desc->registry); |
| 3432 | mark_object (desc->char_cache); | 3747 | mark_object (desc->char_cache); |