Fix problems caught with --enable-gcc-warnings
[emacs.git] / src / xfont.c
blobd5a7d64e6972ef7419bfbc5999bfa921863d7985
1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2015 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
12 (at 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 "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"
35 #include "ccl.h"
38 /* X core font driver. */
40 struct xfont_info
42 struct font font;
43 Display *display;
44 XFontStruct *xfont;
45 unsigned x_display_id;
48 /* Prototypes of support functions. */
50 static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
52 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
53 is not contained in the font. */
55 static XCharStruct *
56 xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
58 /* The result metric information. */
59 XCharStruct *pcm = NULL;
61 eassert (xfont && char2b);
63 if (xfont->per_char != NULL)
65 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
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;
78 else
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:
85 byte1 = N/D + min_byte1
86 byte2 = N\D + min_char_or_byte2
88 where:
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));
103 else
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;
113 return ((pcm == NULL
114 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
115 ? NULL : pcm);
118 static Lisp_Object xfont_get_cache (struct frame *);
119 static Lisp_Object xfont_list (struct frame *, Lisp_Object);
120 static Lisp_Object xfont_match (struct frame *, Lisp_Object);
121 static Lisp_Object xfont_list_family (struct frame *);
122 static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
123 static void xfont_close (struct font *);
124 static void xfont_prepare_face (struct frame *, struct face *);
125 static int xfont_has_char (Lisp_Object, int);
126 static unsigned xfont_encode_char (struct font *, int);
127 static void xfont_text_extents (struct font *, unsigned *, int,
128 struct font_metrics *);
129 static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
130 static int xfont_check (struct frame *, struct font *);
132 struct font_driver xfont_driver =
134 LISP_INITIALLY_ZERO, /* Qx */
135 false, /* case insensitive */
136 xfont_get_cache,
137 xfont_list,
138 xfont_match,
139 xfont_list_family,
140 NULL,
141 xfont_open,
142 xfont_close,
143 xfont_prepare_face,
144 NULL,
145 xfont_has_char,
146 xfont_encode_char,
147 xfont_text_extents,
148 xfont_draw,
149 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
150 xfont_check,
151 NULL, /* get_variation_glyphs */
152 NULL, /* filter_properties */
155 static Lisp_Object
156 xfont_get_cache (struct frame *f)
158 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
160 return (dpyinfo->name_list_element);
163 static int
164 compare_font_names (const void *name1, const void *name2)
166 char *const *n1 = name1;
167 char *const *n2 = name2;
168 return xstrcasecmp (*n1, *n2);
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. */
176 static ptrdiff_t
177 xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
179 char *p0 = xlfd, *p1 = output;
180 int c;
182 while (*p0)
184 c = *(unsigned char *) p0++;
185 p1 += CHAR_STRING (c, (unsigned char *) p1);
186 if (--len == 0)
187 break;
189 *p1 = 0;
190 return (p1 - output);
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. */
197 static int
198 xfont_encode_coding_xlfd (char *xlfd)
200 const unsigned char *p0 = (unsigned char *) xlfd;
201 unsigned char *p1 = (unsigned char *) xlfd;
202 int len = 0;
204 while (*p0)
206 int c = STRING_CHAR_ADVANCE (p0);
208 if (c >= 0x100)
209 return -1;
210 *p1++ = c;
211 len++;
213 *p1 = 0;
214 return len;
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.
220 Return true if supported. */
222 static bool
223 xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
224 struct charset *encoding, struct charset *repertory)
226 struct charset *charset = repertory ? repertory : encoding;
228 if (CONSP (chars))
230 for (; CONSP (chars); chars = XCDR (chars))
232 int c = XINT (XCAR (chars));
233 unsigned code = ENCODE_CHAR (charset, c);
234 XChar2b char2b;
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;
247 return (NILP (chars));
249 else if (VECTORP (chars))
251 ptrdiff_t i;
253 for (i = ASIZE (chars) - 1; i >= 0; i--)
255 int c = XINT (AREF (chars, i));
256 unsigned code = ENCODE_CHAR (charset, c);
257 XChar2b char2b;
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;
270 return (i >= 0);
272 return false;
275 /* A hash table recoding which font supports which scripts. Each key
276 is a vector of characteristic font properties FOUNDRY to WIDTH and
277 ADDSTYLE, and each value is a list of script symbols.
279 We assume that fonts that have the same value in the above
280 properties supports the same set of characters on all displays. */
282 static Lisp_Object xfont_scripts_cache;
284 /* Re-usable vector to store characteristic font properties. */
285 static Lisp_Object xfont_scratch_props;
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. */
291 static Lisp_Object
292 xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
293 struct charset *encoding)
295 Lisp_Object scripts;
297 /* Two special cases to avoid opening rather big fonts. */
298 if (EQ (AREF (props, 2), Qja))
299 return list2 (intern ("kana"), intern ("han"));
300 if (EQ (AREF (props, 2), Qko))
301 return list1 (intern ("hangul"));
302 scripts = Fgethash (props, xfont_scripts_cache, Qt);
303 if (EQ (scripts, Qt))
305 XFontStruct *xfont;
306 Lisp_Object val;
308 scripts = Qnil;
309 xfont = XLoadQueryFont (display, fontname);
310 if (xfont)
312 if (xfont->per_char)
314 for (val = Vscript_representative_chars; CONSP (val);
315 val = XCDR (val))
316 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
318 Lisp_Object script = XCAR (XCAR (val));
319 Lisp_Object chars = XCDR (XCAR (val));
321 if (xfont_chars_supported (chars, xfont, encoding, NULL))
322 scripts = Fcons (script, scripts);
325 XFreeFont (display, xfont);
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);
332 return scripts;
335 static Lisp_Object
336 xfont_list_pattern (Display *display, const char *pattern,
337 Lisp_Object registry, Lisp_Object script)
339 Lisp_Object list = Qnil;
340 Lisp_Object chars = Qnil;
341 struct charset *encoding, *repertory = NULL;
342 int i, limit, num_fonts;
343 char **names;
344 /* Large enough to decode the longest XLFD (255 bytes). */
345 char buf[512];
347 if (! NILP (registry)
348 && font_registry_charsets (registry, &encoding, &repertory) < 0)
349 /* Unknown REGISTRY, not supported. */
350 return Qnil;
351 if (! NILP (script))
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)
360 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
361 return Qnil;
362 script = Qnil;
366 block_input ();
367 x_catch_errors (display);
369 for (limit = 512; ; limit *= 2)
371 names = XListFonts (display, pattern, limit, &num_fonts);
372 if (x_had_errors_p (display))
374 /* This error is perhaps due to insufficient memory on X
375 server. Let's just ignore it. */
376 x_clear_errors (display);
377 num_fonts = 0;
378 break;
380 if (num_fonts < limit)
381 break;
382 XFreeFontNames (names);
385 if (num_fonts > 0)
387 char **indices = alloca (sizeof (char *) * num_fonts);
388 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
389 Lisp_Object scripts = Qnil, entity = Qnil;
391 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
392 ASET (xfont_scratch_props, i, Qnil);
393 for (i = 0; i < num_fonts; i++)
394 indices[i] = names[i];
395 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
397 /* Take one or two passes over the font list. Do the second
398 pass only if we really need it, i.e., only if the first pass
399 found no fonts and skipped some scalable fonts. */
400 bool skipped_some_scalable_fonts = false;
401 for (int i_pass = 0;
402 (i_pass == 0
403 || (i_pass == 1 && NILP (list) && skipped_some_scalable_fonts));
404 i_pass++)
405 for (i = 0; i < num_fonts; i++)
407 ptrdiff_t len;
409 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
410 continue;
411 if (NILP (entity))
412 entity = font_make_entity ();
413 len = xfont_decode_coding_xlfd (indices[i], -1, buf);
414 if (font_parse_xlfd (buf, len, entity) < 0)
415 continue;
416 ASET (entity, FONT_TYPE_INDEX, Qx);
417 /* Avoid auto-scaled fonts. */
418 if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
419 && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
420 && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
421 && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
422 continue;
423 /* Avoid not-allowed scalable fonts. */
424 if (NILP (Vscalable_fonts_allowed))
426 int size = 0;
428 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
429 size = XINT (AREF (entity, FONT_SIZE_INDEX));
430 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
431 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
432 if (size == 0 && i_pass == 0)
434 skipped_some_scalable_fonts = true;
435 continue;
438 else if (CONSP (Vscalable_fonts_allowed))
440 Lisp_Object tail;
442 for (tail = Vscalable_fonts_allowed; CONSP (tail);
443 tail = XCDR (tail))
445 Lisp_Object elt = XCAR (tail);
446 if (STRINGP (elt)
447 && (fast_c_string_match_ignore_case (elt, indices[i],
448 len)
449 >= 0))
450 break;
452 if (! CONSP (tail))
453 continue;
456 /* Avoid fonts of invalid registry. */
457 if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
458 continue;
460 /* Update encoding and repertory if necessary. */
461 if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
463 registry = AREF (entity, FONT_REGISTRY_INDEX);
464 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
465 encoding = NULL;
467 if (! encoding)
468 /* Unknown REGISTRY, not supported. */
469 continue;
470 if (repertory)
472 if (NILP (script)
473 || xfont_chars_supported (chars, NULL, encoding, repertory))
474 list = Fcons (entity, list), entity = Qnil;
475 continue;
477 if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
478 word_size * 7)
479 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
481 vcopy (xfont_scratch_props, 0,
482 aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
483 ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
484 scripts = xfont_supported_scripts (display, indices[i],
485 xfont_scratch_props,
486 encoding);
488 if (NILP (script)
489 || ! NILP (Fmemq (script, scripts)))
490 list = Fcons (entity, list), entity = Qnil;
492 XFreeFontNames (names);
495 x_uncatch_errors ();
496 unblock_input ();
498 FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
499 return list;
502 static Lisp_Object
503 xfont_list (struct frame *f, Lisp_Object spec)
505 Display *display = FRAME_DISPLAY_INFO (f)->display;
506 Lisp_Object registry, list, val, extra, script;
507 int len;
508 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
509 char name[512];
511 extra = AREF (spec, FONT_EXTRA_INDEX);
512 if (CONSP (extra))
514 val = assq_no_quit (QCotf, extra);
515 if (! NILP (val))
516 return Qnil;
517 val = assq_no_quit (QClang, extra);
518 if (! NILP (val))
519 return Qnil;
522 registry = AREF (spec, FONT_REGISTRY_INDEX);
523 len = font_unparse_xlfd (spec, 0, name, 512);
524 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
525 return Qnil;
527 val = assq_no_quit (QCscript, extra);
528 script = CDR (val);
529 list = xfont_list_pattern (display, name, registry, script);
530 if (NILP (list) && NILP (registry))
532 /* Try iso10646-1 */
533 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
535 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
537 strcpy (r, "iso10646-1");
538 list = xfont_list_pattern (display, name, Qiso10646_1, script);
541 if (NILP (list) && ! NILP (registry))
543 /* Try alternate registries. */
544 Lisp_Object alter;
546 if ((alter = Fassoc (SYMBOL_NAME (registry),
547 Vface_alternative_font_registry_alist),
548 CONSP (alter)))
550 /* Pointer to REGISTRY-ENCODING field. */
551 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
553 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
554 if (STRINGP (XCAR (alter))
555 && ((r - name) + SBYTES (XCAR (alter))) < 256)
557 lispstpcpy (r, XCAR (alter));
558 list = xfont_list_pattern (display, name, registry, script);
559 if (! NILP (list))
560 break;
564 if (NILP (list))
566 /* Try alias. */
567 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
568 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
570 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
571 if (xfont_encode_coding_xlfd (name) < 0)
572 return Qnil;
573 list = xfont_list_pattern (display, name, registry, script);
577 return list;
580 static Lisp_Object
581 xfont_match (struct frame *f, Lisp_Object spec)
583 Display *display = FRAME_DISPLAY_INFO (f)->display;
584 Lisp_Object extra, val, entity;
585 char name[512];
586 XFontStruct *xfont;
587 unsigned long value;
589 extra = AREF (spec, FONT_EXTRA_INDEX);
590 val = assq_no_quit (QCname, extra);
591 if (! CONSP (val) || ! STRINGP (XCDR (val)))
593 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
594 return Qnil;
596 else if (SBYTES (XCDR (val)) < 512)
597 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
598 else
599 return Qnil;
600 if (xfont_encode_coding_xlfd (name) < 0)
601 return Qnil;
603 block_input ();
604 entity = Qnil;
605 xfont = XLoadQueryFont (display, name);
606 if (xfont)
608 if (XGetFontProperty (xfont, XA_FONT, &value))
610 char *s = XGetAtomName (display, (Atom) value);
612 /* If DXPC (a Differential X Protocol Compressor)
613 Ver.3.7 is running, XGetAtomName will return null
614 string. We must avoid such a name. */
615 if (*s)
617 ptrdiff_t len;
618 entity = font_make_entity ();
619 ASET (entity, FONT_TYPE_INDEX, Qx);
620 len = xfont_decode_coding_xlfd (s, -1, name);
621 if (font_parse_xlfd (name, len, entity) < 0)
622 entity = Qnil;
624 XFree (s);
626 XFreeFont (display, xfont);
628 unblock_input ();
630 FONT_ADD_LOG ("xfont-match", spec, entity);
631 return entity;
634 static Lisp_Object
635 xfont_list_family (struct frame *f)
637 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
638 char **names;
639 int num_fonts, i;
640 Lisp_Object list;
641 char *last_family IF_LINT (= 0);
642 int last_len;
644 block_input ();
645 x_catch_errors (dpyinfo->display);
646 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
647 0x8000, &num_fonts);
648 if (x_had_errors_p (dpyinfo->display))
650 /* This error is perhaps due to insufficient memory on X server.
651 Let's just ignore it. */
652 x_clear_errors (dpyinfo->display);
653 num_fonts = 0;
656 list = Qnil;
657 for (i = 0, last_len = 0; i < num_fonts; i++)
659 char *p0 = names[i], *p1, buf[512];
660 Lisp_Object family;
661 int decoded_len;
663 p0++; /* skip the leading '-' */
664 while (*p0 && *p0 != '-') p0++; /* skip foundry */
665 if (! *p0)
666 continue;
667 p1 = ++p0;
668 while (*p1 && *p1 != '-') p1++; /* find the end of family */
669 if (! *p1 || p1 == p0)
670 continue;
671 if (last_len == p1 - p0
672 && memcmp (last_family, p0, last_len) == 0)
673 continue;
674 last_len = p1 - p0;
675 last_family = p0;
677 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
678 family = font_intern_prop (p0, decoded_len, 1);
679 if (NILP (assq_no_quit (family, list)))
680 list = Fcons (family, list);
683 XFreeFontNames (names);
684 x_uncatch_errors ();
685 unblock_input ();
687 return list;
690 static Lisp_Object
691 xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
693 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
694 Display *display = dpyinfo->display;
695 char name[512];
696 int len;
697 unsigned long value;
698 Lisp_Object registry;
699 struct charset *encoding, *repertory;
700 Lisp_Object font_object, fullname;
701 struct font *font;
702 XFontStruct *xfont;
704 /* At first, check if we know how to encode characters for this
705 font. */
706 registry = AREF (entity, FONT_REGISTRY_INDEX);
707 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
709 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
710 return Qnil;
713 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
714 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
715 else if (pixel_size == 0)
717 if (FRAME_FONT (f))
718 pixel_size = FRAME_FONT (f)->pixel_size;
719 else
720 pixel_size = 14;
722 len = font_unparse_xlfd (entity, pixel_size, name, 512);
723 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
725 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
726 return Qnil;
729 block_input ();
730 x_catch_errors (display);
731 xfont = XLoadQueryFont (display, name);
732 if (x_had_errors_p (display))
734 /* This error is perhaps due to insufficient memory on X server.
735 Let's just ignore it. */
736 x_clear_errors (display);
737 xfont = NULL;
739 else if (! xfont)
741 /* Some version of X lists:
742 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
743 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
744 but can open only:
745 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
747 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
748 So, we try again with wildcards in RESX and RESY. */
749 Lisp_Object temp;
751 temp = copy_font_spec (entity);
752 ASET (temp, FONT_DPI_INDEX, Qnil);
753 len = font_unparse_xlfd (temp, pixel_size, name, 512);
754 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
756 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
757 return Qnil;
759 xfont = XLoadQueryFont (display, name);
760 if (x_had_errors_p (display))
762 /* This error is perhaps due to insufficient memory on X server.
763 Let's just ignore it. */
764 x_clear_errors (display);
765 xfont = NULL;
768 fullname = Qnil;
769 /* Try to get the full name of FONT. */
770 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
772 char *p0, *p;
773 int dashes = 0;
775 p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
776 /* Count the number of dashes in the "full name".
777 If it is too few, this isn't really the font's full name,
778 so don't use it.
779 In X11R4, the fonts did not come with their canonical names
780 stored in them. */
781 while (*p)
783 if (*p == '-')
784 dashes++;
785 p++;
788 if (dashes >= 13)
790 len = xfont_decode_coding_xlfd (p0, -1, name);
791 fullname = Fdowncase (make_string (name, len));
793 XFree (p0);
795 x_uncatch_errors ();
796 unblock_input ();
798 if (! xfont)
800 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
801 return Qnil;
804 font_object = font_make_object (VECSIZE (struct xfont_info),
805 entity, pixel_size);
806 ASET (font_object, FONT_TYPE_INDEX, Qx);
807 if (STRINGP (fullname))
809 font_parse_xlfd (SSDATA (fullname), SBYTES (fullname), font_object);
810 ASET (font_object, FONT_NAME_INDEX, fullname);
812 else
814 char buf[512];
816 len = xfont_decode_coding_xlfd (name, -1, buf);
817 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
819 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
820 font = XFONT_OBJECT (font_object);
821 ((struct xfont_info *) font)->xfont = xfont;
822 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
823 ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
824 font->pixel_size = pixel_size;
825 font->driver = &xfont_driver;
826 font->encoding_charset = encoding->id;
827 font->repertory_charset = repertory ? repertory->id : -1;
828 font->ascent = xfont->ascent;
829 font->descent = xfont->descent;
830 font->height = font->ascent + font->descent;
831 font->min_width = xfont->min_bounds.width;
832 font->max_width = xfont->max_bounds.width;
833 if (xfont->min_bounds.width == xfont->max_bounds.width)
835 /* Fixed width font. */
836 font->average_width = font->space_width = xfont->min_bounds.width;
838 else
840 XCharStruct *pcm;
841 XChar2b char2b;
842 Lisp_Object val;
844 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
845 pcm = xfont_get_pcm (xfont, &char2b);
846 if (pcm)
847 font->space_width = pcm->width;
848 else
849 font->space_width = 0;
851 val = Ffont_get (font_object, QCavgwidth);
852 if (INTEGERP (val))
853 font->average_width = XINT (val) / 10;
854 if (font->average_width < 0)
855 font->average_width = - font->average_width;
856 else
858 if (font->average_width == 0
859 && encoding->ascii_compatible_p)
861 int width = font->space_width, n = pcm != NULL;
863 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
864 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
865 width += pcm->width, n++;
866 if (n > 0)
867 font->average_width = width / n;
869 if (font->average_width == 0)
870 /* No easy way other than this to get a reasonable
871 average_width. */
872 font->average_width
873 = (xfont->min_bounds.width + xfont->max_bounds.width) / 2;
877 block_input ();
878 font->underline_thickness
879 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
880 ? (long) value : 0);
881 font->underline_position
882 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
883 ? (long) value : -1);
884 font->baseline_offset
885 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
886 ? (long) value : 0);
887 font->relative_compose
888 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
889 ? (long) value : 0);
890 font->default_ascent
891 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
892 ? (long) value : 0);
893 unblock_input ();
895 if (NILP (fullname))
896 fullname = AREF (font_object, FONT_NAME_INDEX);
897 font->vertical_centering
898 = (STRINGP (Vvertical_centering_font_regexp)
899 && (fast_string_match_ignore_case
900 (Vvertical_centering_font_regexp, fullname) >= 0));
902 return font_object;
905 static void
906 xfont_close (struct font *font)
908 struct x_display_info *xdi;
909 struct xfont_info *xfi = (struct xfont_info *) font;
911 /* This function may be called from GC when X connection is gone
912 (Bug#16093), and an attempt to free font resources on invalid
913 display may lead to X protocol errors or segfaults. Moreover,
914 the memory referenced by 'Display *' pointer may be reused for
915 the logically different X connection after the previous display
916 connection was closed. That's why we also check whether font's
917 ID matches the one recorded in x_display_info for this display.
918 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
919 if (xfi->xfont
920 && ((xdi = x_display_info_for_display (xfi->display))
921 && xfi->x_display_id == xdi->x_id))
923 block_input ();
924 XFreeFont (xfi->display, xfi->xfont);
925 unblock_input ();
926 xfi->xfont = NULL;
930 static void
931 xfont_prepare_face (struct frame *f, struct face *face)
933 block_input ();
934 XSetFont (FRAME_X_DISPLAY (f), face->gc,
935 ((struct xfont_info *) face->font)->xfont->fid);
936 unblock_input ();
939 static int
940 xfont_has_char (Lisp_Object font, int c)
942 Lisp_Object registry = AREF (font, FONT_REGISTRY_INDEX);
943 struct charset *encoding;
944 struct charset *repertory = NULL;
946 if (EQ (registry, Qiso10646_1))
948 encoding = CHARSET_FROM_ID (charset_unicode);
949 /* We use a font of `ja' and `ko' adstyle only for a character
950 in JISX0208 and KSC5601 charsets respectively. */
951 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
952 && charset_jisx0208 >= 0)
953 repertory = CHARSET_FROM_ID (charset_jisx0208);
954 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
955 && charset_ksc5601 >= 0)
956 repertory = CHARSET_FROM_ID (charset_ksc5601);
958 else if (font_registry_charsets (registry, &encoding, &repertory) < 0)
959 /* Unknown REGISTRY, not usable. */
960 return 0;
961 if (ASCII_CHAR_P (c) && encoding->ascii_compatible_p)
962 return 1;
963 if (! repertory)
964 return -1;
965 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
968 static unsigned
969 xfont_encode_char (struct font *font, int c)
971 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
972 struct charset *charset;
973 unsigned code;
974 XChar2b char2b;
976 charset = CHARSET_FROM_ID (font->encoding_charset);
977 code = ENCODE_CHAR (charset, c);
978 if (code == CHARSET_INVALID_CODE (charset))
979 return FONT_INVALID_CODE;
980 if (font->repertory_charset >= 0)
982 charset = CHARSET_FROM_ID (font->repertory_charset);
983 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
984 ? code : FONT_INVALID_CODE);
986 char2b.byte1 = code >> 8;
987 char2b.byte2 = code & 0xFF;
988 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
991 static void
992 xfont_text_extents (struct font *font, unsigned int *code,
993 int nglyphs, struct font_metrics *metrics)
995 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
996 int i, width = 0;
997 bool first;
999 for (i = 0, first = true; i < nglyphs; i++)
1001 XChar2b char2b;
1002 static XCharStruct *pcm;
1004 if (code[i] >= 0x10000)
1005 continue;
1006 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
1007 pcm = xfont_get_pcm (xfont, &char2b);
1008 if (! pcm)
1009 continue;
1010 if (first)
1012 metrics->lbearing = pcm->lbearing;
1013 metrics->rbearing = pcm->rbearing;
1014 metrics->ascent = pcm->ascent;
1015 metrics->descent = pcm->descent;
1016 first = false;
1018 else
1020 if (metrics->lbearing > width + pcm->lbearing)
1021 metrics->lbearing = width + pcm->lbearing;
1022 if (metrics->rbearing < width + pcm->rbearing)
1023 metrics->rbearing = width + pcm->rbearing;
1024 if (metrics->ascent < pcm->ascent)
1025 metrics->ascent = pcm->ascent;
1026 if (metrics->descent < pcm->descent)
1027 metrics->descent = pcm->descent;
1029 width += pcm->width;
1032 metrics->width = width;
1035 static int
1036 xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1037 bool with_background)
1039 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
1040 int len = to - from;
1041 GC gc = s->gc;
1042 int i;
1044 if (s->gc != s->face->gc)
1046 block_input ();
1047 XSetFont (s->display, gc, xfont->fid);
1048 unblock_input ();
1051 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1053 USE_SAFE_ALLOCA;
1054 char *str = SAFE_ALLOCA (len);
1055 for (i = 0; i < len ; i++)
1056 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
1057 block_input ();
1058 if (with_background)
1060 if (s->padding_p)
1061 for (i = 0; i < len; i++)
1062 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1063 gc, x + i, y, str + i, 1);
1064 else
1065 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1066 gc, x, y, str, len);
1068 else
1070 if (s->padding_p)
1071 for (i = 0; i < len; i++)
1072 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1073 gc, x + i, y, str + i, 1);
1074 else
1075 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1076 gc, x, y, str, len);
1078 unblock_input ();
1079 SAFE_FREE ();
1080 return s->nchars;
1083 block_input ();
1084 if (with_background)
1086 if (s->padding_p)
1087 for (i = 0; i < len; i++)
1088 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1089 gc, x + i, y, s->char2b + from + i, 1);
1090 else
1091 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1092 gc, x, y, s->char2b + from, len);
1094 else
1096 if (s->padding_p)
1097 for (i = 0; i < len; i++)
1098 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1099 gc, x + i, y, s->char2b + from + i, 1);
1100 else
1101 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1102 gc, x, y, s->char2b + from, len);
1104 unblock_input ();
1106 return len;
1109 static int
1110 xfont_check (struct frame *f, struct font *font)
1112 struct xfont_info *xfont = (struct xfont_info *) font;
1114 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1118 void
1119 syms_of_xfont (void)
1121 staticpro (&xfont_scripts_cache);
1122 xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
1123 staticpro (&xfont_scratch_props);
1124 xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
1125 xfont_driver.type = Qx;
1126 register_font_driver (&xfont_driver, NULL);