gnus-start-draft-setup: Move doc string forward.
[emacs.git] / src / xfont.c
blob368587de6d8f2b507ef560f9209e772a3b493e9f
1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010
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 <stdlib.h>
25 #include <setjmp.h>
26 #include <X11/Xlib.h>
28 #include "lisp.h"
29 #include "dispextern.h"
30 #include "xterm.h"
31 #include "frame.h"
32 #include "blockinput.h"
33 #include "character.h"
34 #include "charset.h"
35 #include "fontset.h"
36 #include "font.h"
37 #include "ccl.h"
40 /* X core font driver. */
42 struct xfont_info
44 struct font font;
45 Display *display;
46 XFontStruct *xfont;
49 /* Prototypes of support functions. */
50 extern void x_clear_errors (Display *);
52 static XCharStruct *xfont_get_pcm (XFontStruct *, XChar2b *);
54 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
55 is not contained in the font. */
57 static XCharStruct *
58 xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
60 /* The result metric information. */
61 XCharStruct *pcm = NULL;
63 font_assert (xfont && char2b);
65 if (xfont->per_char != NULL)
67 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
69 /* min_char_or_byte2 specifies the linear character index
70 corresponding to the first element of the per_char array,
71 max_char_or_byte2 is the index of the last character. A
72 character with non-zero CHAR2B->byte1 is not in the font.
73 A character with byte2 less than min_char_or_byte2 or
74 greater max_char_or_byte2 is not in the font. */
75 if (char2b->byte1 == 0
76 && char2b->byte2 >= xfont->min_char_or_byte2
77 && char2b->byte2 <= xfont->max_char_or_byte2)
78 pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
80 else
82 /* If either min_byte1 or max_byte1 are nonzero, both
83 min_char_or_byte2 and max_char_or_byte2 are less than
84 256, and the 2-byte character index values corresponding
85 to the per_char array element N (counting from 0) are:
87 byte1 = N/D + min_byte1
88 byte2 = N\D + min_char_or_byte2
90 where:
92 D = max_char_or_byte2 - min_char_or_byte2 + 1
93 / = integer division
94 \ = integer modulus */
95 if (char2b->byte1 >= xfont->min_byte1
96 && char2b->byte1 <= xfont->max_byte1
97 && char2b->byte2 >= xfont->min_char_or_byte2
98 && char2b->byte2 <= xfont->max_char_or_byte2)
99 pcm = (xfont->per_char
100 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
101 * (char2b->byte1 - xfont->min_byte1))
102 + (char2b->byte2 - xfont->min_char_or_byte2));
105 else
107 /* If the per_char pointer is null, all glyphs between the first
108 and last character indexes inclusive have the same
109 information, as given by both min_bounds and max_bounds. */
110 if (char2b->byte2 >= xfont->min_char_or_byte2
111 && char2b->byte2 <= xfont->max_char_or_byte2)
112 pcm = &xfont->max_bounds;
115 return ((pcm == NULL
116 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
117 ? NULL : pcm);
120 static Lisp_Object xfont_get_cache (FRAME_PTR);
121 static Lisp_Object xfont_list (Lisp_Object, Lisp_Object);
122 static Lisp_Object xfont_match (Lisp_Object, Lisp_Object);
123 static Lisp_Object xfont_list_family (Lisp_Object);
124 static Lisp_Object xfont_open (FRAME_PTR, Lisp_Object, int);
125 static void xfont_close (FRAME_PTR, struct font *);
126 static int xfont_prepare_face (FRAME_PTR, struct face *);
127 static int xfont_has_char (Lisp_Object, int);
128 static unsigned xfont_encode_char (struct font *, int);
129 static int xfont_text_extents (struct font *, unsigned *, int,
130 struct font_metrics *);
131 static int xfont_draw (struct glyph_string *, int, int, int, int, int);
132 static int xfont_check (FRAME_PTR, struct font *);
134 struct font_driver xfont_driver =
136 0, /* Qx */
137 0, /* case insensitive */
138 xfont_get_cache,
139 xfont_list,
140 xfont_match,
141 xfont_list_family,
142 NULL,
143 xfont_open,
144 xfont_close,
145 xfont_prepare_face,
146 NULL,
147 xfont_has_char,
148 xfont_encode_char,
149 xfont_text_extents,
150 xfont_draw,
151 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
152 xfont_check,
153 NULL, /* get_variation_glyphs */
154 NULL, /* filter_properties */
157 static Lisp_Object
158 xfont_get_cache (FRAME_PTR f)
160 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
162 return (dpyinfo->name_list_element);
165 static int
166 compare_font_names (const void *name1, const void *name2)
168 return xstrcasecmp (*(const unsigned char **) name1,
169 *(const unsigned char **) name2);
172 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
173 of the decoding result. LEN is the byte length of XLFD, or -1 if
174 XLFD is NULL terminated. The caller must assure that OUTPUT is at
175 least twice (plus 1) as large as XLFD. */
177 static int
178 xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
180 char *p0 = xlfd, *p1 = output;
181 int c;
183 while (*p0)
185 c = *(unsigned char *) p0++;
186 p1 += CHAR_STRING (c, p1);
187 if (--len == 0)
188 break;
190 *p1 = 0;
191 return (p1 - output);
194 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
195 resulting byte length. If XLFD contains unencodable character,
196 return -1. */
198 static int
199 xfont_encode_coding_xlfd (char *xlfd)
201 const unsigned char *p0 = (unsigned char *) xlfd;
202 unsigned char *p1 = (unsigned char *) xlfd;
203 int len = 0;
205 while (*p0)
207 int c = STRING_CHAR_ADVANCE (p0);
209 if (c >= 0x100)
210 return -1;
211 *p1++ = c;
212 len++;
214 *p1 = 0;
215 return len;
218 /* Check if CHARS (cons or vector) is supported by XFONT whose
219 encoding charset is ENCODING (XFONT is NULL) or by a font whose
220 registry corresponds to ENCODING and REPERTORY.
221 Return 1 if supported, return 0 otherwise. */
223 static int
224 xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
225 struct charset *encoding, struct charset *repertory)
227 struct charset *charset = repertory ? repertory : encoding;
229 if (CONSP (chars))
231 for (; CONSP (chars); chars = XCDR (chars))
233 int c = XINT (XCAR (chars));
234 unsigned code = ENCODE_CHAR (charset, c);
235 XChar2b char2b;
237 if (code == CHARSET_INVALID_CODE (charset))
238 break;
239 if (! xfont)
240 continue;
241 if (code >= 0x10000)
242 break;
243 char2b.byte1 = code >> 8;
244 char2b.byte2 = code & 0xFF;
245 if (! xfont_get_pcm (xfont, &char2b))
246 break;
248 return (NILP (chars));
250 else if (VECTORP (chars))
252 int i;
254 for (i = ASIZE (chars) - 1; i >= 0; i--)
256 int c = XINT (AREF (chars, i));
257 unsigned code = ENCODE_CHAR (charset, c);
258 XChar2b char2b;
260 if (code == CHARSET_INVALID_CODE (charset))
261 continue;
262 if (! xfont)
263 break;
264 if (code >= 0x10000)
265 continue;
266 char2b.byte1 = code >> 8;
267 char2b.byte2 = code & 0xFF;
268 if (xfont_get_pcm (xfont, &char2b))
269 break;
271 return (i >= 0);
273 return 0;
276 /* A hash table recoding which font supports which scritps. Each key
277 is a vector of characteristic font propertis FOUNDRY to WIDTH and
278 ADDSTYLE, and each value is a list of script symbols.
280 We assume that fonts that have the same value in the above
281 properties supports the same set of characters on all displays. */
283 static Lisp_Object xfont_scripts_cache;
285 /* Re-usable vector to store characteristic font properites. */
286 static Lisp_Object xfont_scratch_props;
288 /* Return a list of scripts supported by the font of FONTNAME whose
289 characteristic properties are in PROPS and whose encoding charset
290 is ENCODING. A caller must call BLOCK_INPUT in advance. */
292 static Lisp_Object
293 xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
294 struct charset *encoding)
296 Lisp_Object scripts;
298 /* Two special cases to avoid opening rather big fonts. */
299 if (EQ (AREF (props, 2), Qja))
300 return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil));
301 if (EQ (AREF (props, 2), Qko))
302 return Fcons (intern ("hangul"), Qnil);
303 scripts = Fgethash (props, xfont_scripts_cache, Qt);
304 if (EQ (scripts, Qt))
306 XFontStruct *xfont;
307 Lisp_Object val;
309 scripts = Qnil;
310 xfont = XLoadQueryFont (display, fontname);
311 if (xfont)
313 if (xfont->per_char)
315 for (val = Vscript_representative_chars; CONSP (val);
316 val = XCDR (val))
317 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
319 Lisp_Object script = XCAR (XCAR (val));
320 Lisp_Object chars = XCDR (XCAR (val));
322 if (xfont_chars_supported (chars, xfont, encoding, NULL))
323 scripts = Fcons (script, scripts);
326 XFreeFont (display, xfont);
328 if (EQ (AREF (props, 3), Qiso10646_1)
329 && NILP (Fmemq (Qlatin, scripts)))
330 scripts = Fcons (Qlatin, scripts);
331 Fputhash (Fcopy_sequence (props), scripts, xfont_scripts_cache);
333 return scripts;
336 static Lisp_Object
337 xfont_list_pattern (Display *display, const char *pattern,
338 Lisp_Object registry, Lisp_Object script)
340 Lisp_Object list = Qnil;
341 Lisp_Object chars = Qnil;
342 struct charset *encoding, *repertory = NULL;
343 int i, limit, num_fonts;
344 char **names;
345 /* Large enough to decode the longest XLFD (255 bytes). */
346 char buf[512];
348 if (! NILP (registry)
349 && font_registry_charsets (registry, &encoding, &repertory) < 0)
350 /* Unknown REGISTRY, not supported. */
351 return Qnil;
352 if (! NILP (script))
354 chars = assq_no_quit (script, Vscript_representative_chars);
355 if (NILP (chars))
356 /* We can't tell whether or not a font supports SCRIPT. */
357 return Qnil;
358 chars = XCDR (chars);
359 if (repertory)
361 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
362 return Qnil;
363 script = Qnil;
367 BLOCK_INPUT;
368 x_catch_errors (display);
370 for (limit = 512; ; limit *= 2)
372 names = XListFonts (display, pattern, limit, &num_fonts);
373 if (x_had_errors_p (display))
375 /* This error is perhaps due to insufficient memory on X
376 server. Let's just ignore it. */
377 x_clear_errors (display);
378 num_fonts = 0;
379 break;
381 if (num_fonts < limit)
382 break;
383 XFreeFontNames (names);
386 if (num_fonts > 0)
388 char **indices = alloca (sizeof (char *) * num_fonts);
389 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
390 Lisp_Object scripts = Qnil;
392 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
393 props[i] = Qnil;
394 for (i = 0; i < num_fonts; i++)
395 indices[i] = names[i];
396 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
398 for (i = 0; i < num_fonts; i++)
400 Lisp_Object entity;
402 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
403 continue;
404 entity = font_make_entity ();
405 xfont_decode_coding_xlfd (indices[i], -1, buf);
406 if (font_parse_xlfd (buf, entity) < 0)
407 continue;
408 ASET (entity, FONT_TYPE_INDEX, Qx);
409 /* Avoid auto-scaled fonts. */
410 if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
411 && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
412 && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
413 && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
414 continue;
415 /* Avoid not-allowed scalable fonts. */
416 if (NILP (Vscalable_fonts_allowed))
418 int size = 0;
420 if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
421 size = XINT (AREF (entity, FONT_SIZE_INDEX));
422 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
423 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
424 if (size == 0)
425 continue;
427 else if (CONSP (Vscalable_fonts_allowed))
429 Lisp_Object tail, elt;
431 for (tail = Vscalable_fonts_allowed; CONSP (tail);
432 tail = XCDR (tail))
434 elt = XCAR (tail);
435 if (STRINGP (elt)
436 && fast_c_string_match_ignore_case (elt, indices[i]) >= 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 (entity, FONT_FOUNDRY_INDEX)),
465 sizeof (Lisp_Object) * 7)
466 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
468 memcpy (props, &(AREF (entity, FONT_FOUNDRY_INDEX)),
469 sizeof (Lisp_Object) * 7);
470 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 (Lisp_Object frame, Lisp_Object spec)
491 FRAME_PTR f = XFRAME (frame);
492 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
493 Lisp_Object registry, list, val, extra, script;
494 int len;
495 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
496 char name[512];
498 extra = AREF (spec, FONT_EXTRA_INDEX);
499 if (CONSP (extra))
501 val = assq_no_quit (QCotf, extra);
502 if (! NILP (val))
503 return Qnil;
504 val = assq_no_quit (QClang, extra);
505 if (! NILP (val))
506 return Qnil;
509 registry = AREF (spec, FONT_REGISTRY_INDEX);
510 len = font_unparse_xlfd (spec, 0, name, 512);
511 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
512 return Qnil;
514 val = assq_no_quit (QCscript, extra);
515 script = CDR (val);
516 list = xfont_list_pattern (display, name, registry, script);
517 if (NILP (list) && NILP (registry))
519 /* Try iso10646-1 */
520 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
522 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
524 strcpy (r, "iso10646-1");
525 list = xfont_list_pattern (display, name, Qiso10646_1, script);
528 if (NILP (list) && ! NILP (registry))
530 /* Try alternate registries. */
531 Lisp_Object alter;
533 if ((alter = Fassoc (SYMBOL_NAME (registry),
534 Vface_alternative_font_registry_alist),
535 CONSP (alter)))
537 /* Pointer to REGISTRY-ENCODING field. */
538 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
540 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
541 if (STRINGP (XCAR (alter))
542 && ((r - name) + SBYTES (XCAR (alter))) < 256)
544 strcpy (r, (char *) SDATA (XCAR (alter)));
545 list = xfont_list_pattern (display, name, registry, script);
546 if (! NILP (list))
547 break;
551 if (NILP (list))
553 /* Try alias. */
554 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
555 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
557 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
558 if (xfont_encode_coding_xlfd (name) < 0)
559 return Qnil;
560 list = xfont_list_pattern (display, name, registry, script);
564 return list;
567 static Lisp_Object
568 xfont_match (Lisp_Object frame, Lisp_Object spec)
570 FRAME_PTR f = XFRAME (frame);
571 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
572 Lisp_Object extra, val, entity;
573 char name[512];
574 XFontStruct *xfont;
575 unsigned long value;
577 extra = AREF (spec, FONT_EXTRA_INDEX);
578 val = assq_no_quit (QCname, extra);
579 if (! CONSP (val) || ! STRINGP (XCDR (val)))
581 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
582 return Qnil;
584 else if (SBYTES (XCDR (val)) < 512)
585 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
586 else
587 return Qnil;
588 if (xfont_encode_coding_xlfd (name) < 0)
589 return Qnil;
591 BLOCK_INPUT;
592 entity = Qnil;
593 xfont = XLoadQueryFont (display, name);
594 if (xfont)
596 if (XGetFontProperty (xfont, XA_FONT, &value))
598 int len;
599 char *s;
601 s = (char *) XGetAtomName (display, (Atom) value);
602 len = strlen (s);
604 /* If DXPC (a Differential X Protocol Compressor)
605 Ver.3.7 is running, XGetAtomName will return null
606 string. We must avoid such a name. */
607 if (len > 0)
609 entity = font_make_entity ();
610 ASET (entity, FONT_TYPE_INDEX, Qx);
611 xfont_decode_coding_xlfd (s, -1, name);
612 if (font_parse_xlfd (name, entity) < 0)
613 entity = Qnil;
615 XFree (s);
617 XFreeFont (display, xfont);
619 UNBLOCK_INPUT;
621 FONT_ADD_LOG ("xfont-match", spec, entity);
622 return entity;
625 static Lisp_Object
626 xfont_list_family (Lisp_Object frame)
628 FRAME_PTR f = XFRAME (frame);
629 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
630 char **names;
631 int num_fonts, i;
632 Lisp_Object list;
633 char *last_family;
634 int last_len;
636 BLOCK_INPUT;
637 x_catch_errors (dpyinfo->display);
638 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
639 0x8000, &num_fonts);
640 if (x_had_errors_p (dpyinfo->display))
642 /* This error is perhaps due to insufficient memory on X server.
643 Let's just ignore it. */
644 x_clear_errors (dpyinfo->display);
645 num_fonts = 0;
648 list = Qnil;
649 for (i = 0, last_len = 0; i < num_fonts; i++)
651 char *p0 = names[i], *p1, buf[512];
652 Lisp_Object family;
653 int decoded_len;
655 p0++; /* skip the leading '-' */
656 while (*p0 && *p0 != '-') p0++; /* skip foundry */
657 if (! *p0)
658 continue;
659 p1 = ++p0;
660 while (*p1 && *p1 != '-') p1++; /* find the end of family */
661 if (! *p1 || p1 == p0)
662 continue;
663 if (last_len == p1 - p0
664 && memcmp (last_family, p0, last_len) == 0)
665 continue;
666 last_len = p1 - p0;
667 last_family = p0;
669 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
670 family = font_intern_prop (p0, decoded_len, 1);
671 if (NILP (assq_no_quit (family, list)))
672 list = Fcons (family, list);
675 XFreeFontNames (names);
676 x_uncatch_errors ();
677 UNBLOCK_INPUT;
679 return list;
682 static Lisp_Object
683 xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
685 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
686 Display *display = dpyinfo->display;
687 char name[512];
688 int len;
689 unsigned long value;
690 Lisp_Object registry;
691 struct charset *encoding, *repertory;
692 Lisp_Object font_object, fullname;
693 struct font *font;
694 XFontStruct *xfont;
696 /* At first, check if we know how to encode characters for this
697 font. */
698 registry = AREF (entity, FONT_REGISTRY_INDEX);
699 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
701 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
702 return Qnil;
705 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
706 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
707 else if (pixel_size == 0)
709 if (FRAME_FONT (f))
710 pixel_size = FRAME_FONT (f)->pixel_size;
711 else
712 pixel_size = 14;
714 len = font_unparse_xlfd (entity, pixel_size, name, 512);
715 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
717 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
718 return Qnil;
721 BLOCK_INPUT;
722 x_catch_errors (display);
723 xfont = XLoadQueryFont (display, name);
724 if (x_had_errors_p (display))
726 /* This error is perhaps due to insufficient memory on X server.
727 Let's just ignore it. */
728 x_clear_errors (display);
729 xfont = NULL;
731 else if (! xfont)
733 /* Some version of X lists:
734 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
735 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
736 but can open only:
737 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
739 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
740 So, we try again with wildcards in RESX and RESY. */
741 Lisp_Object temp;
743 temp = Fcopy_font_spec (entity);
744 ASET (temp, FONT_DPI_INDEX, Qnil);
745 len = font_unparse_xlfd (temp, pixel_size, name, 512);
746 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
748 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
749 return Qnil;
751 xfont = XLoadQueryFont (display, name);
752 if (x_had_errors_p (display))
754 /* This error is perhaps due to insufficient memory on X server.
755 Let's just ignore it. */
756 x_clear_errors (display);
757 xfont = NULL;
760 fullname = Qnil;
761 /* Try to get the full name of FONT. */
762 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
764 char *p0, *p;
765 int dashes = 0;
767 p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
768 /* Count the number of dashes in the "full name".
769 If it is too few, this isn't really the font's full name,
770 so don't use it.
771 In X11R4, the fonts did not come with their canonical names
772 stored in them. */
773 while (*p)
775 if (*p == '-')
776 dashes++;
777 p++;
780 if (dashes >= 13)
782 len = xfont_decode_coding_xlfd (p0, -1, name);
783 fullname = Fdowncase (make_string (name, len));
785 XFree (p0);
787 x_uncatch_errors ();
788 UNBLOCK_INPUT;
790 if (! xfont)
792 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
793 return Qnil;
796 font_object = font_make_object (VECSIZE (struct xfont_info),
797 entity, pixel_size);
798 ASET (font_object, FONT_TYPE_INDEX, Qx);
799 if (STRINGP (fullname))
801 font_parse_xlfd ((char *) SDATA (fullname), font_object);
802 ASET (font_object, FONT_NAME_INDEX, fullname);
804 else
806 char buf[512];
808 len = xfont_decode_coding_xlfd (name, -1, buf);
809 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
811 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
812 ASET (font_object, FONT_FILE_INDEX, Qnil);
813 ASET (font_object, FONT_FORMAT_INDEX, Qx);
814 font = XFONT_OBJECT (font_object);
815 ((struct xfont_info *) font)->xfont = xfont;
816 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
817 font->pixel_size = pixel_size;
818 font->driver = &xfont_driver;
819 font->encoding_charset = encoding->id;
820 font->repertory_charset = repertory ? repertory->id : -1;
821 font->ascent = xfont->ascent;
822 font->descent = xfont->descent;
823 font->height = font->ascent + font->descent;
824 font->min_width = xfont->min_bounds.width;
825 if (xfont->min_bounds.width == xfont->max_bounds.width)
827 /* Fixed width font. */
828 font->average_width = font->space_width = xfont->min_bounds.width;
830 else
832 XCharStruct *pcm;
833 XChar2b char2b;
834 Lisp_Object val;
836 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
837 pcm = xfont_get_pcm (xfont, &char2b);
838 if (pcm)
839 font->space_width = pcm->width;
840 else
841 font->space_width = 0;
843 val = Ffont_get (font_object, QCavgwidth);
844 if (INTEGERP (val))
845 font->average_width = XINT (val);
846 if (font->average_width < 0)
847 font->average_width = - font->average_width;
848 if (font->average_width == 0
849 && encoding->ascii_compatible_p)
851 int width = font->space_width, n = pcm != NULL;
853 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
854 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
855 width += pcm->width, n++;
856 if (n > 0)
857 font->average_width = width / n;
859 if (font->average_width == 0)
860 /* No easy way other than this to get a reasonable
861 average_width. */
862 font->average_width
863 = (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 (FRAME_PTR 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 (FRAME_PTR 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, x;
972 if (metrics)
973 memset (metrics, 0, sizeof (struct font_metrics));
974 for (i = 0, x = 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, int with_background)
1020 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
1021 int len = to - from;
1022 GC gc = s->gc;
1023 int i;
1025 if (s->gc != s->face->gc)
1027 BLOCK_INPUT;
1028 XSetFont (s->display, gc, xfont->fid);
1029 UNBLOCK_INPUT;
1032 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1034 char *str;
1035 USE_SAFE_ALLOCA;
1037 SAFE_ALLOCA (str, char *, len);
1038 for (i = 0; i < len ; i++)
1039 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
1040 BLOCK_INPUT;
1041 if (with_background > 0)
1043 if (s->padding_p)
1044 for (i = 0; i < len; i++)
1045 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1046 gc, x + i, y, str + i, 1);
1047 else
1048 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1049 gc, x, y, str, len);
1051 else
1053 if (s->padding_p)
1054 for (i = 0; i < len; i++)
1055 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1056 gc, x + i, y, str + i, 1);
1057 else
1058 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1059 gc, x, y, str, len);
1061 UNBLOCK_INPUT;
1062 SAFE_FREE ();
1063 return s->nchars;
1066 BLOCK_INPUT;
1067 if (with_background > 0)
1069 if (s->padding_p)
1070 for (i = 0; i < len; i++)
1071 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1072 gc, x + i, y, s->char2b + from + i, 1);
1073 else
1074 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1075 gc, x, y, s->char2b + from, len);
1077 else
1079 if (s->padding_p)
1080 for (i = 0; i < len; i++)
1081 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1082 gc, x + i, y, s->char2b + from + i, 1);
1083 else
1084 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
1085 gc, x, y, s->char2b + from, len);
1087 UNBLOCK_INPUT;
1089 return len;
1092 static int
1093 xfont_check (FRAME_PTR f, struct font *font)
1095 struct xfont_info *xfont = (struct xfont_info *) font;
1097 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1101 void
1102 syms_of_xfont (void)
1104 staticpro (&xfont_scripts_cache);
1105 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1106 is called fairly late, when QCtest and Qequal are known to be set. */
1107 Lisp_Object args[2];
1108 args[0] = QCtest;
1109 args[1] = Qequal;
1110 xfont_scripts_cache = Fmake_hash_table (2, args);
1112 staticpro (&xfont_scratch_props);
1113 xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
1114 xfont_driver.type = Qx;
1115 register_font_driver (&xfont_driver, NULL);
1118 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1119 (do not change this comment) */