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 font_parse_xlfd (buf
, entity
);
415 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
416 /* Avoid auto-scaled fonts. */
417 if (XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
418 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
420 /* Avoid not-allowed scalable fonts. */
421 if (NILP (Vscalable_fonts_allowed
))
423 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) == 0)
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
]) >= 0)
442 /* Update encoding and repertory if necessary. */
443 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
445 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
446 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
450 /* Unknown REGISTRY, not supported. */
455 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
456 list
= Fcons (entity
, list
);
459 if (memcmp (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
460 sizeof (Lisp_Object
) * 7)
461 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
463 memcpy (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
464 sizeof (Lisp_Object
) * 7);
465 props
[7] = AREF (entity
, FONT_SPACING_INDEX
);
466 scripts
= xfont_supported_scripts (display
, indices
[i
],
467 xfont_scratch_props
, encoding
);
470 || ! NILP (Fmemq (script
, scripts
)))
471 list
= Fcons (entity
, list
);
473 XFreeFontNames (names
);
479 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
484 xfont_list (frame
, spec
)
485 Lisp_Object frame
, spec
;
487 FRAME_PTR f
= XFRAME (frame
);
488 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
489 Lisp_Object registry
, list
, val
, extra
, script
;
491 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
494 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
497 val
= assq_no_quit (QCotf
, extra
);
500 val
= assq_no_quit (QClang
, extra
);
505 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
506 len
= font_unparse_xlfd (spec
, 0, name
, 512);
507 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
510 val
= assq_no_quit (QCscript
, extra
);
512 list
= xfont_list_pattern (display
, name
, registry
, script
);
513 if (NILP (list
) && NILP (registry
))
516 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
518 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
520 strcpy (r
, "iso10646-1");
521 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
524 if (NILP (list
) && ! NILP (registry
))
526 /* Try alternate registries. */
529 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
530 Vface_alternative_font_registry_alist
),
533 /* Pointer to REGISTRY-ENCODING field. */
534 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
536 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
537 if (STRINGP (XCAR (alter
))
538 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
540 strcpy (r
, (char *) SDATA (XCAR (alter
)));
541 list
= xfont_list_pattern (display
, name
, registry
, script
);
550 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
551 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
553 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
554 if (xfont_encode_coding_xlfd (name
) < 0)
556 list
= xfont_list_pattern (display
, name
, registry
, script
);
564 xfont_match (frame
, spec
)
565 Lisp_Object frame
, spec
;
567 FRAME_PTR f
= XFRAME (frame
);
568 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
569 Lisp_Object extra
, val
, entity
;
574 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
575 val
= assq_no_quit (QCname
, extra
);
576 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
578 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
581 else if (SBYTES (XCDR (val
)) < 512)
582 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
585 if (xfont_encode_coding_xlfd (name
) < 0)
590 xfont
= XLoadQueryFont (display
, name
);
593 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
598 s
= (char *) XGetAtomName (display
, (Atom
) value
);
601 /* If DXPC (a Differential X Protocol Compressor)
602 Ver.3.7 is running, XGetAtomName will return null
603 string. We must avoid such a name. */
606 entity
= font_make_entity ();
607 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
608 xfont_decode_coding_xlfd (s
, -1, name
);
609 if (font_parse_xlfd (name
, entity
) < 0)
614 XFreeFont (display
, xfont
);
618 FONT_ADD_LOG ("xfont-match", spec
, entity
);
623 xfont_list_family (frame
)
626 FRAME_PTR f
= XFRAME (frame
);
627 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
635 x_catch_errors (dpyinfo
->display
);
636 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
638 if (x_had_errors_p (dpyinfo
->display
))
640 /* This error is perhaps due to insufficient memory on X server.
641 Let's just ignore it. */
642 x_clear_errors (dpyinfo
->display
);
647 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
649 char *p0
= names
[i
], *p1
, buf
[512];
653 p0
++; /* skip the leading '-' */
654 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
658 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
659 if (! *p1
|| p1
== p0
)
661 if (last_len
== p1
- p0
662 && bcmp (last_family
, p0
, last_len
) == 0)
667 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
668 family
= font_intern_prop (p0
, decoded_len
, 1);
669 if (NILP (assq_no_quit (family
, list
)))
670 list
= Fcons (family
, list
);
673 XFreeFontNames (names
);
680 extern Lisp_Object QCavgwidth
;
683 xfont_open (f
, entity
, pixel_size
)
688 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
689 Display
*display
= dpyinfo
->display
;
693 Lisp_Object registry
;
694 struct charset
*encoding
, *repertory
;
695 Lisp_Object font_object
, fullname
;
699 /* At first, check if we know how to encode characters for this
701 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
702 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
704 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
708 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
709 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
710 else if (pixel_size
== 0)
713 pixel_size
= FRAME_FONT (f
)->pixel_size
;
717 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
718 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
720 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
725 x_catch_errors (display
);
726 xfont
= XLoadQueryFont (display
, name
);
727 if (x_had_errors_p (display
))
729 /* This error is perhaps due to insufficient memory on X server.
730 Let's just ignore it. */
731 x_clear_errors (display
);
736 /* Some version of X lists:
737 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
738 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
740 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
742 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
743 So, we try again with wildcards in RESX and RESY. */
746 temp
= Fcopy_font_spec (entity
);
747 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
748 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
749 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
751 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
754 xfont
= XLoadQueryFont (display
, name
);
755 if (x_had_errors_p (display
))
757 /* This error is perhaps due to insufficient memory on X server.
758 Let's just ignore it. */
759 x_clear_errors (display
);
764 /* Try to get the full name of FONT. */
765 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
770 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
771 /* Count the number of dashes in the "full name".
772 If it is too few, this isn't really the font's full name,
774 In X11R4, the fonts did not come with their canonical names
785 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
786 fullname
= Fdowncase (make_string (name
, len
));
795 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
799 font_object
= font_make_object (VECSIZE (struct xfont_info
),
801 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
802 if (STRINGP (fullname
))
804 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
805 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
811 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
812 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
814 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
815 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
816 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
817 font
= XFONT_OBJECT (font_object
);
818 ((struct xfont_info
*) font
)->xfont
= xfont
;
819 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
820 font
->pixel_size
= pixel_size
;
821 font
->driver
= &xfont_driver
;
822 font
->encoding_charset
= encoding
->id
;
823 font
->repertory_charset
= repertory
? repertory
->id
: -1;
824 font
->ascent
= xfont
->ascent
;
825 font
->descent
= xfont
->descent
;
826 font
->height
= font
->ascent
+ font
->descent
;
827 font
->min_width
= xfont
->min_bounds
.width
;
828 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
830 /* Fixed width font. */
831 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
839 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
840 pcm
= xfont_get_pcm (xfont
, &char2b
);
842 font
->space_width
= pcm
->width
;
844 font
->space_width
= 0;
846 val
= Ffont_get (font_object
, QCavgwidth
);
848 font
->average_width
= XINT (val
);
849 if (font
->average_width
< 0)
850 font
->average_width
= - font
->average_width
;
851 if (font
->average_width
== 0
852 && encoding
->ascii_compatible_p
)
854 int width
= font
->space_width
, n
= pcm
!= NULL
;
856 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
857 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
858 width
+= pcm
->width
, n
++;
860 font
->average_width
= width
/ n
;
862 if (font
->average_width
== 0)
863 /* No easy way other than this to get a reasonable
866 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
870 font
->underline_thickness
871 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
873 font
->underline_position
874 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
875 ? (long) value
: -1);
876 font
->baseline_offset
877 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
879 font
->relative_compose
880 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
883 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
888 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
889 font
->vertical_centering
890 = (STRINGP (Vvertical_centering_font_regexp
)
891 && (fast_string_match_ignore_case
892 (Vvertical_centering_font_regexp
, fullname
) >= 0));
898 xfont_close (f
, font
)
903 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
908 xfont_prepare_face (f
, face
)
913 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
914 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
921 xfont_has_char (font
, c
)
925 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
926 struct charset
*encoding
;
927 struct charset
*repertory
= NULL
;
929 if (EQ (registry
, Qiso10646_1
))
931 encoding
= CHARSET_FROM_ID (charset_unicode
);
932 /* We use a font of `ja' and `ko' adstyle only for a character
933 in JISX0208 and KSC5601 charsets respectively. */
934 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
935 && charset_jisx0208
>= 0)
936 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
937 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
938 && charset_ksc5601
>= 0)
939 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
941 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
942 /* Unknown REGISTRY, not usable. */
944 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
948 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
952 xfont_encode_char (font
, c
)
956 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
957 struct charset
*charset
;
961 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
962 code
= ENCODE_CHAR (charset
, c
);
963 if (code
== CHARSET_INVALID_CODE (charset
))
964 return FONT_INVALID_CODE
;
965 if (font
->repertory_charset
>= 0)
967 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
968 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
969 ? code
: FONT_INVALID_CODE
);
971 char2b
.byte1
= code
>> 8;
972 char2b
.byte2
= code
& 0xFF;
973 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
977 xfont_text_extents (font
, code
, nglyphs
, metrics
)
981 struct font_metrics
*metrics
;
983 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
988 bzero (metrics
, sizeof (struct font_metrics
));
989 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
992 static XCharStruct
*pcm
;
994 if (code
[i
] >= 0x10000)
996 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
997 pcm
= xfont_get_pcm (xfont
, &char2b
);
1004 metrics
->lbearing
= pcm
->lbearing
;
1005 metrics
->rbearing
= pcm
->rbearing
;
1006 metrics
->ascent
= pcm
->ascent
;
1007 metrics
->descent
= pcm
->descent
;
1015 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1016 metrics
->lbearing
= width
+ pcm
->lbearing
;
1017 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1018 metrics
->rbearing
= width
+ pcm
->rbearing
;
1019 if (metrics
->ascent
< pcm
->ascent
)
1020 metrics
->ascent
= pcm
->ascent
;
1021 if (metrics
->descent
< pcm
->descent
)
1022 metrics
->descent
= pcm
->descent
;
1025 width
+= pcm
->width
;
1028 metrics
->width
= width
;
1033 xfont_draw (s
, from
, to
, x
, y
, with_background
)
1034 struct glyph_string
*s
;
1035 int from
, to
, x
, y
, 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)
1054 SAFE_ALLOCA (str
, char *, len
);
1055 for (i
= 0; i
< len
; i
++)
1056 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1058 if (with_background
> 0)
1061 for (i
= 0; i
< len
; i
++)
1062 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1063 gc
, x
+ i
, y
, str
+ i
, 1);
1065 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1066 gc
, x
, y
, str
, len
);
1071 for (i
= 0; i
< len
; i
++)
1072 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1073 gc
, x
+ i
, y
, str
+ i
, 1);
1075 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1076 gc
, x
, y
, str
, len
);
1084 if (with_background
> 0)
1087 for (i
= 0; i
< len
; i
++)
1088 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1089 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1091 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1092 gc
, x
, y
, s
->char2b
+ from
, len
);
1097 for (i
= 0; i
< len
; i
++)
1098 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1099 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1101 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1102 gc
, x
, y
, s
->char2b
+ from
, len
);
1110 xfont_check (f
, font
)
1114 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1116 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1123 staticpro (&xfont_scripts_cache
);
1124 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1125 is called fairly late, when QCtest and Qequal are known to be set. */
1126 Lisp_Object args
[2];
1129 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1131 staticpro (&xfont_scratch_props
);
1132 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1133 xfont_driver
.type
= Qx
;
1134 register_font_driver (&xfont_driver
, NULL
);
1137 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1138 (do not change this comment) */