1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010
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 (Display
*);
51 static XCharStruct
*xfont_get_pcm (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 (XFontStruct
*xfont
, XChar2b
*char2b
)
59 /* The result metric information. */
60 XCharStruct
*pcm
= NULL
;
62 font_assert (xfont
&& char2b
);
64 if (xfont
->per_char
!= NULL
)
66 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
68 /* min_char_or_byte2 specifies the linear character index
69 corresponding to the first element of the per_char array,
70 max_char_or_byte2 is the index of the last character. A
71 character with non-zero CHAR2B->byte1 is not in the font.
72 A character with byte2 less than min_char_or_byte2 or
73 greater max_char_or_byte2 is not in the font. */
74 if (char2b
->byte1
== 0
75 && char2b
->byte2
>= xfont
->min_char_or_byte2
76 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
77 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
81 /* If either min_byte1 or max_byte1 are nonzero, both
82 min_char_or_byte2 and max_char_or_byte2 are less than
83 256, and the 2-byte character index values corresponding
84 to the per_char array element N (counting from 0) are:
86 byte1 = N/D + min_byte1
87 byte2 = N\D + min_char_or_byte2
91 D = max_char_or_byte2 - min_char_or_byte2 + 1
93 \ = integer modulus */
94 if (char2b
->byte1
>= xfont
->min_byte1
95 && char2b
->byte1
<= xfont
->max_byte1
96 && char2b
->byte2
>= xfont
->min_char_or_byte2
97 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
98 pcm
= (xfont
->per_char
99 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
100 * (char2b
->byte1
- xfont
->min_byte1
))
101 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
106 /* If the per_char pointer is null, all glyphs between the first
107 and last character indexes inclusive have the same
108 information, as given by both min_bounds and max_bounds. */
109 if (char2b
->byte2
>= xfont
->min_char_or_byte2
110 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
111 pcm
= &xfont
->max_bounds
;
115 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
119 static Lisp_Object
xfont_get_cache (FRAME_PTR
);
120 static Lisp_Object
xfont_list (Lisp_Object
, Lisp_Object
);
121 static Lisp_Object
xfont_match (Lisp_Object
, Lisp_Object
);
122 static Lisp_Object
xfont_list_family (Lisp_Object
);
123 static Lisp_Object
xfont_open (FRAME_PTR
, Lisp_Object
, int);
124 static void xfont_close (FRAME_PTR
, struct font
*);
125 static int xfont_prepare_face (FRAME_PTR
, struct face
*);
126 static int xfont_has_char (Lisp_Object
, int);
127 static unsigned xfont_encode_char (struct font
*, int);
128 static int xfont_text_extents (struct font
*, unsigned *, int,
129 struct font_metrics
*);
130 static int xfont_draw (struct glyph_string
*, int, int, int, int, int);
131 static int xfont_check (FRAME_PTR
, struct font
*);
133 struct font_driver xfont_driver
=
136 0, /* case insensitive */
150 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
152 NULL
, /* get_variation_glyphs */
153 NULL
, /* filter_properties */
157 xfont_get_cache (FRAME_PTR f
)
159 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
161 return (dpyinfo
->name_list_element
);
165 compare_font_names (const void *name1
, const void *name2
)
167 return xstrcasecmp (*(const unsigned char **) name1
,
168 *(const unsigned char **) name2
);
171 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
172 of the decoding result. LEN is the byte length of XLFD, or -1 if
173 XLFD is NULL terminated. The caller must assure that OUTPUT is at
174 least twice (plus 1) as large as XLFD. */
177 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
179 char *p0
= xlfd
, *p1
= output
;
184 c
= *(unsigned char *) p0
++;
185 p1
+= CHAR_STRING (c
, p1
);
190 return (p1
- output
);
193 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
194 resulting byte length. If XLFD contains unencodable character,
198 xfont_encode_coding_xlfd (char *xlfd
)
200 const unsigned char *p0
= (unsigned char *) xlfd
;
201 unsigned char *p1
= (unsigned char *) xlfd
;
206 int c
= STRING_CHAR_ADVANCE (p0
);
217 /* Check if CHARS (cons or vector) is supported by XFONT whose
218 encoding charset is ENCODING (XFONT is NULL) or by a font whose
219 registry corresponds to ENCODING and REPERTORY.
220 Return 1 if supported, return 0 otherwise. */
223 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
224 struct charset
*encoding
, struct charset
*repertory
)
226 struct charset
*charset
= repertory
? repertory
: encoding
;
230 for (; CONSP (chars
); chars
= XCDR (chars
))
232 int c
= XINT (XCAR (chars
));
233 unsigned code
= ENCODE_CHAR (charset
, c
);
236 if (code
== CHARSET_INVALID_CODE (charset
))
242 char2b
.byte1
= code
>> 8;
243 char2b
.byte2
= code
& 0xFF;
244 if (! xfont_get_pcm (xfont
, &char2b
))
247 return (NILP (chars
));
249 else if (VECTORP (chars
))
253 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
255 int c
= XINT (AREF (chars
, i
));
256 unsigned code
= ENCODE_CHAR (charset
, c
);
259 if (code
== CHARSET_INVALID_CODE (charset
))
265 char2b
.byte1
= code
>> 8;
266 char2b
.byte2
= code
& 0xFF;
267 if (xfont_get_pcm (xfont
, &char2b
))
275 /* A hash table recoding which font supports which scritps. Each key
276 is a vector of characteristic font propertis FOUNDRY to WIDTH and
277 ADDSTYLE, and each value is a list of script symbols.
279 We assume that fonts that have the same value in the above
280 properties supports the same set of characters on all displays. */
282 static Lisp_Object xfont_scripts_cache
;
284 /* Re-usable vector to store characteristic font properites. */
285 static Lisp_Object xfont_scratch_props
;
287 /* Return a list of scripts supported by the font of FONTNAME whose
288 characteristic properties are in PROPS and whose encoding charset
289 is ENCODING. A caller must call BLOCK_INPUT in advance. */
292 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
293 struct charset
*encoding
)
297 /* Two special cases to avoid opening rather big fonts. */
298 if (EQ (AREF (props
, 2), Qja
))
299 return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil
));
300 if (EQ (AREF (props
, 2), Qko
))
301 return Fcons (intern ("hangul"), Qnil
);
302 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
303 if (EQ (scripts
, Qt
))
309 xfont
= XLoadQueryFont (display
, fontname
);
314 for (val
= Vscript_representative_chars
; CONSP (val
);
316 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
318 Lisp_Object script
= XCAR (XCAR (val
));
319 Lisp_Object chars
= XCDR (XCAR (val
));
321 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
322 scripts
= Fcons (script
, scripts
);
325 XFreeFont (display
, xfont
);
327 if (EQ (AREF (props
, 3), Qiso10646_1
)
328 && NILP (Fmemq (Qlatin
, scripts
)))
329 scripts
= Fcons (Qlatin
, scripts
);
330 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
336 xfont_list_pattern (Display
*display
, const char *pattern
,
337 Lisp_Object registry
, Lisp_Object script
)
339 Lisp_Object list
= Qnil
;
340 Lisp_Object chars
= Qnil
;
341 struct charset
*encoding
, *repertory
= NULL
;
342 int i
, limit
, num_fonts
;
344 /* Large enough to decode the longest XLFD (255 bytes). */
347 if (! NILP (registry
)
348 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
349 /* Unknown REGISTRY, not supported. */
353 chars
= assq_no_quit (script
, Vscript_representative_chars
);
355 /* We can't tell whether or not a font supports SCRIPT. */
357 chars
= XCDR (chars
);
360 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
367 x_catch_errors (display
);
369 for (limit
= 512; ; limit
*= 2)
371 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
372 if (x_had_errors_p (display
))
374 /* This error is perhaps due to insufficient memory on X
375 server. Let's just ignore it. */
376 x_clear_errors (display
);
380 if (num_fonts
< limit
)
382 XFreeFontNames (names
);
387 char **indices
= alloca (sizeof (char *) * num_fonts
);
388 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
389 Lisp_Object scripts
= Qnil
;
391 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
393 for (i
= 0; i
< num_fonts
; i
++)
394 indices
[i
] = names
[i
];
395 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
397 for (i
= 0; i
< num_fonts
; i
++)
401 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
403 entity
= font_make_entity ();
404 xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
405 if (font_parse_xlfd (buf
, 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
]) >= 0)
442 /* Avoid fonts of invalid registry. */
443 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
446 /* Update encoding and repertory if necessary. */
447 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
449 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
450 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
454 /* Unknown REGISTRY, not supported. */
459 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
460 list
= Fcons (entity
, list
);
463 if (memcmp (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
464 sizeof (Lisp_Object
) * 7)
465 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
467 memcpy (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
468 sizeof (Lisp_Object
) * 7);
469 props
[7] = AREF (entity
, FONT_SPACING_INDEX
);
470 scripts
= xfont_supported_scripts (display
, indices
[i
],
471 xfont_scratch_props
, encoding
);
474 || ! NILP (Fmemq (script
, scripts
)))
475 list
= Fcons (entity
, list
);
477 XFreeFontNames (names
);
483 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
488 xfont_list (Lisp_Object frame
, Lisp_Object spec
)
490 FRAME_PTR f
= XFRAME (frame
);
491 Display
*display
= FRAME_X_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
, (char *) SDATA (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 (Lisp_Object frame
, Lisp_Object spec
)
569 FRAME_PTR f
= XFRAME (frame
);
570 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
571 Lisp_Object extra
, val
, entity
;
576 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
577 val
= assq_no_quit (QCname
, extra
);
578 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
580 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
583 else if (SBYTES (XCDR (val
)) < 512)
584 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
587 if (xfont_encode_coding_xlfd (name
) < 0)
592 xfont
= XLoadQueryFont (display
, name
);
595 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
600 s
= (char *) XGetAtomName (display
, (Atom
) value
);
603 /* If DXPC (a Differential X Protocol Compressor)
604 Ver.3.7 is running, XGetAtomName will return null
605 string. We must avoid such a name. */
608 entity
= font_make_entity ();
609 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
610 xfont_decode_coding_xlfd (s
, -1, name
);
611 if (font_parse_xlfd (name
, entity
) < 0)
616 XFreeFont (display
, xfont
);
620 FONT_ADD_LOG ("xfont-match", spec
, entity
);
625 xfont_list_family (Lisp_Object frame
)
627 FRAME_PTR f
= XFRAME (frame
);
628 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
636 x_catch_errors (dpyinfo
->display
);
637 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
639 if (x_had_errors_p (dpyinfo
->display
))
641 /* This error is perhaps due to insufficient memory on X server.
642 Let's just ignore it. */
643 x_clear_errors (dpyinfo
->display
);
648 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
650 char *p0
= names
[i
], *p1
, buf
[512];
654 p0
++; /* skip the leading '-' */
655 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
659 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
660 if (! *p1
|| p1
== p0
)
662 if (last_len
== p1
- p0
663 && memcmp (last_family
, p0
, last_len
) == 0)
668 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
669 family
= font_intern_prop (p0
, decoded_len
, 1);
670 if (NILP (assq_no_quit (family
, list
)))
671 list
= Fcons (family
, list
);
674 XFreeFontNames (names
);
682 xfont_open (FRAME_PTR f
, Lisp_Object entity
, int pixel_size
)
684 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
685 Display
*display
= dpyinfo
->display
;
689 Lisp_Object registry
;
690 struct charset
*encoding
, *repertory
;
691 Lisp_Object font_object
, fullname
;
695 /* At first, check if we know how to encode characters for this
697 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
698 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
700 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
704 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
705 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
706 else if (pixel_size
== 0)
709 pixel_size
= FRAME_FONT (f
)->pixel_size
;
713 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
714 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
716 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
721 x_catch_errors (display
);
722 xfont
= XLoadQueryFont (display
, name
);
723 if (x_had_errors_p (display
))
725 /* This error is perhaps due to insufficient memory on X server.
726 Let's just ignore it. */
727 x_clear_errors (display
);
732 /* Some version of X lists:
733 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
734 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
736 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
738 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
739 So, we try again with wildcards in RESX and RESY. */
742 temp
= Fcopy_font_spec (entity
);
743 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
744 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
745 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
747 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
750 xfont
= XLoadQueryFont (display
, name
);
751 if (x_had_errors_p (display
))
753 /* This error is perhaps due to insufficient memory on X server.
754 Let's just ignore it. */
755 x_clear_errors (display
);
760 /* Try to get the full name of FONT. */
761 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
766 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
767 /* Count the number of dashes in the "full name".
768 If it is too few, this isn't really the font's full name,
770 In X11R4, the fonts did not come with their canonical names
781 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
782 fullname
= Fdowncase (make_string (name
, len
));
791 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
795 font_object
= font_make_object (VECSIZE (struct xfont_info
),
797 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
798 if (STRINGP (fullname
))
800 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
801 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
807 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
808 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
810 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
811 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
812 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
813 font
= XFONT_OBJECT (font_object
);
814 ((struct xfont_info
*) font
)->xfont
= xfont
;
815 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
816 font
->pixel_size
= pixel_size
;
817 font
->driver
= &xfont_driver
;
818 font
->encoding_charset
= encoding
->id
;
819 font
->repertory_charset
= repertory
? repertory
->id
: -1;
820 font
->ascent
= xfont
->ascent
;
821 font
->descent
= xfont
->descent
;
822 font
->height
= font
->ascent
+ font
->descent
;
823 font
->min_width
= xfont
->min_bounds
.width
;
824 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
826 /* Fixed width font. */
827 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
835 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
836 pcm
= xfont_get_pcm (xfont
, &char2b
);
838 font
->space_width
= pcm
->width
;
840 font
->space_width
= 0;
842 val
= Ffont_get (font_object
, QCavgwidth
);
844 font
->average_width
= XINT (val
) / 10;
845 if (font
->average_width
< 0)
846 font
->average_width
= - font
->average_width
;
847 if (font
->average_width
== 0
848 && encoding
->ascii_compatible_p
)
850 int width
= font
->space_width
, n
= pcm
!= NULL
;
852 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
853 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
854 width
+= pcm
->width
, n
++;
856 font
->average_width
= width
/ n
;
858 if (font
->average_width
== 0)
859 /* No easy way other than this to get a reasonable
862 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
866 font
->underline_thickness
867 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
869 font
->underline_position
870 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
871 ? (long) value
: -1);
872 font
->baseline_offset
873 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
875 font
->relative_compose
876 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
879 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
884 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
885 font
->vertical_centering
886 = (STRINGP (Vvertical_centering_font_regexp
)
887 && (fast_string_match_ignore_case
888 (Vvertical_centering_font_regexp
, fullname
) >= 0));
894 xfont_close (FRAME_PTR f
, struct font
*font
)
897 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
902 xfont_prepare_face (FRAME_PTR f
, struct face
*face
)
905 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
906 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
913 xfont_has_char (Lisp_Object font
, int c
)
915 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
916 struct charset
*encoding
;
917 struct charset
*repertory
= NULL
;
919 if (EQ (registry
, Qiso10646_1
))
921 encoding
= CHARSET_FROM_ID (charset_unicode
);
922 /* We use a font of `ja' and `ko' adstyle only for a character
923 in JISX0208 and KSC5601 charsets respectively. */
924 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
925 && charset_jisx0208
>= 0)
926 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
927 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
928 && charset_ksc5601
>= 0)
929 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
931 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
932 /* Unknown REGISTRY, not usable. */
934 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
938 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
942 xfont_encode_char (struct font
*font
, int c
)
944 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
945 struct charset
*charset
;
949 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
950 code
= ENCODE_CHAR (charset
, c
);
951 if (code
== CHARSET_INVALID_CODE (charset
))
952 return FONT_INVALID_CODE
;
953 if (font
->repertory_charset
>= 0)
955 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
956 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
957 ? code
: FONT_INVALID_CODE
);
959 char2b
.byte1
= code
>> 8;
960 char2b
.byte2
= code
& 0xFF;
961 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
965 xfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
967 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
972 memset (metrics
, 0, sizeof (struct font_metrics
));
973 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
976 static XCharStruct
*pcm
;
978 if (code
[i
] >= 0x10000)
980 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
981 pcm
= xfont_get_pcm (xfont
, &char2b
);
988 metrics
->lbearing
= pcm
->lbearing
;
989 metrics
->rbearing
= pcm
->rbearing
;
990 metrics
->ascent
= pcm
->ascent
;
991 metrics
->descent
= pcm
->descent
;
999 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1000 metrics
->lbearing
= width
+ pcm
->lbearing
;
1001 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1002 metrics
->rbearing
= width
+ pcm
->rbearing
;
1003 if (metrics
->ascent
< pcm
->ascent
)
1004 metrics
->ascent
= pcm
->ascent
;
1005 if (metrics
->descent
< pcm
->descent
)
1006 metrics
->descent
= pcm
->descent
;
1009 width
+= pcm
->width
;
1012 metrics
->width
= width
;
1017 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
, int with_background
)
1019 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1020 int len
= to
- from
;
1024 if (s
->gc
!= s
->face
->gc
)
1027 XSetFont (s
->display
, gc
, xfont
->fid
);
1031 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1036 SAFE_ALLOCA (str
, char *, len
);
1037 for (i
= 0; i
< len
; i
++)
1038 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1040 if (with_background
> 0)
1043 for (i
= 0; i
< len
; i
++)
1044 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1045 gc
, x
+ i
, y
, str
+ i
, 1);
1047 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1048 gc
, x
, y
, str
, len
);
1053 for (i
= 0; i
< len
; i
++)
1054 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1055 gc
, x
+ i
, y
, str
+ i
, 1);
1057 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1058 gc
, x
, y
, str
, len
);
1066 if (with_background
> 0)
1069 for (i
= 0; i
< len
; i
++)
1070 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1071 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1073 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1074 gc
, x
, y
, s
->char2b
+ from
, len
);
1079 for (i
= 0; i
< len
; i
++)
1080 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1081 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1083 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1084 gc
, x
, y
, s
->char2b
+ from
, len
);
1092 xfont_check (FRAME_PTR f
, struct font
*font
)
1094 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1096 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1101 syms_of_xfont (void)
1103 staticpro (&xfont_scripts_cache
);
1104 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1105 is called fairly late, when QCtest and Qequal are known to be set. */
1106 Lisp_Object args
[2];
1109 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1111 staticpro (&xfont_scratch_props
);
1112 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1113 xfont_driver
.type
= Qx
;
1114 register_font_driver (&xfont_driver
, NULL
);
1117 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1118 (do not change this comment) */