aboutsummaryrefslogtreecommitdiffstats
path: root/src/font.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/font.c')
-rw-r--r--src/font.c203
1 files changed, 101 insertions, 102 deletions
diff --git a/src/font.c b/src/font.c
index 5f8d22157d6..34cacb37ce4 100644
--- a/src/font.c
+++ b/src/font.c
@@ -21,6 +21,7 @@ You should have received a copy of the GNU General Public License
21along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 21along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 22
23#include <config.h> 23#include <config.h>
24#include <float.h>
24#include <stdio.h> 25#include <stdio.h>
25#include <ctype.h> 26#include <ctype.h>
26#include <setjmp.h> 27#include <setjmp.h>
@@ -1180,7 +1181,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1180 char *p; 1181 char *p;
1181 const char *f[XLFD_REGISTRY_INDEX + 1]; 1182 const char *f[XLFD_REGISTRY_INDEX + 1];
1182 Lisp_Object val; 1183 Lisp_Object val;
1183 int i, j, len = 0; 1184 int i, j, len;
1184 1185
1185 font_assert (FONTP (font)); 1186 font_assert (FONTP (font));
1186 1187
@@ -1195,9 +1196,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1195 if (NILP (val)) 1196 if (NILP (val))
1196 { 1197 {
1197 if (j == XLFD_REGISTRY_INDEX) 1198 if (j == XLFD_REGISTRY_INDEX)
1198 f[j] = "*-*", len += 4; 1199 f[j] = "*-*";
1199 else 1200 else
1200 f[j] = "*", len += 2; 1201 f[j] = "*";
1201 } 1202 }
1202 else 1203 else
1203 { 1204 {
@@ -1207,21 +1208,15 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1207 && ! strchr (SSDATA (val), '-')) 1208 && ! strchr (SSDATA (val), '-'))
1208 { 1209 {
1209 /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */ 1210 /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */
1210 if (SDATA (val)[SBYTES (val) - 1] == '*') 1211 ptrdiff_t alloc = SBYTES (val) + 4;
1211 { 1212 if (nbytes <= alloc)
1212 f[j] = p = alloca (SBYTES (val) + 3); 1213 return -1;
1213 sprintf (p, "%s-*", SDATA (val)); 1214 f[j] = p = alloca (alloc);
1214 len += SBYTES (val) + 3; 1215 sprintf (p, "%s%s-*", SDATA (val),
1215 } 1216 "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
1216 else
1217 {
1218 f[j] = p = alloca (SBYTES (val) + 4);
1219 sprintf (p, "%s*-*", SDATA (val));
1220 len += SBYTES (val) + 4;
1221 }
1222 } 1217 }
1223 else 1218 else
1224 f[j] = SSDATA (val), len += SBYTES (val) + 1; 1219 f[j] = SSDATA (val);
1225 } 1220 }
1226 } 1221 }
1227 1222
@@ -1230,11 +1225,11 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1230 { 1225 {
1231 val = font_style_symbolic (font, i, 0); 1226 val = font_style_symbolic (font, i, 0);
1232 if (NILP (val)) 1227 if (NILP (val))
1233 f[j] = "*", len += 2; 1228 f[j] = "*";
1234 else 1229 else
1235 { 1230 {
1236 val = SYMBOL_NAME (val); 1231 val = SYMBOL_NAME (val);
1237 f[j] = SSDATA (val), len += SBYTES (val) + 1; 1232 f[j] = SSDATA (val);
1238 } 1233 }
1239 } 1234 }
1240 1235
@@ -1242,64 +1237,62 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1242 font_assert (NUMBERP (val) || NILP (val)); 1237 font_assert (NUMBERP (val) || NILP (val));
1243 if (INTEGERP (val)) 1238 if (INTEGERP (val))
1244 { 1239 {
1245 i = XINT (val); 1240 EMACS_INT v = XINT (val);
1246 if (i <= 0) 1241 if (v <= 0)
1247 i = pixel_size; 1242 v = pixel_size;
1248 if (i > 0) 1243 if (v > 0)
1249 { 1244 {
1250 f[XLFD_PIXEL_INDEX] = p = alloca (22); 1245 f[XLFD_PIXEL_INDEX] = p =
1251 len += sprintf (p, "%d-*", i) + 1; 1246 alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
1247 sprintf (p, "%"pI"d-*", v);
1252 } 1248 }
1253 else 1249 else
1254 f[XLFD_PIXEL_INDEX] = "*-*", len += 4; 1250 f[XLFD_PIXEL_INDEX] = "*-*";
1255 } 1251 }
1256 else if (FLOATP (val)) 1252 else if (FLOATP (val))
1257 { 1253 {
1258 i = XFLOAT_DATA (val) * 10; 1254 double v = XFLOAT_DATA (val) * 10;
1259 f[XLFD_PIXEL_INDEX] = p = alloca (12); 1255 f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
1260 len += sprintf (p, "*-%d", i) + 1; 1256 sprintf (p, "*-%.0f", v);
1261 } 1257 }
1262 else 1258 else
1263 f[XLFD_PIXEL_INDEX] = "*-*", len += 4; 1259 f[XLFD_PIXEL_INDEX] = "*-*";
1264 1260
1265 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) 1261 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1266 { 1262 {
1267 i = XINT (AREF (font, FONT_DPI_INDEX)); 1263 EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
1268 f[XLFD_RESX_INDEX] = p = alloca (22); 1264 f[XLFD_RESX_INDEX] = p =
1269 len += sprintf (p, "%d-%d", i, i) + 1; 1265 alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
1266 sprintf (p, "%"pI"d-%"pI"d", v, v);
1270 } 1267 }
1271 else 1268 else
1272 f[XLFD_RESX_INDEX] = "*-*", len += 4; 1269 f[XLFD_RESX_INDEX] = "*-*";
1273 if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) 1270 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1274 { 1271 {
1275 int spacing = XINT (AREF (font, FONT_SPACING_INDEX)); 1272 EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
1276 1273
1277 f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p" 1274 f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
1278 : spacing <= FONT_SPACING_DUAL ? "d" 1275 : spacing <= FONT_SPACING_DUAL ? "d"
1279 : spacing <= FONT_SPACING_MONO ? "m" 1276 : spacing <= FONT_SPACING_MONO ? "m"
1280 : "c"); 1277 : "c");
1281 len += 2;
1282 } 1278 }
1283 else 1279 else
1284 f[XLFD_SPACING_INDEX] = "*", len += 2; 1280 f[XLFD_SPACING_INDEX] = "*";
1285 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) 1281 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1286 { 1282 {
1287 f[XLFD_AVGWIDTH_INDEX] = p = alloca (22); 1283 f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
1288 len += sprintf (p, "%"pI"d", 1284 sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
1289 XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
1290 } 1285 }
1291 else 1286 else
1292 f[XLFD_AVGWIDTH_INDEX] = "*", len += 2; 1287 f[XLFD_AVGWIDTH_INDEX] = "*";
1293 len++; /* for terminating '\0'. */ 1288 len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
1294 if (len >= nbytes)
1295 return -1;
1296 return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
1297 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], 1289 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
1298 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], 1290 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
1299 f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX], 1291 f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
1300 f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX], 1292 f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
1301 f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX], 1293 f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
1302 f[XLFD_REGISTRY_INDEX]); 1294 f[XLFD_REGISTRY_INDEX]);
1295 return len < nbytes ? len : -1;
1303} 1296}
1304 1297
1305/* Parse NAME (null terminated) and store information in FONT 1298/* Parse NAME (null terminated) and store information in FONT
@@ -1553,23 +1546,19 @@ int
1553font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) 1546font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1554{ 1547{
1555 Lisp_Object family, foundry; 1548 Lisp_Object family, foundry;
1556 Lisp_Object tail, val; 1549 Lisp_Object val;
1557 int point_size; 1550 int point_size;
1558 int i; 1551 int i;
1559 ptrdiff_t len = 1;
1560 char *p; 1552 char *p;
1553 char *lim;
1561 Lisp_Object styles[3]; 1554 Lisp_Object styles[3];
1562 const char *style_names[3] = { "weight", "slant", "width" }; 1555 const char *style_names[3] = { "weight", "slant", "width" };
1563 char work[256];
1564 1556
1565 family = AREF (font, FONT_FAMILY_INDEX); 1557 family = AREF (font, FONT_FAMILY_INDEX);
1566 if (! NILP (family)) 1558 if (! NILP (family))
1567 { 1559 {
1568 if (SYMBOLP (family)) 1560 if (SYMBOLP (family))
1569 { 1561 family = SYMBOL_NAME (family);
1570 family = SYMBOL_NAME (family);
1571 len += SBYTES (family);
1572 }
1573 else 1562 else
1574 family = Qnil; 1563 family = Qnil;
1575 } 1564 }
@@ -1580,7 +1569,6 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1580 if (XINT (val) != 0) 1569 if (XINT (val) != 0)
1581 pixel_size = XINT (val); 1570 pixel_size = XINT (val);
1582 point_size = -1; 1571 point_size = -1;
1583 len += 21; /* for ":pixelsize=NUM" */
1584 } 1572 }
1585 else 1573 else
1586 { 1574 {
@@ -1588,80 +1576,91 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1588 abort (); 1576 abort ();
1589 pixel_size = -1; 1577 pixel_size = -1;
1590 point_size = (int) XFLOAT_DATA (val); 1578 point_size = (int) XFLOAT_DATA (val);
1591 len += 11; /* for "-NUM" */
1592 } 1579 }
1593 1580
1594 foundry = AREF (font, FONT_FOUNDRY_INDEX); 1581 foundry = AREF (font, FONT_FOUNDRY_INDEX);
1595 if (! NILP (foundry)) 1582 if (! NILP (foundry))
1596 { 1583 {
1597 if (SYMBOLP (foundry)) 1584 if (SYMBOLP (foundry))
1598 { 1585 foundry = SYMBOL_NAME (foundry);
1599 foundry = SYMBOL_NAME (foundry);
1600 len += 9 + SBYTES (foundry); /* ":foundry=NAME" */
1601 }
1602 else 1586 else
1603 foundry = Qnil; 1587 foundry = Qnil;
1604 } 1588 }
1605 1589
1606 for (i = 0; i < 3; i++) 1590 for (i = 0; i < 3; i++)
1607 { 1591 styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
1608 styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
1609 if (! NILP (styles[i]))
1610 len += sprintf (work, ":%s=%s", style_names[i],
1611 SDATA (SYMBOL_NAME (styles[i])));
1612 }
1613
1614 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1615 len += sprintf (work, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
1616 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1617 len += strlen (":spacing=100");
1618 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1619 len += strlen (":scalable=false"); /* or ":scalable=true" */
1620 for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
1621 {
1622 Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail));
1623
1624 len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
1625 if (STRINGP (value))
1626 len += SBYTES (value);
1627 else if (INTEGERP (value))
1628 len += sprintf (work, "%"pI"d", XINT (value));
1629 else if (SYMBOLP (value))
1630 len += (NILP (value) ? 5 : 4); /* for "false" or "true" */
1631 }
1632 1592
1633 if (len > nbytes)
1634 return -1;
1635 p = name; 1593 p = name;
1594 lim = name + nbytes;
1636 if (! NILP (family)) 1595 if (! NILP (family))
1637 p += sprintf (p, "%s", SDATA (family)); 1596 {
1597 int len = snprintf (p, lim - p, "%s", SSDATA (family));
1598 if (! (0 <= len && len < lim - p))
1599 return -1;
1600 p += len;
1601 }
1638 if (point_size > 0) 1602 if (point_size > 0)
1639 { 1603 {
1640 if (p == name) 1604 int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
1641 p += sprintf (p, "%d", point_size); 1605 if (! (0 <= len && len < lim - p))
1642 else 1606 return -1;
1643 p += sprintf (p, "-%d", point_size); 1607 p += len;
1644 } 1608 }
1645 else if (pixel_size > 0) 1609 else if (pixel_size > 0)
1646 p += sprintf (p, ":pixelsize=%d", pixel_size); 1610 {
1611 int len = snprintf (p, lim - p, ":pixelsize=%d", pixel_size);
1612 if (! (0 <= len && len < lim - p))
1613 return -1;
1614 p += len;
1615 }
1647 if (! NILP (AREF (font, FONT_FOUNDRY_INDEX))) 1616 if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
1648 p += sprintf (p, ":foundry=%s", 1617 {
1649 SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX)))); 1618 int len = snprintf (p, lim - p, ":foundry=%s",
1619 SSDATA (SYMBOL_NAME (AREF (font,
1620 FONT_FOUNDRY_INDEX))));
1621 if (! (0 <= len && len < lim - p))
1622 return -1;
1623 p += len;
1624 }
1650 for (i = 0; i < 3; i++) 1625 for (i = 0; i < 3; i++)
1651 if (! NILP (styles[i])) 1626 if (! NILP (styles[i]))
1652 p += sprintf (p, ":%s=%s", style_names[i], 1627 {
1653 SDATA (SYMBOL_NAME (styles[i]))); 1628 int len = snprintf (p, lim - p, ":%s=%s", style_names[i],
1629 SSDATA (SYMBOL_NAME (styles[i])));
1630 if (! (0 <= len && len < lim - p))
1631 return -1;
1632 p += len;
1633 }
1634
1654 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) 1635 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1655 p += sprintf (p, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX))); 1636 {
1637 int len = snprintf (p, lim - p, ":dpi=%"pI"d",
1638 XINT (AREF (font, FONT_DPI_INDEX)));
1639 if (! (0 <= len && len < lim - p))
1640 return -1;
1641 p += len;
1642 }
1643
1656 if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) 1644 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1657 p += sprintf (p, ":spacing=%"pI"d", XINT (AREF (font, FONT_SPACING_INDEX))); 1645 {
1646 int len = snprintf (p, lim - p, ":spacing=%"pI"d",
1647 XINT (AREF (font, FONT_SPACING_INDEX)));
1648 if (! (0 <= len && len < lim - p))
1649 return -1;
1650 p += len;
1651 }
1652
1658 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) 1653 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1659 { 1654 {
1660 if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0) 1655 int len = snprintf (p, lim - p,
1661 p += sprintf (p, ":scalable=true"); 1656 (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
1662 else 1657 ? ":scalable=true"
1663 p += sprintf (p, ":scalable=false"); 1658 : ":scalable=false"));
1659 if (! (0 <= len && len < lim - p))
1660 return -1;
1661 p += len;
1664 } 1662 }
1663
1665 return (p - name); 1664 return (p - name);
1666} 1665}
1667 1666
@@ -1952,12 +1951,12 @@ generate_otf_features (Lisp_Object spec, char *features)
1952 else if (! asterisk) 1951 else if (! asterisk)
1953 { 1952 {
1954 val = SYMBOL_NAME (val); 1953 val = SYMBOL_NAME (val);
1955 p += sprintf (p, "%s", SDATA (val)); 1954 p += esprintf (p, "%s", SDATA (val));
1956 } 1955 }
1957 else 1956 else
1958 { 1957 {
1959 val = SYMBOL_NAME (val); 1958 val = SYMBOL_NAME (val);
1960 p += sprintf (p, "~%s", SDATA (val)); 1959 p += esprintf (p, "~%s", SDATA (val));
1961 } 1960 }
1962 } 1961 }
1963 if (CONSP (spec)) 1962 if (CONSP (spec))