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/>. */
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 (Display
*);
52 static XCharStruct
*xfont_get_pcm (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 (XFontStruct
*xfont
, XChar2b
*char2b
)
60 /* The result metric information. */
61 XCharStruct
*pcm
= NULL
;
63 font_assert (xfont
&& char2b
);
65 if (xfont
->per_char
!= NULL
)
67 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
69 /* min_char_or_byte2 specifies the linear character index
70 corresponding to the first element of the per_char array,
71 max_char_or_byte2 is the index of the last character. A
72 character with non-zero CHAR2B->byte1 is not in the font.
73 A character with byte2 less than min_char_or_byte2 or
74 greater max_char_or_byte2 is not in the font. */
75 if (char2b
->byte1
== 0
76 && char2b
->byte2
>= xfont
->min_char_or_byte2
77 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
78 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
82 /* If either min_byte1 or max_byte1 are nonzero, both
83 min_char_or_byte2 and max_char_or_byte2 are less than
84 256, and the 2-byte character index values corresponding
85 to the per_char array element N (counting from 0) are:
87 byte1 = N/D + min_byte1
88 byte2 = N\D + min_char_or_byte2
92 D = max_char_or_byte2 - min_char_or_byte2 + 1
94 \ = integer modulus */
95 if (char2b
->byte1
>= xfont
->min_byte1
96 && char2b
->byte1
<= xfont
->max_byte1
97 && char2b
->byte2
>= xfont
->min_char_or_byte2
98 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
99 pcm
= (xfont
->per_char
100 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
101 * (char2b
->byte1
- xfont
->min_byte1
))
102 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
107 /* If the per_char pointer is null, all glyphs between the first
108 and last character indexes inclusive have the same
109 information, as given by both min_bounds and max_bounds. */
110 if (char2b
->byte2
>= xfont
->min_char_or_byte2
111 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
112 pcm
= &xfont
->max_bounds
;
116 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
120 static Lisp_Object
xfont_get_cache (FRAME_PTR
);
121 static Lisp_Object
xfont_list (Lisp_Object
, Lisp_Object
);
122 static Lisp_Object
xfont_match (Lisp_Object
, Lisp_Object
);
123 static Lisp_Object
xfont_list_family (Lisp_Object
);
124 static Lisp_Object
xfont_open (FRAME_PTR
, Lisp_Object
, int);
125 static void xfont_close (FRAME_PTR
, struct font
*);
126 static int xfont_prepare_face (FRAME_PTR
, struct face
*);
127 static int xfont_has_char (Lisp_Object
, int);
128 static unsigned xfont_encode_char (struct font
*, int);
129 static int xfont_text_extents (struct font
*, unsigned *, int,
130 struct font_metrics
*);
131 static int xfont_draw (struct glyph_string
*, int, int, int, int, int);
132 static int xfont_check (FRAME_PTR
, struct font
*);
134 struct font_driver xfont_driver
=
137 0, /* case insensitive */
151 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
153 NULL
, /* get_variation_glyphs */
154 NULL
, /* filter_properties */
157 extern Lisp_Object QCname
;
160 xfont_get_cache (FRAME_PTR f
)
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 (Lisp_Object frame
, Lisp_Object spec
)
499 FRAME_PTR f
= XFRAME (frame
);
500 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
501 Lisp_Object registry
, list
, val
, extra
, script
;
503 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
506 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
509 val
= assq_no_quit (QCotf
, extra
);
512 val
= assq_no_quit (QClang
, extra
);
517 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
518 len
= font_unparse_xlfd (spec
, 0, name
, 512);
519 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
522 val
= assq_no_quit (QCscript
, extra
);
524 list
= xfont_list_pattern (display
, name
, registry
, script
);
525 if (NILP (list
) && NILP (registry
))
528 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
530 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
532 strcpy (r
, "iso10646-1");
533 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
536 if (NILP (list
) && ! NILP (registry
))
538 /* Try alternate registries. */
541 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
542 Vface_alternative_font_registry_alist
),
545 /* Pointer to REGISTRY-ENCODING field. */
546 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
548 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
549 if (STRINGP (XCAR (alter
))
550 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
552 strcpy (r
, (char *) SDATA (XCAR (alter
)));
553 list
= xfont_list_pattern (display
, name
, registry
, script
);
562 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
563 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
565 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
566 if (xfont_encode_coding_xlfd (name
) < 0)
568 list
= xfont_list_pattern (display
, name
, registry
, script
);
576 xfont_match (Lisp_Object frame
, Lisp_Object spec
)
578 FRAME_PTR f
= XFRAME (frame
);
579 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
580 Lisp_Object extra
, val
, entity
;
585 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
586 val
= assq_no_quit (QCname
, extra
);
587 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
589 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
592 else if (SBYTES (XCDR (val
)) < 512)
593 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
596 if (xfont_encode_coding_xlfd (name
) < 0)
601 xfont
= XLoadQueryFont (display
, name
);
604 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
609 s
= (char *) XGetAtomName (display
, (Atom
) value
);
612 /* If DXPC (a Differential X Protocol Compressor)
613 Ver.3.7 is running, XGetAtomName will return null
614 string. We must avoid such a name. */
617 entity
= font_make_entity ();
618 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
619 xfont_decode_coding_xlfd (s
, -1, name
);
620 if (font_parse_xlfd (name
, entity
) < 0)
625 XFreeFont (display
, xfont
);
629 FONT_ADD_LOG ("xfont-match", spec
, entity
);
634 xfont_list_family (Lisp_Object frame
)
636 FRAME_PTR f
= XFRAME (frame
);
637 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
645 x_catch_errors (dpyinfo
->display
);
646 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
648 if (x_had_errors_p (dpyinfo
->display
))
650 /* This error is perhaps due to insufficient memory on X server.
651 Let's just ignore it. */
652 x_clear_errors (dpyinfo
->display
);
657 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
659 char *p0
= names
[i
], *p1
, buf
[512];
663 p0
++; /* skip the leading '-' */
664 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
668 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
669 if (! *p1
|| p1
== p0
)
671 if (last_len
== p1
- p0
672 && memcmp (last_family
, p0
, last_len
) == 0)
677 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
678 family
= font_intern_prop (p0
, decoded_len
, 1);
679 if (NILP (assq_no_quit (family
, list
)))
680 list
= Fcons (family
, list
);
683 XFreeFontNames (names
);
690 extern Lisp_Object QCavgwidth
;
693 xfont_open (FRAME_PTR f
, Lisp_Object entity
, int pixel_size
)
695 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
696 Display
*display
= dpyinfo
->display
;
700 Lisp_Object registry
;
701 struct charset
*encoding
, *repertory
;
702 Lisp_Object font_object
, fullname
;
706 /* At first, check if we know how to encode characters for this
708 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
709 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
711 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
715 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
716 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
717 else if (pixel_size
== 0)
720 pixel_size
= FRAME_FONT (f
)->pixel_size
;
724 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
725 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
727 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
732 x_catch_errors (display
);
733 xfont
= XLoadQueryFont (display
, name
);
734 if (x_had_errors_p (display
))
736 /* This error is perhaps due to insufficient memory on X server.
737 Let's just ignore it. */
738 x_clear_errors (display
);
743 /* Some version of X lists:
744 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
745 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
747 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
749 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
750 So, we try again with wildcards in RESX and RESY. */
753 temp
= Fcopy_font_spec (entity
);
754 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
755 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
756 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
758 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
761 xfont
= XLoadQueryFont (display
, name
);
762 if (x_had_errors_p (display
))
764 /* This error is perhaps due to insufficient memory on X server.
765 Let's just ignore it. */
766 x_clear_errors (display
);
771 /* Try to get the full name of FONT. */
772 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
777 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
778 /* Count the number of dashes in the "full name".
779 If it is too few, this isn't really the font's full name,
781 In X11R4, the fonts did not come with their canonical names
792 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
793 fullname
= Fdowncase (make_string (name
, len
));
802 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
806 font_object
= font_make_object (VECSIZE (struct xfont_info
),
808 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
809 if (STRINGP (fullname
))
811 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
812 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
818 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
819 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
821 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
822 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
823 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
824 font
= XFONT_OBJECT (font_object
);
825 ((struct xfont_info
*) font
)->xfont
= xfont
;
826 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
827 font
->pixel_size
= pixel_size
;
828 font
->driver
= &xfont_driver
;
829 font
->encoding_charset
= encoding
->id
;
830 font
->repertory_charset
= repertory
? repertory
->id
: -1;
831 font
->ascent
= xfont
->ascent
;
832 font
->descent
= xfont
->descent
;
833 font
->height
= font
->ascent
+ font
->descent
;
834 font
->min_width
= xfont
->min_bounds
.width
;
835 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
837 /* Fixed width font. */
838 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
846 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
847 pcm
= xfont_get_pcm (xfont
, &char2b
);
849 font
->space_width
= pcm
->width
;
851 font
->space_width
= 0;
853 val
= Ffont_get (font_object
, QCavgwidth
);
855 font
->average_width
= XINT (val
);
856 if (font
->average_width
< 0)
857 font
->average_width
= - font
->average_width
;
858 if (font
->average_width
== 0
859 && encoding
->ascii_compatible_p
)
861 int width
= font
->space_width
, n
= pcm
!= NULL
;
863 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
864 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
865 width
+= pcm
->width
, n
++;
867 font
->average_width
= width
/ n
;
869 if (font
->average_width
== 0)
870 /* No easy way other than this to get a reasonable
873 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
877 font
->underline_thickness
878 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
880 font
->underline_position
881 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
882 ? (long) value
: -1);
883 font
->baseline_offset
884 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
886 font
->relative_compose
887 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
890 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
895 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
896 font
->vertical_centering
897 = (STRINGP (Vvertical_centering_font_regexp
)
898 && (fast_string_match_ignore_case
899 (Vvertical_centering_font_regexp
, fullname
) >= 0));
905 xfont_close (FRAME_PTR f
, struct font
*font
)
908 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
913 xfont_prepare_face (FRAME_PTR f
, struct face
*face
)
916 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
917 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
924 xfont_has_char (Lisp_Object font
, int c
)
926 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
927 struct charset
*encoding
;
928 struct charset
*repertory
= NULL
;
930 if (EQ (registry
, Qiso10646_1
))
932 encoding
= CHARSET_FROM_ID (charset_unicode
);
933 /* We use a font of `ja' and `ko' adstyle only for a character
934 in JISX0208 and KSC5601 charsets respectively. */
935 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
936 && charset_jisx0208
>= 0)
937 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
938 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
939 && charset_ksc5601
>= 0)
940 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
942 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
943 /* Unknown REGISTRY, not usable. */
945 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
949 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
953 xfont_encode_char (struct font
*font
, int c
)
955 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
956 struct charset
*charset
;
960 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
961 code
= ENCODE_CHAR (charset
, c
);
962 if (code
== CHARSET_INVALID_CODE (charset
))
963 return FONT_INVALID_CODE
;
964 if (font
->repertory_charset
>= 0)
966 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
967 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
968 ? code
: FONT_INVALID_CODE
);
970 char2b
.byte1
= code
>> 8;
971 char2b
.byte2
= code
& 0xFF;
972 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
976 xfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
978 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
983 memset (metrics
, 0, sizeof (struct font_metrics
));
984 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
987 static XCharStruct
*pcm
;
989 if (code
[i
] >= 0x10000)
991 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
992 pcm
= xfont_get_pcm (xfont
, &char2b
);
999 metrics
->lbearing
= pcm
->lbearing
;
1000 metrics
->rbearing
= pcm
->rbearing
;
1001 metrics
->ascent
= pcm
->ascent
;
1002 metrics
->descent
= pcm
->descent
;
1010 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1011 metrics
->lbearing
= width
+ pcm
->lbearing
;
1012 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1013 metrics
->rbearing
= width
+ pcm
->rbearing
;
1014 if (metrics
->ascent
< pcm
->ascent
)
1015 metrics
->ascent
= pcm
->ascent
;
1016 if (metrics
->descent
< pcm
->descent
)
1017 metrics
->descent
= pcm
->descent
;
1020 width
+= pcm
->width
;
1023 metrics
->width
= width
;
1028 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
, int with_background
)
1030 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1031 int len
= to
- from
;
1035 if (s
->gc
!= s
->face
->gc
)
1038 XSetFont (s
->display
, gc
, xfont
->fid
);
1042 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1047 SAFE_ALLOCA (str
, char *, len
);
1048 for (i
= 0; i
< len
; i
++)
1049 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1051 if (with_background
> 0)
1054 for (i
= 0; i
< len
; i
++)
1055 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1056 gc
, x
+ i
, y
, str
+ i
, 1);
1058 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1059 gc
, x
, y
, str
, len
);
1064 for (i
= 0; i
< len
; i
++)
1065 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1066 gc
, x
+ i
, y
, str
+ i
, 1);
1068 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1069 gc
, x
, y
, str
, len
);
1077 if (with_background
> 0)
1080 for (i
= 0; i
< len
; i
++)
1081 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1082 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1084 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1085 gc
, x
, y
, s
->char2b
+ from
, len
);
1090 for (i
= 0; i
< len
; i
++)
1091 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1092 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1094 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1095 gc
, x
, y
, s
->char2b
+ from
, len
);
1103 xfont_check (FRAME_PTR f
, struct font
*font
)
1105 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1107 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1112 syms_of_xfont (void)
1114 staticpro (&xfont_scripts_cache
);
1115 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1116 is called fairly late, when QCtest and Qequal are known to be set. */
1117 Lisp_Object args
[2];
1120 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1122 staticpro (&xfont_scratch_props
);
1123 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1124 xfont_driver
.type
= Qx
;
1125 register_font_driver (&xfont_driver
, NULL
);
1128 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1129 (do not change this comment) */