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. */
47 /* Prototypes of support functions. */
49 static XCharStruct
*xfont_get_pcm (XFontStruct
*, XChar2b
*);
51 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
52 is not contained in the font. */
55 xfont_get_pcm (XFontStruct
*xfont
, XChar2b
*char2b
)
57 /* The result metric information. */
58 XCharStruct
*pcm
= NULL
;
60 eassert (xfont
&& char2b
);
62 if (xfont
->per_char
!= NULL
)
64 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
66 /* min_char_or_byte2 specifies the linear character index
67 corresponding to the first element of the per_char array,
68 max_char_or_byte2 is the index of the last character. A
69 character with non-zero CHAR2B->byte1 is not in the font.
70 A character with byte2 less than min_char_or_byte2 or
71 greater max_char_or_byte2 is not in the font. */
72 if (char2b
->byte1
== 0
73 && char2b
->byte2
>= xfont
->min_char_or_byte2
74 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
75 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
79 /* If either min_byte1 or max_byte1 are nonzero, both
80 min_char_or_byte2 and max_char_or_byte2 are less than
81 256, and the 2-byte character index values corresponding
82 to the per_char array element N (counting from 0) are:
84 byte1 = N/D + min_byte1
85 byte2 = N\D + min_char_or_byte2
89 D = max_char_or_byte2 - min_char_or_byte2 + 1
91 \ = integer modulus */
92 if (char2b
->byte1
>= xfont
->min_byte1
93 && char2b
->byte1
<= xfont
->max_byte1
94 && char2b
->byte2
>= xfont
->min_char_or_byte2
95 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
96 pcm
= (xfont
->per_char
97 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
98 * (char2b
->byte1
- xfont
->min_byte1
))
99 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
104 /* If the per_char pointer is null, all glyphs between the first
105 and last character indexes inclusive have the same
106 information, as given by both min_bounds and max_bounds. */
107 if (char2b
->byte2
>= xfont
->min_char_or_byte2
108 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
109 pcm
= &xfont
->max_bounds
;
113 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
117 static Lisp_Object
xfont_get_cache (struct frame
*);
118 static Lisp_Object
xfont_list (struct frame
*, Lisp_Object
);
119 static Lisp_Object
xfont_match (struct frame
*, Lisp_Object
);
120 static Lisp_Object
xfont_list_family (struct frame
*);
121 static Lisp_Object
xfont_open (struct frame
*, Lisp_Object
, int);
122 static void xfont_close (struct font
*);
123 static int xfont_prepare_face (struct frame
*, struct face
*);
124 static int xfont_has_char (Lisp_Object
, int);
125 static unsigned xfont_encode_char (struct font
*, int);
126 static int xfont_text_extents (struct font
*, unsigned *, int,
127 struct font_metrics
*);
128 static int xfont_draw (struct glyph_string
*, int, int, int, int, bool);
129 static int xfont_check (struct frame
*, struct font
*);
131 struct font_driver xfont_driver
=
133 LISP_INITIALLY_ZERO
, /* Qx */
134 0, /* case insensitive */
148 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
150 NULL
, /* get_variation_glyphs */
151 NULL
, /* filter_properties */
155 xfont_get_cache (struct frame
*f
)
157 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
159 return (dpyinfo
->name_list_element
);
163 compare_font_names (const void *name1
, const void *name2
)
165 char *const *n1
= name1
;
166 char *const *n2
= name2
;
167 return xstrcasecmp (*n1
, *n2
);
170 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
171 of the decoding result. LEN is the byte length of XLFD, or -1 if
172 XLFD is NULL terminated. The caller must assure that OUTPUT is at
173 least twice (plus 1) as large as XLFD. */
176 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
178 char *p0
= xlfd
, *p1
= output
;
183 c
= *(unsigned char *) p0
++;
184 p1
+= CHAR_STRING (c
, (unsigned char *) p1
);
189 return (p1
- output
);
192 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
193 resulting byte length. If XLFD contains unencodable character,
197 xfont_encode_coding_xlfd (char *xlfd
)
199 const unsigned char *p0
= (unsigned char *) xlfd
;
200 unsigned char *p1
= (unsigned char *) xlfd
;
205 int c
= STRING_CHAR_ADVANCE (p0
);
216 /* Check if CHARS (cons or vector) is supported by XFONT whose
217 encoding charset is ENCODING (XFONT is NULL) or by a font whose
218 registry corresponds to ENCODING and REPERTORY.
219 Return true if supported. */
222 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
223 struct charset
*encoding
, struct charset
*repertory
)
225 struct charset
*charset
= repertory
? repertory
: encoding
;
229 for (; CONSP (chars
); chars
= XCDR (chars
))
231 int c
= XINT (XCAR (chars
));
232 unsigned code
= ENCODE_CHAR (charset
, c
);
235 if (code
== CHARSET_INVALID_CODE (charset
))
241 char2b
.byte1
= code
>> 8;
242 char2b
.byte2
= code
& 0xFF;
243 if (! xfont_get_pcm (xfont
, &char2b
))
246 return (NILP (chars
));
248 else if (VECTORP (chars
))
252 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
254 int c
= XINT (AREF (chars
, i
));
255 unsigned code
= ENCODE_CHAR (charset
, c
);
258 if (code
== CHARSET_INVALID_CODE (charset
))
264 char2b
.byte1
= code
>> 8;
265 char2b
.byte2
= code
& 0xFF;
266 if (xfont_get_pcm (xfont
, &char2b
))
274 /* A hash table recoding which font supports which scripts. Each key
275 is a vector of characteristic font properties FOUNDRY to WIDTH and
276 ADDSTYLE, and each value is a list of script symbols.
278 We assume that fonts that have the same value in the above
279 properties supports the same set of characters on all displays. */
281 static Lisp_Object xfont_scripts_cache
;
283 /* Re-usable vector to store characteristic font properties. */
284 static Lisp_Object xfont_scratch_props
;
286 /* Return a list of scripts supported by the font of FONTNAME whose
287 characteristic properties are in PROPS and whose encoding charset
288 is ENCODING. A caller must call BLOCK_INPUT in advance. */
291 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
292 struct charset
*encoding
)
296 /* Two special cases to avoid opening rather big fonts. */
297 if (EQ (AREF (props
, 2), Qja
))
298 return list2 (intern ("kana"), intern ("han"));
299 if (EQ (AREF (props
, 2), Qko
))
300 return list1 (intern ("hangul"));
301 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
302 if (EQ (scripts
, Qt
))
308 xfont
= XLoadQueryFont (display
, fontname
);
313 for (val
= Vscript_representative_chars
; CONSP (val
);
315 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
317 Lisp_Object script
= XCAR (XCAR (val
));
318 Lisp_Object chars
= XCDR (XCAR (val
));
320 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
321 scripts
= Fcons (script
, scripts
);
324 XFreeFont (display
, xfont
);
326 if (EQ (AREF (props
, 3), Qiso10646_1
)
327 && NILP (Fmemq (Qlatin
, scripts
)))
328 scripts
= Fcons (Qlatin
, scripts
);
329 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
335 xfont_list_pattern (Display
*display
, const char *pattern
,
336 Lisp_Object registry
, Lisp_Object script
)
338 Lisp_Object list
= Qnil
;
339 Lisp_Object chars
= Qnil
;
340 struct charset
*encoding
, *repertory
= NULL
;
341 int i
, limit
, num_fonts
;
343 /* Large enough to decode the longest XLFD (255 bytes). */
346 if (! NILP (registry
)
347 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
348 /* Unknown REGISTRY, not supported. */
352 chars
= assq_no_quit (script
, Vscript_representative_chars
);
354 /* We can't tell whether or not a font supports SCRIPT. */
356 chars
= XCDR (chars
);
359 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
366 x_catch_errors (display
);
368 for (limit
= 512; ; limit
*= 2)
370 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
371 if (x_had_errors_p (display
))
373 /* This error is perhaps due to insufficient memory on X
374 server. Let's just ignore it. */
375 x_clear_errors (display
);
379 if (num_fonts
< limit
)
381 XFreeFontNames (names
);
386 char **indices
= alloca (sizeof (char *) * num_fonts
);
387 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
388 Lisp_Object scripts
= Qnil
;
390 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
391 ASET (xfont_scratch_props
, i
, Qnil
);
392 for (i
= 0; i
< num_fonts
; i
++)
393 indices
[i
] = names
[i
];
394 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
396 for (i
= 0; i
< num_fonts
; i
++)
401 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
403 entity
= font_make_entity ();
404 len
= xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
405 if (font_parse_xlfd (buf
, len
, entity
) < 0)
407 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
408 /* Avoid auto-scaled fonts. */
409 if (INTEGERP (AREF (entity
, FONT_DPI_INDEX
))
410 && INTEGERP (AREF (entity
, FONT_AVGWIDTH_INDEX
))
411 && XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
412 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
414 /* Avoid not-allowed scalable fonts. */
415 if (NILP (Vscalable_fonts_allowed
))
419 if (INTEGERP (AREF (entity
, FONT_SIZE_INDEX
)))
420 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
421 else if (FLOATP (AREF (entity
, FONT_SIZE_INDEX
)))
422 size
= XFLOAT_DATA (AREF (entity
, FONT_SIZE_INDEX
));
426 else if (CONSP (Vscalable_fonts_allowed
))
428 Lisp_Object tail
, elt
;
430 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
435 && fast_c_string_match_ignore_case (elt
, indices
[i
],
443 /* Avoid fonts of invalid registry. */
444 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
447 /* Update encoding and repertory if necessary. */
448 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
450 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
451 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
455 /* Unknown REGISTRY, not supported. */
460 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
461 list
= Fcons (entity
, list
);
464 if (memcmp (props
, aref_addr (entity
, FONT_FOUNDRY_INDEX
),
466 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
468 vcopy (xfont_scratch_props
, 0,
469 aref_addr (entity
, FONT_FOUNDRY_INDEX
), 7);
470 ASET (xfont_scratch_props
, 7, AREF (entity
, FONT_SPACING_INDEX
));
471 scripts
= xfont_supported_scripts (display
, indices
[i
],
472 xfont_scratch_props
, encoding
);
475 || ! NILP (Fmemq (script
, scripts
)))
476 list
= Fcons (entity
, list
);
478 XFreeFontNames (names
);
484 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
489 xfont_list (struct frame
*f
, Lisp_Object spec
)
491 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
492 Lisp_Object registry
, list
, val
, extra
, script
;
494 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
497 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
500 val
= assq_no_quit (QCotf
, extra
);
503 val
= assq_no_quit (QClang
, extra
);
508 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
509 len
= font_unparse_xlfd (spec
, 0, name
, 512);
510 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
513 val
= assq_no_quit (QCscript
, extra
);
515 list
= xfont_list_pattern (display
, name
, registry
, script
);
516 if (NILP (list
) && NILP (registry
))
519 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
521 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
523 strcpy (r
, "iso10646-1");
524 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
527 if (NILP (list
) && ! NILP (registry
))
529 /* Try alternate registries. */
532 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
533 Vface_alternative_font_registry_alist
),
536 /* Pointer to REGISTRY-ENCODING field. */
537 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
539 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
540 if (STRINGP (XCAR (alter
))
541 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
543 strcpy (r
, SSDATA (XCAR (alter
)));
544 list
= xfont_list_pattern (display
, name
, registry
, script
);
553 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
554 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
556 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
557 if (xfont_encode_coding_xlfd (name
) < 0)
559 list
= xfont_list_pattern (display
, name
, registry
, script
);
567 xfont_match (struct frame
*f
, Lisp_Object spec
)
569 Display
*display
= FRAME_DISPLAY_INFO (f
)->display
;
570 Lisp_Object extra
, val
, entity
;
575 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
576 val
= assq_no_quit (QCname
, extra
);
577 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
579 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
582 else if (SBYTES (XCDR (val
)) < 512)
583 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
586 if (xfont_encode_coding_xlfd (name
) < 0)
591 xfont
= XLoadQueryFont (display
, name
);
594 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
596 char *s
= XGetAtomName (display
, (Atom
) value
);
598 /* If DXPC (a Differential X Protocol Compressor)
599 Ver.3.7 is running, XGetAtomName will return null
600 string. We must avoid such a name. */
604 entity
= font_make_entity ();
605 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
606 len
= xfont_decode_coding_xlfd (s
, -1, name
);
607 if (font_parse_xlfd (name
, len
, entity
) < 0)
612 XFreeFont (display
, xfont
);
616 FONT_ADD_LOG ("xfont-match", spec
, entity
);
621 xfont_list_family (struct frame
*f
)
623 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
627 char *last_family
IF_LINT (= 0);
631 x_catch_errors (dpyinfo
->display
);
632 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
634 if (x_had_errors_p (dpyinfo
->display
))
636 /* This error is perhaps due to insufficient memory on X server.
637 Let's just ignore it. */
638 x_clear_errors (dpyinfo
->display
);
643 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
645 char *p0
= names
[i
], *p1
, buf
[512];
649 p0
++; /* skip the leading '-' */
650 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
654 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
655 if (! *p1
|| p1
== p0
)
657 if (last_len
== p1
- p0
658 && memcmp (last_family
, p0
, last_len
) == 0)
663 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
664 family
= font_intern_prop (p0
, decoded_len
, 1);
665 if (NILP (assq_no_quit (family
, list
)))
666 list
= Fcons (family
, list
);
669 XFreeFontNames (names
);
677 xfont_open (struct frame
*f
, Lisp_Object entity
, int pixel_size
)
679 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
680 Display
*display
= dpyinfo
->display
;
684 Lisp_Object registry
;
685 struct charset
*encoding
, *repertory
;
686 Lisp_Object font_object
, fullname
;
690 /* At first, check if we know how to encode characters for this
692 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
693 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
695 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
699 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
700 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
701 else if (pixel_size
== 0)
704 pixel_size
= FRAME_FONT (f
)->pixel_size
;
708 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
709 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
711 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
716 x_catch_errors (display
);
717 xfont
= XLoadQueryFont (display
, name
);
718 if (x_had_errors_p (display
))
720 /* This error is perhaps due to insufficient memory on X server.
721 Let's just ignore it. */
722 x_clear_errors (display
);
727 /* Some version of X lists:
728 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
729 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
731 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
733 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
734 So, we try again with wildcards in RESX and RESY. */
737 temp
= copy_font_spec (entity
);
738 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
739 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
740 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
742 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
745 xfont
= XLoadQueryFont (display
, name
);
746 if (x_had_errors_p (display
))
748 /* This error is perhaps due to insufficient memory on X server.
749 Let's just ignore it. */
750 x_clear_errors (display
);
755 /* Try to get the full name of FONT. */
756 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
761 p0
= p
= XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
762 /* Count the number of dashes in the "full name".
763 If it is too few, this isn't really the font's full name,
765 In X11R4, the fonts did not come with their canonical names
776 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
777 fullname
= Fdowncase (make_string (name
, len
));
786 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
790 font_object
= font_make_object (VECSIZE (struct xfont_info
),
792 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
793 if (STRINGP (fullname
))
795 font_parse_xlfd (SSDATA (fullname
), SBYTES (fullname
), font_object
);
796 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
802 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
803 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
805 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
806 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
807 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
808 font
= XFONT_OBJECT (font_object
);
809 ((struct xfont_info
*) font
)->xfont
= xfont
;
810 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
811 font
->pixel_size
= pixel_size
;
812 font
->driver
= &xfont_driver
;
813 font
->encoding_charset
= encoding
->id
;
814 font
->repertory_charset
= repertory
? repertory
->id
: -1;
815 font
->ascent
= xfont
->ascent
;
816 font
->descent
= xfont
->descent
;
817 font
->height
= font
->ascent
+ font
->descent
;
818 font
->min_width
= xfont
->min_bounds
.width
;
819 font
->max_width
= xfont
->max_bounds
.width
;
820 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
822 /* Fixed width font. */
823 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
831 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
832 pcm
= xfont_get_pcm (xfont
, &char2b
);
834 font
->space_width
= pcm
->width
;
836 font
->space_width
= 0;
838 val
= Ffont_get (font_object
, QCavgwidth
);
840 font
->average_width
= XINT (val
) / 10;
841 if (font
->average_width
< 0)
842 font
->average_width
= - font
->average_width
;
845 if (font
->average_width
== 0
846 && encoding
->ascii_compatible_p
)
848 int width
= font
->space_width
, n
= pcm
!= NULL
;
850 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
851 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
852 width
+= pcm
->width
, n
++;
854 font
->average_width
= width
/ n
;
856 if (font
->average_width
== 0)
857 /* No easy way other than this to get a reasonable
860 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
865 font
->underline_thickness
866 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
868 font
->underline_position
869 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
870 ? (long) value
: -1);
871 font
->baseline_offset
872 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
874 font
->relative_compose
875 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
878 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
883 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
884 font
->vertical_centering
885 = (STRINGP (Vvertical_centering_font_regexp
)
886 && (fast_string_match_ignore_case
887 (Vvertical_centering_font_regexp
, fullname
) >= 0));
893 xfont_close (struct font
*font
)
895 struct xfont_info
*xfi
= (struct xfont_info
*) font
;
897 /* This function may be called from GC when X connection is gone
898 (Bug#16093), and an attempt to free font resources on invalid
899 display may lead to X protocol errors or segfaults. */
900 if (xfi
->xfont
&& x_display_info_for_display (xfi
->display
))
903 XFreeFont (xfi
->display
, xfi
->xfont
);
910 xfont_prepare_face (struct frame
*f
, struct face
*face
)
913 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
914 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
921 xfont_has_char (Lisp_Object font
, int c
)
923 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
924 struct charset
*encoding
;
925 struct charset
*repertory
= NULL
;
927 if (EQ (registry
, Qiso10646_1
))
929 encoding
= CHARSET_FROM_ID (charset_unicode
);
930 /* We use a font of `ja' and `ko' adstyle only for a character
931 in JISX0208 and KSC5601 charsets respectively. */
932 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
933 && charset_jisx0208
>= 0)
934 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
935 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
936 && charset_ksc5601
>= 0)
937 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
939 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
940 /* Unknown REGISTRY, not usable. */
942 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
946 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
950 xfont_encode_char (struct font
*font
, int c
)
952 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
953 struct charset
*charset
;
957 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
958 code
= ENCODE_CHAR (charset
, c
);
959 if (code
== CHARSET_INVALID_CODE (charset
))
960 return FONT_INVALID_CODE
;
961 if (font
->repertory_charset
>= 0)
963 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
964 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
965 ? code
: FONT_INVALID_CODE
);
967 char2b
.byte1
= code
>> 8;
968 char2b
.byte2
= code
& 0xFF;
969 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
973 xfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
975 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
980 memset (metrics
, 0, sizeof (struct font_metrics
));
981 for (i
= 0, first
= 1; i
< nglyphs
; i
++)
984 static XCharStruct
*pcm
;
986 if (code
[i
] >= 0x10000)
988 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
989 pcm
= xfont_get_pcm (xfont
, &char2b
);
996 metrics
->lbearing
= pcm
->lbearing
;
997 metrics
->rbearing
= pcm
->rbearing
;
998 metrics
->ascent
= pcm
->ascent
;
999 metrics
->descent
= pcm
->descent
;
1007 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1008 metrics
->lbearing
= width
+ pcm
->lbearing
;
1009 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1010 metrics
->rbearing
= width
+ pcm
->rbearing
;
1011 if (metrics
->ascent
< pcm
->ascent
)
1012 metrics
->ascent
= pcm
->ascent
;
1013 if (metrics
->descent
< pcm
->descent
)
1014 metrics
->descent
= pcm
->descent
;
1017 width
+= pcm
->width
;
1020 metrics
->width
= width
;
1025 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
,
1026 bool with_background
)
1028 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1029 int len
= to
- from
;
1033 if (s
->gc
!= s
->face
->gc
)
1036 XSetFont (s
->display
, gc
, xfont
->fid
);
1040 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1043 char *str
= SAFE_ALLOCA (len
);
1044 for (i
= 0; i
< len
; i
++)
1045 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1047 if (with_background
)
1050 for (i
= 0; i
< len
; i
++)
1051 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1052 gc
, x
+ i
, y
, str
+ i
, 1);
1054 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1055 gc
, x
, y
, str
, len
);
1060 for (i
= 0; i
< len
; i
++)
1061 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1062 gc
, x
+ i
, y
, str
+ i
, 1);
1064 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1065 gc
, x
, y
, str
, len
);
1073 if (with_background
)
1076 for (i
= 0; i
< len
; i
++)
1077 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1078 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1080 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1081 gc
, x
, y
, s
->char2b
+ from
, len
);
1086 for (i
= 0; i
< len
; i
++)
1087 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1088 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1090 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1091 gc
, x
, y
, s
->char2b
+ from
, len
);
1099 xfont_check (struct frame
*f
, struct font
*font
)
1101 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1103 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1108 syms_of_xfont (void)
1110 staticpro (&xfont_scripts_cache
);
1111 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1112 is called fairly late, when QCtest and Qequal are known to be set. */
1113 Lisp_Object args
[2];
1116 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1118 staticpro (&xfont_scratch_props
);
1119 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1120 xfont_driver
.type
= Qx
;
1121 register_font_driver (&xfont_driver
, NULL
);