remove `declare' macro
[bpt/emacs.git] / src / xfont.c
CommitLineData
c2f5bfd6 1/* xfont.c -- X core font driver.
ba318903 2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
5df4f04c 3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
c2f5bfd6
KH
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
6
7This file is part of GNU Emacs.
8
9ec0b715 9GNU Emacs is free software: you can redistribute it and/or modify
c2f5bfd6 10it under the terms of the GNU General Public License as published by
9ec0b715
GM
11the Free Software Foundation, either version 3 of the License, or
12(at your option) any later version.
c2f5bfd6
KH
13
14GNU Emacs is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
9ec0b715 20along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
c2f5bfd6
KH
21
22#include <config.h>
23#include <stdio.h>
24#include <X11/Xlib.h>
25
26#include "lisp.h"
27#include "dispextern.h"
28#include "xterm.h"
29#include "frame.h"
30#include "blockinput.h"
31#include "character.h"
32#include "charset.h"
33#include "fontset.h"
34#include "font.h"
f0c55750 35#include "ccl.h"
c2f5bfd6
KH
36
37\f
38/* X core font driver. */
39
f0c55750
KH
40struct xfont_info
41{
42 struct font font;
43 Display *display;
44 XFontStruct *xfont;
19dae293 45 unsigned x_display_id;
f0c55750
KH
46};
47
c2f5bfd6 48/* Prototypes of support functions. */
c2f5bfd6 49
f57e2426 50static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
c2f5bfd6
KH
51
52/* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
53 is not contained in the font. */
54
55static XCharStruct *
971de7fb 56xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
c2f5bfd6
KH
57{
58 /* The result metric information. */
59 XCharStruct *pcm = NULL;
60
4e6a86c6 61 eassert (xfont && char2b);
c2f5bfd6
KH
62
63 if (xfont->per_char != NULL)
64 {
65 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
66 {
67 /* min_char_or_byte2 specifies the linear character index
68 corresponding to the first element of the per_char array,
69 max_char_or_byte2 is the index of the last character. A
70 character with non-zero CHAR2B->byte1 is not in the font.
71 A character with byte2 less than min_char_or_byte2 or
72 greater max_char_or_byte2 is not in the font. */
73 if (char2b->byte1 == 0
74 && char2b->byte2 >= xfont->min_char_or_byte2
75 && char2b->byte2 <= xfont->max_char_or_byte2)
76 pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
77 }
78 else
79 {
80 /* If either min_byte1 or max_byte1 are nonzero, both
81 min_char_or_byte2 and max_char_or_byte2 are less than
82 256, and the 2-byte character index values corresponding
83 to the per_char array element N (counting from 0) are:
84
85 byte1 = N/D + min_byte1
86 byte2 = N\D + min_char_or_byte2
87
88 where:
89
90 D = max_char_or_byte2 - min_char_or_byte2 + 1
91 / = integer division
92 \ = integer modulus */
93 if (char2b->byte1 >= xfont->min_byte1
94 && char2b->byte1 <= xfont->max_byte1
95 && char2b->byte2 >= xfont->min_char_or_byte2
96 && char2b->byte2 <= xfont->max_char_or_byte2)
97 pcm = (xfont->per_char
98 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
99 * (char2b->byte1 - xfont->min_byte1))
100 + (char2b->byte2 - xfont->min_char_or_byte2));
101 }
102 }
103 else
104 {
105 /* If the per_char pointer is null, all glyphs between the first
106 and last character indexes inclusive have the same
107 information, as given by both min_bounds and max_bounds. */
108 if (char2b->byte2 >= xfont->min_char_or_byte2
109 && char2b->byte2 <= xfont->max_char_or_byte2)
110 pcm = &xfont->max_bounds;
111 }
112
113 return ((pcm == NULL
114 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
115 ? NULL : pcm);
116}
117
a10c8269 118static Lisp_Object xfont_get_cache (struct frame *);
fdb396e2
DA
119static Lisp_Object xfont_list (struct frame *, Lisp_Object);
120static Lisp_Object xfont_match (struct frame *, Lisp_Object);
121static Lisp_Object xfont_list_family (struct frame *);
a10c8269 122static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
78e0b35c 123static void xfont_close (struct font *);
24ce6a02 124static void xfont_prepare_face (struct frame *, struct face *);
f57e2426
J
125static int xfont_has_char (Lisp_Object, int);
126static unsigned xfont_encode_char (struct font *, int);
127static int xfont_text_extents (struct font *, unsigned *, int,
128 struct font_metrics *);
a864ef14 129static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
a10c8269 130static int xfont_check (struct frame *, struct font *);
c2f5bfd6
KH
131
132struct font_driver xfont_driver =
133 {
bfe3e0a2 134 LISP_INITIALLY_ZERO, /* Qx */
f0c55750 135 0, /* case insensitive */
c2f5bfd6 136 xfont_get_cache,
c2f5bfd6 137 xfont_list,
6e34c9c1 138 xfont_match,
c2f5bfd6
KH
139 xfont_list_family,
140 NULL,
141 xfont_open,
142 xfont_close,
143 xfont_prepare_face,
f0c55750 144 NULL,
c2f5bfd6
KH
145 xfont_has_char,
146 xfont_encode_char,
147 xfont_text_extents,
f0c55750
KH
148 xfont_draw,
149 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
637fa988
JD
150 xfont_check,
151 NULL, /* get_variation_glyphs */
152 NULL, /* filter_properties */
c2f5bfd6
KH
153 };
154
c2f5bfd6 155static Lisp_Object
a10c8269 156xfont_get_cache (struct frame *f)
c2f5bfd6 157{
aad3612f 158 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
c2f5bfd6
KH
159
160 return (dpyinfo->name_list_element);
161}
162
f0c55750
KH
163static int
164compare_font_names (const void *name1, const void *name2)
165{
fd573f31
PE
166 char *const *n1 = name1;
167 char *const *n2 = name2;
168 return xstrcasecmp (*n1, *n2);
f0c55750
KH
169}
170
6a705b23
KH
171/* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
172 of the decoding result. LEN is the byte length of XLFD, or -1 if
173 XLFD is NULL terminated. The caller must assure that OUTPUT is at
174 least twice (plus 1) as large as XLFD. */
175
984e7f30 176static ptrdiff_t
6a705b23
KH
177xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
178{
179 char *p0 = xlfd, *p1 = output;
180 int c;
8510724d 181
6a705b23
KH
182 while (*p0)
183 {
184 c = *(unsigned char *) p0++;
efe0234f 185 p1 += CHAR_STRING (c, (unsigned char *) p1);
6a705b23
KH
186 if (--len == 0)
187 break;
188 }
189 *p1 = 0;
190 return (p1 - output);
191}
192
193/* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
194 resulting byte length. If XLFD contains unencodable character,
195 return -1. */
196
197static int
198xfont_encode_coding_xlfd (char *xlfd)
199{
200 const unsigned char *p0 = (unsigned char *) xlfd;
201 unsigned char *p1 = (unsigned char *) xlfd;
202 int len = 0;
8510724d 203
6a705b23
KH
204 while (*p0)
205 {
206 int c = STRING_CHAR_ADVANCE (p0);
207
208 if (c >= 0x100)
209 return -1;
210 *p1++ = c;
211 len++;
212 }
213 *p1 = 0;
214 return len;
215}
216
5a189ffa
KH
217/* Check if CHARS (cons or vector) is supported by XFONT whose
218 encoding charset is ENCODING (XFONT is NULL) or by a font whose
219 registry corresponds to ENCODING and REPERTORY.
a864ef14 220 Return true if supported. */
5a189ffa 221
a864ef14 222static bool
5a189ffa
KH
223xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
224 struct charset *encoding, struct charset *repertory)
225{
226 struct charset *charset = repertory ? repertory : encoding;
227
228 if (CONSP (chars))
229 {
230 for (; CONSP (chars); chars = XCDR (chars))
231 {
232 int c = XINT (XCAR (chars));
233 unsigned code = ENCODE_CHAR (charset, c);
234 XChar2b char2b;
235
236 if (code == CHARSET_INVALID_CODE (charset))
237 break;
238 if (! xfont)
239 continue;
240 if (code >= 0x10000)
241 break;
242 char2b.byte1 = code >> 8;
243 char2b.byte2 = code & 0xFF;
244 if (! xfont_get_pcm (xfont, &char2b))
245 break;
246 }
247 return (NILP (chars));
248 }
249 else if (VECTORP (chars))
250 {
d311d28c 251 ptrdiff_t i;
5a189ffa
KH
252
253 for (i = ASIZE (chars) - 1; i >= 0; i--)
254 {
255 int c = XINT (AREF (chars, i));
256 unsigned code = ENCODE_CHAR (charset, c);
257 XChar2b char2b;
258
259 if (code == CHARSET_INVALID_CODE (charset))
260 continue;
261 if (! xfont)
262 break;
263 if (code >= 0x10000)
264 continue;
265 char2b.byte1 = code >> 8;
266 char2b.byte2 = code & 0xFF;
267 if (xfont_get_pcm (xfont, &char2b))
268 break;
269 }
270 return (i >= 0);
271 }
272 return 0;
273}
274
0b381c7e
JB
275/* A hash table recoding which font supports which scripts. Each key
276 is a vector of characteristic font properties FOUNDRY to WIDTH and
5a189ffa
KH
277 ADDSTYLE, and each value is a list of script symbols.
278
279 We assume that fonts that have the same value in the above
280 properties supports the same set of characters on all displays. */
281
282static Lisp_Object xfont_scripts_cache;
283
0b381c7e 284/* Re-usable vector to store characteristic font properties. */
5a189ffa
KH
285static Lisp_Object xfont_scratch_props;
286
5a189ffa
KH
287/* Return a list of scripts supported by the font of FONTNAME whose
288 characteristic properties are in PROPS and whose encoding charset
289 is ENCODING. A caller must call BLOCK_INPUT in advance. */
92f19280
KH
290
291static Lisp_Object
5a189ffa
KH
292xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
293 struct charset *encoding)
294{
295 Lisp_Object scripts;
296
297 /* Two special cases to avoid opening rather big fonts. */
298 if (EQ (AREF (props, 2), Qja))
6c6f1994 299 return list2 (intern ("kana"), intern ("han"));
5a189ffa 300 if (EQ (AREF (props, 2), Qko))
6c6f1994 301 return list1 (intern ("hangul"));
5a189ffa
KH
302 scripts = Fgethash (props, xfont_scripts_cache, Qt);
303 if (EQ (scripts, Qt))
304 {
305 XFontStruct *xfont;
306 Lisp_Object val;
307
308 scripts = Qnil;
309 xfont = XLoadQueryFont (display, fontname);
310 if (xfont)
311 {
312 if (xfont->per_char)
313 {
314 for (val = Vscript_representative_chars; CONSP (val);
315 val = XCDR (val))
316 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
317 {
318 Lisp_Object script = XCAR (XCAR (val));
319 Lisp_Object chars = XCDR (XCAR (val));
320
321 if (xfont_chars_supported (chars, xfont, encoding, NULL))
322 scripts = Fcons (script, scripts);
323 }
324 }
325 XFreeFont (display, xfont);
326 }
327 if (EQ (AREF (props, 3), Qiso10646_1)
328 && NILP (Fmemq (Qlatin, scripts)))
329 scripts = Fcons (Qlatin, scripts);
330 Fputhash (Fcopy_sequence (props), scripts, xfont_scripts_cache);
331 }
332 return scripts;
333}
334
5a189ffa 335static Lisp_Object
675e2c69 336xfont_list_pattern (Display *display, const char *pattern,
5a189ffa 337 Lisp_Object registry, Lisp_Object script)
c2f5bfd6 338{
6c4aeab6 339 Lisp_Object list = Qnil;
5a189ffa
KH
340 Lisp_Object chars = Qnil;
341 struct charset *encoding, *repertory = NULL;
6c4aeab6
KH
342 int i, limit, num_fonts;
343 char **names;
6a705b23
KH
344 /* Large enough to decode the longest XLFD (255 bytes). */
345 char buf[512];
c2f5bfd6 346
5a189ffa
KH
347 if (! NILP (registry)
348 && font_registry_charsets (registry, &encoding, &repertory) < 0)
349 /* Unknown REGISTRY, not supported. */
350 return Qnil;
351 if (! NILP (script))
352 {
353 chars = assq_no_quit (script, Vscript_representative_chars);
354 if (NILP (chars))
355 /* We can't tell whether or not a font supports SCRIPT. */
356 return Qnil;
357 chars = XCDR (chars);
358 if (repertory)
359 {
360 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
361 return Qnil;
362 script = Qnil;
363 }
364 }
51b59d79 365
4d7e6e51 366 block_input ();
6c4aeab6 367 x_catch_errors (display);
c2f5bfd6 368
6c4aeab6 369 for (limit = 512; ; limit *= 2)
c2f5bfd6 370 {
6c4aeab6
KH
371 names = XListFonts (display, pattern, limit, &num_fonts);
372 if (x_had_errors_p (display))
c2f5bfd6
KH
373 {
374 /* This error is perhaps due to insufficient memory on X
375 server. Let's just ignore it. */
6c4aeab6
KH
376 x_clear_errors (display);
377 num_fonts = 0;
378 break;
c2f5bfd6 379 }
6c4aeab6
KH
380 if (num_fonts < limit)
381 break;
382 XFreeFontNames (names);
383 }
384
f0c55750 385 if (num_fonts > 0)
6c4aeab6 386 {
f0c55750 387 char **indices = alloca (sizeof (char *) * num_fonts);
91f2d272 388 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
5a189ffa 389 Lisp_Object scripts = Qnil;
6c4aeab6 390
46306a17 391 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
086ca913 392 ASET (xfont_scratch_props, i, Qnil);
f0c55750
KH
393 for (i = 0; i < num_fonts; i++)
394 indices[i] = names[i];
395 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
6c4aeab6 396
f0c55750 397 for (i = 0; i < num_fonts; i++)
c2f5bfd6 398 {
984e7f30 399 ptrdiff_t len;
f0c55750 400 Lisp_Object entity;
6c4aeab6 401
05131107 402 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
6c4aeab6 403 continue;
f0c55750 404 entity = font_make_entity ();
984e7f30
DA
405 len = xfont_decode_coding_xlfd (indices[i], -1, buf);
406 if (font_parse_xlfd (buf, len, entity) < 0)
4fa58085 407 continue;
5a189ffa
KH
408 ASET (entity, FONT_TYPE_INDEX, Qx);
409 /* Avoid auto-scaled fonts. */
4fa58085
KH
410 if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
411 && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
412 && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
5a189ffa
KH
413 && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
414 continue;
415 /* Avoid not-allowed scalable fonts. */
416 if (NILP (Vscalable_fonts_allowed))
c2f5bfd6 417 {
4fa58085
KH
418 int size = 0;
419
420 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
421 size = XINT (AREF (entity, FONT_SIZE_INDEX));
422 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
423 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
424 if (size == 0)
6c4aeab6 425 continue;
5a189ffa
KH
426 }
427 else if (CONSP (Vscalable_fonts_allowed))
428 {
429 Lisp_Object tail, elt;
430
431 for (tail = Vscalable_fonts_allowed; CONSP (tail);
432 tail = XCDR (tail))
f0c55750 433 {
5a189ffa
KH
434 elt = XCAR (tail);
435 if (STRINGP (elt)
d923b542
DA
436 && fast_c_string_match_ignore_case (elt, indices[i],
437 len) >= 0)
5a189ffa 438 break;
f0c55750 439 }
5a189ffa
KH
440 if (! CONSP (tail))
441 continue;
c2f5bfd6 442 }
f0c55750 443
4fa58085
KH
444 /* Avoid fonts of invalid registry. */
445 if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
446 continue;
447
5a189ffa
KH
448 /* Update encoding and repertory if necessary. */
449 if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
450 {
451 registry = AREF (entity, FONT_REGISTRY_INDEX);
452 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
453 encoding = NULL;
454 }
455 if (! encoding)
456 /* Unknown REGISTRY, not supported. */
457 continue;
458 if (repertory)
459 {
460 if (NILP (script)
461 || xfont_chars_supported (chars, NULL, encoding, repertory))
462 list = Fcons (entity, list);
463 continue;
464 }
4939150c 465 if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
663e2b3f 466 word_size * 7)
5a189ffa
KH
467 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
468 {
086ca913
DA
469 vcopy (xfont_scratch_props, 0,
470 aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
471 ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
5a189ffa
KH
472 scripts = xfont_supported_scripts (display, indices[i],
473 xfont_scratch_props, encoding);
474 }
475 if (NILP (script)
476 || ! NILP (Fmemq (script, scripts)))
f0c55750 477 list = Fcons (entity, list);
c2f5bfd6 478 }
019e13ef 479 XFreeFontNames (names);
c2f5bfd6
KH
480 }
481
482 x_uncatch_errors ();
4d7e6e51 483 unblock_input ();
c2f5bfd6 484
678dca3d 485 FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
6c4aeab6
KH
486 return list;
487}
c2f5bfd6 488
6c4aeab6 489static Lisp_Object
fdb396e2 490xfont_list (struct frame *f, Lisp_Object spec)
6c4aeab6 491{
aad3612f 492 Display *display = FRAME_DISPLAY_INFO (f)->display;
5a189ffa 493 Lisp_Object registry, list, val, extra, script;
6c4aeab6 494 int len;
6a705b23
KH
495 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
496 char name[512];
8510724d 497
6c4aeab6 498 extra = AREF (spec, FONT_EXTRA_INDEX);
6c4aeab6 499 if (CONSP (extra))
c2f5bfd6 500 {
6c4aeab6 501 val = assq_no_quit (QCotf, extra);
6c4aeab6 502 if (! NILP (val))
f0c55750
KH
503 return Qnil;
504 val = assq_no_quit (QClang, extra);
6c4aeab6 505 if (! NILP (val))
f0c55750 506 return Qnil;
c2f5bfd6 507 }
398dbf26 508
f0c55750 509 registry = AREF (spec, FONT_REGISTRY_INDEX);
6a705b23
KH
510 len = font_unparse_xlfd (spec, 0, name, 512);
511 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
f0c55750 512 return Qnil;
5a189ffa
KH
513
514 val = assq_no_quit (QCscript, extra);
515 script = CDR (val);
516 list = xfont_list_pattern (display, name, registry, script);
f0c55750 517 if (NILP (list) && NILP (registry))
c2f5bfd6 518 {
f0c55750
KH
519 /* Try iso10646-1 */
520 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
521
522 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
6c4aeab6 523 {
f0c55750 524 strcpy (r, "iso10646-1");
5a189ffa 525 list = xfont_list_pattern (display, name, Qiso10646_1, script);
f0c55750
KH
526 }
527 }
528 if (NILP (list) && ! NILP (registry))
529 {
37470f4d 530 /* Try alternate registries. */
f0c55750 531 Lisp_Object alter;
6c4aeab6 532
f0c55750
KH
533 if ((alter = Fassoc (SYMBOL_NAME (registry),
534 Vface_alternative_font_registry_alist),
535 CONSP (alter)))
536 {
537 /* Pointer to REGISTRY-ENCODING field. */
538 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
539
540 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
541 if (STRINGP (XCAR (alter))
542 && ((r - name) + SBYTES (XCAR (alter))) < 256)
543 {
51b59d79 544 strcpy (r, SSDATA (XCAR (alter)));
5a189ffa 545 list = xfont_list_pattern (display, name, registry, script);
f0c55750
KH
546 if (! NILP (list))
547 break;
548 }
6c4aeab6 549 }
c2f5bfd6 550 }
37470f4d
KH
551 if (NILP (list))
552 {
553 /* Try alias. */
554 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
6a705b23
KH
555 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
556 {
72af86bd 557 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
6a705b23
KH
558 if (xfont_encode_coding_xlfd (name) < 0)
559 return Qnil;
5a189ffa 560 list = xfont_list_pattern (display, name, registry, script);
6a705b23 561 }
37470f4d 562 }
398dbf26 563
f0c55750 564 return list;
c2f5bfd6
KH
565}
566
6e34c9c1 567static Lisp_Object
fdb396e2 568xfont_match (struct frame *f, Lisp_Object spec)
6e34c9c1 569{
aad3612f 570 Display *display = FRAME_DISPLAY_INFO (f)->display;
6e34c9c1 571 Lisp_Object extra, val, entity;
6a705b23 572 char name[512];
6e34c9c1
KH
573 XFontStruct *xfont;
574 unsigned long value;
575
576 extra = AREF (spec, FONT_EXTRA_INDEX);
577 val = assq_no_quit (QCname, extra);
578 if (! CONSP (val) || ! STRINGP (XCDR (val)))
f0c55750 579 {
6a705b23 580 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
f0c55750 581 return Qnil;
f0c55750 582 }
6a705b23 583 else if (SBYTES (XCDR (val)) < 512)
72af86bd 584 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
f0c55750 585 else
6a705b23
KH
586 return Qnil;
587 if (xfont_encode_coding_xlfd (name) < 0)
588 return Qnil;
6e34c9c1 589
4d7e6e51 590 block_input ();
6e34c9c1 591 entity = Qnil;
6e34c9c1
KH
592 xfont = XLoadQueryFont (display, name);
593 if (xfont)
594 {
595 if (XGetFontProperty (xfont, XA_FONT, &value))
596 {
7d652d97 597 char *s = XGetAtomName (display, (Atom) value);
6e34c9c1
KH
598
599 /* If DXPC (a Differential X Protocol Compressor)
600 Ver.3.7 is running, XGetAtomName will return null
601 string. We must avoid such a name. */
7de51af5 602 if (*s)
6e34c9c1 603 {
984e7f30 604 ptrdiff_t len;
f0c55750 605 entity = font_make_entity ();
6e34c9c1 606 ASET (entity, FONT_TYPE_INDEX, Qx);
984e7f30
DA
607 len = xfont_decode_coding_xlfd (s, -1, name);
608 if (font_parse_xlfd (name, len, entity) < 0)
6e34c9c1
KH
609 entity = Qnil;
610 }
6a705b23 611 XFree (s);
6e34c9c1
KH
612 }
613 XFreeFont (display, xfont);
614 }
4d7e6e51 615 unblock_input ();
6e34c9c1 616
678dca3d 617 FONT_ADD_LOG ("xfont-match", spec, entity);
6e34c9c1
KH
618 return entity;
619}
620
c2f5bfd6 621static Lisp_Object
fdb396e2 622xfont_list_family (struct frame *f)
c2f5bfd6 623{
aad3612f 624 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
c2f5bfd6
KH
625 char **names;
626 int num_fonts, i;
627 Lisp_Object list;
e2be39f6 628 char *last_family IF_LINT (= 0);
c2f5bfd6
KH
629 int last_len;
630
4d7e6e51 631 block_input ();
c2f5bfd6
KH
632 x_catch_errors (dpyinfo->display);
633 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
634 0x8000, &num_fonts);
635 if (x_had_errors_p (dpyinfo->display))
636 {
637 /* This error is perhaps due to insufficient memory on X server.
638 Let's just ignore it. */
639 x_clear_errors (dpyinfo->display);
640 num_fonts = 0;
641 }
642
643 list = Qnil;
644 for (i = 0, last_len = 0; i < num_fonts; i++)
645 {
6a705b23 646 char *p0 = names[i], *p1, buf[512];
c2f5bfd6 647 Lisp_Object family;
6a705b23 648 int decoded_len;
c2f5bfd6
KH
649
650 p0++; /* skip the leading '-' */
651 while (*p0 && *p0 != '-') p0++; /* skip foundry */
652 if (! *p0)
653 continue;
654 p1 = ++p0;
655 while (*p1 && *p1 != '-') p1++; /* find the end of family */
656 if (! *p1 || p1 == p0)
657 continue;
658 if (last_len == p1 - p0
72af86bd 659 && memcmp (last_family, p0, last_len) == 0)
c2f5bfd6
KH
660 continue;
661 last_len = p1 - p0;
662 last_family = p0;
6a705b23
KH
663
664 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
665 family = font_intern_prop (p0, decoded_len, 1);
29428bb8 666 if (NILP (assq_no_quit (family, list)))
c2f5bfd6
KH
667 list = Fcons (family, list);
668 }
669
670 XFreeFontNames (names);
671 x_uncatch_errors ();
4d7e6e51 672 unblock_input ();
c2f5bfd6
KH
673
674 return list;
675}
676
f0c55750 677static Lisp_Object
a10c8269 678xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
c2f5bfd6 679{
aad3612f 680 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
c2f5bfd6 681 Display *display = dpyinfo->display;
6a705b23 682 char name[512];
c2f5bfd6
KH
683 int len;
684 unsigned long value;
685 Lisp_Object registry;
686 struct charset *encoding, *repertory;
f0c55750 687 Lisp_Object font_object, fullname;
c2f5bfd6
KH
688 struct font *font;
689 XFontStruct *xfont;
690
691 /* At first, check if we know how to encode characters for this
692 font. */
693 registry = AREF (entity, FONT_REGISTRY_INDEX);
a9822ae8 694 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
c8e0e16d 695 {
678dca3d 696 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
c8e0e16d
KH
697 return Qnil;
698 }
c2f5bfd6
KH
699
700 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
701 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
f0c55750
KH
702 else if (pixel_size == 0)
703 {
704 if (FRAME_FONT (f))
705 pixel_size = FRAME_FONT (f)->pixel_size;
706 else
707 pixel_size = 14;
708 }
6a705b23
KH
709 len = font_unparse_xlfd (entity, pixel_size, name, 512);
710 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
c8e0e16d 711 {
678dca3d 712 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
c8e0e16d
KH
713 return Qnil;
714 }
c2f5bfd6 715
4d7e6e51 716 block_input ();
c2f5bfd6
KH
717 x_catch_errors (display);
718 xfont = XLoadQueryFont (display, name);
719 if (x_had_errors_p (display))
720 {
721 /* This error is perhaps due to insufficient memory on X server.
722 Let's just ignore it. */
723 x_clear_errors (display);
724 xfont = NULL;
725 }
2f73901f
KH
726 else if (! xfont)
727 {
728 /* Some version of X lists:
729 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
730 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
731 but can open only:
732 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
733 and
734 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
735 So, we try again with wildcards in RESX and RESY. */
736 Lisp_Object temp;
737
92470028 738 temp = copy_font_spec (entity);
2f73901f 739 ASET (temp, FONT_DPI_INDEX, Qnil);
6a705b23
KH
740 len = font_unparse_xlfd (temp, pixel_size, name, 512);
741 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
2f73901f 742 {
678dca3d 743 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
2f73901f
KH
744 return Qnil;
745 }
746 xfont = XLoadQueryFont (display, name);
747 if (x_had_errors_p (display))
748 {
749 /* This error is perhaps due to insufficient memory on X server.
750 Let's just ignore it. */
751 x_clear_errors (display);
752 xfont = NULL;
753 }
754 }
f0c55750
KH
755 fullname = Qnil;
756 /* Try to get the full name of FONT. */
757 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
758 {
759 char *p0, *p;
760 int dashes = 0;
761
7d652d97 762 p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
f0c55750
KH
763 /* Count the number of dashes in the "full name".
764 If it is too few, this isn't really the font's full name,
765 so don't use it.
766 In X11R4, the fonts did not come with their canonical names
767 stored in them. */
768 while (*p)
769 {
770 if (*p == '-')
771 dashes++;
772 p++;
773 }
774
775 if (dashes >= 13)
6a705b23
KH
776 {
777 len = xfont_decode_coding_xlfd (p0, -1, name);
778 fullname = Fdowncase (make_string (name, len));
779 }
f0c55750
KH
780 XFree (p0);
781 }
c2f5bfd6 782 x_uncatch_errors ();
4d7e6e51 783 unblock_input ();
c2f5bfd6
KH
784
785 if (! xfont)
c8e0e16d 786 {
678dca3d 787 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
c8e0e16d
KH
788 return Qnil;
789 }
f0c55750 790
947eecfb
KH
791 font_object = font_make_object (VECSIZE (struct xfont_info),
792 entity, pixel_size);
f0c55750
KH
793 ASET (font_object, FONT_TYPE_INDEX, Qx);
794 if (STRINGP (fullname))
6a705b23 795 {
984e7f30 796 font_parse_xlfd (SSDATA (fullname), SBYTES (fullname), font_object);
6a705b23
KH
797 ASET (font_object, FONT_NAME_INDEX, fullname);
798 }
f0c55750 799 else
6a705b23
KH
800 {
801 char buf[512];
802
803 len = xfont_decode_coding_xlfd (name, -1, buf);
804 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
805 }
f0c55750
KH
806 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
807 ASET (font_object, FONT_FILE_INDEX, Qnil);
808 ASET (font_object, FONT_FORMAT_INDEX, Qx);
809 font = XFONT_OBJECT (font_object);
810 ((struct xfont_info *) font)->xfont = xfont;
811 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
19dae293 812 ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
c2f5bfd6
KH
813 font->pixel_size = pixel_size;
814 font->driver = &xfont_driver;
c2f5bfd6 815 font->encoding_charset = encoding->id;
1886668d 816 font->repertory_charset = repertory ? repertory->id : -1;
c2f5bfd6
KH
817 font->ascent = xfont->ascent;
818 font->descent = xfont->descent;
f0c55750
KH
819 font->height = font->ascent + font->descent;
820 font->min_width = xfont->min_bounds.width;
032a42c8 821 font->max_width = xfont->max_bounds.width;
c2f5bfd6
KH
822 if (xfont->min_bounds.width == xfont->max_bounds.width)
823 {
824 /* Fixed width font. */
f0c55750 825 font->average_width = font->space_width = xfont->min_bounds.width;
c2f5bfd6
KH
826 }
827 else
828 {
c2f5bfd6 829 XCharStruct *pcm;
f0c55750
KH
830 XChar2b char2b;
831 Lisp_Object val;
c2f5bfd6
KH
832
833 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
834 pcm = xfont_get_pcm (xfont, &char2b);
835 if (pcm)
f0c55750 836 font->space_width = pcm->width;
c2f5bfd6 837 else
f0c55750
KH
838 font->space_width = 0;
839
840 val = Ffont_get (font_object, QCavgwidth);
841 if (INTEGERP (val))
18acb5ad 842 font->average_width = XINT (val) / 10;
f0c55750
KH
843 if (font->average_width < 0)
844 font->average_width = - font->average_width;
625a3eb1 845 else
c2f5bfd6 846 {
625a3eb1
PE
847 if (font->average_width == 0
848 && encoding->ascii_compatible_p)
849 {
850 int width = font->space_width, n = pcm != NULL;
c2f5bfd6 851
625a3eb1
PE
852 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
853 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
854 width += pcm->width, n++;
855 if (n > 0)
856 font->average_width = width / n;
857 }
858 if (font->average_width == 0)
859 /* No easy way other than this to get a reasonable
860 average_width. */
861 font->average_width
862 = (xfont->min_bounds.width + xfont->max_bounds.width) / 2;
c2f5bfd6 863 }
c2f5bfd6 864 }
c2f5bfd6 865
4d7e6e51 866 block_input ();
f0c55750
KH
867 font->underline_thickness
868 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
869 ? (long) value : 0);
870 font->underline_position
871 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
872 ? (long) value : -1);
873 font->baseline_offset
c2f5bfd6
KH
874 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
875 ? (long) value : 0);
f0c55750 876 font->relative_compose
c2f5bfd6
KH
877 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
878 ? (long) value : 0);
f0c55750 879 font->default_ascent
c2f5bfd6
KH
880 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
881 ? (long) value : 0);
4d7e6e51 882 unblock_input ();
c2f5bfd6 883
f0c55750
KH
884 if (NILP (fullname))
885 fullname = AREF (font_object, FONT_NAME_INDEX);
634c4da0
KH
886 font->vertical_centering
887 = (STRINGP (Vvertical_centering_font_regexp)
888 && (fast_string_match_ignore_case
889 (Vvertical_centering_font_regexp, fullname) >= 0));
c2f5bfd6 890
f0c55750 891 return font_object;
c2f5bfd6
KH
892}
893
894static void
78e0b35c 895xfont_close (struct font *font)
c2f5bfd6 896{
19dae293 897 struct x_display_info *xdi;
78e0b35c
DA
898 struct xfont_info *xfi = (struct xfont_info *) font;
899
5ae356d9 900 /* This function may be called from GC when X connection is gone
61d208ad 901 (Bug#16093), and an attempt to free font resources on invalid
19dae293
DA
902 display may lead to X protocol errors or segfaults. Moreover,
903 the memory referenced by 'Display *' pointer may be reused for
904 the logically different X connection after the previous display
905 connection was closed. That's why we also check whether font's
906 ID matches the one recorded in x_display_info for this display.
907 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
908 if (xfi->xfont
909 && ((xdi = x_display_info_for_display (xfi->display))
910 && xfi->x_display_id == xdi->x_id))
78e0b35c
DA
911 {
912 block_input ();
913 XFreeFont (xfi->display, xfi->xfont);
914 unblock_input ();
915 xfi->xfont = NULL;
916 }
c2f5bfd6
KH
917}
918
24ce6a02 919static void
a10c8269 920xfont_prepare_face (struct frame *f, struct face *face)
c2f5bfd6 921{
4d7e6e51 922 block_input ();
f0c55750
KH
923 XSetFont (FRAME_X_DISPLAY (f), face->gc,
924 ((struct xfont_info *) face->font)->xfont->fid);
4d7e6e51 925 unblock_input ();
c2f5bfd6
KH
926}
927
c2f5bfd6 928static int
971de7fb 929xfont_has_char (Lisp_Object font, int c)
c2f5bfd6 930{
bd0af90d 931 Lisp_Object registry = AREF (font, FONT_REGISTRY_INDEX);
d156542d 932 struct charset *encoding;
bd0af90d 933 struct charset *repertory = NULL;
c2f5bfd6 934
bd0af90d
KH
935 if (EQ (registry, Qiso10646_1))
936 {
5a189ffa 937 encoding = CHARSET_FROM_ID (charset_unicode);
bd0af90d
KH
938 /* We use a font of `ja' and `ko' adstyle only for a character
939 in JISX0208 and KSC5601 charsets respectively. */
940 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
941 && charset_jisx0208 >= 0)
5a189ffa 942 repertory = CHARSET_FROM_ID (charset_jisx0208);
bd0af90d
KH
943 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
944 && charset_ksc5601 >= 0)
5a189ffa 945 repertory = CHARSET_FROM_ID (charset_ksc5601);
bd0af90d
KH
946 }
947 else if (font_registry_charsets (registry, &encoding, &repertory) < 0)
948 /* Unknown REGISTRY, not usable. */
949 return 0;
d156542d
KH
950 if (ASCII_CHAR_P (c) && encoding->ascii_compatible_p)
951 return 1;
c2f5bfd6
KH
952 if (! repertory)
953 return -1;
954 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
955}
956
957static unsigned
971de7fb 958xfont_encode_char (struct font *font, int c)
c2f5bfd6 959{
f0c55750 960 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
c2f5bfd6
KH
961 struct charset *charset;
962 unsigned code;
963 XChar2b char2b;
964
965 charset = CHARSET_FROM_ID (font->encoding_charset);
966 code = ENCODE_CHAR (charset, c);
967 if (code == CHARSET_INVALID_CODE (charset))
21138cff 968 return FONT_INVALID_CODE;
1886668d 969 if (font->repertory_charset >= 0)
c2f5bfd6 970 {
1886668d 971 charset = CHARSET_FROM_ID (font->repertory_charset);
c2f5bfd6 972 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
21138cff 973 ? code : FONT_INVALID_CODE);
c2f5bfd6 974 }
88649c62
KH
975 char2b.byte1 = code >> 8;
976 char2b.byte2 = code & 0xFF;
f0c55750 977 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
c2f5bfd6
KH
978}
979
980static int
971de7fb 981xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics)
c2f5bfd6 982{
f0c55750 983 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
c2f5bfd6 984 int width = 0;
bc7b6697 985 int i, first;
c2f5bfd6
KH
986
987 if (metrics)
72af86bd 988 memset (metrics, 0, sizeof (struct font_metrics));
bc7b6697 989 for (i = 0, first = 1; i < nglyphs; i++)
c2f5bfd6
KH
990 {
991 XChar2b char2b;
992 static XCharStruct *pcm;
993
994 if (code[i] >= 0x10000)
995 continue;
996 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
f0c55750 997 pcm = xfont_get_pcm (xfont, &char2b);
c2f5bfd6
KH
998 if (! pcm)
999 continue;
41fa3e2c
KH
1000 if (first)
1001 {
1002 if (metrics)
1003 {
1004 metrics->lbearing = pcm->lbearing;
1005 metrics->rbearing = pcm->rbearing;
1006 metrics->ascent = pcm->ascent;
1007 metrics->descent = pcm->descent;
1008 }
1009 first = 0;
1010 }
1011 else
1012 {
1013 if (metrics)
1014 {
1015 if (metrics->lbearing > width + pcm->lbearing)
1016 metrics->lbearing = width + pcm->lbearing;
1017 if (metrics->rbearing < width + pcm->rbearing)
1018 metrics->rbearing = width + pcm->rbearing;
1019 if (metrics->ascent < pcm->ascent)
1020 metrics->ascent = pcm->ascent;
1021 if (metrics->descent < pcm->descent)
1022 metrics->descent = pcm->descent;
1023 }
1024 }
c2f5bfd6
KH
1025 width += pcm->width;
1026 }
1027 if (metrics)
1028 metrics->width = width;
1029 return width;
1030}
1031
1032static int
a864ef14
PE
1033xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1034 bool with_background)
c2f5bfd6 1035{
f0c55750 1036 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
c2f5bfd6 1037 int len = to - from;
6e34c9c1 1038 GC gc = s->gc;
298fd5b1 1039 int i;
6e34c9c1 1040
f0c55750 1041 if (s->gc != s->face->gc)
6e34c9c1 1042 {
4d7e6e51 1043 block_input ();
f0c55750 1044 XSetFont (s->display, gc, xfont->fid);
4d7e6e51 1045 unblock_input ();
6e34c9c1 1046 }
c2f5bfd6
KH
1047
1048 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1049 {
c2f5bfd6 1050 USE_SAFE_ALLOCA;
98c6f1e3 1051 char *str = SAFE_ALLOCA (len);
c2f5bfd6
KH
1052 for (i = 0; i < len ; i++)
1053 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
4d7e6e51 1054 block_input ();
a864ef14 1055 if (with_background)
298fd5b1
KH
1056 {
1057 if (s->padding_p)
1058 for (i = 0; i < len; i++)
1059 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1060 gc, x + i, y, str + i, 1);
1061 else
1062 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1063 gc, x, y, str, len);
1064 }
c2f5bfd6 1065 else
298fd5b1
KH
1066 {
1067 if (s->padding_p)
1068 for (i = 0; i < len; i++)
1069 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1070 gc, x + i, y, str + i, 1);
1071 else
1072 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1073 gc, x, y, str, len);
1074 }
4d7e6e51 1075 unblock_input ();
c2f5bfd6
KH
1076 SAFE_FREE ();
1077 return s->nchars;
1078 }
1079
4d7e6e51 1080 block_input ();
a864ef14 1081 if (with_background)
298fd5b1
KH
1082 {
1083 if (s->padding_p)
1084 for (i = 0; i < len; i++)
1085 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1086 gc, x + i, y, s->char2b + from + i, 1);
1087 else
1088 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1089 gc, x, y, s->char2b + from, len);
1090 }
c2f5bfd6 1091 else
298fd5b1
KH
1092 {
1093 if (s->padding_p)
1094 for (i = 0; i < len; i++)
1095 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1096 gc, x + i, y, s->char2b + from + i, 1);
1097 else
1098 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1099 gc, x, y, s->char2b + from, len);
1100 }
4d7e6e51 1101 unblock_input ();
c2f5bfd6
KH
1102
1103 return len;
1104}
1105
f0c55750 1106static int
a10c8269 1107xfont_check (struct frame *f, struct font *font)
f0c55750
KH
1108{
1109 struct xfont_info *xfont = (struct xfont_info *) font;
1110
1111 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1112}
1113
c2f5bfd6
KH
1114\f
1115void
971de7fb 1116syms_of_xfont (void)
c2f5bfd6 1117{
5a189ffa 1118 staticpro (&xfont_scripts_cache);
46306a17
SM
1119 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1120 is called fairly late, when QCtest and Qequal are known to be set. */
1121 Lisp_Object args[2];
1122 args[0] = QCtest;
1123 args[1] = Qequal;
1124 xfont_scripts_cache = Fmake_hash_table (2, args);
1125 }
5a189ffa 1126 staticpro (&xfont_scratch_props);
46306a17 1127 xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
c2f5bfd6
KH
1128 xfont_driver.type = Qx;
1129 register_font_driver (&xfont_driver, NULL);
1130}