1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2017 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 <http://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
),
511 /* Pointer to REGISTRY-ENCODING field. */
512 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
514 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
515 if (STRINGP (XCAR (alter
))
516 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
518 lispstpcpy (r
, XCAR (alter
));
519 list
= xfont_list_pattern (display
, name
, registry
, script
);
528 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
529 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
531 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
532 if (xfont_encode_coding_xlfd (name
) < 0)
534 list
= xfont_list_pattern (display
, name
, registry
, script
);
542 xfont_match (struct frame
*f
, Lisp_Object spec
)
544 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
545 Lisp_Object extra
, val
, entity
;
550 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
551 val
= assq_no_quit (QCname
, extra
);
552 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
554 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
557 else if (SBYTES (XCDR (val
)) < 512)
558 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
561 if (xfont_encode_coding_xlfd (name
) < 0)
566 xfont
= XLoadQueryFont (display
, name
);
569 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
571 char *s
= XGetAtomName (display
, (Atom
) value
);
573 /* If DXPC (a Differential X Protocol Compressor)
574 Ver.3.7 is running, XGetAtomName will return null
575 string. We must avoid such a name. */
579 entity
= font_make_entity ();
580 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
581 len
= xfont_decode_coding_xlfd (s
, -1, name
);
582 if (font_parse_xlfd (name
, len
, entity
) < 0)
587 XFreeFont (display
, xfont
);
591 FONT_ADD_LOG ("xfont-match", spec
, entity
);
596 xfont_list_family (struct frame
*f
)
598 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
602 char *last_family UNINIT
;
606 x_catch_errors (dpyinfo
->display
);
607 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
609 if (x_had_errors_p (dpyinfo
->display
))
611 /* This error is perhaps due to insufficient memory on X server.
612 Let's just ignore it. */
613 x_clear_errors (dpyinfo
->display
);
618 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
620 char *p0
= names
[i
], *p1
, buf
[512];
624 p0
++; /* skip the leading '-' */
625 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
629 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
630 if (! *p1
|| p1
== p0
)
632 if (last_len
== p1
- p0
633 && memcmp (last_family
, p0
, last_len
) == 0)
638 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
639 family
= font_intern_prop (p0
, decoded_len
, 1);
640 if (NILP (assq_no_quit (family
, list
)))
641 list
= Fcons (family
, list
);
644 XFreeFontNames (names
);
652 xfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
654 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
655 Display
*display
= dpyinfo
->display
;
659 Lisp_Object registry
;
660 struct charset
*encoding
, *repertory
;
661 Lisp_Object font_object
, fullname
;
665 /* At first, check if we know how to encode characters for this
667 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
668 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
670 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
674 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
675 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
676 else if (pixel_size
== 0)
679 pixel_size
= FRAME_FONT (f
)->pixel_size
;
683 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
684 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
686 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
691 x_catch_errors (display
);
692 xfont
= XLoadQueryFont (display
, name
);
693 if (x_had_errors_p (display
))
695 /* This error is perhaps due to insufficient memory on X server.
696 Let's just ignore it. */
697 x_clear_errors (display
);
702 /* Some version of X lists:
703 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
704 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
706 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
708 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
709 So, we try again with wildcards in RESX and RESY. */
712 temp
= copy_font_spec (entity
);
713 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
714 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
715 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
717 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
720 xfont
= XLoadQueryFont (display
, name
);
721 if (x_had_errors_p (display
))
723 /* This error is perhaps due to insufficient memory on X server.
724 Let's just ignore it. */
725 x_clear_errors (display
);
730 /* Try to get the full name of FONT. */
731 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
736 p0
= p
= XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
737 /* Count the number of dashes in the "full name".
738 If it is too few, this isn't really the font's full name,
740 In X11R4, the fonts did not come with their canonical names
751 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
752 fullname
= Fdowncase (make_string (name
, len
));
761 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
765 font_object
= font_make_object (VECSIZE (struct xfont_info
),
767 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
768 if (STRINGP (fullname
))
770 font_parse_xlfd (SSDATA (fullname
), SBYTES (fullname
), font_object
);
771 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
777 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
778 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
780 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
781 font
= XFONT_OBJECT (font_object
);
782 ((struct xfont_info
*) font
)->xfont
= xfont
;
783 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
784 ((struct xfont_info
*) font
)->x_display_id
= FRAME_DISPLAY_INFO (f
)->x_id
;
785 font
->pixel_size
= pixel_size
;
786 font
->driver
= &xfont_driver
;
787 font
->encoding_charset
= encoding
->id
;
788 font
->repertory_charset
= repertory
? repertory
->id
: -1;
789 font
->ascent
= xfont
->ascent
;
790 font
->descent
= xfont
->descent
;
791 font
->height
= font
->ascent
+ font
->descent
;
792 font
->min_width
= xfont
->min_bounds
.width
;
793 font
->max_width
= xfont
->max_bounds
.width
;
794 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
796 /* Fixed width font. */
797 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
805 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
806 pcm
= xfont_get_pcm (xfont
, &char2b
);
808 font
->space_width
= pcm
->width
;
810 font
->space_width
= 0;
812 val
= Ffont_get (font_object
, QCavgwidth
);
814 font
->average_width
= XINT (val
) / 10;
815 if (font
->average_width
< 0)
816 font
->average_width
= - font
->average_width
;
819 if (font
->average_width
== 0
820 && encoding
->ascii_compatible_p
)
822 int width
= font
->space_width
, n
= pcm
!= NULL
;
824 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
825 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
826 width
+= pcm
->width
, n
++;
828 font
->average_width
= width
/ n
;
830 if (font
->average_width
== 0)
831 /* No easy way other than this to get a reasonable
834 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
839 font
->underline_thickness
840 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
842 font
->underline_position
843 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
844 ? (long) value
: -1);
845 font
->baseline_offset
846 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
848 font
->relative_compose
849 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
852 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
857 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
858 font
->vertical_centering
859 = (STRINGP (Vvertical_centering_font_regexp
)
860 && (fast_string_match_ignore_case
861 (Vvertical_centering_font_regexp
, fullname
) >= 0));
867 xfont_close (struct font
*font
)
869 struct x_display_info
*xdi
;
870 struct xfont_info
*xfi
= (struct xfont_info
*) font
;
872 /* This function may be called from GC when X connection is gone
873 (Bug#16093), and an attempt to free font resources on invalid
874 display may lead to X protocol errors or segfaults. Moreover,
875 the memory referenced by 'Display *' pointer may be reused for
876 the logically different X connection after the previous display
877 connection was closed. That's why we also check whether font's
878 ID matches the one recorded in x_display_info for this display.
879 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
881 && ((xdi
= x_display_info_for_display (xfi
->display
))
882 && xfi
->x_display_id
== xdi
->x_id
))
885 XFreeFont (xfi
->display
, xfi
->xfont
);
892 xfont_prepare_face (struct frame
*f
, struct face
*face
)
895 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
896 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
901 xfont_has_char (Lisp_Object font
, int c
)
903 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
904 struct charset
*encoding
;
905 struct charset
*repertory
= NULL
;
907 if (EQ (registry
, Qiso10646_1
))
909 encoding
= CHARSET_FROM_ID (charset_unicode
);
910 /* We use a font of `ja' and `ko' adstyle only for a character
911 in JISX0208 and KSC5601 charsets respectively. */
912 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
913 && charset_jisx0208
>= 0)
914 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
915 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
916 && charset_ksc5601
>= 0)
917 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
919 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
920 /* Unknown REGISTRY, not usable. */
922 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
926 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
930 xfont_encode_char (struct font
*font
, int c
)
932 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
933 struct charset
*charset
;
937 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
938 code
= ENCODE_CHAR (charset
, c
);
939 if (code
== CHARSET_INVALID_CODE (charset
))
940 return FONT_INVALID_CODE
;
941 if (font
->repertory_charset
>= 0)
943 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
944 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
945 ? code
: FONT_INVALID_CODE
);
947 char2b
.byte1
= code
>> 8;
948 char2b
.byte2
= code
& 0xFF;
949 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
953 xfont_text_extents (struct font
*font
, unsigned int *code
,
954 int nglyphs
, struct font_metrics
*metrics
)
956 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
960 for (i
= 0, first
= true; i
< nglyphs
; i
++)
963 static XCharStruct
*pcm
;
965 if (code
[i
] >= 0x10000)
967 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
968 pcm
= xfont_get_pcm (xfont
, &char2b
);
973 metrics
->lbearing
= pcm
->lbearing
;
974 metrics
->rbearing
= pcm
->rbearing
;
975 metrics
->ascent
= pcm
->ascent
;
976 metrics
->descent
= pcm
->descent
;
981 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
982 metrics
->lbearing
= width
+ pcm
->lbearing
;
983 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
984 metrics
->rbearing
= width
+ pcm
->rbearing
;
985 if (metrics
->ascent
< pcm
->ascent
)
986 metrics
->ascent
= pcm
->ascent
;
987 if (metrics
->descent
< pcm
->descent
)
988 metrics
->descent
= pcm
->descent
;
993 metrics
->width
= width
;
997 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
998 bool with_background
)
1000 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1001 int len
= to
- from
;
1005 if (s
->gc
!= s
->face
->gc
)
1008 XSetFont (s
->display
, gc
, xfont
->fid
);
1012 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1015 char *str
= SAFE_ALLOCA (len
);
1016 for (i
= 0; i
< len
; i
++)
1017 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1019 if (with_background
)
1022 for (i
= 0; i
< len
; i
++)
1023 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1024 gc
, x
+ i
, y
, str
+ i
, 1);
1026 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1027 gc
, x
, y
, str
, len
);
1032 for (i
= 0; i
< len
; i
++)
1033 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1034 gc
, x
+ i
, y
, str
+ i
, 1);
1036 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1037 gc
, x
, y
, str
, len
);
1045 if (with_background
)
1048 for (i
= 0; i
< len
; i
++)
1049 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1050 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1052 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1053 gc
, x
, y
, s
->char2b
+ from
, len
);
1058 for (i
= 0; i
< len
; i
++)
1059 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1060 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1062 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_DRAWABLE (s
->f
),
1063 gc
, x
, y
, s
->char2b
+ from
, len
);
1071 xfont_check (struct frame
*f
, struct font
*font
)
1073 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1075 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1080 struct font_driver
const xfont_driver
=
1082 .type
= LISPSYM_INITIALLY (Qx
),
1083 .get_cache
= xfont_get_cache
,
1085 .match
= xfont_match
,
1086 .list_family
= xfont_list_family
,
1088 .close
= xfont_close
,
1089 .prepare_face
= xfont_prepare_face
,
1090 .has_char
= xfont_has_char
,
1091 .encode_char
= xfont_encode_char
,
1092 .text_extents
= xfont_text_extents
,
1094 .check
= xfont_check
,
1098 syms_of_xfont (void)
1100 staticpro (&xfont_scripts_cache
);
1101 xfont_scripts_cache
= CALLN (Fmake_hash_table
, QCtest
, Qequal
);
1102 staticpro (&xfont_scratch_props
);
1103 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1104 register_font_driver (&xfont_driver
, NULL
);