* lisp/emacs-lisp/checkdoc.el: Remove redundant :group keywords.
[emacs.git] / src / xfont.c
blobf673adbbd5ecebeacc6ede679cda0f0090ff7e80
1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2013 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;
47 /* Prototypes of support functions. */
49 static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
51 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
52 is not contained in the font. */
54 static XCharStruct *
55 xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
57 /* The result metric information. */
58 XCharStruct *pcm = NULL;
60 eassert (xfont && char2b);
62 if (xfont->per_char != NULL)
64 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
66 /* min_char_or_byte2 specifies the linear character index
67 corresponding to the first element of the per_char array,
68 max_char_or_byte2 is the index of the last character. A
69 character with non-zero CHAR2B->byte1 is not in the font.
70 A character with byte2 less than min_char_or_byte2 or
71 greater max_char_or_byte2 is not in the font. */
72 if (char2b->byte1 == 0
73 && char2b->byte2 >= xfont->min_char_or_byte2
74 && char2b->byte2 <= xfont->max_char_or_byte2)
75 pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
77 else
79 /* If either min_byte1 or max_byte1 are nonzero, both
80 min_char_or_byte2 and max_char_or_byte2 are less than
81 256, and the 2-byte character index values corresponding
82 to the per_char array element N (counting from 0) are:
84 byte1 = N/D + min_byte1
85 byte2 = N\D + min_char_or_byte2
87 where:
89 D = max_char_or_byte2 - min_char_or_byte2 + 1
90 / = integer division
91 \ = integer modulus */
92 if (char2b->byte1 >= xfont->min_byte1
93 && char2b->byte1 <= xfont->max_byte1
94 && char2b->byte2 >= xfont->min_char_or_byte2
95 && char2b->byte2 <= xfont->max_char_or_byte2)
96 pcm = (xfont->per_char
97 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
98 * (char2b->byte1 - xfont->min_byte1))
99 + (char2b->byte2 - xfont->min_char_or_byte2));
102 else
104 /* If the per_char pointer is null, all glyphs between the first
105 and last character indexes inclusive have the same
106 information, as given by both min_bounds and max_bounds. */
107 if (char2b->byte2 >= xfont->min_char_or_byte2
108 && char2b->byte2 <= xfont->max_char_or_byte2)
109 pcm = &xfont->max_bounds;
112 return ((pcm == NULL
113 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
114 ? NULL : pcm);
117 static Lisp_Object xfont_get_cache (struct frame *);
118 static Lisp_Object xfont_list (struct frame *, Lisp_Object);
119 static Lisp_Object xfont_match (struct frame *, Lisp_Object);
120 static Lisp_Object xfont_list_family (struct frame *);
121 static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
122 static void xfont_close (struct frame *, struct font *);
123 static int xfont_prepare_face (struct frame *, struct face *);
124 static int xfont_has_char (Lisp_Object, int);
125 static unsigned xfont_encode_char (struct font *, int);
126 static int xfont_text_extents (struct font *, unsigned *, int,
127 struct font_metrics *);
128 static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
129 static int xfont_check (struct frame *, struct font *);
131 struct font_driver xfont_driver =
133 LISP_INITIALLY_ZERO, /* Qx */
134 0, /* case insensitive */
135 xfont_get_cache,
136 xfont_list,
137 xfont_match,
138 xfont_list_family,
139 NULL,
140 xfont_open,
141 xfont_close,
142 xfont_prepare_face,
143 NULL,
144 xfont_has_char,
145 xfont_encode_char,
146 xfont_text_extents,
147 xfont_draw,
148 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
149 xfont_check,
150 NULL, /* get_variation_glyphs */
151 NULL, /* filter_properties */
154 static Lisp_Object
155 xfont_get_cache (struct frame *f)
157 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
159 return (dpyinfo->name_list_element);
162 static int
163 compare_font_names (const void *name1, const void *name2)
165 char *const *n1 = name1;
166 char *const *n2 = name2;
167 return xstrcasecmp (*n1, *n2);
170 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
171 of the decoding result. LEN is the byte length of XLFD, or -1 if
172 XLFD is NULL terminated. The caller must assure that OUTPUT is at
173 least twice (plus 1) as large as XLFD. */
175 static ptrdiff_t
176 xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
178 char *p0 = xlfd, *p1 = output;
179 int c;
181 while (*p0)
183 c = *(unsigned char *) p0++;
184 p1 += CHAR_STRING (c, (unsigned char *) p1);
185 if (--len == 0)
186 break;
188 *p1 = 0;
189 return (p1 - output);
192 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
193 resulting byte length. If XLFD contains unencodable character,
194 return -1. */
196 static int
197 xfont_encode_coding_xlfd (char *xlfd)
199 const unsigned char *p0 = (unsigned char *) xlfd;
200 unsigned char *p1 = (unsigned char *) xlfd;
201 int len = 0;
203 while (*p0)
205 int c = STRING_CHAR_ADVANCE (p0);
207 if (c >= 0x100)
208 return -1;
209 *p1++ = c;
210 len++;
212 *p1 = 0;
213 return len;
216 /* Check if CHARS (cons or vector) is supported by XFONT whose
217 encoding charset is ENCODING (XFONT is NULL) or by a font whose
218 registry corresponds to ENCODING and REPERTORY.
219 Return true if supported. */
221 static bool
222 xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
223 struct charset *encoding, struct charset *repertory)
225 struct charset *charset = repertory ? repertory : encoding;
227 if (CONSP (chars))
229 for (; CONSP (chars); chars = XCDR (chars))
231 int c = XINT (XCAR (chars));
232 unsigned code = ENCODE_CHAR (charset, c);
233 XChar2b char2b;
235 if (code == CHARSET_INVALID_CODE (charset))
236 break;
237 if (! xfont)
238 continue;
239 if (code >= 0x10000)
240 break;
241 char2b.byte1 = code >> 8;
242 char2b.byte2 = code & 0xFF;
243 if (! xfont_get_pcm (xfont, &char2b))
244 break;
246 return (NILP (chars));
248 else if (VECTORP (chars))
250 ptrdiff_t i;
252 for (i = ASIZE (chars) - 1; i >= 0; i--)
254 int c = XINT (AREF (chars, i));
255 unsigned code = ENCODE_CHAR (charset, c);
256 XChar2b char2b;
258 if (code == CHARSET_INVALID_CODE (charset))
259 continue;
260 if (! xfont)
261 break;
262 if (code >= 0x10000)
263 continue;
264 char2b.byte1 = code >> 8;
265 char2b.byte2 = code & 0xFF;
266 if (xfont_get_pcm (xfont, &char2b))
267 break;
269 return (i >= 0);
271 return 0;
274 /* A hash table recoding which font supports which scripts. Each key
275 is a vector of characteristic font properties FOUNDRY to WIDTH and
276 ADDSTYLE, and each value is a list of script symbols.
278 We assume that fonts that have the same value in the above
279 properties supports the same set of characters on all displays. */
281 static Lisp_Object xfont_scripts_cache;
283 /* Re-usable vector to store characteristic font properties. */
284 static Lisp_Object xfont_scratch_props;
286 /* Return a list of scripts supported by the font of FONTNAME whose
287 characteristic properties are in PROPS and whose encoding charset
288 is ENCODING. A caller must call BLOCK_INPUT in advance. */
290 static Lisp_Object
291 xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
292 struct charset *encoding)
294 Lisp_Object scripts;
296 /* Two special cases to avoid opening rather big fonts. */
297 if (EQ (AREF (props, 2), Qja))
298 return list2 (intern ("kana"), intern ("han"));
299 if (EQ (AREF (props, 2), Qko))
300 return list1 (intern ("hangul"));
301 scripts = Fgethash (props, xfont_scripts_cache, Qt);
302 if (EQ (scripts, Qt))
304 XFontStruct *xfont;
305 Lisp_Object val;
307 scripts = Qnil;
308 xfont = XLoadQueryFont (display, fontname);
309 if (xfont)
311 if (xfont->per_char)
313 for (val = Vscript_representative_chars; CONSP (val);
314 val = XCDR (val))
315 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
317 Lisp_Object script = XCAR (XCAR (val));
318 Lisp_Object chars = XCDR (XCAR (val));
320 if (xfont_chars_supported (chars, xfont, encoding, NULL))
321 scripts = Fcons (script, scripts);
324 XFreeFont (display, xfont);
326 if (EQ (AREF (props, 3), Qiso10646_1)
327 && NILP (Fmemq (Qlatin, scripts)))
328 scripts = Fcons (Qlatin, scripts);
329 Fputhash (Fcopy_sequence (props), scripts, xfont_scripts_cache);
331 return scripts;
334 static Lisp_Object
335 xfont_list_pattern (Display *display, const char *pattern,
336 Lisp_Object registry, Lisp_Object script)
338 Lisp_Object list = Qnil;
339 Lisp_Object chars = Qnil;
340 struct charset *encoding, *repertory = NULL;
341 int i, limit, num_fonts;
342 char **names;
343 /* Large enough to decode the longest XLFD (255 bytes). */
344 char buf[512];
346 if (! NILP (registry)
347 && font_registry_charsets (registry, &encoding, &repertory) < 0)
348 /* Unknown REGISTRY, not supported. */
349 return Qnil;
350 if (! NILP (script))
352 chars = assq_no_quit (script, Vscript_representative_chars);
353 if (NILP (chars))
354 /* We can't tell whether or not a font supports SCRIPT. */
355 return Qnil;
356 chars = XCDR (chars);
357 if (repertory)
359 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
360 return Qnil;
361 script = Qnil;
365 block_input ();
366 x_catch_errors (display);
368 for (limit = 512; ; limit *= 2)
370 names = XListFonts (display, pattern, limit, &num_fonts);
371 if (x_had_errors_p (display))
373 /* This error is perhaps due to insufficient memory on X
374 server. Let's just ignore it. */
375 x_clear_errors (display);
376 num_fonts = 0;
377 break;
379 if (num_fonts < limit)
380 break;
381 XFreeFontNames (names);
384 if (num_fonts > 0)
386 char **indices = alloca (sizeof (char *) * num_fonts);
387 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
388 Lisp_Object scripts = Qnil;
390 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
391 ASET (xfont_scratch_props, i, Qnil);
392 for (i = 0; i < num_fonts; i++)
393 indices[i] = names[i];
394 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
396 for (i = 0; i < num_fonts; i++)
398 ptrdiff_t len;
399 Lisp_Object entity;
401 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
402 continue;
403 entity = font_make_entity ();
404 len = xfont_decode_coding_xlfd (indices[i], -1, buf);
405 if (font_parse_xlfd (buf, len, entity) < 0)
406 continue;
407 ASET (entity, FONT_TYPE_INDEX, Qx);
408 /* Avoid auto-scaled fonts. */
409 if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
410 && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
411 && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
412 && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
413 continue;
414 /* Avoid not-allowed scalable fonts. */
415 if (NILP (Vscalable_fonts_allowed))
417 int size = 0;
419 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
420 size = XINT (AREF (entity, FONT_SIZE_INDEX));
421 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
422 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
423 if (size == 0)
424 continue;
426 else if (CONSP (Vscalable_fonts_allowed))
428 Lisp_Object tail, elt;
430 for (tail = Vscalable_fonts_allowed; CONSP (tail);
431 tail = XCDR (tail))
433 elt = XCAR (tail);
434 if (STRINGP (elt)
435 && fast_c_string_match_ignore_case (elt, indices[i],
436 len) >= 0)
437 break;
439 if (! CONSP (tail))
440 continue;
443 /* Avoid fonts of invalid registry. */
444 if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
445 continue;
447 /* Update encoding and repertory if necessary. */
448 if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
450 registry = AREF (entity, FONT_REGISTRY_INDEX);
451 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
452 encoding = NULL;
454 if (! encoding)
455 /* Unknown REGISTRY, not supported. */
456 continue;
457 if (repertory)
459 if (NILP (script)
460 || xfont_chars_supported (chars, NULL, encoding, repertory))
461 list = Fcons (entity, list);
462 continue;
464 if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
465 word_size * 7)
466 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
468 vcopy (xfont_scratch_props, 0,
469 aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
470 ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
471 scripts = xfont_supported_scripts (display, indices[i],
472 xfont_scratch_props, encoding);
474 if (NILP (script)
475 || ! NILP (Fmemq (script, scripts)))
476 list = Fcons (entity, list);
478 XFreeFontNames (names);
481 x_uncatch_errors ();
482 unblock_input ();
484 FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
485 return list;
488 static Lisp_Object
489 xfont_list (struct frame *f, Lisp_Object spec)
491 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
492 Lisp_Object registry, list, val, extra, script;
493 int len;
494 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
495 char name[512];
497 extra = AREF (spec, FONT_EXTRA_INDEX);
498 if (CONSP (extra))
500 val = assq_no_quit (QCotf, extra);
501 if (! NILP (val))
502 return Qnil;
503 val = assq_no_quit (QClang, extra);
504 if (! NILP (val))
505 return Qnil;
508 registry = AREF (spec, FONT_REGISTRY_INDEX);
509 len = font_unparse_xlfd (spec, 0, name, 512);
510 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
511 return Qnil;
513 val = assq_no_quit (QCscript, extra);
514 script = CDR (val);
515 list = xfont_list_pattern (display, name, registry, script);
516 if (NILP (list) && NILP (registry))
518 /* Try iso10646-1 */
519 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
521 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
523 strcpy (r, "iso10646-1");
524 list = xfont_list_pattern (display, name, Qiso10646_1, script);
527 if (NILP (list) && ! NILP (registry))
529 /* Try alternate registries. */
530 Lisp_Object alter;
532 if ((alter = Fassoc (SYMBOL_NAME (registry),
533 Vface_alternative_font_registry_alist),
534 CONSP (alter)))
536 /* Pointer to REGISTRY-ENCODING field. */
537 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
539 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
540 if (STRINGP (XCAR (alter))
541 && ((r - name) + SBYTES (XCAR (alter))) < 256)
543 strcpy (r, SSDATA (XCAR (alter)));
544 list = xfont_list_pattern (display, name, registry, script);
545 if (! NILP (list))
546 break;
550 if (NILP (list))
552 /* Try alias. */
553 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
554 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
556 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
557 if (xfont_encode_coding_xlfd (name) < 0)
558 return Qnil;
559 list = xfont_list_pattern (display, name, registry, script);
563 return list;
566 static Lisp_Object
567 xfont_match (struct frame *f, Lisp_Object spec)
569 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
570 Lisp_Object extra, val, entity;
571 char name[512];
572 XFontStruct *xfont;
573 unsigned long value;
575 extra = AREF (spec, FONT_EXTRA_INDEX);
576 val = assq_no_quit (QCname, extra);
577 if (! CONSP (val) || ! STRINGP (XCDR (val)))
579 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
580 return Qnil;
582 else if (SBYTES (XCDR (val)) < 512)
583 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
584 else
585 return Qnil;
586 if (xfont_encode_coding_xlfd (name) < 0)
587 return Qnil;
589 block_input ();
590 entity = Qnil;
591 xfont = XLoadQueryFont (display, name);
592 if (xfont)
594 if (XGetFontProperty (xfont, XA_FONT, &value))
596 char *s;
598 s = (char *) XGetAtomName (display, (Atom) value);
600 /* If DXPC (a Differential X Protocol Compressor)
601 Ver.3.7 is running, XGetAtomName will return null
602 string. We must avoid such a name. */
603 if (*s)
605 ptrdiff_t len;
606 entity = font_make_entity ();
607 ASET (entity, FONT_TYPE_INDEX, Qx);
608 len = xfont_decode_coding_xlfd (s, -1, name);
609 if (font_parse_xlfd (name, len, entity) < 0)
610 entity = Qnil;
612 XFree (s);
614 XFreeFont (display, xfont);
616 unblock_input ();
618 FONT_ADD_LOG ("xfont-match", spec, entity);
619 return entity;
622 static Lisp_Object
623 xfont_list_family (struct frame *f)
625 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
626 char **names;
627 int num_fonts, i;
628 Lisp_Object list;
629 char *last_family IF_LINT (= 0);
630 int last_len;
632 block_input ();
633 x_catch_errors (dpyinfo->display);
634 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
635 0x8000, &num_fonts);
636 if (x_had_errors_p (dpyinfo->display))
638 /* This error is perhaps due to insufficient memory on X server.
639 Let's just ignore it. */
640 x_clear_errors (dpyinfo->display);
641 num_fonts = 0;
644 list = Qnil;
645 for (i = 0, last_len = 0; i < num_fonts; i++)
647 char *p0 = names[i], *p1, buf[512];
648 Lisp_Object family;
649 int decoded_len;
651 p0++; /* skip the leading '-' */
652 while (*p0 && *p0 != '-') p0++; /* skip foundry */
653 if (! *p0)
654 continue;
655 p1 = ++p0;
656 while (*p1 && *p1 != '-') p1++; /* find the end of family */
657 if (! *p1 || p1 == p0)
658 continue;
659 if (last_len == p1 - p0
660 && memcmp (last_family, p0, last_len) == 0)
661 continue;
662 last_len = p1 - p0;
663 last_family = p0;
665 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
666 family = font_intern_prop (p0, decoded_len, 1);
667 if (NILP (assq_no_quit (family, list)))
668 list = Fcons (family, list);
671 XFreeFontNames (names);
672 x_uncatch_errors ();
673 unblock_input ();
675 return list;
678 static Lisp_Object
679 xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
681 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
682 Display *display = dpyinfo->display;
683 char name[512];
684 int len;
685 unsigned long value;
686 Lisp_Object registry;
687 struct charset *encoding, *repertory;
688 Lisp_Object font_object, fullname;
689 struct font *font;
690 XFontStruct *xfont;
692 /* At first, check if we know how to encode characters for this
693 font. */
694 registry = AREF (entity, FONT_REGISTRY_INDEX);
695 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
697 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
698 return Qnil;
701 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
702 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
703 else if (pixel_size == 0)
705 if (FRAME_FONT (f))
706 pixel_size = FRAME_FONT (f)->pixel_size;
707 else
708 pixel_size = 14;
710 len = font_unparse_xlfd (entity, pixel_size, name, 512);
711 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
713 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
714 return Qnil;
717 block_input ();
718 x_catch_errors (display);
719 xfont = XLoadQueryFont (display, name);
720 if (x_had_errors_p (display))
722 /* This error is perhaps due to insufficient memory on X server.
723 Let's just ignore it. */
724 x_clear_errors (display);
725 xfont = NULL;
727 else if (! xfont)
729 /* Some version of X lists:
730 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
731 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
732 but can open only:
733 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
735 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
736 So, we try again with wildcards in RESX and RESY. */
737 Lisp_Object temp;
739 temp = copy_font_spec (entity);
740 ASET (temp, FONT_DPI_INDEX, Qnil);
741 len = font_unparse_xlfd (temp, pixel_size, name, 512);
742 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
744 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
745 return Qnil;
747 xfont = XLoadQueryFont (display, name);
748 if (x_had_errors_p (display))
750 /* This error is perhaps due to insufficient memory on X server.
751 Let's just ignore it. */
752 x_clear_errors (display);
753 xfont = NULL;
756 fullname = Qnil;
757 /* Try to get the full name of FONT. */
758 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
760 char *p0, *p;
761 int dashes = 0;
763 p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
764 /* Count the number of dashes in the "full name".
765 If it is too few, this isn't really the font's full name,
766 so don't use it.
767 In X11R4, the fonts did not come with their canonical names
768 stored in them. */
769 while (*p)
771 if (*p == '-')
772 dashes++;
773 p++;
776 if (dashes >= 13)
778 len = xfont_decode_coding_xlfd (p0, -1, name);
779 fullname = Fdowncase (make_string (name, len));
781 XFree (p0);
783 x_uncatch_errors ();
784 unblock_input ();
786 if (! xfont)
788 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
789 return Qnil;
792 font_object = font_make_object (VECSIZE (struct xfont_info),
793 entity, pixel_size);
794 ASET (font_object, FONT_TYPE_INDEX, Qx);
795 if (STRINGP (fullname))
797 font_parse_xlfd (SSDATA (fullname), SBYTES (fullname), font_object);
798 ASET (font_object, FONT_NAME_INDEX, fullname);
800 else
802 char buf[512];
804 len = xfont_decode_coding_xlfd (name, -1, buf);
805 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
807 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
808 ASET (font_object, FONT_FILE_INDEX, Qnil);
809 ASET (font_object, FONT_FORMAT_INDEX, Qx);
810 font = XFONT_OBJECT (font_object);
811 ((struct xfont_info *) font)->xfont = xfont;
812 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
813 font->pixel_size = pixel_size;
814 font->driver = &xfont_driver;
815 font->encoding_charset = encoding->id;
816 font->repertory_charset = repertory ? repertory->id : -1;
817 font->ascent = xfont->ascent;
818 font->descent = xfont->descent;
819 font->height = font->ascent + font->descent;
820 font->min_width = xfont->min_bounds.width;
821 font->max_width = xfont->max_bounds.width;
822 if (xfont->min_bounds.width == xfont->max_bounds.width)
824 /* Fixed width font. */
825 font->average_width = font->space_width = xfont->min_bounds.width;
827 else
829 XCharStruct *pcm;
830 XChar2b char2b;
831 Lisp_Object val;
833 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
834 pcm = xfont_get_pcm (xfont, &char2b);
835 if (pcm)
836 font->space_width = pcm->width;
837 else
838 font->space_width = 0;
840 val = Ffont_get (font_object, QCavgwidth);
841 if (INTEGERP (val))
842 font->average_width = XINT (val) / 10;
843 if (font->average_width < 0)
844 font->average_width = - font->average_width;
845 else
847 if (font->average_width == 0
848 && encoding->ascii_compatible_p)
850 int width = font->space_width, n = pcm != NULL;
852 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
853 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
854 width += pcm->width, n++;
855 if (n > 0)
856 font->average_width = width / n;
858 if (font->average_width == 0)
859 /* No easy way other than this to get a reasonable
860 average_width. */
861 font->average_width
862 = (xfont->min_bounds.width + xfont->max_bounds.width) / 2;
866 block_input ();
867 font->underline_thickness
868 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
869 ? (long) value : 0);
870 font->underline_position
871 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
872 ? (long) value : -1);
873 font->baseline_offset
874 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
875 ? (long) value : 0);
876 font->relative_compose
877 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
878 ? (long) value : 0);
879 font->default_ascent
880 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
881 ? (long) value : 0);
882 unblock_input ();
884 if (NILP (fullname))
885 fullname = AREF (font_object, FONT_NAME_INDEX);
886 font->vertical_centering
887 = (STRINGP (Vvertical_centering_font_regexp)
888 && (fast_string_match_ignore_case
889 (Vvertical_centering_font_regexp, fullname) >= 0));
891 return font_object;
894 static void
895 xfont_close (struct frame *f, struct font *font)
897 block_input ();
898 XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
899 unblock_input ();
902 static int
903 xfont_prepare_face (struct frame *f, struct face *face)
905 block_input ();
906 XSetFont (FRAME_X_DISPLAY (f), face->gc,
907 ((struct xfont_info *) face->font)->xfont->fid);
908 unblock_input ();
910 return 0;
913 static int
914 xfont_has_char (Lisp_Object font, int c)
916 Lisp_Object registry = AREF (font, FONT_REGISTRY_INDEX);
917 struct charset *encoding;
918 struct charset *repertory = NULL;
920 if (EQ (registry, Qiso10646_1))
922 encoding = CHARSET_FROM_ID (charset_unicode);
923 /* We use a font of `ja' and `ko' adstyle only for a character
924 in JISX0208 and KSC5601 charsets respectively. */
925 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
926 && charset_jisx0208 >= 0)
927 repertory = CHARSET_FROM_ID (charset_jisx0208);
928 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
929 && charset_ksc5601 >= 0)
930 repertory = CHARSET_FROM_ID (charset_ksc5601);
932 else if (font_registry_charsets (registry, &encoding, &repertory) < 0)
933 /* Unknown REGISTRY, not usable. */
934 return 0;
935 if (ASCII_CHAR_P (c) && encoding->ascii_compatible_p)
936 return 1;
937 if (! repertory)
938 return -1;
939 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
942 static unsigned
943 xfont_encode_char (struct font *font, int c)
945 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
946 struct charset *charset;
947 unsigned code;
948 XChar2b char2b;
950 charset = CHARSET_FROM_ID (font->encoding_charset);
951 code = ENCODE_CHAR (charset, c);
952 if (code == CHARSET_INVALID_CODE (charset))
953 return FONT_INVALID_CODE;
954 if (font->repertory_charset >= 0)
956 charset = CHARSET_FROM_ID (font->repertory_charset);
957 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
958 ? code : FONT_INVALID_CODE);
960 char2b.byte1 = code >> 8;
961 char2b.byte2 = code & 0xFF;
962 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
965 static int
966 xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics)
968 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
969 int width = 0;
970 int i, first;
972 if (metrics)
973 memset (metrics, 0, sizeof (struct font_metrics));
974 for (i = 0, first = 1; i < nglyphs; i++)
976 XChar2b char2b;
977 static XCharStruct *pcm;
979 if (code[i] >= 0x10000)
980 continue;
981 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
982 pcm = xfont_get_pcm (xfont, &char2b);
983 if (! pcm)
984 continue;
985 if (first)
987 if (metrics)
989 metrics->lbearing = pcm->lbearing;
990 metrics->rbearing = pcm->rbearing;
991 metrics->ascent = pcm->ascent;
992 metrics->descent = pcm->descent;
994 first = 0;
996 else
998 if (metrics)
1000 if (metrics->lbearing > width + pcm->lbearing)
1001 metrics->lbearing = width + pcm->lbearing;
1002 if (metrics->rbearing < width + pcm->rbearing)
1003 metrics->rbearing = width + pcm->rbearing;
1004 if (metrics->ascent < pcm->ascent)
1005 metrics->ascent = pcm->ascent;
1006 if (metrics->descent < pcm->descent)
1007 metrics->descent = pcm->descent;
1010 width += pcm->width;
1012 if (metrics)
1013 metrics->width = width;
1014 return width;
1017 static int
1018 xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1019 bool with_background)
1021 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
1022 int len = to - from;
1023 GC gc = s->gc;
1024 int i;
1026 if (s->gc != s->face->gc)
1028 block_input ();
1029 XSetFont (s->display, gc, xfont->fid);
1030 unblock_input ();
1033 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1035 USE_SAFE_ALLOCA;
1036 char *str = SAFE_ALLOCA (len);
1037 for (i = 0; i < len ; i++)
1038 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
1039 block_input ();
1040 if (with_background)
1042 if (s->padding_p)
1043 for (i = 0; i < len; i++)
1044 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1045 gc, x + i, y, str + i, 1);
1046 else
1047 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1048 gc, x, y, str, len);
1050 else
1052 if (s->padding_p)
1053 for (i = 0; i < len; i++)
1054 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1055 gc, x + i, y, str + i, 1);
1056 else
1057 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1058 gc, x, y, str, len);
1060 unblock_input ();
1061 SAFE_FREE ();
1062 return s->nchars;
1065 block_input ();
1066 if (with_background)
1068 if (s->padding_p)
1069 for (i = 0; i < len; i++)
1070 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1071 gc, x + i, y, s->char2b + from + i, 1);
1072 else
1073 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1074 gc, x, y, s->char2b + from, len);
1076 else
1078 if (s->padding_p)
1079 for (i = 0; i < len; i++)
1080 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1081 gc, x + i, y, s->char2b + from + i, 1);
1082 else
1083 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1084 gc, x, y, s->char2b + from, len);
1086 unblock_input ();
1088 return len;
1091 static int
1092 xfont_check (struct frame *f, struct font *font)
1094 struct xfont_info *xfont = (struct xfont_info *) font;
1096 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1100 void
1101 syms_of_xfont (void)
1103 staticpro (&xfont_scripts_cache);
1104 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1105 is called fairly late, when QCtest and Qequal are known to be set. */
1106 Lisp_Object args[2];
1107 args[0] = QCtest;
1108 args[1] = Qequal;
1109 xfont_scripts_cache = Fmake_hash_table (2, args);
1111 staticpro (&xfont_scratch_props);
1112 xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
1113 xfont_driver.type = Qx;
1114 register_font_driver (&xfont_driver, NULL);