1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2016 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))
116 static Lisp_Object
xfont_get_cache (struct frame
*);
117 static Lisp_Object
xfont_list (struct frame
*, Lisp_Object
);
118 static Lisp_Object
xfont_match (struct frame
*, Lisp_Object
);
119 static Lisp_Object
xfont_list_family (struct frame
*);
120 static Lisp_Object
xfont_open (struct frame
*, Lisp_Object
, int);
121 static void xfont_close (struct font
*);
122 static void xfont_prepare_face (struct frame
*, struct face
*);
123 static int xfont_has_char (Lisp_Object
, int);
124 static unsigned xfont_encode_char (struct font
*, int);
125 static void xfont_text_extents (struct font
*, unsigned *, int,
126 struct font_metrics
*);
127 static int xfont_draw (struct glyph_string
*, int, int, int, int, bool);
128 static int xfont_check (struct frame
*, struct font
*);
130 struct font_driver xfont_driver
=
132 LISP_INITIALLY_ZERO
, /* Qx */
133 false, /* case insensitive */
147 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
149 NULL
, /* get_variation_glyphs */
150 NULL
, /* filter_properties */
154 xfont_get_cache (struct frame
*f
)
156 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
158 return (dpyinfo
->name_list_element
);
162 compare_font_names (const void *name1
, const void *name2
)
164 char *const *n1
= name1
;
165 char *const *n2
= name2
;
166 return xstrcasecmp (*n1
, *n2
);
169 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
170 of the decoding result. LEN is the byte length of XLFD, or -1 if
171 XLFD is NULL terminated. The caller must assure that OUTPUT is at
172 least twice (plus 1) as large as XLFD. */
175 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
177 char *p0
= xlfd
, *p1
= output
;
182 c
= *(unsigned char *) p0
++;
183 p1
+= CHAR_STRING (c
, (unsigned char *) p1
);
188 return (p1
- output
);
191 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
192 resulting byte length. If XLFD contains unencodable character,
196 xfont_encode_coding_xlfd (char *xlfd
)
198 const unsigned char *p0
= (unsigned char *) xlfd
;
199 unsigned char *p1
= (unsigned char *) xlfd
;
204 int c
= STRING_CHAR_ADVANCE (p0
);
215 /* Check if CHARS (cons or vector) is supported by XFONT whose
216 encoding charset is ENCODING (XFONT is NULL) or by a font whose
217 registry corresponds to ENCODING and REPERTORY.
218 Return true if supported. */
221 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
222 struct charset
*encoding
, struct charset
*repertory
)
224 struct charset
*charset
= repertory
? repertory
: encoding
;
228 for (; CONSP (chars
); chars
= XCDR (chars
))
230 int c
= XINT (XCAR (chars
));
231 unsigned code
= ENCODE_CHAR (charset
, c
);
234 if (code
== CHARSET_INVALID_CODE (charset
))
240 char2b
.byte1
= code
>> 8;
241 char2b
.byte2
= code
& 0xFF;
242 if (! xfont_get_pcm (xfont
, &char2b
))
245 return (NILP (chars
));
247 else if (VECTORP (chars
))
251 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
253 int c
= XINT (AREF (chars
, i
));
254 unsigned code
= ENCODE_CHAR (charset
, c
);
257 if (code
== CHARSET_INVALID_CODE (charset
))
263 char2b
.byte1
= code
>> 8;
264 char2b
.byte2
= code
& 0xFF;
265 if (xfont_get_pcm (xfont
, &char2b
))
273 /* A hash table recoding which font supports which scripts. Each key
274 is a vector of characteristic font properties FOUNDRY to WIDTH and
275 ADDSTYLE, and each value is a list of script symbols.
277 We assume that fonts that have the same value in the above
278 properties supports the same set of characters on all displays. */
280 static Lisp_Object xfont_scripts_cache
;
282 /* Re-usable vector to store characteristic font properties. */
283 static Lisp_Object xfont_scratch_props
;
285 /* Return a list of scripts supported by the font of FONTNAME whose
286 characteristic properties are in PROPS and whose encoding charset
287 is ENCODING. A caller must call BLOCK_INPUT in advance. */
290 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
291 struct charset
*encoding
)
295 /* Two special cases to avoid opening rather big fonts. */
296 if (EQ (AREF (props
, 2), Qja
))
297 return list2 (intern ("kana"), intern ("han"));
298 if (EQ (AREF (props
, 2), Qko
))
299 return list1 (intern ("hangul"));
300 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
301 if (EQ (scripts
, Qt
))
307 xfont
= XLoadQueryFont (display
, fontname
);
312 for (val
= Vscript_representative_chars
; CONSP (val
);
314 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
316 Lisp_Object script
= XCAR (XCAR (val
));
317 Lisp_Object chars
= XCDR (XCAR (val
));
319 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
320 scripts
= Fcons (script
, scripts
);
323 XFreeFont (display
, xfont
);
325 if (EQ (AREF (props
, 3), Qiso10646_1
)
326 && NILP (Fmemq (Qlatin
, scripts
)))
327 scripts
= Fcons (Qlatin
, scripts
);
328 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
334 xfont_list_pattern (Display
*display
, const char *pattern
,
335 Lisp_Object registry
, Lisp_Object script
)
337 Lisp_Object list
= Qnil
;
338 Lisp_Object chars
= Qnil
;
339 struct charset
*encoding
, *repertory
= NULL
;
340 int i
, limit
, num_fonts
;
342 /* Large enough to decode the longest XLFD (255 bytes). */
345 if (! NILP (registry
)
346 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
347 /* Unknown REGISTRY, not supported. */
351 chars
= assq_no_quit (script
, Vscript_representative_chars
);
353 /* We can't tell whether or not a font supports SCRIPT. */
355 chars
= XCDR (chars
);
358 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
365 x_catch_errors (display
);
367 for (limit
= 512; ; limit
*= 2)
369 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
370 if (x_had_errors_p (display
))
372 /* This error is perhaps due to insufficient memory on X
373 server. Let's just ignore it. */
374 x_clear_errors (display
);
378 if (num_fonts
< limit
)
380 XFreeFontNames (names
);
385 char **indices
= alloca (sizeof (char *) * num_fonts
);
386 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
387 Lisp_Object scripts
= Qnil
, entity
= Qnil
;
389 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
390 ASET (xfont_scratch_props
, i
, Qnil
);
391 for (i
= 0; i
< num_fonts
; i
++)
392 indices
[i
] = names
[i
];
393 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
395 /* Take one or two passes over the font list. Do the second
396 pass only if we really need it, i.e., only if the first pass
397 found no fonts and skipped some scalable fonts. */
398 bool skipped_some_scalable_fonts
= false;
401 || (i_pass
== 1 && NILP (list
) && skipped_some_scalable_fonts
));
403 for (i
= 0; i
< num_fonts
; i
++)
407 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
410 entity
= font_make_entity ();
411 len
= xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
412 if (font_parse_xlfd (buf
, len
, entity
) < 0)
414 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
415 /* Avoid auto-scaled fonts. */
416 if (INTEGERP (AREF (entity
, FONT_DPI_INDEX
))
417 && INTEGERP (AREF (entity
, FONT_AVGWIDTH_INDEX
))
418 && XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
419 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
421 /* Avoid not-allowed scalable fonts. */
422 if (NILP (Vscalable_fonts_allowed
))
426 if (INTEGERP (AREF (entity
, FONT_SIZE_INDEX
)))
427 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
428 else if (FLOATP (AREF (entity
, FONT_SIZE_INDEX
)))
429 size
= XFLOAT_DATA (AREF (entity
, FONT_SIZE_INDEX
));
430 if (size
== 0 && i_pass
== 0)
432 skipped_some_scalable_fonts
= true;
436 else if (CONSP (Vscalable_fonts_allowed
))
440 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
443 Lisp_Object elt
= XCAR (tail
);
445 && (fast_c_string_match_ignore_case (elt
, indices
[i
],
454 /* Avoid fonts of invalid registry. */
455 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
458 /* Update encoding and repertory if necessary. */
459 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
461 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
462 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
466 /* Unknown REGISTRY, not supported. */
471 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
472 list
= Fcons (entity
, list
), entity
= Qnil
;
475 if (memcmp (props
, aref_addr (entity
, FONT_FOUNDRY_INDEX
),
477 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
479 vcopy (xfont_scratch_props
, 0,
480 aref_addr (entity
, FONT_FOUNDRY_INDEX
), 7);
481 ASET (xfont_scratch_props
, 7, AREF (entity
, FONT_SPACING_INDEX
));
482 scripts
= xfont_supported_scripts (display
, indices
[i
],
487 || ! NILP (Fmemq (script
, scripts
)))
488 list
= Fcons (entity
, list
), entity
= Qnil
;
490 XFreeFontNames (names
);
496 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
501 xfont_list (struct frame
*f
, Lisp_Object spec
)
503 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
504 Lisp_Object registry
, list
, val
, extra
, script
;
506 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
509 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
512 val
= assq_no_quit (QCotf
, extra
);
515 val
= assq_no_quit (QClang
, extra
);
520 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
521 len
= font_unparse_xlfd (spec
, 0, name
, 512);
522 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
525 val
= assq_no_quit (QCscript
, extra
);
527 list
= xfont_list_pattern (display
, name
, registry
, script
);
528 if (NILP (list
) && NILP (registry
))
531 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
533 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
535 strcpy (r
, "iso10646-1");
536 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
539 if (NILP (list
) && ! NILP (registry
))
541 /* Try alternate registries. */
544 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
545 Vface_alternative_font_registry_alist
),
548 /* Pointer to REGISTRY-ENCODING field. */
549 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
551 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
552 if (STRINGP (XCAR (alter
))
553 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
555 lispstpcpy (r
, XCAR (alter
));
556 list
= xfont_list_pattern (display
, name
, registry
, script
);
565 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
566 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
568 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
569 if (xfont_encode_coding_xlfd (name
) < 0)
571 list
= xfont_list_pattern (display
, name
, registry
, script
);
579 xfont_match (struct frame
*f
, Lisp_Object spec
)
581 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
582 Lisp_Object extra
, val
, entity
;
587 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
588 val
= assq_no_quit (QCname
, extra
);
589 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
591 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
594 else if (SBYTES (XCDR (val
)) < 512)
595 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
598 if (xfont_encode_coding_xlfd (name
) < 0)
603 xfont
= XLoadQueryFont (display
, name
);
606 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
608 char *s
= XGetAtomName (display
, (Atom
) value
);
610 /* If DXPC (a Differential X Protocol Compressor)
611 Ver.3.7 is running, XGetAtomName will return null
612 string. We must avoid such a name. */
616 entity
= font_make_entity ();
617 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
618 len
= xfont_decode_coding_xlfd (s
, -1, name
);
619 if (font_parse_xlfd (name
, len
, entity
) < 0)
624 XFreeFont (display
, xfont
);
628 FONT_ADD_LOG ("xfont-match", spec
, entity
);
633 xfont_list_family (struct frame
*f
)
635 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
639 char *last_family UNINIT
;
643 x_catch_errors (dpyinfo
->display
);
644 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
646 if (x_had_errors_p (dpyinfo
->display
))
648 /* This error is perhaps due to insufficient memory on X server.
649 Let's just ignore it. */
650 x_clear_errors (dpyinfo
->display
);
655 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
657 char *p0
= names
[i
], *p1
, buf
[512];
661 p0
++; /* skip the leading '-' */
662 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
666 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
667 if (! *p1
|| p1
== p0
)
669 if (last_len
== p1
- p0
670 && memcmp (last_family
, p0
, last_len
) == 0)
675 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
676 family
= font_intern_prop (p0
, decoded_len
, 1);
677 if (NILP (assq_no_quit (family
, list
)))
678 list
= Fcons (family
, list
);
681 XFreeFontNames (names
);
689 xfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
691 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
692 Display
*display
= dpyinfo
->display
;
696 Lisp_Object registry
;
697 struct charset
*encoding
, *repertory
;
698 Lisp_Object font_object
, fullname
;
702 /* At first, check if we know how to encode characters for this
704 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
705 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
707 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
711 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
712 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
713 else if (pixel_size
== 0)
716 pixel_size
= FRAME_FONT (f
)->pixel_size
;
720 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
721 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
723 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
728 x_catch_errors (display
);
729 xfont
= XLoadQueryFont (display
, name
);
730 if (x_had_errors_p (display
))
732 /* This error is perhaps due to insufficient memory on X server.
733 Let's just ignore it. */
734 x_clear_errors (display
);
739 /* Some version of X lists:
740 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
741 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
743 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
745 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
746 So, we try again with wildcards in RESX and RESY. */
749 temp
= copy_font_spec (entity
);
750 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
751 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
752 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
754 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
757 xfont
= XLoadQueryFont (display
, name
);
758 if (x_had_errors_p (display
))
760 /* This error is perhaps due to insufficient memory on X server.
761 Let's just ignore it. */
762 x_clear_errors (display
);
767 /* Try to get the full name of FONT. */
768 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
773 p0
= p
= XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
774 /* Count the number of dashes in the "full name".
775 If it is too few, this isn't really the font's full name,
777 In X11R4, the fonts did not come with their canonical names
788 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
789 fullname
= Fdowncase (make_string (name
, len
));
798 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
802 font_object
= font_make_object (VECSIZE (struct xfont_info
),
804 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
805 if (STRINGP (fullname
))
807 font_parse_xlfd (SSDATA (fullname
), SBYTES (fullname
), font_object
);
808 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
814 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
815 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
817 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
818 font
= XFONT_OBJECT (font_object
);
819 ((struct xfont_info
*) font
)->xfont
= xfont
;
820 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
821 ((struct xfont_info
*) font
)->x_display_id
= FRAME_DISPLAY_INFO (f
)->x_id
;
822 font
->pixel_size
= pixel_size
;
823 font
->driver
= &xfont_driver
;
824 font
->encoding_charset
= encoding
->id
;
825 font
->repertory_charset
= repertory
? repertory
->id
: -1;
826 font
->ascent
= xfont
->ascent
;
827 font
->descent
= xfont
->descent
;
828 font
->height
= font
->ascent
+ font
->descent
;
829 font
->min_width
= xfont
->min_bounds
.width
;
830 font
->max_width
= xfont
->max_bounds
.width
;
831 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
833 /* Fixed width font. */
834 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
842 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
843 pcm
= xfont_get_pcm (xfont
, &char2b
);
845 font
->space_width
= pcm
->width
;
847 font
->space_width
= 0;
849 val
= Ffont_get (font_object
, QCavgwidth
);
851 font
->average_width
= XINT (val
) / 10;
852 if (font
->average_width
< 0)
853 font
->average_width
= - font
->average_width
;
856 if (font
->average_width
== 0
857 && encoding
->ascii_compatible_p
)
859 int width
= font
->space_width
, n
= pcm
!= NULL
;
861 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
862 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
863 width
+= pcm
->width
, n
++;
865 font
->average_width
= width
/ n
;
867 if (font
->average_width
== 0)
868 /* No easy way other than this to get a reasonable
871 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
876 font
->underline_thickness
877 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
879 font
->underline_position
880 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
881 ? (long) value
: -1);
882 font
->baseline_offset
883 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
885 font
->relative_compose
886 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
889 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
894 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
895 font
->vertical_centering
896 = (STRINGP (Vvertical_centering_font_regexp
)
897 && (fast_string_match_ignore_case
898 (Vvertical_centering_font_regexp
, fullname
) >= 0));
904 xfont_close (struct font
*font
)
906 struct x_display_info
*xdi
;
907 struct xfont_info
*xfi
= (struct xfont_info
*) font
;
909 /* This function may be called from GC when X connection is gone
910 (Bug#16093), and an attempt to free font resources on invalid
911 display may lead to X protocol errors or segfaults. Moreover,
912 the memory referenced by 'Display *' pointer may be reused for
913 the logically different X connection after the previous display
914 connection was closed. That's why we also check whether font's
915 ID matches the one recorded in x_display_info for this display.
916 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
918 && ((xdi
= x_display_info_for_display (xfi
->display
))
919 && xfi
->x_display_id
== xdi
->x_id
))
922 XFreeFont (xfi
->display
, xfi
->xfont
);
929 xfont_prepare_face (struct frame
*f
, struct face
*face
)
932 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
933 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
938 xfont_has_char (Lisp_Object font
, int c
)
940 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
941 struct charset
*encoding
;
942 struct charset
*repertory
= NULL
;
944 if (EQ (registry
, Qiso10646_1
))
946 encoding
= CHARSET_FROM_ID (charset_unicode
);
947 /* We use a font of `ja' and `ko' adstyle only for a character
948 in JISX0208 and KSC5601 charsets respectively. */
949 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
950 && charset_jisx0208
>= 0)
951 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
952 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
953 && charset_ksc5601
>= 0)
954 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
956 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
957 /* Unknown REGISTRY, not usable. */
959 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
963 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
967 xfont_encode_char (struct font
*font
, int c
)
969 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
970 struct charset
*charset
;
974 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
975 code
= ENCODE_CHAR (charset
, c
);
976 if (code
== CHARSET_INVALID_CODE (charset
))
977 return FONT_INVALID_CODE
;
978 if (font
->repertory_charset
>= 0)
980 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
981 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
982 ? code
: FONT_INVALID_CODE
);
984 char2b
.byte1
= code
>> 8;
985 char2b
.byte2
= code
& 0xFF;
986 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
990 xfont_text_extents (struct font
*font
, unsigned int *code
,
991 int nglyphs
, struct font_metrics
*metrics
)
993 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
997 for (i
= 0, first
= true; i
< nglyphs
; i
++)
1000 static XCharStruct
*pcm
;
1002 if (code
[i
] >= 0x10000)
1004 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
1005 pcm
= xfont_get_pcm (xfont
, &char2b
);
1010 metrics
->lbearing
= pcm
->lbearing
;
1011 metrics
->rbearing
= pcm
->rbearing
;
1012 metrics
->ascent
= pcm
->ascent
;
1013 metrics
->descent
= pcm
->descent
;
1018 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1019 metrics
->lbearing
= width
+ pcm
->lbearing
;
1020 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1021 metrics
->rbearing
= width
+ pcm
->rbearing
;
1022 if (metrics
->ascent
< pcm
->ascent
)
1023 metrics
->ascent
= pcm
->ascent
;
1024 if (metrics
->descent
< pcm
->descent
)
1025 metrics
->descent
= pcm
->descent
;
1027 width
+= pcm
->width
;
1030 metrics
->width
= width
;
1034 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
1035 bool with_background
)
1037 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1038 int len
= to
- from
;
1042 if (s
->gc
!= s
->face
->gc
)
1045 XSetFont (s
->display
, gc
, xfont
->fid
);
1049 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1052 char *str
= SAFE_ALLOCA (len
);
1053 for (i
= 0; i
< len
; i
++)
1054 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1056 if (with_background
)
1059 for (i
= 0; i
< len
; i
++)
1060 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1061 gc
, x
+ i
, y
, str
+ i
, 1);
1063 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1064 gc
, x
, y
, str
, len
);
1069 for (i
= 0; i
< len
; i
++)
1070 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1071 gc
, x
+ i
, y
, str
+ i
, 1);
1073 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1074 gc
, x
, y
, str
, len
);
1082 if (with_background
)
1085 for (i
= 0; i
< len
; i
++)
1086 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1087 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1089 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1090 gc
, x
, y
, s
->char2b
+ from
, len
);
1095 for (i
= 0; i
< len
; i
++)
1096 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1097 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1099 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1100 gc
, x
, y
, s
->char2b
+ from
, len
);
1108 xfont_check (struct frame
*f
, struct font
*font
)
1110 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1112 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1117 syms_of_xfont (void)
1119 staticpro (&xfont_scripts_cache
);
1120 xfont_scripts_cache
= CALLN (Fmake_hash_table
, QCtest
, Qequal
);
1121 staticpro (&xfont_scratch_props
);
1122 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1123 xfont_driver
.type
= Qx
;
1124 register_font_driver (&xfont_driver
, NULL
);