diff options
| author | Kenichi Handa | 2006-07-28 12:51:10 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-07-28 12:51:10 +0000 |
| commit | e80e09b416a0f44a4af75aeb7952df807bb3d235 (patch) | |
| tree | 537c83231345711253fa7e51d9c7787676d67b90 /src/font.c | |
| parent | c9c0c42905ae7c22d4628caca6a0cdf0e2194328 (diff) | |
| download | emacs-e80e09b416a0f44a4af75aeb7952df807bb3d235.tar.gz emacs-e80e09b416a0f44a4af75aeb7952df807bb3d235.zip | |
(font_otf_capability): Fix handling of the default
langsys.
(parse_gsub_gpos_spec): Type changed to void. New arg nbytes.
Check the contents of SPEC.
(LGSTRING_HEADER_SIZE, LGSTRING_GLYPH_SIZE): New macros.
(check_gstring): New function.
(REPLACEMENT_CHARACTER): New macro.
(font_otf_gsub): New arg alternate_subst. Be sure to set all
glyph codes of GSTRING.
(font_otf_gpos): Be sure to set all glyph codes of GSTRING.
(font_prepare_composition): Set cmp->glyph_len.
(font_open_entity): Set font->scalable.
(Ffont_get): Handle :otf property.
(Ffont_otf_gsub, Ffont_otf_gpos, Ffont_otf_alternates): New
functions.
(Fquery_font): Use font->font.full_name.
(syms_of_font): Defsubr Sfont_otf_gsub, Sfont_otf_gpos, and
Sfont_otf_alternates.
Diffstat (limited to 'src/font.c')
| -rw-r--r-- | src/font.c | 404 |
1 files changed, 356 insertions, 48 deletions
diff --git a/src/font.c b/src/font.c index 021c8f335b8..d6f1b642429 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -1518,7 +1518,7 @@ font_otf_capability (font) | |||
| 1518 | Lisp_Object langsys_tag; | 1518 | Lisp_Object langsys_tag; |
| 1519 | int l; | 1519 | int l; |
| 1520 | 1520 | ||
| 1521 | if (j == script->LangSysCount) | 1521 | if (k == script->LangSysCount) |
| 1522 | { | 1522 | { |
| 1523 | langsys = &script->DefaultLangSys; | 1523 | langsys = &script->DefaultLangSys; |
| 1524 | langsys_tag = Qnil; | 1524 | langsys_tag = Qnil; |
| @@ -1529,7 +1529,7 @@ font_otf_capability (font) | |||
| 1529 | langsys_tag | 1529 | langsys_tag |
| 1530 | = otf_tag_symbol (script->LangSysRecord[k].LangSysTag); | 1530 | = otf_tag_symbol (script->LangSysRecord[k].LangSysTag); |
| 1531 | } | 1531 | } |
| 1532 | for (l = langsys->FeatureCount -1; l >= 0; l--) | 1532 | for (l = langsys->FeatureCount - 1; l >= 0; l--) |
| 1533 | { | 1533 | { |
| 1534 | OTF_Feature *feature | 1534 | OTF_Feature *feature |
| 1535 | = gsub_gpos->FeatureList.Feature + langsys->FeatureIndex[l]; | 1535 | = gsub_gpos->FeatureList.Feature + langsys->FeatureIndex[l]; |
| @@ -1554,41 +1554,122 @@ font_otf_capability (font) | |||
| 1554 | return capability; | 1554 | return capability; |
| 1555 | } | 1555 | } |
| 1556 | 1556 | ||
| 1557 | static int | 1557 | static void |
| 1558 | parse_gsub_gpos_spec (spec, script, langsys, features) | 1558 | parse_gsub_gpos_spec (spec, script, langsys, features, nbytes) |
| 1559 | Lisp_Object spec; | 1559 | Lisp_Object spec; |
| 1560 | char **script, **langsys, **features; | 1560 | char **script, **langsys, *features; |
| 1561 | int nbytes; | ||
| 1561 | { | 1562 | { |
| 1562 | Lisp_Object val; | 1563 | Lisp_Object val; |
| 1563 | int len; | 1564 | int len; |
| 1564 | char *p; | 1565 | char *p, *pend; |
| 1565 | int asterisk; | 1566 | int asterisk; |
| 1566 | 1567 | ||
| 1568 | CHECK_CONS (spec); | ||
| 1567 | val = XCAR (spec); | 1569 | val = XCAR (spec); |
| 1570 | CHECK_SYMBOL (val); | ||
| 1568 | *script = (char *) SDATA (SYMBOL_NAME (val)); | 1571 | *script = (char *) SDATA (SYMBOL_NAME (val)); |
| 1569 | spec = XCDR (spec); | 1572 | spec = XCDR (spec); |
| 1573 | CHECK_CONS (spec); | ||
| 1570 | val = XCAR (spec); | 1574 | val = XCAR (spec); |
| 1575 | CHECK_SYMBOL (val); | ||
| 1571 | *langsys = NILP (val) ? NULL : (char *) SDATA (SYMBOL_NAME (val)); | 1576 | *langsys = NILP (val) ? NULL : (char *) SDATA (SYMBOL_NAME (val)); |
| 1572 | spec = XCDR (spec); | 1577 | spec = XCDR (spec); |
| 1573 | len = XINT (Flength (spec)); | ||
| 1574 | *features = p = malloc (6 * len); | ||
| 1575 | if (! p) | ||
| 1576 | return -1; | ||
| 1577 | 1578 | ||
| 1579 | p = features, pend = p + nbytes - 1; | ||
| 1580 | *p = '\0'; | ||
| 1578 | for (asterisk = 0; CONSP (spec); spec = XCDR (spec)) | 1581 | for (asterisk = 0; CONSP (spec); spec = XCDR (spec)) |
| 1579 | { | 1582 | { |
| 1580 | val = XCAR (spec); | 1583 | val = XCAR (spec); |
| 1584 | CHECK_SYMBOL (val); | ||
| 1585 | if (p > features) | ||
| 1586 | { | ||
| 1587 | if (p >= pend) | ||
| 1588 | break; | ||
| 1589 | *p++ = ','; | ||
| 1590 | } | ||
| 1581 | if (SREF (SYMBOL_NAME (val), 0) == '*') | 1591 | if (SREF (SYMBOL_NAME (val), 0) == '*') |
| 1582 | { | 1592 | { |
| 1583 | asterisk = 1; | 1593 | asterisk = 1; |
| 1584 | p += sprintf (p, ",*"); | 1594 | if (p >= pend) |
| 1595 | break; | ||
| 1596 | *p++ = '*'; | ||
| 1585 | } | 1597 | } |
| 1586 | else if (! asterisk) | 1598 | else if (! asterisk) |
| 1587 | p += sprintf (p, ",%s", SDATA (SYMBOL_NAME (val))); | 1599 | { |
| 1600 | val = SYMBOL_NAME (val); | ||
| 1601 | if (p + SBYTES (val) >= pend) | ||
| 1602 | break; | ||
| 1603 | p += sprintf (p, "%s", SDATA (val)); | ||
| 1604 | } | ||
| 1588 | else | 1605 | else |
| 1589 | p += sprintf (p, ",~%s", SDATA (SYMBOL_NAME (val))); | 1606 | { |
| 1607 | val = SYMBOL_NAME (val); | ||
| 1608 | if (p + 1 + SBYTES (val)>= pend) | ||
| 1609 | break; | ||
| 1610 | p += sprintf (p, "~%s", SDATA (val)); | ||
| 1611 | } | ||
| 1590 | } | 1612 | } |
| 1591 | return 0; | 1613 | if (CONSP (spec)) |
| 1614 | error ("OTF spec too long"); | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | #define LGSTRING_HEADER_SIZE 6 | ||
| 1618 | #define LGSTRING_GLYPH_SIZE 8 | ||
| 1619 | |||
| 1620 | static int | ||
| 1621 | check_gstring (gstring) | ||
| 1622 | Lisp_Object gstring; | ||
| 1623 | { | ||
| 1624 | Lisp_Object val; | ||
| 1625 | int i, j; | ||
| 1626 | |||
| 1627 | CHECK_VECTOR (gstring); | ||
| 1628 | val = AREF (gstring, 0); | ||
| 1629 | CHECK_VECTOR (val); | ||
| 1630 | if (ASIZE (val) < LGSTRING_HEADER_SIZE) | ||
| 1631 | goto err; | ||
| 1632 | CHECK_FONT_OBJECT (LGSTRING_FONT (gstring)); | ||
| 1633 | if (! NILP (LGSTRING_LBEARING (gstring))) | ||
| 1634 | CHECK_NUMBER (LGSTRING_LBEARING (gstring)); | ||
| 1635 | if (! NILP (LGSTRING_RBEARING (gstring))) | ||
| 1636 | CHECK_NUMBER (LGSTRING_RBEARING (gstring)); | ||
| 1637 | if (! NILP (LGSTRING_WIDTH (gstring))) | ||
| 1638 | CHECK_NATNUM (LGSTRING_WIDTH (gstring)); | ||
| 1639 | if (! NILP (LGSTRING_ASCENT (gstring))) | ||
| 1640 | CHECK_NUMBER (LGSTRING_ASCENT (gstring)); | ||
| 1641 | if (! NILP (LGSTRING_DESCENT (gstring))) | ||
| 1642 | CHECK_NUMBER (LGSTRING_DESCENT(gstring)); | ||
| 1643 | |||
| 1644 | for (i = 0; i < LGSTRING_LENGTH (gstring); i++) | ||
| 1645 | { | ||
| 1646 | val = LGSTRING_GLYPH (gstring, i); | ||
| 1647 | CHECK_VECTOR (val); | ||
| 1648 | if (ASIZE (val) < LGSTRING_GLYPH_SIZE) | ||
| 1649 | goto err; | ||
| 1650 | if (NILP (LGLYPH_CHAR (val))) | ||
| 1651 | break; | ||
| 1652 | CHECK_NATNUM (LGLYPH_FROM (val)); | ||
| 1653 | CHECK_NATNUM (LGLYPH_TO (val)); | ||
| 1654 | CHECK_CHARACTER (LGLYPH_CHAR (val)); | ||
| 1655 | if (! NILP (LGLYPH_CODE (val))) | ||
| 1656 | CHECK_NATNUM (LGLYPH_CODE (val)); | ||
| 1657 | if (! NILP (LGLYPH_WIDTH (val))) | ||
| 1658 | CHECK_NATNUM (LGLYPH_WIDTH (val)); | ||
| 1659 | if (! NILP (LGLYPH_ADJUSTMENT (val))) | ||
| 1660 | { | ||
| 1661 | val = LGLYPH_ADJUSTMENT (val); | ||
| 1662 | CHECK_VECTOR (val); | ||
| 1663 | if (ASIZE (val) < 3) | ||
| 1664 | goto err; | ||
| 1665 | for (j = 0; j < 3; j++) | ||
| 1666 | CHECK_NUMBER (AREF (val, j)); | ||
| 1667 | } | ||
| 1668 | } | ||
| 1669 | return i; | ||
| 1670 | err: | ||
| 1671 | error ("Invalid glyph-string format"); | ||
| 1672 | return -1; | ||
| 1592 | } | 1673 | } |
| 1593 | 1674 | ||
| 1594 | #define DEVICE_DELTA(table, size) \ | 1675 | #define DEVICE_DELTA(table, size) \ |
| @@ -1617,49 +1698,66 @@ adjust_anchor (struct font *font, OTF_Anchor *anchor, | |||
| 1617 | } | 1698 | } |
| 1618 | } | 1699 | } |
| 1619 | 1700 | ||
| 1701 | #define REPLACEMENT_CHARACTER 0xFFFD | ||
| 1620 | 1702 | ||
| 1621 | /* Drive FONT's OTF GSUB features according to GSUB_SPEC. See the | 1703 | /* Drive FONT's OTF GSUB features according to GSUB_SPEC. See the |
| 1622 | comment of (sturct font_driver).otf_gsub. */ | 1704 | comment of (sturct font_driver).otf_gsub. */ |
| 1623 | 1705 | ||
| 1624 | int | 1706 | int |
| 1625 | font_otf_gsub (font, gsub_spec, gstring_in, from, to, gstring_out, idx) | 1707 | font_otf_gsub (font, gsub_spec, gstring_in, from, to, gstring_out, idx, |
| 1708 | alternate_subst) | ||
| 1626 | struct font *font; | 1709 | struct font *font; |
| 1627 | Lisp_Object gsub_spec; | 1710 | Lisp_Object gsub_spec; |
| 1628 | Lisp_Object gstring_in; | 1711 | Lisp_Object gstring_in; |
| 1629 | int from, to; | 1712 | int from, to; |
| 1630 | Lisp_Object gstring_out; | 1713 | Lisp_Object gstring_out; |
| 1631 | int idx; | 1714 | int idx, alternate_subst; |
| 1632 | { | 1715 | { |
| 1633 | int len; | 1716 | int len; |
| 1634 | int i; | 1717 | int i; |
| 1635 | OTF *otf; | 1718 | OTF *otf; |
| 1636 | OTF_GlyphString otf_gstring; | 1719 | OTF_GlyphString otf_gstring; |
| 1637 | OTF_Glyph *g; | 1720 | OTF_Glyph *g; |
| 1638 | char *script, *langsys, *features; | 1721 | char *script, *langsys, features[256]; |
| 1722 | int need_cmap; | ||
| 1723 | |||
| 1724 | parse_gsub_gpos_spec (gsub_spec, &script, &langsys, features, 256); | ||
| 1639 | 1725 | ||
| 1640 | otf = otf_open (font->entity, font->file_name); | 1726 | otf = otf_open (font->entity, font->file_name); |
| 1641 | if (! otf) | 1727 | if (! otf) |
| 1642 | return 0; | 1728 | return 0; |
| 1643 | if (OTF_get_table (otf, "head") < 0) | 1729 | if (OTF_get_table (otf, "head") < 0) |
| 1644 | return 0; | 1730 | return 0; |
| 1731 | if (OTF_get_table (otf, "cmap") < 0) | ||
| 1732 | return 0; | ||
| 1645 | if (OTF_check_table (otf, "GSUB") < 0) | 1733 | if (OTF_check_table (otf, "GSUB") < 0) |
| 1646 | return 0; | 1734 | return 0; |
| 1647 | if (parse_gsub_gpos_spec (gsub_spec, &script, &langsys, &features) < 0) | ||
| 1648 | return 0; | ||
| 1649 | len = to - from; | 1735 | len = to - from; |
| 1650 | otf_gstring.size = otf_gstring.used = len; | 1736 | otf_gstring.size = otf_gstring.used = len; |
| 1651 | otf_gstring.glyphs = (OTF_Glyph *) malloc (sizeof (OTF_Glyph) * len); | 1737 | otf_gstring.glyphs = (OTF_Glyph *) malloc (sizeof (OTF_Glyph) * len); |
| 1652 | memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * len); | 1738 | memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * len); |
| 1653 | for (i = 0; i < len; i++) | 1739 | for (i = 0, need_cmap = 0; i < len; i++) |
| 1654 | { | 1740 | { |
| 1655 | Lisp_Object g = LGSTRING_GLYPH (gstring_in, from + i); | 1741 | Lisp_Object g = LGSTRING_GLYPH (gstring_in, from + i); |
| 1656 | 1742 | ||
| 1657 | otf_gstring.glyphs[i].c = XINT (LGLYPH_CHAR (g)); | 1743 | otf_gstring.glyphs[i].c = XINT (LGLYPH_CHAR (g)); |
| 1658 | otf_gstring.glyphs[i].glyph_id = XINT (LGLYPH_CODE (g)); | 1744 | if (otf_gstring.glyphs[i].c == REPLACEMENT_CHARACTER) |
| 1745 | otf_gstring.glyphs[i].c = 0; | ||
| 1746 | if (NILP (LGLYPH_CODE (g))) | ||
| 1747 | { | ||
| 1748 | otf_gstring.glyphs[i].glyph_id = 0; | ||
| 1749 | need_cmap = 1; | ||
| 1750 | } | ||
| 1751 | else | ||
| 1752 | otf_gstring.glyphs[i].glyph_id = XINT (LGLYPH_CODE (g)); | ||
| 1659 | } | 1753 | } |
| 1660 | 1754 | ||
| 1755 | if (need_cmap) | ||
| 1756 | OTF_drive_cmap (otf, &otf_gstring); | ||
| 1661 | OTF_drive_gdef (otf, &otf_gstring); | 1757 | OTF_drive_gdef (otf, &otf_gstring); |
| 1662 | if (OTF_drive_gsub (otf, &otf_gstring, script, langsys, features) < 0) | 1758 | if ((alternate_subst |
| 1759 | ? OTF_drive_gsub_alternate (otf, &otf_gstring, script, langsys, features) | ||
| 1760 | : OTF_drive_gsub (otf, &otf_gstring, script, langsys, features)) < 0) | ||
| 1663 | { | 1761 | { |
| 1664 | free (otf_gstring.glyphs); | 1762 | free (otf_gstring.glyphs); |
| 1665 | return 0; | 1763 | return 0; |
| @@ -1698,7 +1796,10 @@ font_otf_gsub (font, gsub_spec, gstring_in, from, to, gstring_out, idx) | |||
| 1698 | glyph = LGSTRING_GLYPH (gstring_out, idx + i); | 1796 | glyph = LGSTRING_GLYPH (gstring_out, idx + i); |
| 1699 | ASET (glyph, 0, min_idx); | 1797 | ASET (glyph, 0, min_idx); |
| 1700 | ASET (glyph, 1, max_idx); | 1798 | ASET (glyph, 1, max_idx); |
| 1701 | LGLYPH_SET_CHAR (glyph, make_number (g->c)); | 1799 | if (g->c > 0) |
| 1800 | LGLYPH_SET_CHAR (glyph, make_number (g->c)); | ||
| 1801 | else | ||
| 1802 | LGLYPH_SET_CHAR (glyph, make_number (REPLACEMENT_CHARACTER)); | ||
| 1702 | LGLYPH_SET_CODE (glyph, make_number (g->glyph_id)); | 1803 | LGLYPH_SET_CODE (glyph, make_number (g->glyph_id)); |
| 1703 | } | 1804 | } |
| 1704 | } | 1805 | } |
| @@ -1722,30 +1823,43 @@ font_otf_gpos (font, gpos_spec, gstring, from, to) | |||
| 1722 | OTF *otf; | 1823 | OTF *otf; |
| 1723 | OTF_GlyphString otf_gstring; | 1824 | OTF_GlyphString otf_gstring; |
| 1724 | OTF_Glyph *g; | 1825 | OTF_Glyph *g; |
| 1725 | char *script, *langsys, *features; | 1826 | char *script, *langsys, features[256]; |
| 1827 | int need_cmap; | ||
| 1726 | Lisp_Object glyph; | 1828 | Lisp_Object glyph; |
| 1727 | int u, size; | 1829 | int u, size; |
| 1728 | Lisp_Object base, mark; | 1830 | Lisp_Object base, mark; |
| 1729 | 1831 | ||
| 1832 | parse_gsub_gpos_spec (gpos_spec, &script, &langsys, features, 256); | ||
| 1833 | |||
| 1730 | otf = otf_open (font->entity, font->file_name); | 1834 | otf = otf_open (font->entity, font->file_name); |
| 1731 | if (! otf) | 1835 | if (! otf) |
| 1732 | return 0; | 1836 | return 0; |
| 1733 | if (OTF_get_table (otf, "head") < 0) | 1837 | if (OTF_get_table (otf, "head") < 0) |
| 1734 | return 0; | 1838 | return 0; |
| 1839 | if (OTF_get_table (otf, "cmap") < 0) | ||
| 1840 | return 0; | ||
| 1735 | if (OTF_check_table (otf, "GPOS") < 0) | 1841 | if (OTF_check_table (otf, "GPOS") < 0) |
| 1736 | return 0; | 1842 | return 0; |
| 1737 | if (parse_gsub_gpos_spec (gpos_spec, &script, &langsys, &features) < 0) | ||
| 1738 | return 0; | ||
| 1739 | len = to - from; | 1843 | len = to - from; |
| 1740 | otf_gstring.size = otf_gstring.used = len; | 1844 | otf_gstring.size = otf_gstring.used = len; |
| 1741 | otf_gstring.glyphs = (OTF_Glyph *) malloc (sizeof (OTF_Glyph) * len); | 1845 | otf_gstring.glyphs = (OTF_Glyph *) malloc (sizeof (OTF_Glyph) * len); |
| 1742 | memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * len); | 1846 | memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * len); |
| 1743 | for (i = 0; i < len; i++) | 1847 | for (i = 0, need_cmap = 0; i < len; i++) |
| 1744 | { | 1848 | { |
| 1745 | glyph = LGSTRING_GLYPH (gstring, from + i); | 1849 | glyph = LGSTRING_GLYPH (gstring, from + i); |
| 1746 | otf_gstring.glyphs[i].glyph_id = XINT (LGLYPH_CODE (glyph)); | 1850 | otf_gstring.glyphs[i].c = XINT (LGLYPH_CHAR (glyph)); |
| 1851 | if (otf_gstring.glyphs[i].c == REPLACEMENT_CHARACTER) | ||
| 1852 | otf_gstring.glyphs[i].c = 0; | ||
| 1853 | if (NILP (LGLYPH_CODE (glyph))) | ||
| 1854 | { | ||
| 1855 | otf_gstring.glyphs[i].glyph_id = 0; | ||
| 1856 | need_cmap = 1; | ||
| 1857 | } | ||
| 1858 | else | ||
| 1859 | otf_gstring.glyphs[i].glyph_id = XINT (LGLYPH_CODE (glyph)); | ||
| 1747 | } | 1860 | } |
| 1748 | 1861 | if (need_cmap) | |
| 1862 | OTF_drive_cmap (otf, &otf_gstring); | ||
| 1749 | OTF_drive_gdef (otf, &otf_gstring); | 1863 | OTF_drive_gdef (otf, &otf_gstring); |
| 1750 | 1864 | ||
| 1751 | if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, features) < 0) | 1865 | if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, features) < 0) |
| @@ -1850,25 +1964,16 @@ font_otf_gpos (font, gpos_spec, gstring, from, to) | |||
| 1850 | } | 1964 | } |
| 1851 | 1965 | ||
| 1852 | free (otf_gstring.glyphs); | 1966 | free (otf_gstring.glyphs); |
| 1853 | return 0; | 1967 | return i; |
| 1854 | } | 1968 | } |
| 1855 | 1969 | ||
| 1856 | #endif /* HAVE_LIBOTF */ | 1970 | #endif /* HAVE_LIBOTF */ |
| 1857 | 1971 | ||
| 1858 | 1972 | ||
| 1859 | /* glyph-string handler */ | 1973 | /* G-string (glyph string) handler */ |
| 1860 | 1974 | ||
| 1861 | /* GSTRING is a vector of this form: | 1975 | /* G-string is a vector of the form [HEADER GLYPH ...]. |
| 1862 | [ [FONT-OBJECT LBEARING RBEARING WIDTH ASCENT DESCENT] GLYPH ... ] | 1976 | See the docstring of `font-make-gstring' for more detail. */ |
| 1863 | and GLYPH is a vector of this form: | ||
| 1864 | [ FROM-IDX TO-IDX C CODE WIDTH [ [X-OFF Y-OFF WADJUST] | nil] ] | ||
| 1865 | where | ||
| 1866 | FROM-IDX and TO-IDX are used internally and should not be touched. | ||
| 1867 | C is a character of the glyph. | ||
| 1868 | CODE is a glyph-code of C in FONT-OBJECT. | ||
| 1869 | X-OFF and Y-OFF are offests to the base position for the glyph. | ||
| 1870 | WIDTH is a normal width of the glyph. | ||
| 1871 | WADJUST is an adjustment to the normal width of the glyph. */ | ||
| 1872 | 1977 | ||
| 1873 | struct font * | 1978 | struct font * |
| 1874 | font_prepare_composition (cmp) | 1979 | font_prepare_composition (cmp) |
| @@ -1912,6 +2017,7 @@ font_prepare_composition (cmp) | |||
| 1912 | cmp->descent = metrics.descent; | 2017 | cmp->descent = metrics.descent; |
| 1913 | cmp->pixel_width += metrics.width + LGLYPH_WADJUST (g); | 2018 | cmp->pixel_width += metrics.width + LGLYPH_WADJUST (g); |
| 1914 | } | 2019 | } |
| 2020 | cmp->glyph_len = i; | ||
| 1915 | LGSTRING_SET_LBEARING (gstring, make_number (cmp->lbearing)); | 2021 | LGSTRING_SET_LBEARING (gstring, make_number (cmp->lbearing)); |
| 1916 | LGSTRING_SET_RBEARING (gstring, make_number (cmp->rbearing)); | 2022 | LGSTRING_SET_RBEARING (gstring, make_number (cmp->rbearing)); |
| 1917 | LGSTRING_SET_WIDTH (gstring, make_number (cmp->pixel_width)); | 2023 | LGSTRING_SET_WIDTH (gstring, make_number (cmp->pixel_width)); |
| @@ -2326,6 +2432,8 @@ font_open_entity (f, entity, pixel_size) | |||
| 2326 | font = driver_list->driver->open (f, entity, pixel_size); | 2432 | font = driver_list->driver->open (f, entity, pixel_size); |
| 2327 | if (! font) | 2433 | if (! font) |
| 2328 | return Qnil; | 2434 | return Qnil; |
| 2435 | font->scalable = XINT (size) == 0; | ||
| 2436 | |||
| 2329 | val = make_save_value (font, 1); | 2437 | val = make_save_value (font, 1); |
| 2330 | ASET (entity, FONT_OBJLIST_INDEX, | 2438 | ASET (entity, FONT_OBJLIST_INDEX, |
| 2331 | Fcons (val, AREF (entity, FONT_OBJLIST_INDEX))); | 2439 | Fcons (val, AREF (entity, FONT_OBJLIST_INDEX))); |
| @@ -2833,7 +2941,13 @@ If FONT is font-entity and PROP is :extra, always nil is returned. */) | |||
| 2833 | enum font_property_index idx; | 2941 | enum font_property_index idx; |
| 2834 | 2942 | ||
| 2835 | if (FONT_OBJECT_P (font)) | 2943 | if (FONT_OBJECT_P (font)) |
| 2836 | font = ((struct font *) XSAVE_VALUE (font)->pointer)->entity; | 2944 | { |
| 2945 | struct font *fontp = XSAVE_VALUE (font)->pointer; | ||
| 2946 | |||
| 2947 | if (EQ (prop, QCotf)) | ||
| 2948 | return font_otf_capability (fontp); | ||
| 2949 | font = fontp->entity; | ||
| 2950 | } | ||
| 2837 | else | 2951 | else |
| 2838 | CHECK_FONT (font); | 2952 | CHECK_FONT (font); |
| 2839 | idx = get_font_prop_index (prop, 0); | 2953 | idx = get_font_prop_index (prop, 0); |
| @@ -3089,8 +3203,26 @@ sorted by numeric values. */) | |||
| 3089 | } | 3203 | } |
| 3090 | 3204 | ||
| 3091 | DEFUN ("font-make-gstring", Ffont_make_gstring, Sfont_make_gstring, 2, 2, 0, | 3205 | DEFUN ("font-make-gstring", Ffont_make_gstring, Sfont_make_gstring, 2, 2, 0, |
| 3092 | doc: /* Return a newly created glyph-string for FONT-OBJECT with NUM glyphs. | 3206 | doc: /* Return a newly created g-string for FONT-OBJECT with NUM glyphs. |
| 3093 | FONT-OBJECT may be nil if it is not yet known. */) | 3207 | FONT-OBJECT may be nil if it is not yet known. |
| 3208 | |||
| 3209 | G-string is sequence of glyphs of a specific font, | ||
| 3210 | and is a vector of this form: | ||
| 3211 | [ HEADER GLYPH ... ] | ||
| 3212 | HEADER is a vector of this form: | ||
| 3213 | [FONT-OBJECT LBEARING RBEARING WIDTH ASCENT DESCENT] | ||
| 3214 | where | ||
| 3215 | FONT-OBJECT is a font-object for all glyphs in the G-string, | ||
| 3216 | LBEARING thry DESCENT is the metrics (in pixels) of the whole G-string. | ||
| 3217 | GLYPH is a vector of this form: | ||
| 3218 | [ FROM-IDX TO-IDX C CODE WIDTH [ [X-OFF Y-OFF WADJUST] | nil] ] | ||
| 3219 | where | ||
| 3220 | FROM-IDX and TO-IDX are used internally and should not be touched. | ||
| 3221 | C is the character of the glyph. | ||
| 3222 | CODE is the glyph-code of C in FONT-OBJECT. | ||
| 3223 | X-OFF and Y-OFF are offests to the base position for the glyph. | ||
| 3224 | WIDTH is the normal width of the glyph. | ||
| 3225 | WADJUST is the adjustment to the normal width of the glyph. */) | ||
| 3094 | (font_object, num) | 3226 | (font_object, num) |
| 3095 | Lisp_Object font_object, num; | 3227 | Lisp_Object font_object, num; |
| 3096 | { | 3228 | { |
| @@ -3192,6 +3324,147 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3192 | return Qnil; | 3324 | return Qnil; |
| 3193 | } | 3325 | } |
| 3194 | 3326 | ||
| 3327 | DEFUN ("font-otf-gsub", Ffont_otf_gsub, Sfont_otf_gsub, 6, 6, 0, | ||
| 3328 | doc: /* Apply OpenType "GSUB" features on glyph-string GSTRING-IN. | ||
| 3329 | FEATURE-SPEC specifies which featuress to apply in this format: | ||
| 3330 | (SCRIPT LANGSYS FEATURE ...) | ||
| 3331 | where | ||
| 3332 | SCRIPT is a symbol specifying a script tag of OpenType, | ||
| 3333 | LANGSYS is a symbol specifying a langsys tag of OpenType, | ||
| 3334 | FEATURE is a symbol specifying a feature tag of Opentype. | ||
| 3335 | |||
| 3336 | If LANGYS is nil, the default langsys is selected. | ||
| 3337 | |||
| 3338 | The features are applied in the order appeared in the list. FEATURE | ||
| 3339 | may be a symbol `*', in which case all available features not appeared | ||
| 3340 | in this list are applied, and the remaining FEATUREs are not ignored. | ||
| 3341 | For instance, (mlym nil vatu pstf * haln) means to apply vatu and pstf | ||
| 3342 | in this order, then to apply all available features other than vatu, | ||
| 3343 | pstf, and haln. | ||
| 3344 | |||
| 3345 | The features are applied to the glyphs in the range FROM and TO of | ||
| 3346 | GSTRING-IN. | ||
| 3347 | |||
| 3348 | If some of a feature is actually applicable, the resulting glyphs are | ||
| 3349 | produced in the glyph-string GSTRING-OUT from the index INDEX. In | ||
| 3350 | this case, the value is the number of produced glyphs. | ||
| 3351 | |||
| 3352 | If no feature is applicable, no glyph is produced in GSTRING-OUT, and | ||
| 3353 | the value is 0. | ||
| 3354 | |||
| 3355 | If GSTRING-OUT is too short to hold produced glyphs, no glyphs is | ||
| 3356 | produced in GSTRING-OUT, and the value is nil. | ||
| 3357 | |||
| 3358 | See the documentation of `font-make-gstring' for the format of | ||
| 3359 | glyph-string. */) | ||
| 3360 | (feature_spec, gstring_in, from, to, gstring_out, index) | ||
| 3361 | Lisp_Object feature_spec, gstring_in, from, to, gstring_out, index; | ||
| 3362 | { | ||
| 3363 | Lisp_Object font_object = LGSTRING_FONT (gstring_in); | ||
| 3364 | struct font *font = XSAVE_VALUE (font_object)->pointer; | ||
| 3365 | int len, num; | ||
| 3366 | |||
| 3367 | CHECK_FONT_GET_OBJECT (font_object, font); | ||
| 3368 | if (! font->driver->otf_gsub) | ||
| 3369 | error ("Font backend %s can't drive OpenType GSUB table", | ||
| 3370 | SDATA (SYMBOL_NAME (font->driver->type))); | ||
| 3371 | CHECK_CONS (feature_spec); | ||
| 3372 | len = check_gstring (gstring_in); | ||
| 3373 | CHECK_VECTOR (gstring_out); | ||
| 3374 | CHECK_NATNUM (from); | ||
| 3375 | CHECK_NATNUM (to); | ||
| 3376 | CHECK_NATNUM (index); | ||
| 3377 | |||
| 3378 | if (XINT (from) >= XINT (to) || XINT (to) > len) | ||
| 3379 | args_out_of_range_3 (from, to, make_number (len)); | ||
| 3380 | if (XINT (index) >= ASIZE (gstring_out)) | ||
| 3381 | args_out_of_range (index, make_number (ASIZE (gstring_out))); | ||
| 3382 | num = font_otf_gsub (font, feature_spec, gstring_in, XINT (from), XINT (to), | ||
| 3383 | gstring_out, XINT (index), 0); | ||
| 3384 | if (num < 0) | ||
| 3385 | return Qnil; | ||
| 3386 | return make_number (num); | ||
| 3387 | } | ||
| 3388 | |||
| 3389 | |||
| 3390 | DEFUN ("font-otf-gpos", Ffont_otf_gpos, Sfont_otf_gpos, 4, 4, 0, | ||
| 3391 | doc: /* Apply OpenType "GPOS" features on glyph-string GSTRING. | ||
| 3392 | FEATURE-SPEC specifies which features to apply in this format: | ||
| 3393 | (SCRIPT LANGSYS FEATURE ...) | ||
| 3394 | See the documentation of `font-otf-gsub' for more detail. | ||
| 3395 | |||
| 3396 | The features are applied to the glyphs in the range FROM and TO of | ||
| 3397 | GSTRING. */) | ||
| 3398 | (gpos_spec, gstring, from, to) | ||
| 3399 | Lisp_Object gpos_spec, gstring, from, to; | ||
| 3400 | { | ||
| 3401 | Lisp_Object font_object = LGSTRING_FONT (gstring); | ||
| 3402 | struct font *font; | ||
| 3403 | int len, num; | ||
| 3404 | |||
| 3405 | CHECK_FONT_GET_OBJECT (font_object, font); | ||
| 3406 | if (! font->driver->otf_gpos) | ||
| 3407 | error ("Font backend %s can't drive OpenType GPOS table", | ||
| 3408 | SDATA (SYMBOL_NAME (font->driver->type))); | ||
| 3409 | CHECK_CONS (gpos_spec); | ||
| 3410 | len = check_gstring (gstring); | ||
| 3411 | CHECK_NATNUM (from); | ||
| 3412 | CHECK_NATNUM (to); | ||
| 3413 | |||
| 3414 | if (XINT (from) >= XINT (to) || XINT (to) > len) | ||
| 3415 | args_out_of_range_3 (from, to, make_number (len)); | ||
| 3416 | num = font_otf_gpos (font, gpos_spec, gstring, XINT (from), XINT (to)); | ||
| 3417 | return (num <= 0 ? Qnil : Qt); | ||
| 3418 | } | ||
| 3419 | |||
| 3420 | |||
| 3421 | DEFUN ("font-otf-alternates", Ffont_otf_alternates, Sfont_otf_alternates, | ||
| 3422 | 3, 3, 0, | ||
| 3423 | doc: /* Return a list of alternate glyphs of CHARACTER in FONT-OBJECT. | ||
| 3424 | FEATURE-SPEC specifies which features of the font FONT-OBJECT to apply | ||
| 3425 | in this format: | ||
| 3426 | (SCRIPT LANGSYS FEATURE ...) | ||
| 3427 | See the documentation of `font-otf-gsub' for more detail. | ||
| 3428 | |||
| 3429 | The value is a list of cons cells of the format (GLYPH-ID . CHARACTER), | ||
| 3430 | where GLYPH-ID is a glyph index of the font, and CHARACTER is a | ||
| 3431 | character code corresponding to the glyph or nil if there's no | ||
| 3432 | corresponding character. */) | ||
| 3433 | (font_object, character, feature_spec) | ||
| 3434 | Lisp_Object font_object, character, feature_spec; | ||
| 3435 | { | ||
| 3436 | struct font *font; | ||
| 3437 | Lisp_Object gstring_in, gstring_out, g; | ||
| 3438 | Lisp_Object alternates; | ||
| 3439 | int i, num; | ||
| 3440 | |||
| 3441 | CHECK_FONT_GET_OBJECT (font_object, font); | ||
| 3442 | CHECK_CHARACTER (character); | ||
| 3443 | CHECK_CONS (feature_spec); | ||
| 3444 | |||
| 3445 | gstring_in = Ffont_make_gstring (font_object, make_number (1)); | ||
| 3446 | g = LGSTRING_GLYPH (gstring_in, 0); | ||
| 3447 | LGLYPH_SET_CHAR (g, character); | ||
| 3448 | gstring_out = Ffont_make_gstring (font_object, make_number (10)); | ||
| 3449 | while ((num = font_otf_gsub (font, feature_spec, gstring_in, 0, 1, | ||
| 3450 | gstring_out, 0, 1)) < 0) | ||
| 3451 | gstring_out = Ffont_make_gstring (font_object, | ||
| 3452 | make_number (ASIZE (gstring_out) * 2)); | ||
| 3453 | alternates = Qnil; | ||
| 3454 | for (i = 0; i < num; i++) | ||
| 3455 | { | ||
| 3456 | Lisp_Object g = LGSTRING_GLYPH (gstring_out, i); | ||
| 3457 | int c = XINT (LGLYPH_CHAR (g)); | ||
| 3458 | unsigned code = XUINT (LGLYPH_CODE (g)); | ||
| 3459 | Lisp_Object elt; | ||
| 3460 | |||
| 3461 | alternates = Fcons (Fcons (make_number (code), | ||
| 3462 | c > 0 ? make_number (c) : Qnil), | ||
| 3463 | alternates); | ||
| 3464 | } | ||
| 3465 | return Fnreverse (alternates); | ||
| 3466 | } | ||
| 3467 | |||
| 3195 | 3468 | ||
| 3196 | #ifdef FONT_DEBUG | 3469 | #ifdef FONT_DEBUG |
| 3197 | 3470 | ||
| @@ -3233,7 +3506,37 @@ DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0, | |||
| 3233 | } | 3506 | } |
| 3234 | 3507 | ||
| 3235 | DEFUN ("query-font", Fquery_font, Squery_font, 1, 1, 0, | 3508 | DEFUN ("query-font", Fquery_font, Squery_font, 1, 1, 0, |
| 3236 | doc: /* Return information about FONT-OBJECT. */) | 3509 | doc: /* Return information about FONT-OBJECT. |
| 3510 | The value is a vector: | ||
| 3511 | [ NAME FILENAME PIXEL-SIZE SIZE ASCENT DESCENT SPACE-WIDTH AVERAGE-WIDTH | ||
| 3512 | OTF-CAPABILITY ] | ||
| 3513 | |||
| 3514 | NAME is a string of the font name (or nil if the font backend doesn't | ||
| 3515 | provide a name). | ||
| 3516 | |||
| 3517 | FILENAME is a string of the font file (or nil if the font backend | ||
| 3518 | doesn't provide a file name). | ||
| 3519 | |||
| 3520 | PIXEL-SIZE is a pixel size by which the font is opened. | ||
| 3521 | |||
| 3522 | SIZE is a maximum advance width of the font in pixel. | ||
| 3523 | |||
| 3524 | ASCENT, DESCENT, SPACE-WIDTH, AVERAGE-WIDTH are metrics of the font in | ||
| 3525 | pixel. | ||
| 3526 | |||
| 3527 | OTF-CAPABILITY is a cons (GSUB . GPOS), where GSUB shows which "GSUB" | ||
| 3528 | features the font supports, and GPOS shows which "GPOS" features the | ||
| 3529 | font supports. Both GSUB and GPOS are lists of the format: | ||
| 3530 | ((SCRIPT (LANGSYS FEATURE ...) ...) ...) | ||
| 3531 | |||
| 3532 | SCRIPT is a symbol representing OpenType script tag. | ||
| 3533 | |||
| 3534 | LANGSYS is a symbol representing OpenType langsys tag, or nil | ||
| 3535 | representing the default langsys. | ||
| 3536 | |||
| 3537 | FEATURE is a symbol representing OpenType feature tag. | ||
| 3538 | |||
| 3539 | If the font is not OpenType font, OTF-CAPABILITY is nil. */) | ||
| 3237 | (font_object) | 3540 | (font_object) |
| 3238 | Lisp_Object font_object; | 3541 | Lisp_Object font_object; |
| 3239 | { | 3542 | { |
| @@ -3243,7 +3546,9 @@ DEFUN ("query-font", Fquery_font, Squery_font, 1, 1, 0, | |||
| 3243 | CHECK_FONT_GET_OBJECT (font_object, font); | 3546 | CHECK_FONT_GET_OBJECT (font_object, font); |
| 3244 | 3547 | ||
| 3245 | val = Fmake_vector (make_number (9), Qnil); | 3548 | val = Fmake_vector (make_number (9), Qnil); |
| 3246 | ASET (val, 0, Ffont_xlfd_name (font_object)); | 3549 | if (font->font.full_name) |
| 3550 | ASET (val, 0, make_unibyte_string (font->font.full_name, | ||
| 3551 | strlen (font->font.full_name))); | ||
| 3247 | if (font->file_name) | 3552 | if (font->file_name) |
| 3248 | ASET (val, 1, make_unibyte_string (font->file_name, | 3553 | ASET (val, 1, make_unibyte_string (font->file_name, |
| 3249 | strlen (font->file_name))); | 3554 | strlen (font->file_name))); |
| @@ -3457,6 +3762,9 @@ syms_of_font () | |||
| 3457 | defsubr (&Sinternal_set_font_style_table); | 3762 | defsubr (&Sinternal_set_font_style_table); |
| 3458 | defsubr (&Sfont_make_gstring); | 3763 | defsubr (&Sfont_make_gstring); |
| 3459 | defsubr (&Sfont_fill_gstring); | 3764 | defsubr (&Sfont_fill_gstring); |
| 3765 | defsubr (&Sfont_otf_gsub); | ||
| 3766 | defsubr (&Sfont_otf_gpos); | ||
| 3767 | defsubr (&Sfont_otf_alternates); | ||
| 3460 | 3768 | ||
| 3461 | #ifdef FONT_DEBUG | 3769 | #ifdef FONT_DEBUG |
| 3462 | defsubr (&Sopen_font); | 3770 | defsubr (&Sopen_font); |