Improve fontification of footnote references in Info buffers
[emacs.git] / src / xfont.c
blob45b0e0a5f5329e5f1a74c4e8f4e4c1e69c5469d9
1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2016 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or (at
12 your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <X11/Xlib.h>
27 #include "lisp.h"
28 #include "xterm.h"
29 #include "frame.h"
30 #include "blockinput.h"
31 #include "character.h"
32 #include "charset.h"
33 #include "font.h"
36 /* X core font driver. */
38 struct xfont_info
40 struct font font;
41 Display *display;
42 XFontStruct *xfont;
43 unsigned x_display_id;
46 /* Prototypes of support functions. */
48 static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
50 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
51 is not contained in the font. */
53 static XCharStruct *
54 xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
56 /* The result metric information. */
57 XCharStruct *pcm = NULL;
59 eassert (xfont && char2b);
61 if (xfont->per_char != NULL)
63 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
65 /* min_char_or_byte2 specifies the linear character index
66 corresponding to the first element of the per_char array,
67 max_char_or_byte2 is the index of the last character. A
68 character with non-zero CHAR2B->byte1 is not in the font.
69 A character with byte2 less than min_char_or_byte2 or
70 greater max_char_or_byte2 is not in the font. */
71 if (char2b->byte1 == 0
72 && char2b->byte2 >= xfont->min_char_or_byte2
73 && char2b->byte2 <= xfont->max_char_or_byte2)
74 pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
76 else
78 /* If either min_byte1 or max_byte1 are nonzero, both
79 min_char_or_byte2 and max_char_or_byte2 are less than
80 256, and the 2-byte character index values corresponding
81 to the per_char array element N (counting from 0) are:
83 byte1 = N/D + min_byte1
84 byte2 = N\D + min_char_or_byte2
86 where:
88 D = max_char_or_byte2 - min_char_or_byte2 + 1
89 / = integer division
90 \ = integer modulus */
91 if (char2b->byte1 >= xfont->min_byte1
92 && char2b->byte1 <= xfont->max_byte1
93 && char2b->byte2 >= xfont->min_char_or_byte2
94 && char2b->byte2 <= xfont->max_char_or_byte2)
95 pcm = (xfont->per_char
96 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
97 * (char2b->byte1 - xfont->min_byte1))
98 + (char2b->byte2 - xfont->min_char_or_byte2));
101 else
103 /* If the per_char pointer is null, all glyphs between the first
104 and last character indexes inclusive have the same
105 information, as given by both min_bounds and max_bounds. */
106 if (char2b->byte2 >= xfont->min_char_or_byte2
107 && char2b->byte2 <= xfont->max_char_or_byte2)
108 pcm = &xfont->max_bounds;
111 return ((pcm == NULL
112 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
113 ? NULL : pcm);
116 static Lisp_Object xfont_get_cache (struct frame *);
117 static Lisp_Object xfont_list (struct frame *, Lisp_Object);
118 static Lisp_Object xfont_match (struct frame *, Lisp_Object);
119 static Lisp_Object xfont_list_family (struct frame *);
120 static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
121 static void xfont_close (struct font *);
122 static void xfont_prepare_face (struct frame *, struct face *);
123 static int xfont_has_char (Lisp_Object, int);
124 static unsigned xfont_encode_char (struct font *, int);
125 static void xfont_text_extents (struct font *, unsigned *, int,
126 struct font_metrics *);
127 static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
128 static int xfont_check (struct frame *, struct font *);
130 struct font_driver xfont_driver =
132 LISP_INITIALLY_ZERO, /* Qx */
133 false, /* case insensitive */
134 xfont_get_cache,
135 xfont_list,
136 xfont_match,
137 xfont_list_family,
138 NULL,
139 xfont_open,
140 xfont_close,
141 xfont_prepare_face,
142 NULL,
143 xfont_has_char,
144 xfont_encode_char,
145 xfont_text_extents,
146 xfont_draw,
147 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
148 xfont_check,
149 NULL, /* get_variation_glyphs */
150 NULL, /* filter_properties */
153 static Lisp_Object
154 xfont_get_cache (struct frame *f)
156 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
158 return (dpyinfo->name_list_element);
161 static int
162 compare_font_names (const void *name1, const void *name2)
164 char *const *n1 = name1;
165 char *const *n2 = name2;
166 return xstrcasecmp (*n1, *n2);
169 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
170 of the decoding result. LEN is the byte length of XLFD, or -1 if
171 XLFD is NULL terminated. The caller must assure that OUTPUT is at
172 least twice (plus 1) as large as XLFD. */
174 static ptrdiff_t
175 xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
177 char *p0 = xlfd, *p1 = output;
178 int c;
180 while (*p0)
182 c = *(unsigned char *) p0++;
183 p1 += CHAR_STRING (c, (unsigned char *) p1);
184 if (--len == 0)
185 break;
187 *p1 = 0;
188 return (p1 - output);
191 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
192 resulting byte length. If XLFD contains unencodable character,
193 return -1. */
195 static int
196 xfont_encode_coding_xlfd (char *xlfd)
198 const unsigned char *p0 = (unsigned char *) xlfd;
199 unsigned char *p1 = (unsigned char *) xlfd;
200 int len = 0;
202 while (*p0)
204 int c = STRING_CHAR_ADVANCE (p0);
206 if (c >= 0x100)
207 return -1;
208 *p1++ = c;
209 len++;
211 *p1 = 0;
212 return len;
215 /* Check if CHARS (cons or vector) is supported by XFONT whose
216 encoding charset is ENCODING (XFONT is NULL) or by a font whose
217 registry corresponds to ENCODING and REPERTORY.
218 Return true if supported. */
220 static bool
221 xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
222 struct charset *encoding, struct charset *repertory)
224 struct charset *charset = repertory ? repertory : encoding;
226 if (CONSP (chars))
228 for (; CONSP (chars); chars = XCDR (chars))
230 int c = XINT (XCAR (chars));
231 unsigned code = ENCODE_CHAR (charset, c);
232 XChar2b char2b;
234 if (code == CHARSET_INVALID_CODE (charset))
235 break;
236 if (! xfont)
237 continue;
238 if (code >= 0x10000)
239 break;
240 char2b.byte1 = code >> 8;
241 char2b.byte2 = code & 0xFF;
242 if (! xfont_get_pcm (xfont, &char2b))
243 break;
245 return (NILP (chars));
247 else if (VECTORP (chars))
249 ptrdiff_t i;
251 for (i = ASIZE (chars) - 1; i >= 0; i--)
253 int c = XINT (AREF (chars, i));
254 unsigned code = ENCODE_CHAR (charset, c);
255 XChar2b char2b;
257 if (code == CHARSET_INVALID_CODE (charset))
258 continue;
259 if (! xfont)
260 break;
261 if (code >= 0x10000)
262 continue;
263 char2b.byte1 = code >> 8;
264 char2b.byte2 = code & 0xFF;
265 if (xfont_get_pcm (xfont, &char2b))
266 break;
268 return (i >= 0);
270 return false;
273 /* A hash table recoding which font supports which scripts. Each key
274 is a vector of characteristic font properties FOUNDRY to WIDTH and
275 ADDSTYLE, and each value is a list of script symbols.
277 We assume that fonts that have the same value in the above
278 properties supports the same set of characters on all displays. */
280 static Lisp_Object xfont_scripts_cache;
282 /* Re-usable vector to store characteristic font properties. */
283 static Lisp_Object xfont_scratch_props;
285 /* Return a list of scripts supported by the font of FONTNAME whose
286 characteristic properties are in PROPS and whose encoding charset
287 is ENCODING. A caller must call BLOCK_INPUT in advance. */
289 static Lisp_Object
290 xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
291 struct charset *encoding)
293 Lisp_Object scripts;
295 /* Two special cases to avoid opening rather big fonts. */
296 if (EQ (AREF (props, 2), Qja))
297 return list2 (intern ("kana"), intern ("han"));
298 if (EQ (AREF (props, 2), Qko))
299 return list1 (intern ("hangul"));
300 scripts = Fgethash (props, xfont_scripts_cache, Qt);
301 if (EQ (scripts, Qt))
303 XFontStruct *xfont;
304 Lisp_Object val;
306 scripts = Qnil;
307 xfont = XLoadQueryFont (display, fontname);
308 if (xfont)
310 if (xfont->per_char)
312 for (val = Vscript_representative_chars; CONSP (val);
313 val = XCDR (val))
314 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
316 Lisp_Object script = XCAR (XCAR (val));
317 Lisp_Object chars = XCDR (XCAR (val));
319 if (xfont_chars_supported (chars, xfont, encoding, NULL))
320 scripts = Fcons (script, scripts);
323 XFreeFont (display, xfont);
325 if (EQ (AREF (props, 3), Qiso10646_1)
326 && NILP (Fmemq (Qlatin, scripts)))
327 scripts = Fcons (Qlatin, scripts);
328 Fputhash (Fcopy_sequence (props), scripts, xfont_scripts_cache);
330 return scripts;
333 static Lisp_Object
334 xfont_list_pattern (Display *display, const char *pattern,
335 Lisp_Object registry, Lisp_Object script)
337 Lisp_Object list = Qnil;
338 Lisp_Object chars = Qnil;
339 struct charset *encoding, *repertory = NULL;
340 int i, limit, num_fonts;
341 char **names;
342 /* Large enough to decode the longest XLFD (255 bytes). */
343 char buf[512];
345 if (! NILP (registry)
346 && font_registry_charsets (registry, &encoding, &repertory) < 0)
347 /* Unknown REGISTRY, not supported. */
348 return Qnil;
349 if (! NILP (script))
351 chars = assq_no_quit (script, Vscript_representative_chars);
352 if (NILP (chars))
353 /* We can't tell whether or not a font supports SCRIPT. */
354 return Qnil;
355 chars = XCDR (chars);
356 if (repertory)
358 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
359 return Qnil;
360 script = Qnil;
364 block_input ();
365 x_catch_errors (display);
367 for (limit = 512; ; limit *= 2)
369 names = XListFonts (display, pattern, limit, &num_fonts);
370 if (x_had_errors_p (display))
372 /* This error is perhaps due to insufficient memory on X
373 server. Let's just ignore it. */
374 x_clear_errors (display);
375 num_fonts = 0;
376 break;
378 if (num_fonts < limit)
379 break;
380 XFreeFontNames (names);
383 if (num_fonts > 0)
385 char **indices = alloca (sizeof (char *) * num_fonts);
386 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
387 Lisp_Object scripts = Qnil, entity = Qnil;
389 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
390 ASET (xfont_scratch_props, i, Qnil);
391 for (i = 0; i < num_fonts; i++)
392 indices[i] = names[i];
393 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
395 /* Take one or two passes over the font list. Do the second
396 pass only if we really need it, i.e., only if the first pass
397 found no fonts and skipped some scalable fonts. */
398 bool skipped_some_scalable_fonts = false;
399 for (int i_pass = 0;
400 (i_pass == 0
401 || (i_pass == 1 && NILP (list) && skipped_some_scalable_fonts));
402 i_pass++)
403 for (i = 0; i < num_fonts; i++)
405 ptrdiff_t len;
407 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
408 continue;
409 if (NILP (entity))
410 entity = font_make_entity ();
411 len = xfont_decode_coding_xlfd (indices[i], -1, buf);
412 if (font_parse_xlfd (buf, len, entity) < 0)
413 continue;
414 ASET (entity, FONT_TYPE_INDEX, Qx);
415 /* Avoid auto-scaled fonts. */
416 if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
417 && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
418 && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
419 && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
420 continue;
421 /* Avoid not-allowed scalable fonts. */
422 if (NILP (Vscalable_fonts_allowed))
424 int size = 0;
426 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
427 size = XINT (AREF (entity, FONT_SIZE_INDEX));
428 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
429 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
430 if (size == 0 && i_pass == 0)
432 skipped_some_scalable_fonts = true;
433 continue;
436 else if (CONSP (Vscalable_fonts_allowed))
438 Lisp_Object tail;
440 for (tail = Vscalable_fonts_allowed; CONSP (tail);
441 tail = XCDR (tail))
443 Lisp_Object elt = XCAR (tail);
444 if (STRINGP (elt)
445 && (fast_c_string_match_ignore_case (elt, indices[i],
446 len)
447 >= 0))
448 break;
450 if (! CONSP (tail))
451 continue;
454 /* Avoid fonts of invalid registry. */
455 if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
456 continue;
458 /* Update encoding and repertory if necessary. */
459 if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
461 registry = AREF (entity, FONT_REGISTRY_INDEX);
462 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
463 encoding = NULL;
465 if (! encoding)
466 /* Unknown REGISTRY, not supported. */
467 continue;
468 if (repertory)
470 if (NILP (script)
471 || xfont_chars_supported (chars, NULL, encoding, repertory))
472 list = Fcons (entity, list), entity = Qnil;
473 continue;
475 if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
476 word_size * 7)
477 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
479 vcopy (xfont_scratch_props, 0,
480 aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
481 ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
482 scripts = xfont_supported_scripts (display, indices[i],
483 xfont_scratch_props,
484 encoding);
486 if (NILP (script)
487 || ! NILP (Fmemq (script, scripts)))
488 list = Fcons (entity, list), entity = Qnil;
490 XFreeFontNames (names);
493 x_uncatch_errors ();
494 unblock_input ();
496 FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
497 return list;
500 static Lisp_Object
501 xfont_list (struct frame *f, Lisp_Object spec)
503 Display *display = FRAME_DISPLAY_INFO (f)->display;
504 Lisp_Object registry, list, val, extra, script;
505 int len;
506 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
507 char name[512];
509 extra = AREF (spec, FONT_EXTRA_INDEX);
510 if (CONSP (extra))
512 val = assq_no_quit (QCotf, extra);
513 if (! NILP (val))
514 return Qnil;
515 val = assq_no_quit (QClang, extra);
516 if (! NILP (val))
517 return Qnil;
520 registry = AREF (spec, FONT_REGISTRY_INDEX);
521 len = font_unparse_xlfd (spec, 0, name, 512);
522 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
523 return Qnil;
525 val = assq_no_quit (QCscript, extra);
526 script = CDR (val);
527 list = xfont_list_pattern (display, name, registry, script);
528 if (NILP (list) && NILP (registry))
530 /* Try iso10646-1 */
531 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
533 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
535 strcpy (r, "iso10646-1");
536 list = xfont_list_pattern (display, name, Qiso10646_1, script);
539 if (NILP (list) && ! NILP (registry))
541 /* Try alternate registries. */
542 Lisp_Object alter;
544 if ((alter = Fassoc (SYMBOL_NAME (registry),
545 Vface_alternative_font_registry_alist),
546 CONSP (alter)))
548 /* Pointer to REGISTRY-ENCODING field. */
549 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
551 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
552 if (STRINGP (XCAR (alter))
553 && ((r - name) + SBYTES (XCAR (alter))) < 256)
555 lispstpcpy (r, XCAR (alter));
556 list = xfont_list_pattern (display, name, registry, script);
557 if (! NILP (list))
558 break;
562 if (NILP (list))
564 /* Try alias. */
565 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
566 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
568 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
569 if (xfont_encode_coding_xlfd (name) < 0)
570 return Qnil;
571 list = xfont_list_pattern (display, name, registry, script);
575 return list;
578 static Lisp_Object
579 xfont_match (struct frame *f, Lisp_Object spec)
581 Display *display = FRAME_DISPLAY_INFO (f)->display;
582 Lisp_Object extra, val, entity;
583 char name[512];
584 XFontStruct *xfont;
585 unsigned long value;
587 extra = AREF (spec, FONT_EXTRA_INDEX);
588 val = assq_no_quit (QCname, extra);
589 if (! CONSP (val) || ! STRINGP (XCDR (val)))
591 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
592 return Qnil;
594 else if (SBYTES (XCDR (val)) < 512)
595 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
596 else
597 return Qnil;
598 if (xfont_encode_coding_xlfd (name) < 0)
599 return Qnil;
601 block_input ();
602 entity = Qnil;
603 xfont = XLoadQueryFont (display, name);
604 if (xfont)
606 if (XGetFontProperty (xfont, XA_FONT, &value))
608 char *s = XGetAtomName (display, (Atom) value);
610 /* If DXPC (a Differential X Protocol Compressor)
611 Ver.3.7 is running, XGetAtomName will return null
612 string. We must avoid such a name. */
613 if (*s)
615 ptrdiff_t len;
616 entity = font_make_entity ();
617 ASET (entity, FONT_TYPE_INDEX, Qx);
618 len = xfont_decode_coding_xlfd (s, -1, name);
619 if (font_parse_xlfd (name, len, entity) < 0)
620 entity = Qnil;
622 XFree (s);
624 XFreeFont (display, xfont);
626 unblock_input ();
628 FONT_ADD_LOG ("xfont-match", spec, entity);
629 return entity;
632 static Lisp_Object
633 xfont_list_family (struct frame *f)
635 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
636 char **names;
637 int num_fonts, i;
638 Lisp_Object list;
639 char *last_family UNINIT;
640 int last_len;
642 block_input ();
643 x_catch_errors (dpyinfo->display);
644 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
645 0x8000, &num_fonts);
646 if (x_had_errors_p (dpyinfo->display))
648 /* This error is perhaps due to insufficient memory on X server.
649 Let's just ignore it. */
650 x_clear_errors (dpyinfo->display);
651 num_fonts = 0;
654 list = Qnil;
655 for (i = 0, last_len = 0; i < num_fonts; i++)
657 char *p0 = names[i], *p1, buf[512];
658 Lisp_Object family;
659 int decoded_len;
661 p0++; /* skip the leading '-' */
662 while (*p0 && *p0 != '-') p0++; /* skip foundry */
663 if (! *p0)
664 continue;
665 p1 = ++p0;
666 while (*p1 && *p1 != '-') p1++; /* find the end of family */
667 if (! *p1 || p1 == p0)
668 continue;
669 if (last_len == p1 - p0
670 && memcmp (last_family, p0, last_len) == 0)
671 continue;
672 last_len = p1 - p0;
673 last_family = p0;
675 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
676 family = font_intern_prop (p0, decoded_len, 1);
677 if (NILP (assq_no_quit (family, list)))
678 list = Fcons (family, list);
681 XFreeFontNames (names);
682 x_uncatch_errors ();
683 unblock_input ();
685 return list;
688 static Lisp_Object
689 xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
691 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
692 Display *display = dpyinfo->display;
693 char name[512];
694 int len;
695 unsigned long value;
696 Lisp_Object registry;
697 struct charset *encoding, *repertory;
698 Lisp_Object font_object, fullname;
699 struct font *font;
700 XFontStruct *xfont;
702 /* At first, check if we know how to encode characters for this
703 font. */
704 registry = AREF (entity, FONT_REGISTRY_INDEX);
705 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
707 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
708 return Qnil;
711 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
712 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
713 else if (pixel_size == 0)
715 if (FRAME_FONT (f))
716 pixel_size = FRAME_FONT (f)->pixel_size;
717 else
718 pixel_size = 14;
720 len = font_unparse_xlfd (entity, pixel_size, name, 512);
721 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
723 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
724 return Qnil;
727 block_input ();
728 x_catch_errors (display);
729 xfont = XLoadQueryFont (display, name);
730 if (x_had_errors_p (display))
732 /* This error is perhaps due to insufficient memory on X server.
733 Let's just ignore it. */
734 x_clear_errors (display);
735 xfont = NULL;
737 else if (! xfont)
739 /* Some version of X lists:
740 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
741 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
742 but can open only:
743 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
745 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
746 So, we try again with wildcards in RESX and RESY. */
747 Lisp_Object temp;
749 temp = copy_font_spec (entity);
750 ASET (temp, FONT_DPI_INDEX, Qnil);
751 len = font_unparse_xlfd (temp, pixel_size, name, 512);
752 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
754 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
755 return Qnil;
757 xfont = XLoadQueryFont (display, name);
758 if (x_had_errors_p (display))
760 /* This error is perhaps due to insufficient memory on X server.
761 Let's just ignore it. */
762 x_clear_errors (display);
763 xfont = NULL;
766 fullname = Qnil;
767 /* Try to get the full name of FONT. */
768 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
770 char *p0, *p;
771 int dashes = 0;
773 p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
774 /* Count the number of dashes in the "full name".
775 If it is too few, this isn't really the font's full name,
776 so don't use it.
777 In X11R4, the fonts did not come with their canonical names
778 stored in them. */
779 while (*p)
781 if (*p == '-')
782 dashes++;
783 p++;
786 if (dashes >= 13)
788 len = xfont_decode_coding_xlfd (p0, -1, name);
789 fullname = Fdowncase (make_string (name, len));
791 XFree (p0);
793 x_uncatch_errors ();
794 unblock_input ();
796 if (! xfont)
798 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
799 return Qnil;
802 font_object = font_make_object (VECSIZE (struct xfont_info),
803 entity, pixel_size);
804 ASET (font_object, FONT_TYPE_INDEX, Qx);
805 if (STRINGP (fullname))
807 font_parse_xlfd (SSDATA (fullname), SBYTES (fullname), font_object);
808 ASET (font_object, FONT_NAME_INDEX, fullname);
810 else
812 char buf[512];
814 len = xfont_decode_coding_xlfd (name, -1, buf);
815 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
817 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
818 font = XFONT_OBJECT (font_object);
819 ((struct xfont_info *) font)->xfont = xfont;
820 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
821 ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
822 font->pixel_size = pixel_size;
823 font->driver = &xfont_driver;
824 font->encoding_charset = encoding->id;
825 font->repertory_charset = repertory ? repertory->id : -1;
826 font->ascent = xfont->ascent;
827 font->descent = xfont->descent;
828 font->height = font->ascent + font->descent;
829 font->min_width = xfont->min_bounds.width;
830 font->max_width = xfont->max_bounds.width;
831 if (xfont->min_bounds.width == xfont->max_bounds.width)
833 /* Fixed width font. */
834 font->average_width = font->space_width = xfont->min_bounds.width;
836 else
838 XCharStruct *pcm;
839 XChar2b char2b;
840 Lisp_Object val;
842 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
843 pcm = xfont_get_pcm (xfont, &char2b);
844 if (pcm)
845 font->space_width = pcm->width;
846 else
847 font->space_width = 0;
849 val = Ffont_get (font_object, QCavgwidth);
850 if (INTEGERP (val))
851 font->average_width = XINT (val) / 10;
852 if (font->average_width < 0)
853 font->average_width = - font->average_width;
854 else
856 if (font->average_width == 0
857 && encoding->ascii_compatible_p)
859 int width = font->space_width, n = pcm != NULL;
861 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
862 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
863 width += pcm->width, n++;
864 if (n > 0)
865 font->average_width = width / n;
867 if (font->average_width == 0)
868 /* No easy way other than this to get a reasonable
869 average_width. */
870 font->average_width
871 = (xfont->min_bounds.width + xfont->max_bounds.width) / 2;
875 block_input ();
876 font->underline_thickness
877 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
878 ? (long) value : 0);
879 font->underline_position
880 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
881 ? (long) value : -1);
882 font->baseline_offset
883 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
884 ? (long) value : 0);
885 font->relative_compose
886 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
887 ? (long) value : 0);
888 font->default_ascent
889 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
890 ? (long) value : 0);
891 unblock_input ();
893 if (NILP (fullname))
894 fullname = AREF (font_object, FONT_NAME_INDEX);
895 font->vertical_centering
896 = (STRINGP (Vvertical_centering_font_regexp)
897 && (fast_string_match_ignore_case
898 (Vvertical_centering_font_regexp, fullname) >= 0));
900 return font_object;
903 static void
904 xfont_close (struct font *font)
906 struct x_display_info *xdi;
907 struct xfont_info *xfi = (struct xfont_info *) font;
909 /* This function may be called from GC when X connection is gone
910 (Bug#16093), and an attempt to free font resources on invalid
911 display may lead to X protocol errors or segfaults. Moreover,
912 the memory referenced by 'Display *' pointer may be reused for
913 the logically different X connection after the previous display
914 connection was closed. That's why we also check whether font's
915 ID matches the one recorded in x_display_info for this display.
916 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
917 if (xfi->xfont
918 && ((xdi = x_display_info_for_display (xfi->display))
919 && xfi->x_display_id == xdi->x_id))
921 block_input ();
922 XFreeFont (xfi->display, xfi->xfont);
923 unblock_input ();
924 xfi->xfont = NULL;
928 static void
929 xfont_prepare_face (struct frame *f, struct face *face)
931 block_input ();
932 XSetFont (FRAME_X_DISPLAY (f), face->gc,
933 ((struct xfont_info *) face->font)->xfont->fid);
934 unblock_input ();
937 static int
938 xfont_has_char (Lisp_Object font, int c)
940 Lisp_Object registry = AREF (font, FONT_REGISTRY_INDEX);
941 struct charset *encoding;
942 struct charset *repertory = NULL;
944 if (EQ (registry, Qiso10646_1))
946 encoding = CHARSET_FROM_ID (charset_unicode);
947 /* We use a font of `ja' and `ko' adstyle only for a character
948 in JISX0208 and KSC5601 charsets respectively. */
949 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
950 && charset_jisx0208 >= 0)
951 repertory = CHARSET_FROM_ID (charset_jisx0208);
952 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
953 && charset_ksc5601 >= 0)
954 repertory = CHARSET_FROM_ID (charset_ksc5601);
956 else if (font_registry_charsets (registry, &encoding, &repertory) < 0)
957 /* Unknown REGISTRY, not usable. */
958 return 0;
959 if (ASCII_CHAR_P (c) && encoding->ascii_compatible_p)
960 return 1;
961 if (! repertory)
962 return -1;
963 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
966 static unsigned
967 xfont_encode_char (struct font *font, int c)
969 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
970 struct charset *charset;
971 unsigned code;
972 XChar2b char2b;
974 charset = CHARSET_FROM_ID (font->encoding_charset);
975 code = ENCODE_CHAR (charset, c);
976 if (code == CHARSET_INVALID_CODE (charset))
977 return FONT_INVALID_CODE;
978 if (font->repertory_charset >= 0)
980 charset = CHARSET_FROM_ID (font->repertory_charset);
981 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
982 ? code : FONT_INVALID_CODE);
984 char2b.byte1 = code >> 8;
985 char2b.byte2 = code & 0xFF;
986 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
989 static void
990 xfont_text_extents (struct font *font, unsigned int *code,
991 int nglyphs, struct font_metrics *metrics)
993 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
994 int i, width = 0;
995 bool first;
997 for (i = 0, first = true; i < nglyphs; i++)
999 XChar2b char2b;
1000 static XCharStruct *pcm;
1002 if (code[i] >= 0x10000)
1003 continue;
1004 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
1005 pcm = xfont_get_pcm (xfont, &char2b);
1006 if (! pcm)
1007 continue;
1008 if (first)
1010 metrics->lbearing = pcm->lbearing;
1011 metrics->rbearing = pcm->rbearing;
1012 metrics->ascent = pcm->ascent;
1013 metrics->descent = pcm->descent;
1014 first = false;
1016 else
1018 if (metrics->lbearing > width + pcm->lbearing)
1019 metrics->lbearing = width + pcm->lbearing;
1020 if (metrics->rbearing < width + pcm->rbearing)
1021 metrics->rbearing = width + pcm->rbearing;
1022 if (metrics->ascent < pcm->ascent)
1023 metrics->ascent = pcm->ascent;
1024 if (metrics->descent < pcm->descent)
1025 metrics->descent = pcm->descent;
1027 width += pcm->width;
1030 metrics->width = width;
1033 static int
1034 xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1035 bool with_background)
1037 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
1038 int len = to - from;
1039 GC gc = s->gc;
1040 int i;
1042 if (s->gc != s->face->gc)
1044 block_input ();
1045 XSetFont (s->display, gc, xfont->fid);
1046 unblock_input ();
1049 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1051 USE_SAFE_ALLOCA;
1052 char *str = SAFE_ALLOCA (len);
1053 for (i = 0; i < len ; i++)
1054 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
1055 block_input ();
1056 if (with_background)
1058 if (s->padding_p)
1059 for (i = 0; i < len; i++)
1060 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1061 gc, x + i, y, str + i, 1);
1062 else
1063 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1064 gc, x, y, str, len);
1066 else
1068 if (s->padding_p)
1069 for (i = 0; i < len; i++)
1070 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1071 gc, x + i, y, str + i, 1);
1072 else
1073 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1074 gc, x, y, str, len);
1076 unblock_input ();
1077 SAFE_FREE ();
1078 return s->nchars;
1081 block_input ();
1082 if (with_background)
1084 if (s->padding_p)
1085 for (i = 0; i < len; i++)
1086 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1087 gc, x + i, y, s->char2b + from + i, 1);
1088 else
1089 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1090 gc, x, y, s->char2b + from, len);
1092 else
1094 if (s->padding_p)
1095 for (i = 0; i < len; i++)
1096 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1097 gc, x + i, y, s->char2b + from + i, 1);
1098 else
1099 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1100 gc, x, y, s->char2b + from, len);
1102 unblock_input ();
1104 return len;
1107 static int
1108 xfont_check (struct frame *f, struct font *font)
1110 struct xfont_info *xfont = (struct xfont_info *) font;
1112 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1116 void
1117 syms_of_xfont (void)
1119 staticpro (&xfont_scripts_cache);
1120 xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
1121 staticpro (&xfont_scratch_props);
1122 xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
1123 xfont_driver.type = Qx;
1124 register_font_driver (&xfont_driver, NULL);