1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006-2012 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
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
=
135 LISP_INITIALLY_ZERO
, /* Qx */
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 char *const *n1
= name1
;
168 char *const *n2
= name2
;
169 return xstrcasecmp (*n1
, *n2
);
172 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
173 of the decoding result. LEN is the byte length of XLFD, or -1 if
174 XLFD is NULL terminated. The caller must assure that OUTPUT is at
175 least twice (plus 1) as large as XLFD. */
178 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
180 char *p0
= xlfd
, *p1
= output
;
185 c
= *(unsigned char *) p0
++;
186 p1
+= CHAR_STRING (c
, (unsigned char *) p1
);
191 return (p1
- output
);
194 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
195 resulting byte length. If XLFD contains unencodable character,
199 xfont_encode_coding_xlfd (char *xlfd
)
201 const unsigned char *p0
= (unsigned char *) xlfd
;
202 unsigned char *p1
= (unsigned char *) xlfd
;
207 int c
= STRING_CHAR_ADVANCE (p0
);
218 /* Check if CHARS (cons or vector) is supported by XFONT whose
219 encoding charset is ENCODING (XFONT is NULL) or by a font whose
220 registry corresponds to ENCODING and REPERTORY.
221 Return 1 if supported, return 0 otherwise. */
224 xfont_chars_supported (Lisp_Object chars
, XFontStruct
*xfont
,
225 struct charset
*encoding
, struct charset
*repertory
)
227 struct charset
*charset
= repertory
? repertory
: encoding
;
231 for (; CONSP (chars
); chars
= XCDR (chars
))
233 int c
= XINT (XCAR (chars
));
234 unsigned code
= ENCODE_CHAR (charset
, c
);
237 if (code
== CHARSET_INVALID_CODE (charset
))
243 char2b
.byte1
= code
>> 8;
244 char2b
.byte2
= code
& 0xFF;
245 if (! xfont_get_pcm (xfont
, &char2b
))
248 return (NILP (chars
));
250 else if (VECTORP (chars
))
254 for (i
= ASIZE (chars
) - 1; i
>= 0; i
--)
256 int c
= XINT (AREF (chars
, i
));
257 unsigned code
= ENCODE_CHAR (charset
, c
);
260 if (code
== CHARSET_INVALID_CODE (charset
))
266 char2b
.byte1
= code
>> 8;
267 char2b
.byte2
= code
& 0xFF;
268 if (xfont_get_pcm (xfont
, &char2b
))
276 /* A hash table recoding which font supports which scripts. Each key
277 is a vector of characteristic font properties FOUNDRY to WIDTH and
278 ADDSTYLE, and each value is a list of script symbols.
280 We assume that fonts that have the same value in the above
281 properties supports the same set of characters on all displays. */
283 static Lisp_Object xfont_scripts_cache
;
285 /* Re-usable vector to store characteristic font properties. */
286 static Lisp_Object xfont_scratch_props
;
288 /* Return a list of scripts supported by the font of FONTNAME whose
289 characteristic properties are in PROPS and whose encoding charset
290 is ENCODING. A caller must call BLOCK_INPUT in advance. */
293 xfont_supported_scripts (Display
*display
, char *fontname
, Lisp_Object props
,
294 struct charset
*encoding
)
298 /* Two special cases to avoid opening rather big fonts. */
299 if (EQ (AREF (props
, 2), Qja
))
300 return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil
));
301 if (EQ (AREF (props
, 2), Qko
))
302 return Fcons (intern ("hangul"), Qnil
);
303 scripts
= Fgethash (props
, xfont_scripts_cache
, Qt
);
304 if (EQ (scripts
, Qt
))
310 xfont
= XLoadQueryFont (display
, fontname
);
315 for (val
= Vscript_representative_chars
; CONSP (val
);
317 if (CONSP (XCAR (val
)) && SYMBOLP (XCAR (XCAR (val
))))
319 Lisp_Object script
= XCAR (XCAR (val
));
320 Lisp_Object chars
= XCDR (XCAR (val
));
322 if (xfont_chars_supported (chars
, xfont
, encoding
, NULL
))
323 scripts
= Fcons (script
, scripts
);
326 XFreeFont (display
, xfont
);
328 if (EQ (AREF (props
, 3), Qiso10646_1
)
329 && NILP (Fmemq (Qlatin
, scripts
)))
330 scripts
= Fcons (Qlatin
, scripts
);
331 Fputhash (Fcopy_sequence (props
), scripts
, xfont_scripts_cache
);
337 xfont_list_pattern (Display
*display
, const char *pattern
,
338 Lisp_Object registry
, Lisp_Object script
)
340 Lisp_Object list
= Qnil
;
341 Lisp_Object chars
= Qnil
;
342 struct charset
*encoding
, *repertory
= NULL
;
343 int i
, limit
, num_fonts
;
345 /* Large enough to decode the longest XLFD (255 bytes). */
348 if (! NILP (registry
)
349 && font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
350 /* Unknown REGISTRY, not supported. */
354 chars
= assq_no_quit (script
, Vscript_representative_chars
);
356 /* We can't tell whether or not a font supports SCRIPT. */
358 chars
= XCDR (chars
);
361 if (! xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
368 x_catch_errors (display
);
370 for (limit
= 512; ; limit
*= 2)
372 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
373 if (x_had_errors_p (display
))
375 /* This error is perhaps due to insufficient memory on X
376 server. Let's just ignore it. */
377 x_clear_errors (display
);
381 if (num_fonts
< limit
)
383 XFreeFontNames (names
);
388 char **indices
= alloca (sizeof (char *) * num_fonts
);
389 Lisp_Object
*props
= XVECTOR (xfont_scratch_props
)->contents
;
390 Lisp_Object scripts
= Qnil
;
392 for (i
= 0; i
< ASIZE (xfont_scratch_props
); i
++)
394 for (i
= 0; i
< num_fonts
; i
++)
395 indices
[i
] = names
[i
];
396 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
398 for (i
= 0; i
< num_fonts
; i
++)
402 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
404 entity
= font_make_entity ();
405 xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
406 if (font_parse_xlfd (buf
, entity
) < 0)
408 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
409 /* Avoid auto-scaled fonts. */
410 if (INTEGERP (AREF (entity
, FONT_DPI_INDEX
))
411 && INTEGERP (AREF (entity
, FONT_AVGWIDTH_INDEX
))
412 && XINT (AREF (entity
, FONT_DPI_INDEX
)) != 0
413 && XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) == 0)
415 /* Avoid not-allowed scalable fonts. */
416 if (NILP (Vscalable_fonts_allowed
))
420 if (INTEGERP (AREF (entity
, FONT_SIZE_INDEX
)))
421 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
422 else if (FLOATP (AREF (entity
, FONT_SIZE_INDEX
)))
423 size
= XFLOAT_DATA (AREF (entity
, FONT_SIZE_INDEX
));
427 else if (CONSP (Vscalable_fonts_allowed
))
429 Lisp_Object tail
, elt
;
431 for (tail
= Vscalable_fonts_allowed
; CONSP (tail
);
436 && fast_c_string_match_ignore_case (elt
, indices
[i
]) >= 0)
443 /* Avoid fonts of invalid registry. */
444 if (NILP (AREF (entity
, FONT_REGISTRY_INDEX
)))
447 /* Update encoding and repertory if necessary. */
448 if (! EQ (registry
, AREF (entity
, FONT_REGISTRY_INDEX
)))
450 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
451 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
455 /* Unknown REGISTRY, not supported. */
460 || xfont_chars_supported (chars
, NULL
, encoding
, repertory
))
461 list
= Fcons (entity
, list
);
464 if (memcmp (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
465 sizeof (Lisp_Object
) * 7)
466 || ! EQ (AREF (entity
, FONT_SPACING_INDEX
), props
[7]))
468 memcpy (props
, &(AREF (entity
, FONT_FOUNDRY_INDEX
)),
469 sizeof (Lisp_Object
) * 7);
470 props
[7] = AREF (entity
, FONT_SPACING_INDEX
);
471 scripts
= xfont_supported_scripts (display
, indices
[i
],
472 xfont_scratch_props
, encoding
);
475 || ! NILP (Fmemq (script
, scripts
)))
476 list
= Fcons (entity
, list
);
478 XFreeFontNames (names
);
484 FONT_ADD_LOG ("xfont-list", build_string (pattern
), list
);
489 xfont_list (Lisp_Object frame
, Lisp_Object spec
)
491 FRAME_PTR f
= XFRAME (frame
);
492 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
493 Lisp_Object registry
, list
, val
, extra
, script
;
495 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
498 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
501 val
= assq_no_quit (QCotf
, extra
);
504 val
= assq_no_quit (QClang
, extra
);
509 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
510 len
= font_unparse_xlfd (spec
, 0, name
, 512);
511 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
514 val
= assq_no_quit (QCscript
, extra
);
516 list
= xfont_list_pattern (display
, name
, registry
, script
);
517 if (NILP (list
) && NILP (registry
))
520 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
522 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
524 strcpy (r
, "iso10646-1");
525 list
= xfont_list_pattern (display
, name
, Qiso10646_1
, script
);
528 if (NILP (list
) && ! NILP (registry
))
530 /* Try alternate registries. */
533 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
534 Vface_alternative_font_registry_alist
),
537 /* Pointer to REGISTRY-ENCODING field. */
538 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
540 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
541 if (STRINGP (XCAR (alter
))
542 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
544 strcpy (r
, SSDATA (XCAR (alter
)));
545 list
= xfont_list_pattern (display
, name
, registry
, script
);
554 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
555 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
557 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
558 if (xfont_encode_coding_xlfd (name
) < 0)
560 list
= xfont_list_pattern (display
, name
, registry
, script
);
568 xfont_match (Lisp_Object frame
, Lisp_Object spec
)
570 FRAME_PTR f
= XFRAME (frame
);
571 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
572 Lisp_Object extra
, val
, entity
;
577 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
578 val
= assq_no_quit (QCname
, extra
);
579 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
581 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
584 else if (SBYTES (XCDR (val
)) < 512)
585 memcpy (name
, SDATA (XCDR (val
)), SBYTES (XCDR (val
)) + 1);
588 if (xfont_encode_coding_xlfd (name
) < 0)
593 xfont
= XLoadQueryFont (display
, name
);
596 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
600 s
= (char *) XGetAtomName (display
, (Atom
) value
);
602 /* If DXPC (a Differential X Protocol Compressor)
603 Ver.3.7 is running, XGetAtomName will return null
604 string. We must avoid such a name. */
607 entity
= font_make_entity ();
608 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
609 xfont_decode_coding_xlfd (s
, -1, name
);
610 if (font_parse_xlfd (name
, entity
) < 0)
615 XFreeFont (display
, xfont
);
619 FONT_ADD_LOG ("xfont-match", spec
, entity
);
624 xfont_list_family (Lisp_Object frame
)
626 FRAME_PTR f
= XFRAME (frame
);
627 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
631 char *last_family
IF_LINT (= 0);
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 && memcmp (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
);
681 xfont_open (FRAME_PTR f
, Lisp_Object entity
, int pixel_size
)
683 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
684 Display
*display
= dpyinfo
->display
;
688 Lisp_Object registry
;
689 struct charset
*encoding
, *repertory
;
690 Lisp_Object font_object
, fullname
;
694 /* At first, check if we know how to encode characters for this
696 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
697 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
699 FONT_ADD_LOG (" x:unknown registry", registry
, Qnil
);
703 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
704 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
705 else if (pixel_size
== 0)
708 pixel_size
= FRAME_FONT (f
)->pixel_size
;
712 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
713 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
715 FONT_ADD_LOG (" x:unparse failed", entity
, Qnil
);
720 x_catch_errors (display
);
721 xfont
= XLoadQueryFont (display
, name
);
722 if (x_had_errors_p (display
))
724 /* This error is perhaps due to insufficient memory on X server.
725 Let's just ignore it. */
726 x_clear_errors (display
);
731 /* Some version of X lists:
732 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
733 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
735 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
737 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
738 So, we try again with wildcards in RESX and RESY. */
741 temp
= copy_font_spec (entity
);
742 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
743 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
744 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
746 FONT_ADD_LOG (" x:unparse failed", temp
, Qnil
);
749 xfont
= XLoadQueryFont (display
, name
);
750 if (x_had_errors_p (display
))
752 /* This error is perhaps due to insufficient memory on X server.
753 Let's just ignore it. */
754 x_clear_errors (display
);
759 /* Try to get the full name of FONT. */
760 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
765 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
766 /* Count the number of dashes in the "full name".
767 If it is too few, this isn't really the font's full name,
769 In X11R4, the fonts did not come with their canonical names
780 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
781 fullname
= Fdowncase (make_string (name
, len
));
790 FONT_ADD_LOG (" x:open failed", build_string (name
), Qnil
);
794 font_object
= font_make_object (VECSIZE (struct xfont_info
),
796 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
797 if (STRINGP (fullname
))
799 font_parse_xlfd (SSDATA (fullname
), font_object
);
800 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
806 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
807 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
809 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
810 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
811 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
812 font
= XFONT_OBJECT (font_object
);
813 ((struct xfont_info
*) font
)->xfont
= xfont
;
814 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
815 font
->pixel_size
= pixel_size
;
816 font
->driver
= &xfont_driver
;
817 font
->encoding_charset
= encoding
->id
;
818 font
->repertory_charset
= repertory
? repertory
->id
: -1;
819 font
->ascent
= xfont
->ascent
;
820 font
->descent
= xfont
->descent
;
821 font
->height
= font
->ascent
+ font
->descent
;
822 font
->min_width
= xfont
->min_bounds
.width
;
823 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
825 /* Fixed width font. */
826 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
834 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
835 pcm
= xfont_get_pcm (xfont
, &char2b
);
837 font
->space_width
= pcm
->width
;
839 font
->space_width
= 0;
841 val
= Ffont_get (font_object
, QCavgwidth
);
843 font
->average_width
= XINT (val
) / 10;
844 if (font
->average_width
< 0)
845 font
->average_width
= - font
->average_width
;
848 if (font
->average_width
== 0
849 && encoding
->ascii_compatible_p
)
851 int width
= font
->space_width
, n
= pcm
!= NULL
;
853 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
854 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
855 width
+= pcm
->width
, n
++;
857 font
->average_width
= width
/ n
;
859 if (font
->average_width
== 0)
860 /* No easy way other than this to get a reasonable
863 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
868 font
->underline_thickness
869 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
871 font
->underline_position
872 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
873 ? (long) value
: -1);
874 font
->baseline_offset
875 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
877 font
->relative_compose
878 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
881 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
886 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
887 font
->vertical_centering
888 = (STRINGP (Vvertical_centering_font_regexp
)
889 && (fast_string_match_ignore_case
890 (Vvertical_centering_font_regexp
, fullname
) >= 0));
896 xfont_close (FRAME_PTR f
, struct font
*font
)
899 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
904 xfont_prepare_face (FRAME_PTR f
, struct face
*face
)
907 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
908 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
915 xfont_has_char (Lisp_Object font
, int c
)
917 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
918 struct charset
*encoding
;
919 struct charset
*repertory
= NULL
;
921 if (EQ (registry
, Qiso10646_1
))
923 encoding
= CHARSET_FROM_ID (charset_unicode
);
924 /* We use a font of `ja' and `ko' adstyle only for a character
925 in JISX0208 and KSC5601 charsets respectively. */
926 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
927 && charset_jisx0208
>= 0)
928 repertory
= CHARSET_FROM_ID (charset_jisx0208
);
929 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
930 && charset_ksc5601
>= 0)
931 repertory
= CHARSET_FROM_ID (charset_ksc5601
);
933 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
934 /* Unknown REGISTRY, not usable. */
936 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
940 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
944 xfont_encode_char (struct font
*font
, int c
)
946 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
947 struct charset
*charset
;
951 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
952 code
= ENCODE_CHAR (charset
, c
);
953 if (code
== CHARSET_INVALID_CODE (charset
))
954 return FONT_INVALID_CODE
;
955 if (font
->repertory_charset
>= 0)
957 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
958 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
959 ? code
: FONT_INVALID_CODE
);
961 char2b
.byte1
= code
>> 8;
962 char2b
.byte2
= code
& 0xFF;
963 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
967 xfont_text_extents (struct font
*font
, unsigned int *code
, int nglyphs
, struct font_metrics
*metrics
)
969 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
974 memset (metrics
, 0, sizeof (struct font_metrics
));
975 for (i
= 0, first
= 1; i
< nglyphs
; i
++)
978 static XCharStruct
*pcm
;
980 if (code
[i
] >= 0x10000)
982 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
983 pcm
= xfont_get_pcm (xfont
, &char2b
);
990 metrics
->lbearing
= pcm
->lbearing
;
991 metrics
->rbearing
= pcm
->rbearing
;
992 metrics
->ascent
= pcm
->ascent
;
993 metrics
->descent
= pcm
->descent
;
1001 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
1002 metrics
->lbearing
= width
+ pcm
->lbearing
;
1003 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
1004 metrics
->rbearing
= width
+ pcm
->rbearing
;
1005 if (metrics
->ascent
< pcm
->ascent
)
1006 metrics
->ascent
= pcm
->ascent
;
1007 if (metrics
->descent
< pcm
->descent
)
1008 metrics
->descent
= pcm
->descent
;
1011 width
+= pcm
->width
;
1014 metrics
->width
= width
;
1019 xfont_draw (struct glyph_string
*s
, int from
, int to
, int x
, int y
, int with_background
)
1021 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
1022 int len
= to
- from
;
1026 if (s
->gc
!= s
->face
->gc
)
1029 XSetFont (s
->display
, gc
, xfont
->fid
);
1033 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
1038 SAFE_ALLOCA (str
, char *, len
);
1039 for (i
= 0; i
< len
; i
++)
1040 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
1042 if (with_background
> 0)
1045 for (i
= 0; i
< len
; i
++)
1046 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1047 gc
, x
+ i
, y
, str
+ i
, 1);
1049 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1050 gc
, x
, y
, str
, len
);
1055 for (i
= 0; i
< len
; i
++)
1056 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1057 gc
, x
+ i
, y
, str
+ i
, 1);
1059 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1060 gc
, x
, y
, str
, len
);
1068 if (with_background
> 0)
1071 for (i
= 0; i
< len
; i
++)
1072 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1073 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1075 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1076 gc
, x
, y
, s
->char2b
+ from
, len
);
1081 for (i
= 0; i
< len
; i
++)
1082 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1083 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
1085 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
1086 gc
, x
, y
, s
->char2b
+ from
, len
);
1094 xfont_check (FRAME_PTR f
, struct font
*font
)
1096 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
1098 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
1103 syms_of_xfont (void)
1105 staticpro (&xfont_scripts_cache
);
1106 { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
1107 is called fairly late, when QCtest and Qequal are known to be set. */
1108 Lisp_Object args
[2];
1111 xfont_scripts_cache
= Fmake_hash_table (2, args
);
1113 staticpro (&xfont_scratch_props
);
1114 xfont_scratch_props
= Fmake_vector (make_number (8), Qnil
);
1115 xfont_driver
.type
= Qx
;
1116 register_font_driver (&xfont_driver
, NULL
);