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/>. */
28 #include "dispextern.h"
31 #include "blockinput.h"
32 #include "character.h"
39 /* X core font driver. */
48 /* Prototypes of support functions. */
49 extern void x_clear_errors
P_ ((Display
*));
51 static XCharStruct
*xfont_get_pcm
P_ ((XFontStruct
*, XChar2b
*));
53 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
54 is not contained in the font. */
57 xfont_get_pcm (xfont
, char2b
)
61 /* The result metric information. */
62 XCharStruct
*pcm
= NULL
;
64 font_assert (xfont
&& char2b
);
66 if (xfont
->per_char
!= NULL
)
68 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
70 /* min_char_or_byte2 specifies the linear character index
71 corresponding to the first element of the per_char array,
72 max_char_or_byte2 is the index of the last character. A
73 character with non-zero CHAR2B->byte1 is not in the font.
74 A character with byte2 less than min_char_or_byte2 or
75 greater max_char_or_byte2 is not in the font. */
76 if (char2b
->byte1
== 0
77 && char2b
->byte2
>= xfont
->min_char_or_byte2
78 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
79 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
83 /* If either min_byte1 or max_byte1 are nonzero, both
84 min_char_or_byte2 and max_char_or_byte2 are less than
85 256, and the 2-byte character index values corresponding
86 to the per_char array element N (counting from 0) are:
88 byte1 = N/D + min_byte1
89 byte2 = N\D + min_char_or_byte2
93 D = max_char_or_byte2 - min_char_or_byte2 + 1
95 \ = integer modulus */
96 if (char2b
->byte1
>= xfont
->min_byte1
97 && char2b
->byte1
<= xfont
->max_byte1
98 && char2b
->byte2
>= xfont
->min_char_or_byte2
99 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
100 pcm
= (xfont
->per_char
101 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
102 * (char2b
->byte1
- xfont
->min_byte1
))
103 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
108 /* If the per_char pointer is null, all glyphs between the first
109 and last character indexes inclusive have the same
110 information, as given by both min_bounds and max_bounds. */
111 if (char2b
->byte2
>= xfont
->min_char_or_byte2
112 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
113 pcm
= &xfont
->max_bounds
;
117 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
121 static Lisp_Object xfont_get_cache
P_ ((FRAME_PTR
));
122 static Lisp_Object xfont_list
P_ ((Lisp_Object
, Lisp_Object
));
123 static Lisp_Object xfont_match
P_ ((Lisp_Object
, Lisp_Object
));
124 static Lisp_Object xfont_list_family
P_ ((Lisp_Object
));
125 static Lisp_Object xfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
126 static void xfont_close
P_ ((FRAME_PTR
, struct font
*));
127 static int xfont_prepare_face
P_ ((FRAME_PTR
, struct face
*));
128 static int xfont_has_char
P_ ((Lisp_Object
, int));
129 static unsigned xfont_encode_char
P_ ((struct font
*, int));
130 static int xfont_text_extents
P_ ((struct font
*, unsigned *, int,
131 struct font_metrics
*));
132 static int xfont_draw
P_ ((struct glyph_string
*, int, int, int, int, int));
133 static int xfont_check
P_ ((FRAME_PTR
, struct font
*));
135 struct font_driver xfont_driver
=
138 0, /* case insensitive */
152 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
156 extern Lisp_Object QCname
;
162 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
164 return (dpyinfo
->name_list_element
);
167 extern Lisp_Object Vface_alternative_font_registry_alist
;
170 compare_font_names (const void *name1
, const void *name2
)
172 return xstrcasecmp (*(const unsigned char **) name1
,
173 *(const unsigned char **) name2
);
176 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
177 of the decoding result. LEN is the byte length of XLFD, or -1 if
178 XLFD is NULL terminated. The caller must assure that OUTPUT is at
179 least twice (plus 1) as large as XLFD. */
182 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
184 char *p0
= xlfd
, *p1
= output
;
189 c
= *(unsigned char *) p0
++;
190 p1
+= CHAR_STRING (c
, p1
);
195 return (p1
- output
);
198 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
199 resulting byte length. If XLFD contains unencodable character,
203 xfont_encode_coding_xlfd (char *xlfd
)
205 const unsigned char *p0
= (unsigned char *) xlfd
;
206 unsigned char *p1
= (unsigned char *) xlfd
;
211 int c
= STRING_CHAR_ADVANCE (p0
);
222 /* Check if CHARS (cons or vector) is supported by XFONT whose
223 encoding charset is ENCODING (XFONT is NULL) or by a font whose
224 registry corresponds to ENCODING and REPERTORY.
225 Return 1 if supported, return 0 otherwise. */
228 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
229 struct charset
*encoding
, struct charset
*repertory
)
231 struct charset
*charset
= repertory
? repertory
: encoding
;
235 for (; CONSP (chars
); chars
= XCDR (chars
))
237 int c
= XINT (XCAR (chars
));
238 unsigned code
= ENCODE_CHAR (charset
, c
);
241 if (code
== CHARSET_INVALID_CODE (charset
))
247 char2b
.byte1
= code
>> 8;
248 char2b
.byte2
= code
& 0xFF;
249 if (! xfont_get_pcm (xfont
, &char2b
))
252 return (NILP (chars
));
254 else if (VECTORP (chars
))
258 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
260 int c
= XINT (AREF (chars
, i
));
261 unsigned code
= ENCODE_CHAR (charset
, c
);
264 if (code
== CHARSET_INVALID_CODE (charset
))
270 char2b
.byte1
= code
>> 8;
271 char2b
.byte2
= code
& 0xFF;
272 if (xfont_get_pcm (xfont
, &char2b
))
280 /* A hash table recoding which font supports which scritps. Each key
281 is a vector of characteristic font propertis FOUNDRY to WIDTH and
282 ADDSTYLE, and each value is a list of script symbols.
284 We assume that fonts that have the same value in the above
285 properties supports the same set of characters on all displays. */
287 static Lisp_Object xfont_scripts_cache
;
289 /* Re-usable vector to store characteristic font properites. */
290 static Lisp_Object xfont_scratch_props
;
292 extern Lisp_Object Qlatin
;
294 /* Return a list of scripts supported by the font of FONTNAME whose
295 characteristic properties are in PROPS and whose encoding charset
296 is ENCODING. A caller must call BLOCK_INPUT in advance. */
299 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
300 struct charset
*encoding
)
304 /* Two special cases to avoid opening rather big fonts. */
305 if (EQ (AREF (props
, 2), Qja
))
306 return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil
));
307 if (EQ (AREF (props
, 2), Qko
))
308 return Fcons (intern ("hangul"), Qnil
);
309 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
310 if (EQ (scripts
, Qt
))
316 xfont
= XLoadQueryFont (display
, fontname
);
321 for (val
= Vscript_representative_chars
; CONSP (val
);
323 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
325 Lisp_Object script
= XCAR (XCAR (val
));
326 Lisp_Object chars
= XCDR (XCAR (val
));
328 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
329 scripts
= Fcons (script
, scripts
);
332 XFreeFont (display
, xfont
);
334 if (EQ (AREF (props
, 3), Qiso10646_1
)
335 && NILP (Fmemq (Qlatin
, scripts
)))
336 scripts
= Fcons (Qlatin
, scripts
);
337 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
342 extern Lisp_Object Vscalable_fonts_allowed
;
345 xfont_list_pattern (Display
*display
, char *pattern
,
346 Lisp_Object registry
, Lisp_Object script
)
348 Lisp_Object list
= Qnil
;
349 Lisp_Object chars
= Qnil
;
350 struct charset
*encoding
, *repertory
= NULL
;
351 int i
, limit
, num_fonts
;
353 /* Large enough to decode the longest XLFD (255 bytes). */
356 if (! NILP (registry
)
357 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
358 /* Unknown REGISTRY, not supported. */
362 chars
= assq_no_quit (script
, Vscript_representative_chars
);
364 /* We can't tell whether or not a font supports SCRIPT. */
366 chars
= XCDR (chars
);
369 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
376 x_catch_errors (display
);
378 for (limit
= 512; ; limit
*= 2)
380 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
381 if (x_had_errors_p (display
))
383 /* This error is perhaps due to insufficient memory on X
384 server. Let's just ignore it. */
385 x_clear_errors (display
);
389 if (num_fonts
< limit
)
391 XFreeFontNames (names
);
396 char **indices
= alloca (sizeof (char *) * num_fonts
);
397 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
398 Lisp_Object scripts
= Qnil
;
400 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
402 for (i
= 0; i
< num_fonts
; i
++)
403 indices
[i
] = names
[i
];
404 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
406 for (i
= 0; i
< num_fonts
; i
++)
410 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
412 entity
= font_make_entity ();
413 xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
414 if (font_parse_xlfd (buf
, entity
) < 0)
416 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
417 /* Avoid auto-scaled fonts. */
418 if (INTEGERP (AREF (entity
, FONT_DPI_INDEX
))
419 && INTEGERP (AREF (entity
, FONT_AVGWIDTH_INDEX
))
420 && XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
421 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
423 /* Avoid not-allowed scalable fonts. */
424 if (NILP (Vscalable_fonts_allowed
))
428 if (INTEGERP (AREF (entity
, FONT_SIZE_INDEX
)))
429 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
430 else if (FLOATP (AREF (entity
, FONT_SIZE_INDEX
)))
431 size
= XFLOAT_DATA (AREF (entity
, FONT_SIZE_INDEX
));
435 else if (CONSP (Vscalable_fonts_allowed
))
437 Lisp_Object tail
, elt
;
439 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
444 && fast_c_string_match_ignore_case (elt
, indices
[i
]) >= 0)
451 /* Avoid fonts of invalid registry. */
452 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
455 /* Update encoding and repertory if necessary. */
456 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
458 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
459 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
463 /* Unknown REGISTRY, not supported. */
468 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
469 list
= Fcons (entity
, list
);
472 if (memcmp (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
473 sizeof (Lisp_Object
) * 7)
474 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
476 memcpy (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
477 sizeof (Lisp_Object
) * 7);
478 props
[7] = AREF (entity
, FONT_SPACING_INDEX
);
479 scripts
= xfont_supported_scripts (display
, indices
[i
],
480 xfont_scratch_props
, encoding
);
483 || ! NILP (Fmemq (script
, scripts
)))
484 list
= Fcons (entity
, list
);
486 XFreeFontNames (names
);
492 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
497 xfont_list (frame
, spec
)
498 Lisp_Object frame
, spec
;
500 FRAME_PTR f
= XFRAME (frame
);
501 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
502 Lisp_Object registry
, list
, val
, extra
, script
;
504 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
507 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
510 val
= assq_no_quit (QCotf
, extra
);
513 val
= assq_no_quit (QClang
, extra
);
518 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
519 len
= font_unparse_xlfd (spec
, 0, name
, 512);
520 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
523 val
= assq_no_quit (QCscript
, extra
);
525 list
= xfont_list_pattern (display
, name
, registry
, script
);
526 if (NILP (list
) && NILP (registry
))
529 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
531 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
533 strcpy (r
, "iso10646-1");
534 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
537 if (NILP (list
) && ! NILP (registry
))
539 /* Try alternate registries. */
542 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
543 Vface_alternative_font_registry_alist
),
546 /* Pointer to REGISTRY-ENCODING field. */
547 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
549 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
550 if (STRINGP (XCAR (alter
))
551 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
553 strcpy (r
, (char *) SDATA (XCAR (alter
)));
554 list
= xfont_list_pattern (display
, name
, registry
, script
);
563 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
564 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
566 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
567 if (xfont_encode_coding_xlfd (name
) < 0)
569 list
= xfont_list_pattern (display
, name
, registry
, script
);
577 xfont_match (frame
, spec
)
578 Lisp_Object frame
, spec
;
580 FRAME_PTR f
= XFRAME (frame
);
581 Display
*display
= FRAME_X_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 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
598 if (xfont_encode_coding_xlfd (name
) < 0)
603 xfont
= XLoadQueryFont (display
, name
);
606 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
611 s
= (char *) XGetAtomName (display
, (Atom
) value
);
614 /* If DXPC (a Differential X Protocol Compressor)
615 Ver.3.7 is running, XGetAtomName will return null
616 string. We must avoid such a name. */
619 entity
= font_make_entity ();
620 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
621 xfont_decode_coding_xlfd (s
, -1, name
);
622 if (font_parse_xlfd (name
, entity
) < 0)
627 XFreeFont (display
, xfont
);
631 FONT_ADD_LOG ("xfont-match", spec
, entity
);
636 xfont_list_family (frame
)
639 FRAME_PTR f
= XFRAME (frame
);
640 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
648 x_catch_errors (dpyinfo
->display
);
649 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
651 if (x_had_errors_p (dpyinfo
->display
))
653 /* This error is perhaps due to insufficient memory on X server.
654 Let's just ignore it. */
655 x_clear_errors (dpyinfo
->display
);
660 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
662 char *p0
= names
[i
], *p1
, buf
[512];
666 p0
++; /* skip the leading '-' */
667 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
671 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
672 if (! *p1
|| p1
== p0
)
674 if (last_len
== p1
- p0
675 && bcmp (last_family
, p0
, last_len
) == 0)
680 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
681 family
= font_intern_prop (p0
, decoded_len
, 1);
682 if (NILP (assq_no_quit (family
, list
)))
683 list
= Fcons (family
, list
);
686 XFreeFontNames (names
);
693 extern Lisp_Object QCavgwidth
;
696 xfont_open (f
, entity
, pixel_size
)
701 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
702 Display
*display
= dpyinfo
->display
;
706 Lisp_Object registry
;
707 struct charset
*encoding
, *repertory
;
708 Lisp_Object font_object
, fullname
;
712 /* At first, check if we know how to encode characters for this
714 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
715 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
717 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
721 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
722 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
723 else if (pixel_size
== 0)
726 pixel_size
= FRAME_FONT (f
)->pixel_size
;
730 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
731 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
733 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
738 x_catch_errors (display
);
739 xfont
= XLoadQueryFont (display
, name
);
740 if (x_had_errors_p (display
))
742 /* This error is perhaps due to insufficient memory on X server.
743 Let's just ignore it. */
744 x_clear_errors (display
);
749 /* Some version of X lists:
750 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
751 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
753 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
755 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
756 So, we try again with wildcards in RESX and RESY. */
759 temp
= Fcopy_font_spec (entity
);
760 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
761 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
762 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
764 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
767 xfont
= XLoadQueryFont (display
, name
);
768 if (x_had_errors_p (display
))
770 /* This error is perhaps due to insufficient memory on X server.
771 Let's just ignore it. */
772 x_clear_errors (display
);
777 /* Try to get the full name of FONT. */
778 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
783 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
784 /* Count the number of dashes in the "full name".
785 If it is too few, this isn't really the font's full name,
787 In X11R4, the fonts did not come with their canonical names
798 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
799 fullname
= Fdowncase (make_string (name
, len
));
808 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
812 font_object
= font_make_object (VECSIZE (struct xfont_info
),
814 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
815 if (STRINGP (fullname
))
817 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
818 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
824 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
825 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
827 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
828 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
829 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
830 font
= XFONT_OBJECT (font_object
);
831 ((struct xfont_info
*) font
)->xfont
= xfont
;
832 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
833 font
->pixel_size
= pixel_size
;
834 font
->driver
= &xfont_driver
;
835 font
->encoding_charset
= encoding
->id
;
836 font
->repertory_charset
= repertory
? repertory
->id
: -1;
837 font
->ascent
= xfont
->ascent
;
838 font
->descent
= xfont
->descent
;
839 font
->height
= font
->ascent
+ font
->descent
;
840 font
->min_width
= xfont
->min_bounds
.width
;
841 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
843 /* Fixed width font. */
844 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
852 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
853 pcm
= xfont_get_pcm (xfont
, &char2b
);
855 font
->space_width
= pcm
->width
;
857 font
->space_width
= 0;
859 val
= Ffont_get (font_object
, QCavgwidth
);
861 font
->average_width
= XINT (val
);
862 if (font
->average_width
< 0)
863 font
->average_width
= - font
->average_width
;
864 if (font
->average_width
== 0
865 && encoding
->ascii_compatible_p
)
867 int width
= font
->space_width
, n
= pcm
!= NULL
;
869 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
870 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
871 width
+= pcm
->width
, n
++;
873 font
->average_width
= width
/ n
;
875 if (font
->average_width
== 0)
876 /* No easy way other than this to get a reasonable
879 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
883 font
->underline_thickness
884 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
886 font
->underline_position
887 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
888 ? (long) value
: -1);
889 font
->baseline_offset
890 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
892 font
->relative_compose
893 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
896 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
901 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
902 font
->vertical_centering
903 = (STRINGP (Vvertical_centering_font_regexp
)
904 && (fast_string_match_ignore_case
905 (Vvertical_centering_font_regexp
, fullname
) >= 0));
911 xfont_close (f
, font
)
916 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
921 xfont_prepare_face (f
, face
)
926 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
927 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
934 xfont_has_char (font
, c
)
938 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
939 struct charset
*encoding
;
940 struct charset
*repertory
= NULL
;
942 if (EQ (registry
, Qiso10646_1
))
944 encoding
= CHARSET_FROM_ID (charset_unicode
);
945 /* We use a font of `ja' and `ko' adstyle only for a character
946 in JISX0208 and KSC5601 charsets respectively. */
947 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
948 && charset_jisx0208
>= 0)
949 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
950 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
951 && charset_ksc5601
>= 0)
952 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
954 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
955 /* Unknown REGISTRY, not usable. */
957 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
961 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
965 xfont_encode_char (font
, 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 (font
, code
, nglyphs
, metrics
)
994 struct font_metrics
*metrics
;
996 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
1001 bzero (metrics
, sizeof (struct font_metrics
));
1002 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
1005 static XCharStruct
*pcm
;
1007 if (code
[i
] >= 0x10000)
1009 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
1010 pcm
= xfont_get_pcm (xfont
, &char2b
);
1017 metrics
->lbearing
= pcm
->lbearing
;
1018 metrics
->rbearing
= pcm
->rbearing
;
1019 metrics
->ascent
= pcm
->ascent
;
1020 metrics
->descent
= pcm
->descent
;
1028 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1029 metrics
->lbearing
= width
+ pcm
->lbearing
;
1030 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1031 metrics
->rbearing
= width
+ pcm
->rbearing
;
1032 if (metrics
->ascent
< pcm
->ascent
)
1033 metrics
->ascent
= pcm
->ascent
;
1034 if (metrics
->descent
< pcm
->descent
)
1035 metrics
->descent
= pcm
->descent
;
1038 width
+= pcm
->width
;
1041 metrics
->width
= width
;
1046 xfont_draw (s
, from
, to
, x
, y
, with_background
)
1047 struct glyph_string
*s
;
1048 int from
, to
, x
, y
, with_background
;
1050 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1051 int len
= to
- from
;
1055 if (s
->gc
!= s
->face
->gc
)
1058 XSetFont (s
->display
, gc
, xfont
->fid
);
1062 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1067 SAFE_ALLOCA (str
, char *, len
);
1068 for (i
= 0; i
< len
; i
++)
1069 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1071 if (with_background
> 0)
1074 for (i
= 0; i
< len
; i
++)
1075 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1076 gc
, x
+ i
, y
, str
+ i
, 1);
1078 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1079 gc
, x
, y
, str
, len
);
1084 for (i
= 0; i
< len
; i
++)
1085 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1086 gc
, x
+ i
, y
, str
+ i
, 1);
1088 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1089 gc
, x
, y
, str
, len
);
1097 if (with_background
> 0)
1100 for (i
= 0; i
< len
; i
++)
1101 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1102 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1104 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1105 gc
, x
, y
, s
->char2b
+ from
, len
);
1110 for (i
= 0; i
< len
; i
++)
1111 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1112 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1114 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1115 gc
, x
, y
, s
->char2b
+ from
, len
);
1123 xfont_check (f
, font
)
1127 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1129 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1136 staticpro (&xfont_scripts_cache
);
1137 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1138 is called fairly late, when QCtest and Qequal are known to be set. */
1139 Lisp_Object args
[2];
1142 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1144 staticpro (&xfont_scratch_props
);
1145 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1146 xfont_driver
.type
= Qx
;
1147 register_font_driver (&xfont_driver
, NULL
);
1150 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1151 (do not change this comment) */