Use save-excursion in xref-location-marker more
[emacs.git] / src / xfont.c
blob0ef64bef10e6ee1501309d1c6ed4fbe6cf70b633
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 <X11/Xlib.h>
26 #include "lisp.h"
27 #include "xterm.h"
28 #include "frame.h"
29 #include "blockinput.h"
30 #include "character.h"
31 #include "charset.h"
32 #include "font.h"
35 /* X core font driver. */
37 struct xfont_info
39 struct font font;
40 Display *display;
41 XFontStruct *xfont;
42 unsigned x_display_id;
45 /* Prototypes of support functions. */
47 static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
49 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
50 is not contained in the font. */
52 static XCharStruct *
53 xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
55 /* The result metric information. */
56 XCharStruct *pcm = NULL;
58 eassert (xfont && char2b);
60 if (xfont->per_char != NULL)
62 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
64 /* min_char_or_byte2 specifies the linear character index
65 corresponding to the first element of the per_char array,
66 max_char_or_byte2 is the index of the last character. A
67 character with non-zero CHAR2B->byte1 is not in the font.
68 A character with byte2 less than min_char_or_byte2 or
69 greater max_char_or_byte2 is not in the font. */
70 if (char2b->byte1 == 0
71 && char2b->byte2 >= xfont->min_char_or_byte2
72 && char2b->byte2 <= xfont->max_char_or_byte2)
73 pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
75 else
77 /* If either min_byte1 or max_byte1 are nonzero, both
78 min_char_or_byte2 and max_char_or_byte2 are less than
79 256, and the 2-byte character index values corresponding
80 to the per_char array element N (counting from 0) are:
82 byte1 = N/D + min_byte1
83 byte2 = N\D + min_char_or_byte2
85 where:
87 D = max_char_or_byte2 - min_char_or_byte2 + 1
88 / = integer division
89 \ = integer modulus */
90 if (char2b->byte1 >= xfont->min_byte1
91 && char2b->byte1 <= xfont->max_byte1
92 && char2b->byte2 >= xfont->min_char_or_byte2
93 && char2b->byte2 <= xfont->max_char_or_byte2)
94 pcm = (xfont->per_char
95 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
96 * (char2b->byte1 - xfont->min_byte1))
97 + (char2b->byte2 - xfont->min_char_or_byte2));
100 else
102 /* If the per_char pointer is null, all glyphs between the first
103 and last character indexes inclusive have the same
104 information, as given by both min_bounds and max_bounds. */
105 if (char2b->byte2 >= xfont->min_char_or_byte2
106 && char2b->byte2 <= xfont->max_char_or_byte2)
107 pcm = &xfont->max_bounds;
110 return ((pcm == NULL
111 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
112 ? NULL : pcm);
115 static Lisp_Object xfont_get_cache (struct frame *);
116 static Lisp_Object xfont_list (struct frame *, Lisp_Object);
117 static Lisp_Object xfont_match (struct frame *, Lisp_Object);
118 static Lisp_Object xfont_list_family (struct frame *);
119 static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
120 static void xfont_close (struct font *);
121 static void xfont_prepare_face (struct frame *, struct face *);
122 static int xfont_has_char (Lisp_Object, int);
123 static unsigned xfont_encode_char (struct font *, int);
124 static void xfont_text_extents (struct font *, unsigned *, int,
125 struct font_metrics *);
126 static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
127 static int xfont_check (struct frame *, struct font *);
129 struct font_driver xfont_driver =
131 LISP_INITIALLY_ZERO, /* Qx */
132 false, /* case insensitive */
133 xfont_get_cache,
134 xfont_list,
135 xfont_match,
136 xfont_list_family,
137 NULL,
138 xfont_open,
139 xfont_close,
140 xfont_prepare_face,
141 NULL,
142 xfont_has_char,
143 xfont_encode_char,
144 xfont_text_extents,
145 xfont_draw,
146 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
147 xfont_check,
148 NULL, /* get_variation_glyphs */
149 NULL, /* filter_properties */
152 static Lisp_Object
153 xfont_get_cache (struct frame *f)
155 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
157 return (dpyinfo->name_list_element);
160 static int
161 compare_font_names (const void *name1, const void *name2)
163 char *const *n1 = name1;
164 char *const *n2 = name2;
165 return xstrcasecmp (*n1, *n2);
168 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
169 of the decoding result. LEN is the byte length of XLFD, or -1 if
170 XLFD is NULL terminated. The caller must assure that OUTPUT is at
171 least twice (plus 1) as large as XLFD. */
173 static ptrdiff_t
174 xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
176 char *p0 = xlfd, *p1 = output;
177 int c;
179 while (*p0)
181 c = *(unsigned char *) p0++;
182 p1 += CHAR_STRING (c, (unsigned char *) p1);
183 if (--len == 0)
184 break;
186 *p1 = 0;
187 return (p1 - output);
190 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
191 resulting byte length. If XLFD contains unencodable character,
192 return -1. */
194 static int
195 xfont_encode_coding_xlfd (char *xlfd)
197 const unsigned char *p0 = (unsigned char *) xlfd;
198 unsigned char *p1 = (unsigned char *) xlfd;
199 int len = 0;
201 while (*p0)
203 int c = STRING_CHAR_ADVANCE (p0);
205 if (c >= 0x100)
206 return -1;
207 *p1++ = c;
208 len++;
210 *p1 = 0;
211 return len;
214 /* Check if CHARS (cons or vector) is supported by XFONT whose
215 encoding charset is ENCODING (XFONT is NULL) or by a font whose
216 registry corresponds to ENCODING and REPERTORY.
217 Return true if supported. */
219 static bool
220 xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
221 struct charset *encoding, struct charset *repertory)
223 struct charset *charset = repertory ? repertory : encoding;
225 if (CONSP (chars))
227 for (; CONSP (chars); chars = XCDR (chars))
229 int c = XINT (XCAR (chars));
230 unsigned code = ENCODE_CHAR (charset, c);
231 XChar2b char2b;
233 if (code == CHARSET_INVALID_CODE (charset))
234 break;
235 if (! xfont)
236 continue;
237 if (code >= 0x10000)
238 break;
239 char2b.byte1 = code >> 8;
240 char2b.byte2 = code & 0xFF;
241 if (! xfont_get_pcm (xfont, &char2b))
242 break;
244 return (NILP (chars));
246 else if (VECTORP (chars))
248 ptrdiff_t i;
250 for (i = ASIZE (chars) - 1; i >= 0; i--)
252 int c = XINT (AREF (chars, i));
253 unsigned code = ENCODE_CHAR (charset, c);
254 XChar2b char2b;
256 if (code == CHARSET_INVALID_CODE (charset))
257 continue;
258 if (! xfont)
259 break;
260 if (code >= 0x10000)
261 continue;
262 char2b.byte1 = code >> 8;
263 char2b.byte2 = code & 0xFF;
264 if (xfont_get_pcm (xfont, &char2b))
265 break;
267 return (i >= 0);
269 return false;
272 /* A hash table recoding which font supports which scripts. Each key
273 is a vector of characteristic font properties FOUNDRY to WIDTH and
274 ADDSTYLE, and each value is a list of script symbols.
276 We assume that fonts that have the same value in the above
277 properties supports the same set of characters on all displays. */
279 static Lisp_Object xfont_scripts_cache;
281 /* Re-usable vector to store characteristic font properties. */
282 static Lisp_Object xfont_scratch_props;
284 /* Return a list of scripts supported by the font of FONTNAME whose
285 characteristic properties are in PROPS and whose encoding charset
286 is ENCODING. A caller must call BLOCK_INPUT in advance. */
288 static Lisp_Object
289 xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
290 struct charset *encoding)
292 Lisp_Object scripts;
294 /* Two special cases to avoid opening rather big fonts. */
295 if (EQ (AREF (props, 2), Qja))
296 return list2 (intern ("kana"), intern ("han"));
297 if (EQ (AREF (props, 2), Qko))
298 return list1 (intern ("hangul"));
299 scripts = Fgethash (props, xfont_scripts_cache, Qt);
300 if (EQ (scripts, Qt))
302 XFontStruct *xfont;
303 Lisp_Object val;
305 scripts = Qnil;
306 xfont = XLoadQueryFont (display, fontname);
307 if (xfont)
309 if (xfont->per_char)
311 for (val = Vscript_representative_chars; CONSP (val);
312 val = XCDR (val))
313 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
315 Lisp_Object script = XCAR (XCAR (val));
316 Lisp_Object chars = XCDR (XCAR (val));
318 if (xfont_chars_supported (chars, xfont, encoding, NULL))
319 scripts = Fcons (script, scripts);
322 XFreeFont (display, xfont);
324 if (EQ (AREF (props, 3), Qiso10646_1)
325 && NILP (Fmemq (Qlatin, scripts)))
326 scripts = Fcons (Qlatin, scripts);
327 Fputhash (Fcopy_sequence (props), scripts, xfont_scripts_cache);
329 return scripts;
332 static Lisp_Object
333 xfont_list_pattern (Display *display, const char *pattern,
334 Lisp_Object registry, Lisp_Object script)
336 Lisp_Object list = Qnil;
337 Lisp_Object chars = Qnil;
338 struct charset *encoding, *repertory = NULL;
339 int i, limit, num_fonts;
340 char **names;
341 /* Large enough to decode the longest XLFD (255 bytes). */
342 char buf[512];
344 if (! NILP (registry)
345 && font_registry_charsets (registry, &encoding, &repertory) < 0)
346 /* Unknown REGISTRY, not supported. */
347 return Qnil;
348 if (! NILP (script))
350 chars = assq_no_quit (script, Vscript_representative_chars);
351 if (NILP (chars))
352 /* We can't tell whether or not a font supports SCRIPT. */
353 return Qnil;
354 chars = XCDR (chars);
355 if (repertory)
357 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
358 return Qnil;
359 script = Qnil;
363 block_input ();
364 x_catch_errors (display);
366 for (limit = 512; ; limit *= 2)
368 names = XListFonts (display, pattern, limit, &num_fonts);
369 if (x_had_errors_p (display))
371 /* This error is perhaps due to insufficient memory on X
372 server. Let's just ignore it. */
373 x_clear_errors (display);
374 num_fonts = 0;
375 break;
377 if (num_fonts < limit)
378 break;
379 XFreeFontNames (names);
382 if (num_fonts > 0)
384 char **indices = alloca (sizeof (char *) * num_fonts);
385 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
386 Lisp_Object scripts = Qnil, entity = Qnil;
388 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
389 ASET (xfont_scratch_props, i, Qnil);
390 for (i = 0; i < num_fonts; i++)
391 indices[i] = names[i];
392 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
394 /* Take one or two passes over the font list. Do the second
395 pass only if we really need it, i.e., only if the first pass
396 found no fonts and skipped some scalable fonts. */
397 bool skipped_some_scalable_fonts = false;
398 for (int i_pass = 0;
399 (i_pass == 0
400 || (i_pass == 1 && NILP (list) && skipped_some_scalable_fonts));
401 i_pass++)
402 for (i = 0; i < num_fonts; i++)
404 ptrdiff_t len;
406 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
407 continue;
408 if (NILP (entity))
409 entity = font_make_entity ();
410 len = xfont_decode_coding_xlfd (indices[i], -1, buf);
411 if (font_parse_xlfd (buf, len, entity) < 0)
412 continue;
413 ASET (entity, FONT_TYPE_INDEX, Qx);
414 /* Avoid auto-scaled fonts. */
415 if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
416 && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
417 && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
418 && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
419 continue;
420 /* Avoid not-allowed scalable fonts. */
421 if (NILP (Vscalable_fonts_allowed))
423 int size = 0;
425 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
426 size = XINT (AREF (entity, FONT_SIZE_INDEX));
427 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
428 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
429 if (size == 0 && i_pass == 0)
431 skipped_some_scalable_fonts = true;
432 continue;
435 else if (CONSP (Vscalable_fonts_allowed))
437 Lisp_Object tail;
439 for (tail = Vscalable_fonts_allowed; CONSP (tail);
440 tail = XCDR (tail))
442 Lisp_Object elt = XCAR (tail);
443 if (STRINGP (elt)
444 && (fast_c_string_match_ignore_case (elt, indices[i],
445 len)
446 >= 0))
447 break;
449 if (! CONSP (tail))
450 continue;
453 /* Avoid fonts of invalid registry. */
454 if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
455 continue;
457 /* Update encoding and repertory if necessary. */
458 if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
460 registry = AREF (entity, FONT_REGISTRY_INDEX);
461 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
462 encoding = NULL;
464 if (! encoding)
465 /* Unknown REGISTRY, not supported. */
466 continue;
467 if (repertory)
469 if (NILP (script)
470 || xfont_chars_supported (chars, NULL, encoding, repertory))
471 list = Fcons (entity, list), entity = Qnil;
472 continue;
474 if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
475 word_size * 7)
476 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
478 vcopy (xfont_scratch_props, 0,
479 aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
480 ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
481 scripts = xfont_supported_scripts (display, indices[i],
482 xfont_scratch_props,
483 encoding);
485 if (NILP (script)
486 || ! NILP (Fmemq (script, scripts)))
487 list = Fcons (entity, list), entity = Qnil;
489 XFreeFontNames (names);
492 x_uncatch_errors ();
493 unblock_input ();
495 FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
496 return list;
499 static Lisp_Object
500 xfont_list (struct frame *f, Lisp_Object spec)
502 Display *display = FRAME_DISPLAY_INFO (f)->display;
503 Lisp_Object registry, list, val, extra, script;
504 int len;
505 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
506 char name[512];
508 extra = AREF (spec, FONT_EXTRA_INDEX);
509 if (CONSP (extra))
511 val = assq_no_quit (QCotf, extra);
512 if (! NILP (val))
513 return Qnil;
514 val = assq_no_quit (QClang, extra);
515 if (! NILP (val))
516 return Qnil;
519 registry = AREF (spec, FONT_REGISTRY_INDEX);
520 len = font_unparse_xlfd (spec, 0, name, 512);
521 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
522 return Qnil;
524 val = assq_no_quit (QCscript, extra);
525 script = CDR (val);
526 list = xfont_list_pattern (display, name, registry, script);
527 if (NILP (list) && NILP (registry))
529 /* Try iso10646-1 */
530 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
532 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
534 strcpy (r, "iso10646-1");
535 list = xfont_list_pattern (display, name, Qiso10646_1, script);
538 if (NILP (list) && ! NILP (registry))
540 /* Try alternate registries. */
541 Lisp_Object alter;
543 if ((alter = Fassoc (SYMBOL_NAME (registry),
544 Vface_alternative_font_registry_alist),
545 CONSP (alter)))
547 /* Pointer to REGISTRY-ENCODING field. */
548 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
550 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
551 if (STRINGP (XCAR (alter))
552 && ((r - name) + SBYTES (XCAR (alter))) < 256)
554 lispstpcpy (r, XCAR (alter));
555 list = xfont_list_pattern (display, name, registry, script);
556 if (! NILP (list))
557 break;
561 if (NILP (list))
563 /* Try alias. */
564 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
565 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
567 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
568 if (xfont_encode_coding_xlfd (name) < 0)
569 return Qnil;
570 list = xfont_list_pattern (display, name, registry, script);
574 return list;
577 static Lisp_Object
578 xfont_match (struct frame *f, Lisp_Object spec)
580 Display *display = FRAME_DISPLAY_INFO (f)->display;
581 Lisp_Object extra, val, entity;
582 char name[512];
583 XFontStruct *xfont;
584 unsigned long value;
586 extra = AREF (spec, FONT_EXTRA_INDEX);
587 val = assq_no_quit (QCname, extra);
588 if (! CONSP (val) || ! STRINGP (XCDR (val)))
590 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
591 return Qnil;
593 else if (SBYTES (XCDR (val)) < 512)
594 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
595 else
596 return Qnil;
597 if (xfont_encode_coding_xlfd (name) < 0)
598 return Qnil;
600 block_input ();
601 entity = Qnil;
602 xfont = XLoadQueryFont (display, name);
603 if (xfont)
605 if (XGetFontProperty (xfont, XA_FONT, &value))
607 char *s = XGetAtomName (display, (Atom) value);
609 /* If DXPC (a Differential X Protocol Compressor)
610 Ver.3.7 is running, XGetAtomName will return null
611 string. We must avoid such a name. */
612 if (*s)
614 ptrdiff_t len;
615 entity = font_make_entity ();
616 ASET (entity, FONT_TYPE_INDEX, Qx);
617 len = xfont_decode_coding_xlfd (s, -1, name);
618 if (font_parse_xlfd (name, len, entity) < 0)
619 entity = Qnil;
621 XFree (s);
623 XFreeFont (display, xfont);
625 unblock_input ();
627 FONT_ADD_LOG ("xfont-match", spec, entity);
628 return entity;
631 static Lisp_Object
632 xfont_list_family (struct frame *f)
634 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
635 char **names;
636 int num_fonts, i;
637 Lisp_Object list;
638 char *last_family IF_LINT (= 0);
639 int last_len;
641 block_input ();
642 x_catch_errors (dpyinfo->display);
643 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
644 0x8000, &num_fonts);
645 if (x_had_errors_p (dpyinfo->display))
647 /* This error is perhaps due to insufficient memory on X server.
648 Let's just ignore it. */
649 x_clear_errors (dpyinfo->display);
650 num_fonts = 0;
653 list = Qnil;
654 for (i = 0, last_len = 0; i < num_fonts; i++)
656 char *p0 = names[i], *p1, buf[512];
657 Lisp_Object family;
658 int decoded_len;
660 p0++; /* skip the leading '-' */
661 while (*p0 && *p0 != '-') p0++; /* skip foundry */
662 if (! *p0)
663 continue;
664 p1 = ++p0;
665 while (*p1 && *p1 != '-') p1++; /* find the end of family */
666 if (! *p1 || p1 == p0)
667 continue;
668 if (last_len == p1 - p0
669 && memcmp (last_family, p0, last_len) == 0)
670 continue;
671 last_len = p1 - p0;
672 last_family = p0;
674 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
675 family = font_intern_prop (p0, decoded_len, 1);
676 if (NILP (assq_no_quit (family, list)))
677 list = Fcons (family, list);
680 XFreeFontNames (names);
681 x_uncatch_errors ();
682 unblock_input ();
684 return list;
687 static Lisp_Object
688 xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
690 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
691 Display *display = dpyinfo->display;
692 char name[512];
693 int len;
694 unsigned long value;
695 Lisp_Object registry;
696 struct charset *encoding, *repertory;
697 Lisp_Object font_object, fullname;
698 struct font *font;
699 XFontStruct *xfont;
701 /* At first, check if we know how to encode characters for this
702 font. */
703 registry = AREF (entity, FONT_REGISTRY_INDEX);
704 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
706 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
707 return Qnil;
710 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
711 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
712 else if (pixel_size == 0)
714 if (FRAME_FONT (f))
715 pixel_size = FRAME_FONT (f)->pixel_size;
716 else
717 pixel_size = 14;
719 len = font_unparse_xlfd (entity, pixel_size, name, 512);
720 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
722 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
723 return Qnil;
726 block_input ();
727 x_catch_errors (display);
728 xfont = XLoadQueryFont (display, name);
729 if (x_had_errors_p (display))
731 /* This error is perhaps due to insufficient memory on X server.
732 Let's just ignore it. */
733 x_clear_errors (display);
734 xfont = NULL;
736 else if (! xfont)
738 /* Some version of X lists:
739 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
740 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
741 but can open only:
742 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
744 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
745 So, we try again with wildcards in RESX and RESY. */
746 Lisp_Object temp;
748 temp = copy_font_spec (entity);
749 ASET (temp, FONT_DPI_INDEX, Qnil);
750 len = font_unparse_xlfd (temp, pixel_size, name, 512);
751 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
753 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
754 return Qnil;
756 xfont = XLoadQueryFont (display, name);
757 if (x_had_errors_p (display))
759 /* This error is perhaps due to insufficient memory on X server.
760 Let's just ignore it. */
761 x_clear_errors (display);
762 xfont = NULL;
765 fullname = Qnil;
766 /* Try to get the full name of FONT. */
767 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
769 char *p0, *p;
770 int dashes = 0;
772 p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
773 /* Count the number of dashes in the "full name".
774 If it is too few, this isn't really the font's full name,
775 so don't use it.
776 In X11R4, the fonts did not come with their canonical names
777 stored in them. */
778 while (*p)
780 if (*p == '-')
781 dashes++;
782 p++;
785 if (dashes >= 13)
787 len = xfont_decode_coding_xlfd (p0, -1, name);
788 fullname = Fdowncase (make_string (name, len));
790 XFree (p0);
792 x_uncatch_errors ();
793 unblock_input ();
795 if (! xfont)
797 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
798 return Qnil;
801 font_object = font_make_object (VECSIZE (struct xfont_info),
802 entity, pixel_size);
803 ASET (font_object, FONT_TYPE_INDEX, Qx);
804 if (STRINGP (fullname))
806 font_parse_xlfd (SSDATA (fullname), SBYTES (fullname), font_object);
807 ASET (font_object, FONT_NAME_INDEX, fullname);
809 else
811 char buf[512];
813 len = xfont_decode_coding_xlfd (name, -1, buf);
814 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
816 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
817 font = XFONT_OBJECT (font_object);
818 ((struct xfont_info *) font)->xfont = xfont;
819 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
820 ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
821 font->pixel_size = pixel_size;
822 font->driver = &xfont_driver;
823 font->encoding_charset = encoding->id;
824 font->repertory_charset = repertory ? repertory->id : -1;
825 font->ascent = xfont->ascent;
826 font->descent = xfont->descent;
827 font->height = font->ascent + font->descent;
828 font->min_width = xfont->min_bounds.width;
829 font->max_width = xfont->max_bounds.width;
830 if (xfont->min_bounds.width == xfont->max_bounds.width)
832 /* Fixed width font. */
833 font->average_width = font->space_width = xfont->min_bounds.width;
835 else
837 XCharStruct *pcm;
838 XChar2b char2b;
839 Lisp_Object val;
841 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
842 pcm = xfont_get_pcm (xfont, &char2b);
843 if (pcm)
844 font->space_width = pcm->width;
845 else
846 font->space_width = 0;
848 val = Ffont_get (font_object, QCavgwidth);
849 if (INTEGERP (val))
850 font->average_width = XINT (val) / 10;
851 if (font->average_width < 0)
852 font->average_width = - font->average_width;
853 else
855 if (font->average_width == 0
856 && encoding->ascii_compatible_p)
858 int width = font->space_width, n = pcm != NULL;
860 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
861 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
862 width += pcm->width, n++;
863 if (n > 0)
864 font->average_width = width / n;
866 if (font->average_width == 0)
867 /* No easy way other than this to get a reasonable
868 average_width. */
869 font->average_width
870 = (xfont->min_bounds.width + xfont->max_bounds.width) / 2;
874 block_input ();
875 font->underline_thickness
876 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
877 ? (long) value : 0);
878 font->underline_position
879 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
880 ? (long) value : -1);
881 font->baseline_offset
882 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
883 ? (long) value : 0);
884 font->relative_compose
885 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
886 ? (long) value : 0);
887 font->default_ascent
888 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
889 ? (long) value : 0);
890 unblock_input ();
892 if (NILP (fullname))
893 fullname = AREF (font_object, FONT_NAME_INDEX);
894 font->vertical_centering
895 = (STRINGP (Vvertical_centering_font_regexp)
896 && (fast_string_match_ignore_case
897 (Vvertical_centering_font_regexp, fullname) >= 0));
899 return font_object;
902 static void
903 xfont_close (struct font *font)
905 struct x_display_info *xdi;
906 struct xfont_info *xfi = (struct xfont_info *) font;
908 /* This function may be called from GC when X connection is gone
909 (Bug#16093), and an attempt to free font resources on invalid
910 display may lead to X protocol errors or segfaults. Moreover,
911 the memory referenced by 'Display *' pointer may be reused for
912 the logically different X connection after the previous display
913 connection was closed. That's why we also check whether font's
914 ID matches the one recorded in x_display_info for this display.
915 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
916 if (xfi->xfont
917 && ((xdi = x_display_info_for_display (xfi->display))
918 && xfi->x_display_id == xdi->x_id))
920 block_input ();
921 XFreeFont (xfi->display, xfi->xfont);
922 unblock_input ();
923 xfi->xfont = NULL;
927 static void
928 xfont_prepare_face (struct frame *f, struct face *face)
930 block_input ();
931 XSetFont (FRAME_X_DISPLAY (f), face->gc,
932 ((struct xfont_info *) face->font)->xfont->fid);
933 unblock_input ();
936 static int
937 xfont_has_char (Lisp_Object font, int c)
939 Lisp_Object registry = AREF (font, FONT_REGISTRY_INDEX);
940 struct charset *encoding;
941 struct charset *repertory = NULL;
943 if (EQ (registry, Qiso10646_1))
945 encoding = CHARSET_FROM_ID (charset_unicode);
946 /* We use a font of `ja' and `ko' adstyle only for a character
947 in JISX0208 and KSC5601 charsets respectively. */
948 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
949 && charset_jisx0208 >= 0)
950 repertory = CHARSET_FROM_ID (charset_jisx0208);
951 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
952 && charset_ksc5601 >= 0)
953 repertory = CHARSET_FROM_ID (charset_ksc5601);
955 else if (font_registry_charsets (registry, &encoding, &repertory) < 0)
956 /* Unknown REGISTRY, not usable. */
957 return 0;
958 if (ASCII_CHAR_P (c) && encoding->ascii_compatible_p)
959 return 1;
960 if (! repertory)
961 return -1;
962 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
965 static unsigned
966 xfont_encode_char (struct font *font, int c)
968 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
969 struct charset *charset;
970 unsigned code;
971 XChar2b char2b;
973 charset = CHARSET_FROM_ID (font->encoding_charset);
974 code = ENCODE_CHAR (charset, c);
975 if (code == CHARSET_INVALID_CODE (charset))
976 return FONT_INVALID_CODE;
977 if (font->repertory_charset >= 0)
979 charset = CHARSET_FROM_ID (font->repertory_charset);
980 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
981 ? code : FONT_INVALID_CODE);
983 char2b.byte1 = code >> 8;
984 char2b.byte2 = code & 0xFF;
985 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
988 static void
989 xfont_text_extents (struct font *font, unsigned int *code,
990 int nglyphs, struct font_metrics *metrics)
992 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
993 int i, width = 0;
994 bool first;
996 for (i = 0, first = true; i < nglyphs; i++)
998 XChar2b char2b;
999 static XCharStruct *pcm;
1001 if (code[i] >= 0x10000)
1002 continue;
1003 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
1004 pcm = xfont_get_pcm (xfont, &char2b);
1005 if (! pcm)
1006 continue;
1007 if (first)
1009 metrics->lbearing = pcm->lbearing;
1010 metrics->rbearing = pcm->rbearing;
1011 metrics->ascent = pcm->ascent;
1012 metrics->descent = pcm->descent;
1013 first = false;
1015 else
1017 if (metrics->lbearing > width + pcm->lbearing)
1018 metrics->lbearing = width + pcm->lbearing;
1019 if (metrics->rbearing < width + pcm->rbearing)
1020 metrics->rbearing = width + pcm->rbearing;
1021 if (metrics->ascent < pcm->ascent)
1022 metrics->ascent = pcm->ascent;
1023 if (metrics->descent < pcm->descent)
1024 metrics->descent = pcm->descent;
1026 width += pcm->width;
1029 metrics->width = width;
1032 static int
1033 xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1034 bool with_background)
1036 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
1037 int len = to - from;
1038 GC gc = s->gc;
1039 int i;
1041 if (s->gc != s->face->gc)
1043 block_input ();
1044 XSetFont (s->display, gc, xfont->fid);
1045 unblock_input ();
1048 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1050 USE_SAFE_ALLOCA;
1051 char *str = SAFE_ALLOCA (len);
1052 for (i = 0; i < len ; i++)
1053 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
1054 block_input ();
1055 if (with_background)
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);
1065 else
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);
1075 unblock_input ();
1076 SAFE_FREE ();
1077 return s->nchars;
1080 block_input ();
1081 if (with_background)
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);
1091 else
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);
1101 unblock_input ();
1103 return len;
1106 static int
1107 xfont_check (struct frame *f, struct font *font)
1109 struct xfont_info *xfont = (struct xfont_info *) font;
1111 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1115 void
1116 syms_of_xfont (void)
1118 staticpro (&xfont_scripts_cache);
1119 xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
1120 staticpro (&xfont_scratch_props);
1121 xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
1122 xfont_driver.type = Qx;
1123 register_font_driver (&xfont_driver, NULL);