aboutsummaryrefslogtreecommitdiffstats
path: root/src/font.c
diff options
context:
space:
mode:
authorKenichi Handa2006-07-28 12:51:10 +0000
committerKenichi Handa2006-07-28 12:51:10 +0000
commite80e09b416a0f44a4af75aeb7952df807bb3d235 (patch)
tree537c83231345711253fa7e51d9c7787676d67b90 /src/font.c
parentc9c0c42905ae7c22d4628caca6a0cdf0e2194328 (diff)
downloademacs-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.c404
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
1557static int 1557static void
1558parse_gsub_gpos_spec (spec, script, langsys, features) 1558parse_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
1620static int
1621check_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
1624int 1706int
1625font_otf_gsub (font, gsub_spec, gstring_in, from, to, gstring_out, idx) 1707font_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
1873struct font * 1978struct font *
1874font_prepare_composition (cmp) 1979font_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
3091DEFUN ("font-make-gstring", Ffont_make_gstring, Sfont_make_gstring, 2, 2, 0, 3205DEFUN ("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.
3093FONT-OBJECT may be nil if it is not yet known. */) 3207FONT-OBJECT may be nil if it is not yet known.
3208
3209G-string is sequence of glyphs of a specific font,
3210and is a vector of this form:
3211 [ HEADER GLYPH ... ]
3212HEADER is a vector of this form:
3213 [FONT-OBJECT LBEARING RBEARING WIDTH ASCENT DESCENT]
3214where
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.
3217GLYPH is a vector of this form:
3218 [ FROM-IDX TO-IDX C CODE WIDTH [ [X-OFF Y-OFF WADJUST] | nil] ]
3219where
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
3327DEFUN ("font-otf-gsub", Ffont_otf_gsub, Sfont_otf_gsub, 6, 6, 0,
3328 doc: /* Apply OpenType "GSUB" features on glyph-string GSTRING-IN.
3329FEATURE-SPEC specifies which featuress to apply in this format:
3330 (SCRIPT LANGSYS FEATURE ...)
3331where
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
3336If LANGYS is nil, the default langsys is selected.
3337
3338The features are applied in the order appeared in the list. FEATURE
3339may be a symbol `*', in which case all available features not appeared
3340in this list are applied, and the remaining FEATUREs are not ignored.
3341For instance, (mlym nil vatu pstf * haln) means to apply vatu and pstf
3342in this order, then to apply all available features other than vatu,
3343pstf, and haln.
3344
3345The features are applied to the glyphs in the range FROM and TO of
3346GSTRING-IN.
3347
3348If some of a feature is actually applicable, the resulting glyphs are
3349produced in the glyph-string GSTRING-OUT from the index INDEX. In
3350this case, the value is the number of produced glyphs.
3351
3352If no feature is applicable, no glyph is produced in GSTRING-OUT, and
3353the value is 0.
3354
3355If GSTRING-OUT is too short to hold produced glyphs, no glyphs is
3356produced in GSTRING-OUT, and the value is nil.
3357
3358See the documentation of `font-make-gstring' for the format of
3359glyph-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
3390DEFUN ("font-otf-gpos", Ffont_otf_gpos, Sfont_otf_gpos, 4, 4, 0,
3391 doc: /* Apply OpenType "GPOS" features on glyph-string GSTRING.
3392FEATURE-SPEC specifies which features to apply in this format:
3393 (SCRIPT LANGSYS FEATURE ...)
3394See the documentation of `font-otf-gsub' for more detail.
3395
3396The features are applied to the glyphs in the range FROM and TO of
3397GSTRING. */)
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
3421DEFUN ("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.
3424FEATURE-SPEC specifies which features of the font FONT-OBJECT to apply
3425in this format:
3426 (SCRIPT LANGSYS FEATURE ...)
3427See the documentation of `font-otf-gsub' for more detail.
3428
3429The value is a list of cons cells of the format (GLYPH-ID . CHARACTER),
3430where GLYPH-ID is a glyph index of the font, and CHARACTER is a
3431character code corresponding to the glyph or nil if there's no
3432corresponding 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
3235DEFUN ("query-font", Fquery_font, Squery_font, 1, 1, 0, 3508DEFUN ("query-font", Fquery_font, Squery_font, 1, 1, 0,
3236 doc: /* Return information about FONT-OBJECT. */) 3509 doc: /* Return information about FONT-OBJECT.
3510The value is a vector:
3511 [ NAME FILENAME PIXEL-SIZE SIZE ASCENT DESCENT SPACE-WIDTH AVERAGE-WIDTH
3512 OTF-CAPABILITY ]
3513
3514NAME is a string of the font name (or nil if the font backend doesn't
3515provide a name).
3516
3517FILENAME is a string of the font file (or nil if the font backend
3518doesn't provide a file name).
3519
3520PIXEL-SIZE is a pixel size by which the font is opened.
3521
3522SIZE is a maximum advance width of the font in pixel.
3523
3524ASCENT, DESCENT, SPACE-WIDTH, AVERAGE-WIDTH are metrics of the font in
3525pixel.
3526
3527OTF-CAPABILITY is a cons (GSUB . GPOS), where GSUB shows which "GSUB"
3528features the font supports, and GPOS shows which "GPOS" features the
3529font supports. Both GSUB and GPOS are lists of the format:
3530 ((SCRIPT (LANGSYS FEATURE ...) ...) ...)
3531
3532SCRIPT is a symbol representing OpenType script tag.
3533
3534LANGSYS is a symbol representing OpenType langsys tag, or nil
3535representing the default langsys.
3536
3537FEATURE is a symbol representing OpenType feature tag.
3538
3539If 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);