1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2014 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/>. */
27 #include "dispextern.h"
30 #include "blockinput.h"
31 #include "character.h"
38 /* X core font driver. */
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. */
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
;
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
90 D = max_char_or_byte2 - min_char_or_byte2 + 1
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
));
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
;
114 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
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 int 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 int 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 0, /* case insensitive */
149 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
151 NULL
, /* get_variation_glyphs */
152 NULL
, /* filter_properties */
156 xfont_get_cache (struct frame
*f
)
158 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
160 return (dpyinfo
->name_list_element
);
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. */
177 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
179 char *p0
= xlfd
, *p1
= output
;
184 c
= *(unsigned char *) p0
++;
185 p1
+= CHAR_STRING (c
, (unsigned char *) p1
);
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,
198 xfont_encode_coding_xlfd (char *xlfd
)
200 const unsigned char *p0
= (unsigned char *) xlfd
;
201 unsigned char *p1
= (unsigned char *) xlfd
;
206 int c
= STRING_CHAR_ADVANCE (p0
);
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. */
223 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
224 struct charset
*encoding
, struct charset
*repertory
)
226 struct charset
*charset
= repertory
? repertory
: encoding
;
230 for (; CONSP (chars
); chars
= XCDR (chars
))
232 int c
= XINT (XCAR (chars
));
233 unsigned code
= ENCODE_CHAR (charset
, c
);
236 if (code
== CHARSET_INVALID_CODE (charset
))
242 char2b
.byte1
= code
>> 8;
243 char2b
.byte2
= code
& 0xFF;
244 if (! xfont_get_pcm (xfont
, &char2b
))
247 return (NILP (chars
));
249 else if (VECTORP (chars
))
253 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
255 int c
= XINT (AREF (chars
, i
));
256 unsigned code
= ENCODE_CHAR (charset
, c
);
259 if (code
== CHARSET_INVALID_CODE (charset
))
265 char2b
.byte1
= code
>> 8;
266 char2b
.byte2
= code
& 0xFF;
267 if (xfont_get_pcm (xfont
, &char2b
))
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. */
292 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
293 struct charset
*encoding
)
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
))
309 xfont
= XLoadQueryFont (display
, fontname
);
314 for (val
= Vscript_representative_chars
; CONSP (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
);
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
;
344 /* Large enough to decode the longest XLFD (255 bytes). */
347 if (! NILP (registry
)
348 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
349 /* Unknown REGISTRY, not supported. */
353 chars
= assq_no_quit (script
, Vscript_representative_chars
);
355 /* We can't tell whether or not a font supports SCRIPT. */
357 chars
= XCDR (chars
);
360 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
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
);
380 if (num_fonts
< limit
)
382 XFreeFontNames (names
);
387 char **indices
= alloca (sizeof (char *) * num_fonts
);
388 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
389 Lisp_Object scripts
= 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 for (i
= 0; i
< num_fonts
; i
++)
402 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
404 entity
= font_make_entity ();
405 len
= xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
406 if (font_parse_xlfd (buf
, len
, entity
) < 0)
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)
415 /* Avoid not-allowed scalable fonts. */
416 if (NILP (Vscalable_fonts_allowed
))
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
));
427 else if (CONSP (Vscalable_fonts_allowed
))
429 Lisp_Object tail
, elt
;
431 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
436 && fast_c_string_match_ignore_case (elt
, indices
[i
],
444 /* Avoid fonts of invalid registry. */
445 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
448 /* Update encoding and repertory if necessary. */
449 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
451 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
452 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
456 /* Unknown REGISTRY, not supported. */
461 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
462 list
= Fcons (entity
, list
);
465 if (memcmp (props
, aref_addr (entity
, FONT_FOUNDRY_INDEX
),
467 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
469 vcopy (xfont_scratch_props
, 0,
470 aref_addr (entity
, FONT_FOUNDRY_INDEX
), 7);
471 ASET (xfont_scratch_props
, 7, AREF (entity
, FONT_SPACING_INDEX
));
472 scripts
= xfont_supported_scripts (display
, indices
[i
],
473 xfont_scratch_props
, encoding
);
476 || ! NILP (Fmemq (script
, scripts
)))
477 list
= Fcons (entity
, list
);
479 XFreeFontNames (names
);
485 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
490 xfont_list (struct frame
*f
, Lisp_Object spec
)
492 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
493 Lisp_Object registry
, list
, val
, extra
, script
;
495 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
498 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
501 val
= assq_no_quit (QCotf
, extra
);
504 val
= assq_no_quit (QClang
, extra
);
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)
514 val
= assq_no_quit (QCscript
, extra
);
516 list
= xfont_list_pattern (display
, name
, registry
, script
);
517 if (NILP (list
) && NILP (registry
))
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. */
533 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
534 Vface_alternative_font_registry_alist
),
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
, SSDATA (XCAR (alter
)));
545 list
= xfont_list_pattern (display
, name
, registry
, script
);
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)
560 list
= xfont_list_pattern (display
, name
, registry
, script
);
568 xfont_match (struct frame
*f
, Lisp_Object spec
)
570 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
571 Lisp_Object extra
, val
, entity
;
576 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
577 val
= assq_no_quit (QCname
, extra
);
578 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
580 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
583 else if (SBYTES (XCDR (val
)) < 512)
584 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
587 if (xfont_encode_coding_xlfd (name
) < 0)
592 xfont
= XLoadQueryFont (display
, name
);
595 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
597 char *s
= XGetAtomName (display
, (Atom
) value
);
599 /* If DXPC (a Differential X Protocol Compressor)
600 Ver.3.7 is running, XGetAtomName will return null
601 string. We must avoid such a name. */
605 entity
= font_make_entity ();
606 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
607 len
= xfont_decode_coding_xlfd (s
, -1, name
);
608 if (font_parse_xlfd (name
, len
, entity
) < 0)
613 XFreeFont (display
, xfont
);
617 FONT_ADD_LOG ("xfont-match", spec
, entity
);
622 xfont_list_family (struct frame
*f
)
624 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
628 char *last_family
IF_LINT (= 0);
632 x_catch_errors (dpyinfo
->display
);
633 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
635 if (x_had_errors_p (dpyinfo
->display
))
637 /* This error is perhaps due to insufficient memory on X server.
638 Let's just ignore it. */
639 x_clear_errors (dpyinfo
->display
);
644 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
646 char *p0
= names
[i
], *p1
, buf
[512];
650 p0
++; /* skip the leading '-' */
651 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
655 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
656 if (! *p1
|| p1
== p0
)
658 if (last_len
== p1
- p0
659 && memcmp (last_family
, p0
, last_len
) == 0)
664 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
665 family
= font_intern_prop (p0
, decoded_len
, 1);
666 if (NILP (assq_no_quit (family
, list
)))
667 list
= Fcons (family
, list
);
670 XFreeFontNames (names
);
678 xfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
680 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
681 Display
*display
= dpyinfo
->display
;
685 Lisp_Object registry
;
686 struct charset
*encoding
, *repertory
;
687 Lisp_Object font_object
, fullname
;
691 /* At first, check if we know how to encode characters for this
693 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
694 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
696 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
700 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
701 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
702 else if (pixel_size
== 0)
705 pixel_size
= FRAME_FONT (f
)->pixel_size
;
709 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
710 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
712 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
717 x_catch_errors (display
);
718 xfont
= XLoadQueryFont (display
, name
);
719 if (x_had_errors_p (display
))
721 /* This error is perhaps due to insufficient memory on X server.
722 Let's just ignore it. */
723 x_clear_errors (display
);
728 /* Some version of X lists:
729 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
730 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
732 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
734 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
735 So, we try again with wildcards in RESX and RESY. */
738 temp
= copy_font_spec (entity
);
739 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
740 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
741 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
743 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
746 xfont
= XLoadQueryFont (display
, name
);
747 if (x_had_errors_p (display
))
749 /* This error is perhaps due to insufficient memory on X server.
750 Let's just ignore it. */
751 x_clear_errors (display
);
756 /* Try to get the full name of FONT. */
757 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
762 p0
= p
= XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
763 /* Count the number of dashes in the "full name".
764 If it is too few, this isn't really the font's full name,
766 In X11R4, the fonts did not come with their canonical names
777 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
778 fullname
= Fdowncase (make_string (name
, len
));
787 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
791 font_object
= font_make_object (VECSIZE (struct xfont_info
),
793 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
794 if (STRINGP (fullname
))
796 font_parse_xlfd (SSDATA (fullname
), SBYTES (fullname
), font_object
);
797 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
803 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
804 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
806 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
807 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
808 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
809 font
= XFONT_OBJECT (font_object
);
810 ((struct xfont_info
*) font
)->xfont
= xfont
;
811 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
812 ((struct xfont_info
*) font
)->x_display_id
= FRAME_DISPLAY_INFO (f
)->x_id
;
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
;
833 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
834 pcm
= xfont_get_pcm (xfont
, &char2b
);
836 font
->space_width
= pcm
->width
;
838 font
->space_width
= 0;
840 val
= Ffont_get (font_object
, QCavgwidth
);
842 font
->average_width
= XINT (val
) / 10;
843 if (font
->average_width
< 0)
844 font
->average_width
= - font
->average_width
;
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
++;
856 font
->average_width
= width
/ n
;
858 if (font
->average_width
== 0)
859 /* No easy way other than this to get a reasonable
862 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
867 font
->underline_thickness
868 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
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
)
876 font
->relative_compose
877 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
880 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
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));
895 xfont_close (struct font
*font
)
897 struct x_display_info
*xdi
;
898 struct xfont_info
*xfi
= (struct xfont_info
*) font
;
900 /* This function may be called from GC when X connection is gone
901 (Bug#16093), and an attempt to free font resources on invalid
902 display may lead to X protocol errors or segfaults. Moreover,
903 the memory referenced by 'Display *' pointer may be reused for
904 the logically different X connection after the previous display
905 connection was closed. That's why we also check whether font's
906 ID matches the one recorded in x_display_info for this display.
907 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
909 && ((xdi
= x_display_info_for_display (xfi
->display
))
910 && xfi
->x_display_id
== xdi
->x_id
))
913 XFreeFont (xfi
->display
, xfi
->xfont
);
920 xfont_prepare_face (struct frame
*f
, struct face
*face
)
923 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
924 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
931 xfont_has_char (Lisp_Object font
, int c
)
933 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
934 struct charset
*encoding
;
935 struct charset
*repertory
= NULL
;
937 if (EQ (registry
, Qiso10646_1
))
939 encoding
= CHARSET_FROM_ID (charset_unicode
);
940 /* We use a font of `ja' and `ko' adstyle only for a character
941 in JISX0208 and KSC5601 charsets respectively. */
942 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
943 && charset_jisx0208
>= 0)
944 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
945 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
946 && charset_ksc5601
>= 0)
947 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
949 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
950 /* Unknown REGISTRY, not usable. */
952 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
956 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
960 xfont_encode_char (struct font
*font
, int c
)
962 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
963 struct charset
*charset
;
967 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
968 code
= ENCODE_CHAR (charset
, c
);
969 if (code
== CHARSET_INVALID_CODE (charset
))
970 return FONT_INVALID_CODE
;
971 if (font
->repertory_charset
>= 0)
973 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
974 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
975 ? code
: FONT_INVALID_CODE
);
977 char2b
.byte1
= code
>> 8;
978 char2b
.byte2
= code
& 0xFF;
979 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
983 xfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
985 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
990 memset (metrics
, 0, sizeof (struct font_metrics
));
991 for (i
= 0, first
= 1; i
< nglyphs
; i
++)
994 static XCharStruct
*pcm
;
996 if (code
[i
] >= 0x10000)
998 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
999 pcm
= xfont_get_pcm (xfont
, &char2b
);
1006 metrics
->lbearing
= pcm
->lbearing
;
1007 metrics
->rbearing
= pcm
->rbearing
;
1008 metrics
->ascent
= pcm
->ascent
;
1009 metrics
->descent
= pcm
->descent
;
1017 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1018 metrics
->lbearing
= width
+ pcm
->lbearing
;
1019 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1020 metrics
->rbearing
= width
+ pcm
->rbearing
;
1021 if (metrics
->ascent
< pcm
->ascent
)
1022 metrics
->ascent
= pcm
->ascent
;
1023 if (metrics
->descent
< pcm
->descent
)
1024 metrics
->descent
= pcm
->descent
;
1027 width
+= pcm
->width
;
1030 metrics
->width
= width
;
1035 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
1036 bool with_background
)
1038 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1039 int len
= to
- from
;
1043 if (s
->gc
!= s
->face
->gc
)
1046 XSetFont (s
->display
, gc
, xfont
->fid
);
1050 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1053 char *str
= SAFE_ALLOCA (len
);
1054 for (i
= 0; i
< len
; i
++)
1055 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1057 if (with_background
)
1060 for (i
= 0; i
< len
; i
++)
1061 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1062 gc
, x
+ i
, y
, str
+ i
, 1);
1064 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1065 gc
, x
, y
, str
, len
);
1070 for (i
= 0; i
< len
; i
++)
1071 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1072 gc
, x
+ i
, y
, str
+ i
, 1);
1074 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1075 gc
, x
, y
, str
, len
);
1083 if (with_background
)
1086 for (i
= 0; i
< len
; i
++)
1087 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1088 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1090 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1091 gc
, x
, y
, s
->char2b
+ from
, len
);
1096 for (i
= 0; i
< len
; i
++)
1097 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1098 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1100 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1101 gc
, x
, y
, s
->char2b
+ from
, len
);
1109 xfont_check (struct frame
*f
, struct font
*font
)
1111 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1113 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1118 syms_of_xfont (void)
1120 staticpro (&xfont_scripts_cache
);
1121 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1122 is called fairly late, when QCtest and Qequal are known to be set. */
1123 Lisp_Object args
[2];
1126 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1128 staticpro (&xfont_scratch_props
);
1129 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1130 xfont_driver
.type
= Qx
;
1131 register_font_driver (&xfont_driver
, NULL
);