1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009
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/>. */
29 #include "dispextern.h"
32 #include "blockinput.h"
33 #include "character.h"
40 /* X core font driver. */
49 /* Prototypes of support functions. */
50 extern void x_clear_errors
P_ ((Display
*));
52 static XCharStruct
*xfont_get_pcm
P_ ((XFontStruct
*, XChar2b
*));
54 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
55 is not contained in the font. */
58 xfont_get_pcm (xfont
, char2b
)
62 /* The result metric information. */
63 XCharStruct
*pcm
= NULL
;
65 font_assert (xfont
&& char2b
);
67 if (xfont
->per_char
!= NULL
)
69 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
71 /* min_char_or_byte2 specifies the linear character index
72 corresponding to the first element of the per_char array,
73 max_char_or_byte2 is the index of the last character. A
74 character with non-zero CHAR2B->byte1 is not in the font.
75 A character with byte2 less than min_char_or_byte2 or
76 greater max_char_or_byte2 is not in the font. */
77 if (char2b
->byte1
== 0
78 && char2b
->byte2
>= xfont
->min_char_or_byte2
79 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
80 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
84 /* If either min_byte1 or max_byte1 are nonzero, both
85 min_char_or_byte2 and max_char_or_byte2 are less than
86 256, and the 2-byte character index values corresponding
87 to the per_char array element N (counting from 0) are:
89 byte1 = N/D + min_byte1
90 byte2 = N\D + min_char_or_byte2
94 D = max_char_or_byte2 - min_char_or_byte2 + 1
96 \ = integer modulus */
97 if (char2b
->byte1
>= xfont
->min_byte1
98 && char2b
->byte1
<= xfont
->max_byte1
99 && char2b
->byte2
>= xfont
->min_char_or_byte2
100 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
101 pcm
= (xfont
->per_char
102 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
103 * (char2b
->byte1
- xfont
->min_byte1
))
104 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
109 /* If the per_char pointer is null, all glyphs between the first
110 and last character indexes inclusive have the same
111 information, as given by both min_bounds and max_bounds. */
112 if (char2b
->byte2
>= xfont
->min_char_or_byte2
113 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
114 pcm
= &xfont
->max_bounds
;
118 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
122 static Lisp_Object xfont_get_cache
P_ ((FRAME_PTR
));
123 static Lisp_Object xfont_list
P_ ((Lisp_Object
, Lisp_Object
));
124 static Lisp_Object xfont_match
P_ ((Lisp_Object
, Lisp_Object
));
125 static Lisp_Object xfont_list_family
P_ ((Lisp_Object
));
126 static Lisp_Object xfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
127 static void xfont_close
P_ ((FRAME_PTR
, struct font
*));
128 static int xfont_prepare_face
P_ ((FRAME_PTR
, struct face
*));
129 static int xfont_has_char
P_ ((Lisp_Object
, int));
130 static unsigned xfont_encode_char
P_ ((struct font
*, int));
131 static int xfont_text_extents
P_ ((struct font
*, unsigned *, int,
132 struct font_metrics
*));
133 static int xfont_draw
P_ ((struct glyph_string
*, int, int, int, int, int));
134 static int xfont_check
P_ ((FRAME_PTR
, struct font
*));
136 struct font_driver xfont_driver
=
139 0, /* case insensitive */
153 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
157 extern Lisp_Object QCname
;
163 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
165 return (dpyinfo
->name_list_element
);
168 extern Lisp_Object Vface_alternative_font_registry_alist
;
171 compare_font_names (const void *name1
, const void *name2
)
173 return xstrcasecmp (*(const unsigned char **) name1
,
174 *(const unsigned char **) name2
);
177 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
178 of the decoding result. LEN is the byte length of XLFD, or -1 if
179 XLFD is NULL terminated. The caller must assure that OUTPUT is at
180 least twice (plus 1) as large as XLFD. */
183 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
185 char *p0
= xlfd
, *p1
= output
;
190 c
= *(unsigned char *) p0
++;
191 p1
+= CHAR_STRING (c
, p1
);
196 return (p1
- output
);
199 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
200 resulting byte length. If XLFD contains unencodable character,
204 xfont_encode_coding_xlfd (char *xlfd
)
206 const unsigned char *p0
= (unsigned char *) xlfd
;
207 unsigned char *p1
= (unsigned char *) xlfd
;
212 int c
= STRING_CHAR_ADVANCE (p0
);
223 /* Check if CHARS (cons or vector) is supported by XFONT whose
224 encoding charset is ENCODING (XFONT is NULL) or by a font whose
225 registry corresponds to ENCODING and REPERTORY.
226 Return 1 if supported, return 0 otherwise. */
229 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
230 struct charset
*encoding
, struct charset
*repertory
)
232 struct charset
*charset
= repertory
? repertory
: encoding
;
236 for (; CONSP (chars
); chars
= XCDR (chars
))
238 int c
= XINT (XCAR (chars
));
239 unsigned code
= ENCODE_CHAR (charset
, c
);
242 if (code
== CHARSET_INVALID_CODE (charset
))
248 char2b
.byte1
= code
>> 8;
249 char2b
.byte2
= code
& 0xFF;
250 if (! xfont_get_pcm (xfont
, &char2b
))
253 return (NILP (chars
));
255 else if (VECTORP (chars
))
259 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
261 int c
= XINT (AREF (chars
, i
));
262 unsigned code
= ENCODE_CHAR (charset
, c
);
265 if (code
== CHARSET_INVALID_CODE (charset
))
271 char2b
.byte1
= code
>> 8;
272 char2b
.byte2
= code
& 0xFF;
273 if (xfont_get_pcm (xfont
, &char2b
))
281 /* A hash table recoding which font supports which scritps. Each key
282 is a vector of characteristic font propertis FOUNDRY to WIDTH and
283 ADDSTYLE, and each value is a list of script symbols.
285 We assume that fonts that have the same value in the above
286 properties supports the same set of characters on all displays. */
288 static Lisp_Object xfont_scripts_cache
;
290 /* Re-usable vector to store characteristic font properites. */
291 static Lisp_Object xfont_scratch_props
;
293 extern Lisp_Object Qlatin
;
295 /* Return a list of scripts supported by the font of FONTNAME whose
296 characteristic properties are in PROPS and whose encoding charset
297 is ENCODING. A caller must call BLOCK_INPUT in advance. */
300 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
301 struct charset
*encoding
)
305 /* Two special cases to avoid opening rather big fonts. */
306 if (EQ (AREF (props
, 2), Qja
))
307 return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil
));
308 if (EQ (AREF (props
, 2), Qko
))
309 return Fcons (intern ("hangul"), Qnil
);
310 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
311 if (EQ (scripts
, Qt
))
317 xfont
= XLoadQueryFont (display
, fontname
);
322 for (val
= Vscript_representative_chars
; CONSP (val
);
324 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
326 Lisp_Object script
= XCAR (XCAR (val
));
327 Lisp_Object chars
= XCDR (XCAR (val
));
329 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
330 scripts
= Fcons (script
, scripts
);
333 XFreeFont (display
, xfont
);
335 if (EQ (AREF (props
, 3), Qiso10646_1
)
336 && NILP (Fmemq (Qlatin
, scripts
)))
337 scripts
= Fcons (Qlatin
, scripts
);
338 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
343 extern Lisp_Object Vscalable_fonts_allowed
;
346 xfont_list_pattern (Display
*display
, char *pattern
,
347 Lisp_Object registry
, Lisp_Object script
)
349 Lisp_Object list
= Qnil
;
350 Lisp_Object chars
= Qnil
;
351 struct charset
*encoding
, *repertory
= NULL
;
352 int i
, limit
, num_fonts
;
354 /* Large enough to decode the longest XLFD (255 bytes). */
357 if (! NILP (registry
)
358 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
359 /* Unknown REGISTRY, not supported. */
363 chars
= assq_no_quit (script
, Vscript_representative_chars
);
365 /* We can't tell whether or not a font supports SCRIPT. */
367 chars
= XCDR (chars
);
370 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
377 x_catch_errors (display
);
379 for (limit
= 512; ; limit
*= 2)
381 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
382 if (x_had_errors_p (display
))
384 /* This error is perhaps due to insufficient memory on X
385 server. Let's just ignore it. */
386 x_clear_errors (display
);
390 if (num_fonts
< limit
)
392 XFreeFontNames (names
);
397 char **indices
= alloca (sizeof (char *) * num_fonts
);
398 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
399 Lisp_Object scripts
= Qnil
;
401 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
403 for (i
= 0; i
< num_fonts
; i
++)
404 indices
[i
] = names
[i
];
405 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
407 for (i
= 0; i
< num_fonts
; i
++)
411 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
413 entity
= font_make_entity ();
414 xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
415 if (font_parse_xlfd (buf
, entity
) < 0)
417 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
418 /* Avoid auto-scaled fonts. */
419 if (INTEGERP (AREF (entity
, FONT_DPI_INDEX
))
420 && INTEGERP (AREF (entity
, FONT_AVGWIDTH_INDEX
))
421 && XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
422 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
424 /* Avoid not-allowed scalable fonts. */
425 if (NILP (Vscalable_fonts_allowed
))
429 if (INTEGERP (AREF (entity
, FONT_SIZE_INDEX
)))
430 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
431 else if (FLOATP (AREF (entity
, FONT_SIZE_INDEX
)))
432 size
= XFLOAT_DATA (AREF (entity
, FONT_SIZE_INDEX
));
436 else if (CONSP (Vscalable_fonts_allowed
))
438 Lisp_Object tail
, elt
;
440 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
445 && fast_c_string_match_ignore_case (elt
, indices
[i
]) >= 0)
452 /* Avoid fonts of invalid registry. */
453 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
456 /* Update encoding and repertory if necessary. */
457 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
459 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
460 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
464 /* Unknown REGISTRY, not supported. */
469 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
470 list
= Fcons (entity
, list
);
473 if (memcmp (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
474 sizeof (Lisp_Object
) * 7)
475 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
477 memcpy (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
478 sizeof (Lisp_Object
) * 7);
479 props
[7] = AREF (entity
, FONT_SPACING_INDEX
);
480 scripts
= xfont_supported_scripts (display
, indices
[i
],
481 xfont_scratch_props
, encoding
);
484 || ! NILP (Fmemq (script
, scripts
)))
485 list
= Fcons (entity
, list
);
487 XFreeFontNames (names
);
493 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
498 xfont_list (frame
, spec
)
499 Lisp_Object frame
, spec
;
501 FRAME_PTR f
= XFRAME (frame
);
502 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
503 Lisp_Object registry
, list
, val
, extra
, script
;
505 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
508 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
511 val
= assq_no_quit (QCotf
, extra
);
514 val
= assq_no_quit (QClang
, extra
);
519 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
520 len
= font_unparse_xlfd (spec
, 0, name
, 512);
521 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
524 val
= assq_no_quit (QCscript
, extra
);
526 list
= xfont_list_pattern (display
, name
, registry
, script
);
527 if (NILP (list
) && NILP (registry
))
530 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
532 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
534 strcpy (r
, "iso10646-1");
535 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
538 if (NILP (list
) && ! NILP (registry
))
540 /* Try alternate registries. */
543 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
544 Vface_alternative_font_registry_alist
),
547 /* Pointer to REGISTRY-ENCODING field. */
548 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
550 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
551 if (STRINGP (XCAR (alter
))
552 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
554 strcpy (r
, (char *) SDATA (XCAR (alter
)));
555 list
= xfont_list_pattern (display
, name
, registry
, script
);
564 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
565 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
567 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
568 if (xfont_encode_coding_xlfd (name
) < 0)
570 list
= xfont_list_pattern (display
, name
, registry
, script
);
578 xfont_match (frame
, spec
)
579 Lisp_Object frame
, spec
;
581 FRAME_PTR f
= XFRAME (frame
);
582 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
583 Lisp_Object extra
, val
, entity
;
588 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
589 val
= assq_no_quit (QCname
, extra
);
590 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
592 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
595 else if (SBYTES (XCDR (val
)) < 512)
596 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
599 if (xfont_encode_coding_xlfd (name
) < 0)
604 xfont
= XLoadQueryFont (display
, name
);
607 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
612 s
= (char *) XGetAtomName (display
, (Atom
) value
);
615 /* If DXPC (a Differential X Protocol Compressor)
616 Ver.3.7 is running, XGetAtomName will return null
617 string. We must avoid such a name. */
620 entity
= font_make_entity ();
621 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
622 xfont_decode_coding_xlfd (s
, -1, name
);
623 if (font_parse_xlfd (name
, entity
) < 0)
628 XFreeFont (display
, xfont
);
632 FONT_ADD_LOG ("xfont-match", spec
, entity
);
637 xfont_list_family (frame
)
640 FRAME_PTR f
= XFRAME (frame
);
641 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
649 x_catch_errors (dpyinfo
->display
);
650 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
652 if (x_had_errors_p (dpyinfo
->display
))
654 /* This error is perhaps due to insufficient memory on X server.
655 Let's just ignore it. */
656 x_clear_errors (dpyinfo
->display
);
661 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
663 char *p0
= names
[i
], *p1
, buf
[512];
667 p0
++; /* skip the leading '-' */
668 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
672 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
673 if (! *p1
|| p1
== p0
)
675 if (last_len
== p1
- p0
676 && bcmp (last_family
, p0
, last_len
) == 0)
681 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
682 family
= font_intern_prop (p0
, decoded_len
, 1);
683 if (NILP (assq_no_quit (family
, list
)))
684 list
= Fcons (family
, list
);
687 XFreeFontNames (names
);
694 extern Lisp_Object QCavgwidth
;
697 xfont_open (f
, entity
, pixel_size
)
702 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
703 Display
*display
= dpyinfo
->display
;
707 Lisp_Object registry
;
708 struct charset
*encoding
, *repertory
;
709 Lisp_Object font_object
, fullname
;
713 /* At first, check if we know how to encode characters for this
715 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
716 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
718 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
722 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
723 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
724 else if (pixel_size
== 0)
727 pixel_size
= FRAME_FONT (f
)->pixel_size
;
731 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
732 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
734 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
739 x_catch_errors (display
);
740 xfont
= XLoadQueryFont (display
, name
);
741 if (x_had_errors_p (display
))
743 /* This error is perhaps due to insufficient memory on X server.
744 Let's just ignore it. */
745 x_clear_errors (display
);
750 /* Some version of X lists:
751 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
752 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
754 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
756 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
757 So, we try again with wildcards in RESX and RESY. */
760 temp
= Fcopy_font_spec (entity
);
761 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
762 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
763 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
765 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
768 xfont
= XLoadQueryFont (display
, name
);
769 if (x_had_errors_p (display
))
771 /* This error is perhaps due to insufficient memory on X server.
772 Let's just ignore it. */
773 x_clear_errors (display
);
778 /* Try to get the full name of FONT. */
779 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
784 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
785 /* Count the number of dashes in the "full name".
786 If it is too few, this isn't really the font's full name,
788 In X11R4, the fonts did not come with their canonical names
799 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
800 fullname
= Fdowncase (make_string (name
, len
));
809 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
813 font_object
= font_make_object (VECSIZE (struct xfont_info
),
815 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
816 if (STRINGP (fullname
))
818 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
819 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
825 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
826 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
828 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
829 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
830 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
831 font
= XFONT_OBJECT (font_object
);
832 ((struct xfont_info
*) font
)->xfont
= xfont
;
833 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
834 font
->pixel_size
= pixel_size
;
835 font
->driver
= &xfont_driver
;
836 font
->encoding_charset
= encoding
->id
;
837 font
->repertory_charset
= repertory
? repertory
->id
: -1;
838 font
->ascent
= xfont
->ascent
;
839 font
->descent
= xfont
->descent
;
840 font
->height
= font
->ascent
+ font
->descent
;
841 font
->min_width
= xfont
->min_bounds
.width
;
842 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
844 /* Fixed width font. */
845 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
853 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
854 pcm
= xfont_get_pcm (xfont
, &char2b
);
856 font
->space_width
= pcm
->width
;
858 font
->space_width
= 0;
860 val
= Ffont_get (font_object
, QCavgwidth
);
862 font
->average_width
= XINT (val
);
863 if (font
->average_width
< 0)
864 font
->average_width
= - font
->average_width
;
865 if (font
->average_width
== 0
866 && encoding
->ascii_compatible_p
)
868 int width
= font
->space_width
, n
= pcm
!= NULL
;
870 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
871 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
872 width
+= pcm
->width
, n
++;
874 font
->average_width
= width
/ n
;
876 if (font
->average_width
== 0)
877 /* No easy way other than this to get a reasonable
880 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
884 font
->underline_thickness
885 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
887 font
->underline_position
888 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
889 ? (long) value
: -1);
890 font
->baseline_offset
891 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
893 font
->relative_compose
894 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
897 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
902 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
903 font
->vertical_centering
904 = (STRINGP (Vvertical_centering_font_regexp
)
905 && (fast_string_match_ignore_case
906 (Vvertical_centering_font_regexp
, fullname
) >= 0));
912 xfont_close (f
, font
)
917 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
922 xfont_prepare_face (f
, face
)
927 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
928 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
935 xfont_has_char (font
, c
)
939 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
940 struct charset
*encoding
;
941 struct charset
*repertory
= NULL
;
943 if (EQ (registry
, Qiso10646_1
))
945 encoding
= CHARSET_FROM_ID (charset_unicode
);
946 /* We use a font of `ja' and `ko' adstyle only for a character
947 in JISX0208 and KSC5601 charsets respectively. */
948 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
949 && charset_jisx0208
>= 0)
950 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
951 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
952 && charset_ksc5601
>= 0)
953 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
955 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
956 /* Unknown REGISTRY, not usable. */
958 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
962 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
966 xfont_encode_char (font
, c
)
970 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
971 struct charset
*charset
;
975 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
976 code
= ENCODE_CHAR (charset
, c
);
977 if (code
== CHARSET_INVALID_CODE (charset
))
978 return FONT_INVALID_CODE
;
979 if (font
->repertory_charset
>= 0)
981 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
982 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
983 ? code
: FONT_INVALID_CODE
);
985 char2b
.byte1
= code
>> 8;
986 char2b
.byte2
= code
& 0xFF;
987 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
991 xfont_text_extents (font
, code
, nglyphs
, metrics
)
995 struct font_metrics
*metrics
;
997 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
1002 bzero (metrics
, sizeof (struct font_metrics
));
1003 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
1006 static XCharStruct
*pcm
;
1008 if (code
[i
] >= 0x10000)
1010 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
1011 pcm
= xfont_get_pcm (xfont
, &char2b
);
1018 metrics
->lbearing
= pcm
->lbearing
;
1019 metrics
->rbearing
= pcm
->rbearing
;
1020 metrics
->ascent
= pcm
->ascent
;
1021 metrics
->descent
= pcm
->descent
;
1029 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1030 metrics
->lbearing
= width
+ pcm
->lbearing
;
1031 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1032 metrics
->rbearing
= width
+ pcm
->rbearing
;
1033 if (metrics
->ascent
< pcm
->ascent
)
1034 metrics
->ascent
= pcm
->ascent
;
1035 if (metrics
->descent
< pcm
->descent
)
1036 metrics
->descent
= pcm
->descent
;
1039 width
+= pcm
->width
;
1042 metrics
->width
= width
;
1047 xfont_draw (s
, from
, to
, x
, y
, with_background
)
1048 struct glyph_string
*s
;
1049 int from
, to
, x
, y
, with_background
;
1051 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1052 int len
= to
- from
;
1056 if (s
->gc
!= s
->face
->gc
)
1059 XSetFont (s
->display
, gc
, xfont
->fid
);
1063 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1068 SAFE_ALLOCA (str
, char *, len
);
1069 for (i
= 0; i
< len
; i
++)
1070 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1072 if (with_background
> 0)
1075 for (i
= 0; i
< len
; i
++)
1076 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1077 gc
, x
+ i
, y
, str
+ i
, 1);
1079 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1080 gc
, x
, y
, str
, len
);
1085 for (i
= 0; i
< len
; i
++)
1086 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1087 gc
, x
+ i
, y
, str
+ i
, 1);
1089 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1090 gc
, x
, y
, str
, len
);
1098 if (with_background
> 0)
1101 for (i
= 0; i
< len
; i
++)
1102 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1103 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1105 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1106 gc
, x
, y
, s
->char2b
+ from
, len
);
1111 for (i
= 0; i
< len
; i
++)
1112 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1113 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1115 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1116 gc
, x
, y
, s
->char2b
+ from
, len
);
1124 xfont_check (f
, font
)
1128 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1130 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1137 staticpro (&xfont_scripts_cache
);
1138 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1139 is called fairly late, when QCtest and Qequal are known to be set. */
1140 Lisp_Object args
[2];
1143 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1145 staticpro (&xfont_scratch_props
);
1146 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1147 xfont_driver
.type
= Qx
;
1148 register_font_driver (&xfont_driver
, NULL
);
1151 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1152 (do not change this comment) */