aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/font.c423
1 files changed, 262 insertions, 161 deletions
diff --git a/src/font.c b/src/font.c
index 69d19068bc6..9986b0f48d0 100644
--- a/src/font.c
+++ b/src/font.c
@@ -51,17 +51,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
51#include "macterm.h" 51#include "macterm.h"
52#endif /* MAC_OS */ 52#endif /* MAC_OS */
53 53
54#ifndef FONT_DEBUG
55#define FONT_DEBUG
56#endif
57
58#ifdef FONT_DEBUG
59#undef xassert
60#define xassert(X) do {if (!(X)) abort ();} while (0)
61#else
62#define xassert(X) (void) 0
63#endif
64
65Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; 54Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
66 55
67Lisp_Object Qopentype; 56Lisp_Object Qopentype;
@@ -73,15 +62,68 @@ Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
73 font_driver *)->list when a specified font is not found. */ 62 font_driver *)->list when a specified font is not found. */
74static Lisp_Object null_vector; 63static Lisp_Object null_vector;
75 64
76/* Vector of 3 elements. Each element is a vector for one of font 65static Lisp_Object Vfont_weight_table, Vfont_slant_table, Vfont_width_table;
77 style properties (weight, slant, width). The vector contains a 66
78 mapping between symbolic property values (e.g. `medium' for weight) 67/* Vector of Vfont_weight_table, Vfont_slant_table, and Vfont_width_table. */
79 and numeric property values (e.g. 100). So, it looks like this:
80 [[(ultra-light . 20) ... (black . 210)]
81 [(reverse-oblique . 0) ... (oblique . 210)]
82 [(ultra-contains . 50) ... (wide . 200)]] */
83static Lisp_Object font_style_table; 68static Lisp_Object font_style_table;
84 69
70/* Structure used for tables mapping weight, slant, and width numeric
71 values and their names. */
72
73struct table_entry
74{
75 int numeric;
76 /* The first one is a valid name as a face attribute.
77 The second one (if any) is a typical name in XLFD field. */
78 char *names[5];
79 Lisp_Object *symbols;
80};
81
82/* Table of weight numeric values and their names. This table must be
83 sorted by numeric values in ascending order. */
84
85static struct table_entry weight_table[] =
86{
87 { 0, { "thin" }},
88 { 20, { "ultra-light", "ultralight" }},
89 { 40, { "extra-light", "extralight" }},
90 { 50, { "light" }},
91 { 75, { "semi-light", "semilight", "demilight", "book" }},
92 { 100, { "normal", "medium", "regular" }},
93 { 180, { "semi-bold", "semibold", "demibold", "demi" }},
94 { 200, { "bold" }},
95 { 205, { "extra-bold", "extrabold" }},
96 { 210, { "ultra-bold", "ultrabold", "black" }}
97};
98
99/* Table of slant numeric values and their names. This table must be
100 sorted by numeric values in ascending order. */
101
102static struct table_entry slant_table[] =
103{
104 { 0, { "reverse-oblique", "ro" }},
105 { 10, { "reverse-italic", "ri" }},
106 { 100, { "normal", "r" }},
107 { 200, { "italic" ,"i", "ot" }},
108 { 210, { "oblique", "o" }}
109};
110
111/* Table of width numeric values and their names. This table must be
112 sorted by numeric values in ascending order. */
113
114static struct table_entry width_table[] =
115{
116 { 50, { "ultra-condensed", "ultracondensed" }},
117 { 63, { "extra-condensed", "extracondensed" }},
118 { 75, { "condensed", "compressed", "narrow" }},
119 { 87, { "semi-condensed", "semicondensed", "demicondensed" }},
120 { 100, { "normal", "medium", "regular" }},
121 { 113, { "semi-expanded", "semiexpanded", "demiexpanded" }},
122 { 125, { "expanded" }},
123 { 150, { "extra-expanded", "extraexpanded" }},
124 { 200, { "ultra-expanded", "ultraexpanded", "wide" }}
125};
126
85extern Lisp_Object Qnormal; 127extern Lisp_Object Qnormal;
86 128
87/* Symbols representing keys of normal font properties. */ 129/* Symbols representing keys of normal font properties. */
@@ -180,7 +222,7 @@ font_intern_prop (str, len)
180 int len; 222 int len;
181{ 223{
182 int i; 224 int i;
183 Lisp_Object tem, string; 225 Lisp_Object tem;
184 Lisp_Object obarray; 226 Lisp_Object obarray;
185 227
186 if (len == 1 && *str == '*') 228 if (len == 1 && *str == '*')
@@ -215,13 +257,13 @@ font_pixel_size (f, spec)
215 Lisp_Object size = AREF (spec, FONT_SIZE_INDEX); 257 Lisp_Object size = AREF (spec, FONT_SIZE_INDEX);
216 double point_size; 258 double point_size;
217 int dpi, pixel_size; 259 int dpi, pixel_size;
218 Lisp_Object extra, val; 260 Lisp_Object val;
219 261
220 if (INTEGERP (size)) 262 if (INTEGERP (size))
221 return XINT (size); 263 return XINT (size);
222 if (NILP (size)) 264 if (NILP (size))
223 return 0; 265 return 0;
224 xassert (FLOATP (size)); 266 font_assert (FLOATP (size));
225 point_size = XFLOAT_DATA (size); 267 point_size = XFLOAT_DATA (size);
226 val = AREF (spec, FONT_DPI_INDEX); 268 val = AREF (spec, FONT_DPI_INDEX);
227 if (INTEGERP (val)) 269 if (INTEGERP (val))
@@ -251,7 +293,7 @@ font_style_to_value (prop, val, noerror)
251{ 293{
252 Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); 294 Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
253 int len = ASIZE (table); 295 int len = ASIZE (table);
254 int i; 296 int i, j;
255 297
256 if (SYMBOLP (val)) 298 if (SYMBOLP (val))
257 { 299 {
@@ -260,50 +302,54 @@ font_style_to_value (prop, val, noerror)
260 302
261 /* At first try exact match. */ 303 /* At first try exact match. */
262 for (i = 0; i < len; i++) 304 for (i = 0; i < len; i++)
263 if (EQ (val, XCAR (AREF (table, i)))) 305 for (j = 1; j < ASIZE (AREF (table, i)); j++)
264 return (XINT (XCDR (AREF (table, i))) << 8) | i; 306 if (EQ (val, AREF (AREF (table, i), j)))
307 return ((XINT (AREF (AREF (table, i), 0)) << 8)
308 | (i << 4) | (j - 1));
265 /* Try also with case-folding match. */ 309 /* Try also with case-folding match. */
266 s = SDATA (SYMBOL_NAME (val)); 310 s = (char *) SDATA (SYMBOL_NAME (val));
267 for (i = 0; i < len; i++) 311 for (i = 0; i < len; i++)
268 { 312 for (j = 1; j < ASIZE (AREF (table, i)); j++)
269 elt = XCAR (AREF (table, i)); 313 {
270 if (strcasecmp (s, (char *) SDATA (SYMBOL_NAME (elt))) == 0) 314 elt = AREF (AREF (table, i), j);
271 return i; 315 if (strcasecmp (s, (char *) SDATA (SYMBOL_NAME (elt))) == 0)
272 } 316 return ((XINT (AREF (AREF (table, i), 0)) << 8)
317 | (i << 4) | (j - 1));
318 }
273 if (! noerror) 319 if (! noerror)
274 return -1; 320 return -1;
275 if (len == 255) 321 if (len == 255)
276 abort (); 322 abort ();
323 elt = Fmake_vector (make_number (2), make_number (255));
324 ASET (elt, 1, val);
277 args[0] = table; 325 args[0] = table;
278 args[1] = Fmake_vector (make_number (1), Fcons (val, make_number (255))); 326 args[1] = Fmake_vector (make_number (1), elt);
279 ASET (font_style_table, prop - FONT_WEIGHT_INDEX, Fvconcat (2, args)); 327 ASET (font_style_table, prop - FONT_WEIGHT_INDEX, Fvconcat (2, args));
280 return (255 << 8) | i; 328 return (255 << 8) | (i << 4);
281 } 329 }
282 else 330 else
283 { 331 {
284 int last_i, i, last_n; 332 int i, last_n;
285 int numeric = XINT (val); 333 int numeric = XINT (val);
286 334
287 for (i = 1, last_i = last_n = -1; i < len;) 335 for (i = 0, last_n = -1; i < len; i++)
288 { 336 {
289 int n = XINT (XCDR (AREF (table, i))); 337 int n = XINT (AREF (AREF (table, i), 0));
290 338
291 if (numeric == n) 339 if (numeric == n)
292 return (n << 8) | i; 340 return (n << 8) | (i << 4);
293 if (numeric < n) 341 if (numeric < n)
294 { 342 {
295 if (! noerror) 343 if (! noerror)
296 return -1; 344 return -1;
297 return ((last_i < 0 || n - numeric < numeric - last_n) 345 return ((i == 0 || n - numeric < numeric - last_n)
298 ? (n << 8) | i : (last_n << 8 | last_i)); 346 ? (n << 8) | (i << 4): (last_n << 8 | ((i - 1) << 4)));
299 } 347 }
300 last_i = i;
301 last_n = n; 348 last_n = n;
302 for (i++; i < len && n == XINT (XCDR (AREF (table, i + 1))); i++);
303 } 349 }
304 if (! noerror) 350 if (! noerror)
305 return -1; 351 return -1;
306 return (last_n << 8) | last_i; 352 return ((last_n << 8) | ((i - 1) << 4));
307 } 353 }
308} 354}
309 355
@@ -314,20 +360,17 @@ font_style_symbolic (font, prop, for_face)
314 int for_face; 360 int for_face;
315{ 361{
316 Lisp_Object val = AREF (font, prop); 362 Lisp_Object val = AREF (font, prop);
317 Lisp_Object table; 363 Lisp_Object table, elt;
318 int i, numeric; 364 int i;
319 365
320 if (NILP (val)) 366 if (NILP (val))
321 return Qnil; 367 return Qnil;
322 table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); 368 table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
323 if (! for_face) 369 i = XINT (val) & 0xFF;
324 return XCAR (AREF (table, XINT (val) & 0xFF)); 370 font_assert (((i >> 4) & 0xF) < ASIZE (table));
325 numeric = XINT (val) >> 8; 371 elt = AREF (table, ((i >> 4) & 0xF));
326 for (i = 0; i < ASIZE (table); i++) 372 font_assert ((i & 0xF) + 1 < ASIZE (elt));
327 if (XINT (XCDR (AREF (table, i))) == numeric) 373 return (for_face ? AREF (elt, 1) : AREF (elt, (i & 0xF) + 1));
328 return XCAR (AREF (table, i));
329 abort ();
330 return Qnil;
331} 374}
332 375
333extern Lisp_Object Vface_alternative_font_family_alist; 376extern Lisp_Object Vface_alternative_font_family_alist;
@@ -996,7 +1039,6 @@ font_parse_xlfd (name, font)
996 { 1039 {
997 /* Fully specified XLFD. */ 1040 /* Fully specified XLFD. */
998 int pixel_size; 1041 int pixel_size;
999 int spacing_char;
1000 1042
1001 ASET (font, FONT_FOUNDRY_INDEX, INTERN_FIELD (XLFD_FOUNDRY_INDEX)); 1043 ASET (font, FONT_FOUNDRY_INDEX, INTERN_FIELD (XLFD_FOUNDRY_INDEX));
1002 ASET (font, FONT_FAMILY_INDEX, INTERN_FIELD (XLFD_FAMILY_INDEX)); 1044 ASET (font, FONT_FAMILY_INDEX, INTERN_FIELD (XLFD_FAMILY_INDEX));
@@ -1030,7 +1072,7 @@ font_parse_xlfd (name, font)
1030 { 1072 {
1031 double point_size = -1; 1073 double point_size = -1;
1032 1074
1033 xassert (FONT_SPEC_P (font)); 1075 font_assert (FONT_SPEC_P (font));
1034 p = f[XLFD_POINT_INDEX]; 1076 p = f[XLFD_POINT_INDEX];
1035 if (*p == '[') 1077 if (*p == '[')
1036 point_size = parse_matrix (p); 1078 point_size = parse_matrix (p);
@@ -1149,7 +1191,7 @@ font_unparse_xlfd (font, pixel_size, name, nbytes)
1149 Lisp_Object val; 1191 Lisp_Object val;
1150 int i, j, len = 0; 1192 int i, j, len = 0;
1151 1193
1152 xassert (FONTP (font)); 1194 font_assert (FONTP (font));
1153 1195
1154 for (i = FONT_FOUNDRY_INDEX, j = XLFD_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; 1196 for (i = FONT_FOUNDRY_INDEX, j = XLFD_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX;
1155 i++, j++) 1197 i++, j++)
@@ -1206,7 +1248,7 @@ font_unparse_xlfd (font, pixel_size, name, nbytes)
1206 } 1248 }
1207 1249
1208 val = AREF (font, FONT_SIZE_INDEX); 1250 val = AREF (font, FONT_SIZE_INDEX);
1209 xassert (NUMBERP (val) || NILP (val)); 1251 font_assert (NUMBERP (val) || NILP (val));
1210 if (INTEGERP (val)) 1252 if (INTEGERP (val))
1211 { 1253 {
1212 i = XINT (val); 1254 i = XINT (val);
@@ -1400,7 +1442,7 @@ font_unparse_fcname (font, pixel_size, name, nbytes)
1400{ 1442{
1401 Lisp_Object tail, val; 1443 Lisp_Object tail, val;
1402 int point_size; 1444 int point_size;
1403 int dpi, spacing, avgwidth; 1445 int dpi;
1404 int i, len = 1; 1446 int i, len = 1;
1405 char *p; 1447 char *p;
1406 Lisp_Object styles[3]; 1448 Lisp_Object styles[3];
@@ -1433,8 +1475,6 @@ font_unparse_fcname (font, pixel_size, name, nbytes)
1433 1475
1434 for (i = 0; i < 3; i++) 1476 for (i = 0; i < 3; i++)
1435 { 1477 {
1436 int this_len;
1437
1438 styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0); 1478 styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
1439 if (! NILP (styles[i])) 1479 if (! NILP (styles[i]))
1440 len += sprintf (work, ":%s=%s", style_names[i], 1480 len += sprintf (work, ":%s=%s", style_names[i],
@@ -1521,7 +1561,8 @@ font_parse_family_registry (family, registry, font_spec)
1521 int len; 1561 int len;
1522 char *p0, *p1; 1562 char *p0, *p1;
1523 1563
1524 if (! NILP (family)) 1564 if (! NILP (family)
1565 && NILP (AREF (font_spec, FONT_FAMILY_INDEX)))
1525 { 1566 {
1526 CHECK_STRING (family); 1567 CHECK_STRING (family);
1527 len = SBYTES (family); 1568 len = SBYTES (family);
@@ -1529,7 +1570,8 @@ font_parse_family_registry (family, registry, font_spec)
1529 p1 = index (p0, '-'); 1570 p1 = index (p0, '-');
1530 if (p1) 1571 if (p1)
1531 { 1572 {
1532 if (*p0 != '*' || p1 - p0 > 1) 1573 if ((*p0 != '*' || p1 - p0 > 1)
1574 && NILP (AREF (font_spec, FONT_FOUNDRY_INDEX)))
1533 ASET (font_spec, FONT_FOUNDRY_INDEX, 1575 ASET (font_spec, FONT_FOUNDRY_INDEX,
1534 font_intern_prop (p0, p1 - p0)); 1576 font_intern_prop (p0, p1 - p0));
1535 p1++; 1577 p1++;
@@ -1936,7 +1978,7 @@ font_score (entity, spec_prop, alternate_families)
1936 Lisp_Object entity_str = SYMBOL_NAME (AREF (entity, i)); 1978 Lisp_Object entity_str = SYMBOL_NAME (AREF (entity, i));
1937 Lisp_Object spec_str = SYMBOL_NAME (spec_prop[i]); 1979 Lisp_Object spec_str = SYMBOL_NAME (spec_prop[i]);
1938 1980
1939 if (strcasecmp (SDATA (spec_str), SDATA (entity_str))) 1981 if (strcasecmp ((char *) SDATA (spec_str), (char *) SDATA (entity_str)))
1940 { 1982 {
1941 if (i == FONT_FAMILY_INDEX && CONSP (alternate_families)) 1983 if (i == FONT_FAMILY_INDEX && CONSP (alternate_families))
1942 { 1984 {
@@ -1946,7 +1988,8 @@ font_score (entity, spec_prop, alternate_families)
1946 j++, alternate_families = XCDR (alternate_families)) 1988 j++, alternate_families = XCDR (alternate_families))
1947 { 1989 {
1948 spec_str = XCAR (alternate_families); 1990 spec_str = XCAR (alternate_families);
1949 if (strcasecmp (SDATA (spec_str), SDATA (entity_str)) == 0) 1991 if (strcasecmp ((char *) SDATA (spec_str),
1992 (char *) SDATA (entity_str)) == 0)
1950 break; 1993 break;
1951 1994
1952 } 1995 }
@@ -1983,7 +2026,7 @@ font_score (entity, spec_prop, alternate_families)
1983 2026
1984 if (diff < 0) 2027 if (diff < 0)
1985 diff = - diff; 2028 diff = - diff;
1986 diff << 1; 2029 diff <<= 1;
1987 if (! NILP (spec_prop[FONT_DPI_INDEX]) 2030 if (! NILP (spec_prop[FONT_DPI_INDEX])
1988 && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX))) 2031 && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX)))
1989 diff |= 1; 2032 diff |= 1;
@@ -2093,6 +2136,7 @@ font_sort_entites (vec, prefer, frame, spec, best_only)
2093 vec = best_entity; 2136 vec = best_entity;
2094 SAFE_FREE (); 2137 SAFE_FREE ();
2095 2138
2139 font_add_log ("sort-by", prefer, vec);
2096 return vec; 2140 return vec;
2097} 2141}
2098 2142
@@ -2133,7 +2177,6 @@ font_match_p (spec, entity)
2133{ 2177{
2134 Lisp_Object prefer_prop[FONT_SPEC_MAX]; 2178 Lisp_Object prefer_prop[FONT_SPEC_MAX];
2135 Lisp_Object alternate_families = Qnil; 2179 Lisp_Object alternate_families = Qnil;
2136 int prefer_style[3];
2137 int i; 2180 int i;
2138 2181
2139 for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++) 2182 for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++)
@@ -2229,7 +2272,7 @@ font_finish_cache (f, driver)
2229 val = XCDR (cache); 2272 val = XCDR (cache);
2230 while (CONSP (val) && ! EQ (XCAR (XCAR (val)), driver->type)) 2273 while (CONSP (val) && ! EQ (XCAR (XCAR (val)), driver->type))
2231 cache = val, val = XCDR (val); 2274 cache = val, val = XCDR (val);
2232 xassert (! NILP (val)); 2275 font_assert (! NILP (val));
2233 tmp = XCDR (XCAR (val)); 2276 tmp = XCDR (XCAR (val));
2234 XSETCAR (tmp, make_number (XINT (XCAR (tmp)) - 1)); 2277 XSETCAR (tmp, make_number (XINT (XCAR (tmp)) - 1));
2235 if (XINT (XCAR (tmp)) == 0) 2278 if (XINT (XCAR (tmp)) == 0)
@@ -2248,9 +2291,9 @@ font_get_cache (f, driver)
2248 Lisp_Object val = driver->get_cache (f); 2291 Lisp_Object val = driver->get_cache (f);
2249 Lisp_Object type = driver->type; 2292 Lisp_Object type = driver->type;
2250 2293
2251 xassert (CONSP (val)); 2294 font_assert (CONSP (val));
2252 for (val = XCDR (val); ! EQ (XCAR (XCAR (val)), type); val = XCDR (val)); 2295 for (val = XCDR (val); ! EQ (XCAR (XCAR (val)), type); val = XCDR (val));
2253 xassert (CONSP (val)); 2296 font_assert (CONSP (val));
2254 /* VAL = ((DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...) ...) */ 2297 /* VAL = ((DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...) ...) */
2255 val = XCDR (XCAR (val)); 2298 val = XCDR (XCAR (val));
2256 return val; 2299 return val;
@@ -2288,7 +2331,7 @@ font_clear_cache (f, cache, driver)
2288 Lisp_Object val = XCAR (objlist); 2331 Lisp_Object val = XCAR (objlist);
2289 struct font *font = XFONT_OBJECT (val); 2332 struct font *font = XFONT_OBJECT (val);
2290 2333
2291 xassert (font && driver == font->driver); 2334 font_assert (font && driver == font->driver);
2292 driver->close (f, font); 2335 driver->close (f, font);
2293 num_fonts--; 2336 num_fonts--;
2294 } 2337 }
@@ -2309,12 +2352,12 @@ font_delete_unmatched (list, spec, size)
2309 Lisp_Object list, spec; 2352 Lisp_Object list, spec;
2310 int size; 2353 int size;
2311{ 2354{
2312 Lisp_Object entity, prev, tail; 2355 Lisp_Object entity, val;
2313 enum font_property_index prop; 2356 enum font_property_index prop;
2314 2357
2315 for (tail = list, prev = Qnil; CONSP (tail); ) 2358 for (val = Qnil; CONSP (list); list = XCDR (list))
2316 { 2359 {
2317 entity = XCAR (tail); 2360 entity = XCAR (list);
2318 for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) 2361 for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++)
2319 if (INTEGERP (AREF (spec, prop)) 2362 if (INTEGERP (AREF (spec, prop))
2320 && ((XINT (AREF (spec, prop)) >> 8) 2363 && ((XINT (AREF (spec, prop)) >> 8)
@@ -2337,13 +2380,9 @@ font_delete_unmatched (list, spec, size)
2337 AREF (entity, FONT_SPACING_INDEX))) 2380 AREF (entity, FONT_SPACING_INDEX)))
2338 prop = FONT_SPEC_MAX; 2381 prop = FONT_SPEC_MAX;
2339 if (prop < FONT_SPEC_MAX) 2382 if (prop < FONT_SPEC_MAX)
2340 prev = tail, tail = XCDR (tail); 2383 val = Fcons (entity, val);
2341 else if (NILP (prev))
2342 list = tail = XCDR (tail);
2343 else
2344 tail = XCDR (tail), XSETCDR (prev, tail);
2345 } 2384 }
2346 return list; 2385 return val;
2347} 2386}
2348 2387
2349 2388
@@ -2355,14 +2394,14 @@ font_list_entities (frame, spec)
2355{ 2394{
2356 FRAME_PTR f = XFRAME (frame); 2395 FRAME_PTR f = XFRAME (frame);
2357 struct font_driver_list *driver_list = f->font_driver_list; 2396 struct font_driver_list *driver_list = f->font_driver_list;
2358 Lisp_Object ftype, family, alternate_familes; 2397 Lisp_Object ftype, family, alternate_familes, val;
2359 Lisp_Object *vec; 2398 Lisp_Object *vec;
2360 int size; 2399 int size;
2361 int need_filtering = 0; 2400 int need_filtering = 0;
2362 int n_family = 1; 2401 int n_family = 1;
2363 int i; 2402 int i;
2364 2403
2365 xassert (FONT_SPEC_P (spec)); 2404 font_assert (FONT_SPEC_P (spec));
2366 2405
2367 family = AREF (spec, FONT_FAMILY_INDEX); 2406 family = AREF (spec, FONT_FAMILY_INDEX);
2368 if (NILP (family)) 2407 if (NILP (family))
@@ -2408,8 +2447,7 @@ font_list_entities (frame, spec)
2408 2447
2409 while (1) 2448 while (1)
2410 { 2449 {
2411 Lisp_Object val = assoc_no_quit (scratch_font_spec, XCDR (cache)); 2450 val = assoc_no_quit (scratch_font_spec, XCDR (cache));
2412
2413 if (CONSP (val)) 2451 if (CONSP (val))
2414 val = XCDR (val); 2452 val = XCDR (val);
2415 else 2453 else
@@ -2417,11 +2455,11 @@ font_list_entities (frame, spec)
2417 Lisp_Object copy; 2455 Lisp_Object copy;
2418 2456
2419 val = driver_list->driver->list (frame, scratch_font_spec); 2457 val = driver_list->driver->list (frame, scratch_font_spec);
2420 if (! NILP (val) && need_filtering)
2421 val = font_delete_unmatched (val, spec, size);
2422 copy = Fcopy_font_spec (scratch_font_spec); 2458 copy = Fcopy_font_spec (scratch_font_spec);
2423 XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); 2459 XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
2424 } 2460 }
2461 if (! NILP (val) && need_filtering)
2462 val = font_delete_unmatched (val, spec, size);
2425 if (! NILP (val)) 2463 if (! NILP (val))
2426 { 2464 {
2427 vec[i++] = val; 2465 vec[i++] = val;
@@ -2435,7 +2473,9 @@ font_list_entities (frame, spec)
2435 } 2473 }
2436 } 2474 }
2437 2475
2438 return (i > 0 ? Fvconcat (i, vec) : null_vector); 2476 val = (i > 0 ? Fvconcat (i, vec) : null_vector);
2477 font_add_log ("list", spec, val);
2478 return (val);
2439} 2479}
2440 2480
2441 2481
@@ -2481,6 +2521,7 @@ font_matching_entity (f, attrs, spec)
2481 } 2521 }
2482 ASET (spec, FONT_TYPE_INDEX, ftype); 2522 ASET (spec, FONT_TYPE_INDEX, ftype);
2483 ASET (spec, FONT_SIZE_INDEX, size); 2523 ASET (spec, FONT_SIZE_INDEX, size);
2524 font_add_log ("match", spec, entity);
2484 return entity; 2525 return entity;
2485} 2526}
2486 2527
@@ -2499,7 +2540,7 @@ font_open_entity (f, entity, pixel_size)
2499 struct font *font; 2540 struct font *font;
2500 int min_width; 2541 int min_width;
2501 2542
2502 xassert (FONT_ENTITY_P (entity)); 2543 font_assert (FONT_ENTITY_P (entity));
2503 size = AREF (entity, FONT_SIZE_INDEX); 2544 size = AREF (entity, FONT_SIZE_INDEX);
2504 if (XINT (size) != 0) 2545 if (XINT (size) != 0)
2505 pixel_size = XINT (size); 2546 pixel_size = XINT (size);
@@ -2517,6 +2558,7 @@ font_open_entity (f, entity, pixel_size)
2517 return Qnil; 2558 return Qnil;
2518 2559
2519 font_object = driver_list->driver->open (f, entity, pixel_size); 2560 font_object = driver_list->driver->open (f, entity, pixel_size);
2561 font_add_log ("open", entity, font_object);
2520 if (NILP (font_object)) 2562 if (NILP (font_object))
2521 return Qnil; 2563 return Qnil;
2522 ASET (entity, FONT_OBJLIST_INDEX, 2564 ASET (entity, FONT_OBJLIST_INDEX,
@@ -2566,9 +2608,10 @@ font_close_object (f, font_object)
2566 prev = tail, tail = XCDR (tail)) 2608 prev = tail, tail = XCDR (tail))
2567 if (EQ (font_object, XCAR (tail))) 2609 if (EQ (font_object, XCAR (tail)))
2568 { 2610 {
2611 font_add_log ("close", font_object, Qnil);
2569 font->driver->close (f, font); 2612 font->driver->close (f, font);
2570#ifdef HAVE_WINDOW_SYSTEM 2613#ifdef HAVE_WINDOW_SYSTEM
2571 xassert (FRAME_X_DISPLAY_INFO (f)->n_fonts); 2614 font_assert (FRAME_X_DISPLAY_INFO (f)->n_fonts);
2572 FRAME_X_DISPLAY_INFO (f)->n_fonts--; 2615 FRAME_X_DISPLAY_INFO (f)->n_fonts--;
2573#endif 2616#endif
2574 if (NILP (prev)) 2617 if (NILP (prev))
@@ -2608,7 +2651,7 @@ font_has_char (f, font, c)
2608 return driver_list->driver->has_char (font, c); 2651 return driver_list->driver->has_char (font, c);
2609 } 2652 }
2610 2653
2611 xassert (FONT_OBJECT_P (font)); 2654 font_assert (FONT_OBJECT_P (font));
2612 fontp = XFONT_OBJECT (font); 2655 fontp = XFONT_OBJECT (font);
2613 if (fontp->driver->has_char) 2656 if (fontp->driver->has_char)
2614 { 2657 {
@@ -2630,7 +2673,7 @@ font_encode_char (font_object, c)
2630{ 2673{
2631 struct font *font; 2674 struct font *font;
2632 2675
2633 xassert (FONT_OBJECT_P (font_object)); 2676 font_assert (FONT_OBJECT_P (font_object));
2634 font = XFONT_OBJECT (font_object); 2677 font = XFONT_OBJECT (font_object);
2635 return font->driver->encode_char (font, c); 2678 return font->driver->encode_char (font, c);
2636} 2679}
@@ -2642,9 +2685,7 @@ Lisp_Object
2642font_get_name (font_object) 2685font_get_name (font_object)
2643 Lisp_Object font_object; 2686 Lisp_Object font_object;
2644{ 2687{
2645 Lisp_Object name; 2688 font_assert (FONT_OBJECT_P (font_object));
2646
2647 xassert (FONT_OBJECT_P (font_object));
2648 return AREF (font_object, FONT_NAME_INDEX); 2689 return AREF (font_object, FONT_NAME_INDEX);
2649} 2690}
2650 2691
@@ -2683,7 +2724,6 @@ font_clear_prop (attrs, prop)
2683 enum font_property_index prop; 2724 enum font_property_index prop;
2684{ 2725{
2685 Lisp_Object font = attrs[LFACE_FONT_INDEX]; 2726 Lisp_Object font = attrs[LFACE_FONT_INDEX];
2686 Lisp_Object extra, prev;
2687 2727
2688 if (! FONTP (font)) 2728 if (! FONTP (font))
2689 return; 2729 return;
@@ -2715,8 +2755,7 @@ font_update_lface (f, attrs)
2715 FRAME_PTR f; 2755 FRAME_PTR f;
2716 Lisp_Object *attrs; 2756 Lisp_Object *attrs;
2717{ 2757{
2718 Lisp_Object spec, val; 2758 Lisp_Object spec;
2719 int n;
2720 2759
2721 spec = attrs[LFACE_FONT_INDEX]; 2760 spec = attrs[LFACE_FONT_INDEX];
2722 if (! FONT_SPEC_P (spec)) 2761 if (! FONT_SPEC_P (spec))
@@ -2816,7 +2855,7 @@ font_find_for_lface (f, attrs, spec, c)
2816 { 2855 {
2817 /* Sort fonts by properties specified in LFACE. */ 2856 /* Sort fonts by properties specified in LFACE. */
2818 Lisp_Object prefer = scratch_font_prefer; 2857 Lisp_Object prefer = scratch_font_prefer;
2819 double pt; 2858
2820 for (i = 0; i < FONT_EXTRA_INDEX; i++) 2859 for (i = 0; i < FONT_EXTRA_INDEX; i++)
2821 ASET (prefer, i, AREF (spec, i)); 2860 ASET (prefer, i, AREF (spec, i));
2822 if (FONTP (attrs[LFACE_FONT_INDEX])) 2861 if (FONTP (attrs[LFACE_FONT_INDEX]))
@@ -3252,7 +3291,7 @@ font_at (c, pos, face, w, string)
3252 if (! face->font) 3291 if (! face->font)
3253 return Qnil; 3292 return Qnil;
3254 3293
3255 xassert (font_check_object ((struct font *) face->font)); 3294 font_assert (font_check_object ((struct font *) face->font));
3256 XSETFONT (font_object, face->font); 3295 XSETFONT (font_object, face->font);
3257 return font_object; 3296 return font_object;
3258} 3297}
@@ -3490,7 +3529,6 @@ DEFUN ("font-put", Ffont_put, Sfont_put, 3, 3, 0,
3490 Lisp_Object font_spec, prop, val; 3529 Lisp_Object font_spec, prop, val;
3491{ 3530{
3492 int idx; 3531 int idx;
3493 Lisp_Object extra, slot;
3494 3532
3495 CHECK_FONT_SPEC (font_spec); 3533 CHECK_FONT_SPEC (font_spec);
3496 idx = get_font_prop_index (prop); 3534 idx = get_font_prop_index (prop);
@@ -3605,12 +3643,14 @@ Optional 2nd argument FRAME, if non-nil, specifies the target frame. */)
3605 return val; 3643 return val;
3606} 3644}
3607 3645
3608DEFUN ("font-xlfd-name", Ffont_xlfd_name, Sfont_xlfd_name, 1, 1, 0, 3646DEFUN ("font-xlfd-name", Ffont_xlfd_name, Sfont_xlfd_name, 1, 2, 0,
3609 doc: /* Return XLFD name of FONT. 3647 doc: /* Return XLFD name of FONT.
3610FONT is a font-spec, font-entity, or font-object. 3648FONT is a font-spec, font-entity, or font-object.
3611If the name is too long for XLFD (maximum 255 chars), return nil. */) 3649If the name is too long for XLFD (maximum 255 chars), return nil.
3612 (font) 3650If the 2nd optional arg FOLD-WILDCARDS is non-nil,
3613 Lisp_Object font; 3651the consecutive wildcards are folded to one. */)
3652 (font, fold_wildcards)
3653 Lisp_Object font, fold_wildcards;
3614{ 3654{
3615 char name[256]; 3655 char name[256];
3616 int pixel_size = 0; 3656 int pixel_size = 0;
@@ -3623,11 +3663,28 @@ If the name is too long for XLFD (maximum 255 chars), return nil. */)
3623 3663
3624 if (STRINGP (font_name) 3664 if (STRINGP (font_name)
3625 && SDATA (font_name)[0] == '-') 3665 && SDATA (font_name)[0] == '-')
3626 return font_name; 3666 {
3667 if (NILP (fold_wildcards))
3668 return font_name;
3669 strcpy (name, (char *) SDATA (font_name));
3670 goto done;
3671 }
3627 pixel_size = XFONT_OBJECT (font)->pixel_size; 3672 pixel_size = XFONT_OBJECT (font)->pixel_size;
3628 } 3673 }
3629 if (font_unparse_xlfd (font, pixel_size, name, 256) < 0) 3674 if (font_unparse_xlfd (font, pixel_size, name, 256) < 0)
3630 return Qnil; 3675 return Qnil;
3676 done:
3677 if (! NILP (fold_wildcards))
3678 {
3679 char *p0 = name, *p1;
3680
3681 while ((p1 = strstr (p0, "-*-*")))
3682 {
3683 strcpy (p1, p1 + 2);
3684 p0 = p1;
3685 }
3686 }
3687
3631 return build_string (name); 3688 return build_string (name);
3632} 3689}
3633 3690
@@ -3652,7 +3709,7 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
3652 while (! NILP (val) 3709 while (! NILP (val)
3653 && ! EQ (XCAR (XCAR (val)), driver_list->driver->type)) 3710 && ! EQ (XCAR (XCAR (val)), driver_list->driver->type))
3654 val = XCDR (val); 3711 val = XCDR (val);
3655 xassert (! NILP (val)); 3712 font_assert (! NILP (val));
3656 val = XCDR (XCAR (val)); 3713 val = XCDR (XCAR (val));
3657 if (XINT (XCAR (val)) == 0) 3714 if (XINT (XCAR (val)) == 0)
3658 { 3715 {
@@ -3665,60 +3722,7 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
3665 return Qnil; 3722 return Qnil;
3666} 3723}
3667 3724
3668DEFUN ("internal-set-font-style-table", Finternal_set_font_style_table, 3725/* The following three functions are still expremental. */
3669 Sinternal_set_font_style_table, 3, 3, 0,
3670 doc: /* Setup font style table from WEIGHT, SLANT, and WIDTH tables.
3671WEIGHT, SLANT, WIDTH must be `font-weight-table', `font-slant-table',
3672`font-width-table' respectivly.
3673This function is called after those tables are initialized. */)
3674 (weight, slant, width)
3675 Lisp_Object weight, slant, width;
3676{
3677 Lisp_Object tables[3];
3678 int i;
3679
3680 tables[0] = weight, tables[1] = slant, tables[2] = width;
3681
3682 font_style_table = Fmake_vector (make_number (3), Qnil);
3683 /* In the following loop, we don't use XCAR and XCDR until assuring
3684 the argument is a cons cell so that the error in the tables can
3685 be detected. */
3686 for (i = 0; i < 3; i++)
3687 {
3688 Lisp_Object tail, elt, list, val;
3689
3690 for (tail = tables[i], list = Qnil; CONSP (tail); tail = XCDR (tail))
3691 {
3692 int numeric = -1;
3693
3694 elt = Fcar (tail);
3695 CHECK_SYMBOL (Fcar (elt));
3696 val = Fcons (XCAR (elt), Qnil);
3697 elt = XCDR (elt);
3698 CHECK_NATNUM (Fcar (elt));
3699 if (numeric >= XINT (XCAR (elt)))
3700 error ("Numeric values not unique nor sorted in %s",
3701 (i == 0 ? "font-weight-table"
3702 : i == 1 ? "font-slant-table"
3703 : "font-width-table"));
3704 numeric = XINT (XCAR (elt));
3705 XSETCDR (val, XCAR (elt));
3706 list = Fcons (val, list);
3707 for (elt = XCDR (elt); CONSP (elt); elt = XCDR (elt))
3708 {
3709 val = XCAR (elt);
3710 CHECK_SYMBOL (val);
3711 list = Fcons (Fcons (XCAR (elt), make_number (numeric)), list);
3712 }
3713 }
3714 list = Fnreverse (list);
3715 ASET (font_style_table, i, Fvconcat (1, &list));
3716 }
3717
3718 return Qnil;
3719}
3720
3721/* The following three functions are still experimental. */
3722 3726
3723DEFUN ("font-make-gstring", Ffont_make_gstring, Sfont_make_gstring, 2, 2, 0, 3727DEFUN ("font-make-gstring", Ffont_make_gstring, Sfont_make_gstring, 2, 2, 0,
3724 doc: /* Return a newly created g-string for FONT-OBJECT with NUM glyphs. 3728 doc: /* Return a newly created g-string for FONT-OBJECT with NUM glyphs.
@@ -4347,6 +4351,77 @@ Type C-l to recover what previously shown. */)
4347#endif /* FONT_DEBUG */ 4351#endif /* FONT_DEBUG */
4348 4352
4349 4353
4354#define BUILD_STYLE_TABLE(TBL) \
4355 build_style_table ((TBL), sizeof TBL / sizeof (struct table_entry))
4356
4357static Lisp_Object
4358build_style_table (entry, nelement)
4359 struct table_entry *entry;
4360 int nelement;
4361{
4362 int i, j;
4363 Lisp_Object table, elt;
4364
4365 table = Fmake_vector (make_number (nelement), Qnil);
4366 for (i = 0; i < nelement; i++)
4367 {
4368 for (j = 0; entry[i].names[j]; j++);
4369 elt = Fmake_vector (make_number (j + 1), Qnil);
4370 ASET (elt, 0, make_number (entry[i].numeric));
4371 for (j = 0; entry[i].names[j]; j++)
4372 ASET (elt, j + 1, intern (entry[i].names[j]));
4373 ASET (table, i, elt);
4374 }
4375 return table;
4376}
4377
4378static Lisp_Object Vfont_log;
4379static int font_log_env_checked;
4380
4381void
4382font_add_log (action, arg, result)
4383 char *action;
4384 Lisp_Object arg, result;
4385{
4386 Lisp_Object tail, val;
4387 int i;
4388
4389 if (! font_log_env_checked)
4390 {
4391 Vfont_log = egetenv ("EMACS_FONT_LOG") ? Qnil : Qt;
4392 font_log_env_checked = 1;
4393 }
4394 if (EQ (Vfont_log, Qt))
4395 return;
4396 if (FONTP (arg))
4397 arg = Ffont_xlfd_name (arg, Qt);
4398 if (FONTP (result))
4399 result = Ffont_xlfd_name (result, Qt);
4400 else if (CONSP (result))
4401 {
4402 result = Fcopy_sequence (result);
4403 for (tail = result; CONSP (tail); tail = XCDR (tail))
4404 {
4405 val = XCAR (tail);
4406 if (FONTP (val))
4407 val = Ffont_xlfd_name (val, Qt);
4408 XSETCAR (tail, val);
4409 }
4410 }
4411 else if (VECTORP (result))
4412 {
4413 result = Fcopy_sequence (result);
4414 for (i = 0; i < ASIZE (result); i++)
4415 {
4416 val = AREF (result, i);
4417 if (FONTP (val))
4418 val = Ffont_xlfd_name (val, Qt);
4419 ASET (result, i, val);
4420 }
4421 }
4422 Vfont_log = Fcons (list3 (intern (action), arg, result), Vfont_log);
4423}
4424
4350extern void syms_of_ftfont P_ (()); 4425extern void syms_of_ftfont P_ (());
4351extern void syms_of_xfont P_ (()); 4426extern void syms_of_xfont P_ (());
4352extern void syms_of_xftfont P_ (()); 4427extern void syms_of_xftfont P_ (());
@@ -4368,9 +4443,6 @@ syms_of_font ()
4368 /* Note that sort_shift_bits[FONT_SORT_TYPE] and 4443 /* Note that sort_shift_bits[FONT_SORT_TYPE] and
4369 sort_shift_bits[FONT_SORT_REGISTRY] are never used. */ 4444 sort_shift_bits[FONT_SORT_REGISTRY] are never used. */
4370 4445
4371 staticpro (&font_style_table);
4372 font_style_table = Fmake_vector (make_number (3), Qnil);
4373
4374 staticpro (&font_charset_alist); 4446 staticpro (&font_charset_alist);
4375 font_charset_alist = Qnil; 4447 font_charset_alist = Qnil;
4376 4448
@@ -4427,7 +4499,6 @@ syms_of_font ()
4427 defsubr (&Sfind_font); 4499 defsubr (&Sfind_font);
4428 defsubr (&Sfont_xlfd_name); 4500 defsubr (&Sfont_xlfd_name);
4429 defsubr (&Sclear_font_cache); 4501 defsubr (&Sclear_font_cache);
4430 defsubr (&Sinternal_set_font_style_table);
4431 defsubr (&Sfont_make_gstring); 4502 defsubr (&Sfont_make_gstring);
4432 defsubr (&Sfont_fill_gstring); 4503 defsubr (&Sfont_fill_gstring);
4433 defsubr (&Sfont_shape_text); 4504 defsubr (&Sfont_shape_text);
@@ -4468,6 +4539,36 @@ non-nil value in the table are supported. If REPERTORY is nil, Emacs
4468gets the repertory information by an opened font and ENCODING. */); 4539gets the repertory information by an opened font and ENCODING. */);
4469 Vfont_encoding_alist = Qnil; 4540 Vfont_encoding_alist = Qnil;
4470 4541
4542 DEFVAR_LISP_NOPRO ("font-weight-table", &Vfont_weight_table,
4543 doc: /* Vector of valid font weight values.
4544Each element has the form:
4545 [NUMERIC-VALUE SYMBOLIC-NAME ALIAS-NAME ...]
4546NUMERIC-VALUE is an integer, and SYMBOLIC-NAME and ALIAS-NAME are symobls. */);
4547 Vfont_weight_table = BUILD_STYLE_TABLE (weight_table);
4548
4549 DEFVAR_LISP_NOPRO ("font-slant-table", &Vfont_slant_table,
4550 doc: /* Vector of font slant symbols vs the corresponding numeric values.
4551See `font-weight_table' for the format of the vector. */);
4552 Vfont_slant_table = BUILD_STYLE_TABLE (slant_table);
4553
4554 DEFVAR_LISP_NOPRO ("font-width-table", &Vfont_width_table,
4555 doc: /* Alist of font width symbols vs the corresponding numeric values.
4556See `font-weight_table' for the format of the vector. */);
4557 Vfont_width_table = BUILD_STYLE_TABLE (width_table);
4558
4559 staticpro (&font_style_table);
4560 font_style_table = Fmake_vector (make_number (3), Qnil);
4561 ASET (font_style_table, 0, Vfont_weight_table);
4562 ASET (font_style_table, 1, Vfont_slant_table);
4563 ASET (font_style_table, 2, Vfont_width_table);
4564
4565 DEFVAR_LISP ("font-log", &Vfont_log, doc: /*
4566*Logging list of font related actions and results.
4567The value t means to suppress the logging.
4568The initial value is set to nil if the environment variable
4569EMACS_FONT_LOG is set. Otherwise, it is set to t. */);
4570 Vfont_log = Qnil;
4571
4471#ifdef HAVE_WINDOW_SYSTEM 4572#ifdef HAVE_WINDOW_SYSTEM
4472#ifdef HAVE_FREETYPE 4573#ifdef HAVE_FREETYPE
4473 syms_of_ftfont (); 4574 syms_of_ftfont ();