1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2018 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or (at
12 your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
30 #include "blockinput.h"
31 #include "character.h"
36 /* X core font driver. */
43 unsigned x_display_id
;
46 /* Prototypes of support functions. */
48 static XCharStruct
*xfont_get_pcm (XFontStruct
*, XChar2b
*);
50 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
51 is not contained in the font. */
54 xfont_get_pcm (XFontStruct
*xfont
, XChar2b
*char2b
)
56 /* The result metric information. */
57 XCharStruct
*pcm
= NULL
;
59 eassert (xfont
&& char2b
);
61 if (xfont
->per_char
!= NULL
)
63 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
65 /* min_char_or_byte2 specifies the linear character index
66 corresponding to the first element of the per_char array,
67 max_char_or_byte2 is the index of the last character. A
68 character with non-zero CHAR2B->byte1 is not in the font.
69 A character with byte2 less than min_char_or_byte2 or
70 greater max_char_or_byte2 is not in the font. */
71 if (char2b
->byte1
== 0
72 && char2b
->byte2
>= xfont
->min_char_or_byte2
73 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
74 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
78 /* If either min_byte1 or max_byte1 are nonzero, both
79 min_char_or_byte2 and max_char_or_byte2 are less than
80 256, and the 2-byte character index values corresponding
81 to the per_char array element N (counting from 0) are:
83 byte1 = N/D + min_byte1
84 byte2 = N\D + min_char_or_byte2
88 D = max_char_or_byte2 - min_char_or_byte2 + 1
90 \ = integer modulus */
91 if (char2b
->byte1
>= xfont
->min_byte1
92 && char2b
->byte1
<= xfont
->max_byte1
93 && char2b
->byte2
>= xfont
->min_char_or_byte2
94 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
95 pcm
= (xfont
->per_char
96 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
97 * (char2b
->byte1
- xfont
->min_byte1
))
98 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
103 /* If the per_char pointer is null, all glyphs between the first
104 and last character indexes inclusive have the same
105 information, as given by both min_bounds and max_bounds. */
106 if (char2b
->byte2
>= xfont
->min_char_or_byte2
107 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
108 pcm
= &xfont
->max_bounds
;
112 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
117 xfont_get_cache (struct frame
*f
)
119 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
121 return (dpyinfo
->name_list_element
);
125 compare_font_names (const void *name1
, const void *name2
)
127 char *const *n1
= name1
;
128 char *const *n2
= name2
;
129 return xstrcasecmp (*n1
, *n2
);
132 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
133 of the decoding result. LEN is the byte length of XLFD, or -1 if
134 XLFD is NULL terminated. The caller must assure that OUTPUT is at
135 least twice (plus 1) as large as XLFD. */
138 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
140 char *p0
= xlfd
, *p1
= output
;
145 c
= *(unsigned char *) p0
++;
146 p1
+= CHAR_STRING (c
, (unsigned char *) p1
);
151 return (p1
- output
);
154 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
155 resulting byte length. If XLFD contains unencodable character,
159 xfont_encode_coding_xlfd (char *xlfd
)
161 const unsigned char *p0
= (unsigned char *) xlfd
;
162 unsigned char *p1
= (unsigned char *) xlfd
;
167 int c
= STRING_CHAR_ADVANCE (p0
);
178 /* Check if CHARS (cons or vector) is supported by XFONT whose
179 encoding charset is ENCODING (XFONT is NULL) or by a font whose
180 registry corresponds to ENCODING and REPERTORY.
181 Return true if supported. */
184 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
185 struct charset
*encoding
, struct charset
*repertory
)
187 struct charset
*charset
= repertory
? repertory
: encoding
;
191 for (; CONSP (chars
); chars
= XCDR (chars
))
193 int c
= XINT (XCAR (chars
));
194 unsigned code
= ENCODE_CHAR (charset
, c
);
197 if (code
== CHARSET_INVALID_CODE (charset
))
203 char2b
.byte1
= code
>> 8;
204 char2b
.byte2
= code
& 0xFF;
205 if (! xfont_get_pcm (xfont
, &char2b
))
208 return (NILP (chars
));
210 else if (VECTORP (chars
))
214 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
216 int c
= XINT (AREF (chars
, i
));
217 unsigned code
= ENCODE_CHAR (charset
, c
);
220 if (code
== CHARSET_INVALID_CODE (charset
))
226 char2b
.byte1
= code
>> 8;
227 char2b
.byte2
= code
& 0xFF;
228 if (xfont_get_pcm (xfont
, &char2b
))
236 /* A hash table recoding which font supports which scripts. Each key
237 is a vector of characteristic font properties FOUNDRY to WIDTH and
238 ADDSTYLE, and each value is a list of script symbols.
240 We assume that fonts that have the same value in the above
241 properties supports the same set of characters on all displays. */
243 static Lisp_Object xfont_scripts_cache
;
245 /* Re-usable vector to store characteristic font properties. */
246 static Lisp_Object xfont_scratch_props
;
248 /* Return a list of scripts supported by the font of FONTNAME whose
249 characteristic properties are in PROPS and whose encoding charset
250 is ENCODING. A caller must call BLOCK_INPUT in advance. */
253 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
254 struct charset
*encoding
)
258 /* Two special cases to avoid opening rather big fonts. */
259 if (EQ (AREF (props
, 2), Qja
))
260 return list2 (intern ("kana"), intern ("han"));
261 if (EQ (AREF (props
, 2), Qko
))
262 return list1 (intern ("hangul"));
263 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
264 if (EQ (scripts
, Qt
))
270 xfont
= XLoadQueryFont (display
, fontname
);
275 for (val
= Vscript_representative_chars
; CONSP (val
);
277 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
279 Lisp_Object script
= XCAR (XCAR (val
));
280 Lisp_Object chars
= XCDR (XCAR (val
));
282 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
283 scripts
= Fcons (script
, scripts
);
286 XFreeFont (display
, xfont
);
288 if (EQ (AREF (props
, 3), Qiso10646_1
)
289 && NILP (Fmemq (Qlatin
, scripts
)))
290 scripts
= Fcons (Qlatin
, scripts
);
291 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
297 xfont_list_pattern (Display
*display
, const char *pattern
,
298 Lisp_Object registry
, Lisp_Object script
)
300 Lisp_Object list
= Qnil
;
301 Lisp_Object chars
= Qnil
;
302 struct charset
*encoding
, *repertory
= NULL
;
303 int i
, limit
, num_fonts
;
305 /* Large enough to decode the longest XLFD (255 bytes). */
308 if (! NILP (registry
)
309 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
310 /* Unknown REGISTRY, not supported. */
314 chars
= assq_no_quit (script
, Vscript_representative_chars
);
316 /* We can't tell whether or not a font supports SCRIPT. */
318 chars
= XCDR (chars
);
321 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
328 x_catch_errors (display
);
330 for (limit
= 512; ; limit
*= 2)
332 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
333 if (x_had_errors_p (display
))
335 /* This error is perhaps due to insufficient memory on X
336 server. Let's just ignore it. */
337 x_clear_errors (display
);
341 if (num_fonts
< limit
)
343 XFreeFontNames (names
);
348 char **indices
= alloca (sizeof (char *) * num_fonts
);
349 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
350 Lisp_Object scripts
= Qnil
, entity
= Qnil
;
352 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
353 ASET (xfont_scratch_props
, i
, Qnil
);
354 for (i
= 0; i
< num_fonts
; i
++)
355 indices
[i
] = names
[i
];
356 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
358 /* Take one or two passes over the font list. Do the second
359 pass only if we really need it, i.e., only if the first pass
360 found no fonts and skipped some scalable fonts. */
361 bool skipped_some_scalable_fonts
= false;
364 || (i_pass
== 1 && NILP (list
) && skipped_some_scalable_fonts
));
366 for (i
= 0; i
< num_fonts
; i
++)
370 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
373 entity
= font_make_entity ();
374 len
= xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
375 if (font_parse_xlfd (buf
, len
, entity
) < 0)
377 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
378 /* Avoid auto-scaled fonts. */
379 if (INTEGERP (AREF (entity
, FONT_DPI_INDEX
))
380 && INTEGERP (AREF (entity
, FONT_AVGWIDTH_INDEX
))
381 && XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
382 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
384 /* Avoid not-allowed scalable fonts. */
385 if (NILP (Vscalable_fonts_allowed
))
389 if (INTEGERP (AREF (entity
, FONT_SIZE_INDEX
)))
390 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
391 else if (FLOATP (AREF (entity
, FONT_SIZE_INDEX
)))
392 size
= XFLOAT_DATA (AREF (entity
, FONT_SIZE_INDEX
));
393 if (size
== 0 && i_pass
== 0)
395 skipped_some_scalable_fonts
= true;
399 else if (CONSP (Vscalable_fonts_allowed
))
403 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
406 Lisp_Object elt
= XCAR (tail
);
408 && (fast_c_string_match_ignore_case (elt
, indices
[i
],
417 /* Avoid fonts of invalid registry. */
418 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
421 /* Update encoding and repertory if necessary. */
422 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
424 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
425 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
429 /* Unknown REGISTRY, not supported. */
434 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
435 list
= Fcons (entity
, list
), entity
= Qnil
;
438 if (memcmp (props
, aref_addr (entity
, FONT_FOUNDRY_INDEX
),
440 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
442 vcopy (xfont_scratch_props
, 0,
443 aref_addr (entity
, FONT_FOUNDRY_INDEX
), 7);
444 ASET (xfont_scratch_props
, 7, AREF (entity
, FONT_SPACING_INDEX
));
445 scripts
= xfont_supported_scripts (display
, indices
[i
],
450 || ! NILP (Fmemq (script
, scripts
)))
451 list
= Fcons (entity
, list
), entity
= Qnil
;
453 XFreeFontNames (names
);
459 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
464 xfont_list (struct frame
*f
, Lisp_Object spec
)
466 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
467 Lisp_Object registry
, list
, val
, extra
, script
;
469 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
472 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
475 val
= assq_no_quit (QCotf
, extra
);
478 val
= assq_no_quit (QClang
, extra
);
483 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
484 len
= font_unparse_xlfd (spec
, 0, name
, 512);
485 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
488 val
= assq_no_quit (QCscript
, extra
);
490 list
= xfont_list_pattern (display
, name
, registry
, script
);
491 if (NILP (list
) && NILP (registry
))
494 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
496 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
498 strcpy (r
, "iso10646-1");
499 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
502 if (NILP (list
) && ! NILP (registry
))
504 /* Try alternate registries. */
507 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
508 Vface_alternative_font_registry_alist
,
512 /* Pointer to REGISTRY-ENCODING field. */
513 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
515 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
516 if (STRINGP (XCAR (alter
))
517 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
519 lispstpcpy (r
, XCAR (alter
));
520 list
= xfont_list_pattern (display
, name
, registry
, script
);
529 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
530 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
532 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
533 if (xfont_encode_coding_xlfd (name
) < 0)
535 list
= xfont_list_pattern (display
, name
, registry
, script
);
543 xfont_match (struct frame
*f
, Lisp_Object spec
)
545 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
546 Lisp_Object extra
, val
, entity
;
551 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
552 val
= assq_no_quit (QCname
, extra
);
553 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
555 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
558 else if (SBYTES (XCDR (val
)) < 512)
559 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
562 if (xfont_encode_coding_xlfd (name
) < 0)
567 xfont
= XLoadQueryFont (display
, name
);
570 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
572 char *s
= XGetAtomName (display
, (Atom
) value
);
574 /* If DXPC (a Differential X Protocol Compressor)
575 Ver.3.7 is running, XGetAtomName will return null
576 string. We must avoid such a name. */
580 entity
= font_make_entity ();
581 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
582 len
= xfont_decode_coding_xlfd (s
, -1, name
);
583 if (font_parse_xlfd (name
, len
, entity
) < 0)
588 XFreeFont (display
, xfont
);
592 FONT_ADD_LOG ("xfont-match", spec
, entity
);
597 xfont_list_family (struct frame
*f
)
599 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
603 char *last_family UNINIT
;
607 x_catch_errors (dpyinfo
->display
);
608 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
610 if (x_had_errors_p (dpyinfo
->display
))
612 /* This error is perhaps due to insufficient memory on X server.
613 Let's just ignore it. */
614 x_clear_errors (dpyinfo
->display
);
619 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
621 char *p0
= names
[i
], *p1
, buf
[512];
625 p0
++; /* skip the leading '-' */
626 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
630 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
631 if (! *p1
|| p1
== p0
)
633 if (last_len
== p1
- p0
634 && memcmp (last_family
, p0
, last_len
) == 0)
639 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
640 family
= font_intern_prop (p0
, decoded_len
, 1);
641 if (NILP (assq_no_quit (family
, list
)))
642 list
= Fcons (family
, list
);
645 XFreeFontNames (names
);
653 xfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
655 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
656 Display
*display
= dpyinfo
->display
;
660 Lisp_Object registry
;
661 struct charset
*encoding
, *repertory
;
662 Lisp_Object font_object
, fullname
;
666 /* At first, check if we know how to encode characters for this
668 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
669 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
671 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
675 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
676 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
677 else if (pixel_size
== 0)
680 pixel_size
= FRAME_FONT (f
)->pixel_size
;
684 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
685 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
687 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
692 x_catch_errors (display
);
693 xfont
= XLoadQueryFont (display
, name
);
694 if (x_had_errors_p (display
))
696 /* This error is perhaps due to insufficient memory on X server.
697 Let's just ignore it. */
698 x_clear_errors (display
);
703 /* Some version of X lists:
704 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
705 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
707 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
709 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
710 So, we try again with wildcards in RESX and RESY. */
713 temp
= copy_font_spec (entity
);
714 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
715 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
716 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
718 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
721 xfont
= XLoadQueryFont (display
, name
);
722 if (x_had_errors_p (display
))
724 /* This error is perhaps due to insufficient memory on X server.
725 Let's just ignore it. */
726 x_clear_errors (display
);
731 /* Try to get the full name of FONT. */
732 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
737 p0
= p
= XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
738 /* Count the number of dashes in the "full name".
739 If it is too few, this isn't really the font's full name,
741 In X11R4, the fonts did not come with their canonical names
752 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
753 fullname
= Fdowncase (make_string (name
, len
));
762 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
766 font_object
= font_make_object (VECSIZE (struct xfont_info
),
768 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
769 if (STRINGP (fullname
))
771 font_parse_xlfd (SSDATA (fullname
), SBYTES (fullname
), font_object
);
772 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
778 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
779 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
781 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
782 font
= XFONT_OBJECT (font_object
);
783 ((struct xfont_info
*) font
)->xfont
= xfont
;
784 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
785 ((struct xfont_info
*) font
)->x_display_id
= FRAME_DISPLAY_INFO (f
)->x_id
;
786 font
->pixel_size
= pixel_size
;
787 font
->driver
= &xfont_driver
;
788 font
->encoding_charset
= encoding
->id
;
789 font
->repertory_charset
= repertory
? repertory
->id
: -1;
790 font
->ascent
= xfont
->ascent
;
791 font
->descent
= xfont
->descent
;
792 font
->height
= font
->ascent
+ font
->descent
;
793 font
->min_width
= xfont
->min_bounds
.width
;
794 font
->max_width
= xfont
->max_bounds
.width
;
795 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
797 /* Fixed width font. */
798 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
806 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
807 pcm
= xfont_get_pcm (xfont
, &char2b
);
809 font
->space_width
= pcm
->width
;
811 font
->space_width
= 0;
813 val
= Ffont_get (font_object
, QCavgwidth
);
815 font
->average_width
= XINT (val
) / 10;
816 if (font
->average_width
< 0)
817 font
->average_width
= - font
->average_width
;
820 if (font
->average_width
== 0
821 && encoding
->ascii_compatible_p
)
823 int width
= font
->space_width
, n
= pcm
!= NULL
;
825 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
826 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
827 width
+= pcm
->width
, n
++;
829 font
->average_width
= width
/ n
;
831 if (font
->average_width
== 0)
832 /* No easy way other than this to get a reasonable
835 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
840 font
->underline_thickness
841 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
843 font
->underline_position
844 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
845 ? (long) value
: -1);
846 font
->baseline_offset
847 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
849 font
->relative_compose
850 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
853 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
858 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
859 font
->vertical_centering
860 = (STRINGP (Vvertical_centering_font_regexp
)
861 && (fast_string_match_ignore_case
862 (Vvertical_centering_font_regexp
, fullname
) >= 0));
868 xfont_close (struct font
*font
)
870 struct x_display_info
*xdi
;
871 struct xfont_info
*xfi
= (struct xfont_info
*) font
;
873 /* This function may be called from GC when X connection is gone
874 (Bug#16093), and an attempt to free font resources on invalid
875 display may lead to X protocol errors or segfaults. Moreover,
876 the memory referenced by 'Display *' pointer may be reused for
877 the logically different X connection after the previous display
878 connection was closed. That's why we also check whether font's
879 ID matches the one recorded in x_display_info for this display.
880 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
882 && ((xdi
= x_display_info_for_display (xfi
->display
))
883 && xfi
->x_display_id
== xdi
->x_id
))
886 XFreeFont (xfi
->display
, xfi
->xfont
);
893 xfont_prepare_face (struct frame
*f
, struct face
*face
)
896 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
897 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
902 xfont_has_char (Lisp_Object font
, int c
)
904 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
905 struct charset
*encoding
;
906 struct charset
*repertory
= NULL
;
908 if (EQ (registry
, Qiso10646_1
))
910 encoding
= CHARSET_FROM_ID (charset_unicode
);
911 /* We use a font of `ja' and `ko' adstyle only for a character
912 in JISX0208 and KSC5601 charsets respectively. */
913 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
914 && charset_jisx0208
>= 0)
915 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
916 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
917 && charset_ksc5601
>= 0)
918 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
920 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
921 /* Unknown REGISTRY, not usable. */
923 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
927 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
931 xfont_encode_char (struct font
*font
, int c
)
933 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
934 struct charset
*charset
;
938 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
939 code
= ENCODE_CHAR (charset
, c
);
940 if (code
== CHARSET_INVALID_CODE (charset
))
941 return FONT_INVALID_CODE
;
942 if (font
->repertory_charset
>= 0)
944 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
945 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
946 ? code
: FONT_INVALID_CODE
);
948 char2b
.byte1
= code
>> 8;
949 char2b
.byte2
= code
& 0xFF;
950 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
954 xfont_text_extents (struct font
*font
, unsigned int *code
,
955 int nglyphs
, struct font_metrics
*metrics
)
957 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
961 for (i
= 0, first
= true; i
< nglyphs
; i
++)
964 static XCharStruct
*pcm
;
966 if (code
[i
] >= 0x10000)
968 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
969 pcm
= xfont_get_pcm (xfont
, &char2b
);
974 metrics
->lbearing
= pcm
->lbearing
;
975 metrics
->rbearing
= pcm
->rbearing
;
976 metrics
->ascent
= pcm
->ascent
;
977 metrics
->descent
= pcm
->descent
;
982 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
983 metrics
->lbearing
= width
+ pcm
->lbearing
;
984 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
985 metrics
->rbearing
= width
+ pcm
->rbearing
;
986 if (metrics
->ascent
< pcm
->ascent
)
987 metrics
->ascent
= pcm
->ascent
;
988 if (metrics
->descent
< pcm
->descent
)
989 metrics
->descent
= pcm
->descent
;
994 metrics
->width
= width
;
998 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
999 bool with_background
)
1001 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1002 int len
= to
- from
;
1006 if (s
->gc
!= s
->face
->gc
)
1009 XSetFont (s
->display
, gc
, xfont
->fid
);
1013 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1016 char *str
= SAFE_ALLOCA (len
);
1017 for (i
= 0; i
< len
; i
++)
1018 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1020 if (with_background
)
1023 for (i
= 0; i
< len
; i
++)
1024 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1025 gc
, x
+ i
, y
, str
+ i
, 1);
1027 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1028 gc
, x
, y
, str
, len
);
1033 for (i
= 0; i
< len
; i
++)
1034 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1035 gc
, x
+ i
, y
, str
+ i
, 1);
1037 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1038 gc
, x
, y
, str
, len
);
1046 if (with_background
)
1049 for (i
= 0; i
< len
; i
++)
1050 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1051 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1053 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1054 gc
, x
, y
, s
->char2b
+ from
, len
);
1059 for (i
= 0; i
< len
; i
++)
1060 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1061 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1063 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1064 gc
, x
, y
, s
->char2b
+ from
, len
);
1072 xfont_check (struct frame
*f
, struct font
*font
)
1074 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1076 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1081 struct font_driver
const xfont_driver
=
1083 .type
= LISPSYM_INITIALLY (Qx
),
1084 .get_cache
= xfont_get_cache
,
1086 .match
= xfont_match
,
1087 .list_family
= xfont_list_family
,
1089 .close
= xfont_close
,
1090 .prepare_face
= xfont_prepare_face
,
1091 .has_char
= xfont_has_char
,
1092 .encode_char
= xfont_encode_char
,
1093 .text_extents
= xfont_text_extents
,
1095 .check
= xfont_check
,
1099 syms_of_xfont (void)
1101 staticpro (&xfont_scripts_cache
);
1102 xfont_scripts_cache
= CALLN (Fmake_hash_table
, QCtest
, Qequal
);
1103 staticpro (&xfont_scratch_props
);
1104 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1105 register_font_driver (&xfont_driver
, NULL
);