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
*));
52 static void xfont_find_ccl_program
P_ ((struct font
*));
54 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
55 is not contained in the font. */
58 xfont_get_pcm (xfont
, char2b
)
62 /* The result metric information. */
63 XCharStruct
*pcm
= NULL
;
65 font_assert (xfont
&& char2b
);
67 if (xfont
->per_char
!= NULL
)
69 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
71 /* min_char_or_byte2 specifies the linear character index
72 corresponding to the first element of the per_char array,
73 max_char_or_byte2 is the index of the last character. A
74 character with non-zero CHAR2B->byte1 is not in the font.
75 A character with byte2 less than min_char_or_byte2 or
76 greater max_char_or_byte2 is not in the font. */
77 if (char2b
->byte1
== 0
78 && char2b
->byte2
>= xfont
->min_char_or_byte2
79 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
80 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
84 /* If either min_byte1 or max_byte1 are nonzero, both
85 min_char_or_byte2 and max_char_or_byte2 are less than
86 256, and the 2-byte character index values corresponding
87 to the per_char array element N (counting from 0) are:
89 byte1 = N/D + min_byte1
90 byte2 = N\D + min_char_or_byte2
94 D = max_char_or_byte2 - min_char_or_byte2 + 1
96 \ = integer modulus */
97 if (char2b
->byte1
>= xfont
->min_byte1
98 && char2b
->byte1
<= xfont
->max_byte1
99 && char2b
->byte2
>= xfont
->min_char_or_byte2
100 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
101 pcm
= (xfont
->per_char
102 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
103 * (char2b
->byte1
- xfont
->min_byte1
))
104 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
109 /* If the per_char pointer is null, all glyphs between the first
110 and last character indexes inclusive have the same
111 information, as given by both min_bounds and max_bounds. */
112 if (char2b
->byte2
>= xfont
->min_char_or_byte2
113 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
114 pcm
= &xfont
->max_bounds
;
118 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
122 /* Find a CCL program for a font specified by FONTP, and set the member
123 `encoder' of the structure. */
126 xfont_find_ccl_program (font
)
129 Lisp_Object list
, elt
;
132 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
136 && STRINGP (XCAR (elt
))
137 && ((fast_string_match_ignore_case (XCAR (elt
),
138 font
->props
[FONT_NAME_INDEX
])
140 || (fast_string_match_ignore_case (XCAR (elt
),
141 font
->props
[FONT_FULLNAME_INDEX
])
148 struct ccl_program
*ccl
149 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
151 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
154 font
->font_encoder
= ccl
;
158 static Lisp_Object xfont_get_cache
P_ ((FRAME_PTR
));
159 static Lisp_Object xfont_list
P_ ((Lisp_Object
, Lisp_Object
));
160 static Lisp_Object xfont_match
P_ ((Lisp_Object
, Lisp_Object
));
161 static Lisp_Object xfont_list_family
P_ ((Lisp_Object
));
162 static Lisp_Object xfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
163 static void xfont_close
P_ ((FRAME_PTR
, struct font
*));
164 static int xfont_prepare_face
P_ ((FRAME_PTR
, struct face
*));
165 static int xfont_has_char
P_ ((Lisp_Object
, int));
166 static unsigned xfont_encode_char
P_ ((struct font
*, int));
167 static int xfont_text_extents
P_ ((struct font
*, unsigned *, int,
168 struct font_metrics
*));
169 static int xfont_draw
P_ ((struct glyph_string
*, int, int, int, int, int));
170 static int xfont_check
P_ ((FRAME_PTR
, struct font
*));
172 struct font_driver xfont_driver
=
175 0, /* case insensitive */
189 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
193 extern Lisp_Object QCname
;
199 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
201 return (dpyinfo
->name_list_element
);
204 extern Lisp_Object Vface_alternative_font_registry_alist
;
207 compare_font_names (const void *name1
, const void *name2
)
209 return xstrcasecmp (*(const unsigned char **) name1
,
210 *(const unsigned char **) name2
);
213 /* Decode XLFD as iso-8859-1 into OUTPUT, and return the byte length
214 of the decoding result. LEN is the byte length of XLFD, or -1 if
215 XLFD is NULL terminated. The caller must assure that OUTPUT is at
216 least twice (plus 1) as large as XLFD. */
219 xfont_decode_coding_xlfd (char *xlfd
, int len
, char *output
)
221 char *p0
= xlfd
, *p1
= output
;
226 c
= *(unsigned char *) p0
++;
227 p1
+= CHAR_STRING (c
, p1
);
232 return (p1
- output
);
235 /* Encode XLFD from UTF-8 to iso-8859-1 destructively, and return the
236 resulting byte length. If XLFD contains unencodable character,
240 xfont_encode_coding_xlfd (char *xlfd
)
242 const unsigned char *p0
= (unsigned char *) xlfd
;
243 unsigned char *p1
= (unsigned char *) xlfd
;
248 int c
= STRING_CHAR_ADVANCE (p0
);
259 static Lisp_Object xfont_list_pattern
P_ ((Lisp_Object
, Display
*, char *));
262 xfont_list_pattern (frame
, display
, pattern
)
267 Lisp_Object list
= Qnil
;
268 int i
, limit
, num_fonts
;
270 /* Large enough to decode the longest XLFD (255 bytes). */
274 x_catch_errors (display
);
276 for (limit
= 512; ; limit
*= 2)
278 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
279 if (x_had_errors_p (display
))
281 /* This error is perhaps due to insufficient memory on X
282 server. Let's just ignore it. */
283 x_clear_errors (display
);
287 if (num_fonts
< limit
)
289 XFreeFontNames (names
);
294 char **indices
= alloca (sizeof (char *) * num_fonts
);
296 for (i
= 0; i
< num_fonts
; i
++)
297 indices
[i
] = names
[i
];
298 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
300 for (i
= 0; i
< num_fonts
; i
++)
306 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
309 entity
= font_make_entity ();
310 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
311 xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
312 result
= font_parse_xlfd (buf
, entity
);
315 /* This may be an alias name. Try to get the full XLFD name
316 from XA_FONT property of the font. */
317 XFontStruct
*font
= XLoadQueryFont (display
, indices
[i
]);
322 if (XGetFontProperty (font
, XA_FONT
, &value
))
324 char *name
= (char *) XGetAtomName (display
, (Atom
) value
);
325 int len
= strlen (name
);
327 /* If DXPC (a Differential X Protocol Compressor)
328 Ver.3.7 is running, XGetAtomName will return null
329 string. We must avoid such a name. */
332 xfont_decode_coding_xlfd (indices
[i
], -1, buf
);
333 result
= font_parse_xlfd (buf
, entity
);
337 XFreeFont (display
, font
);
341 /* Avoid auto-scaled fonts. */
342 && (XINT (AREF (entity
, FONT_DPI_INDEX
)) == 0
343 || XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) > 0))
344 list
= Fcons (entity
, list
);
346 XFreeFontNames (names
);
352 font_add_log ("xfont-list", build_string (pattern
), list
);
357 xfont_list (frame
, spec
)
358 Lisp_Object frame
, spec
;
360 FRAME_PTR f
= XFRAME (frame
);
361 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
362 Lisp_Object registry
, list
, val
, extra
;
364 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
367 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
370 val
= assq_no_quit (QCotf
, extra
);
373 val
= assq_no_quit (QCscript
, extra
);
376 val
= assq_no_quit (QClang
, extra
);
381 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
382 len
= font_unparse_xlfd (spec
, 0, name
, 512);
383 if (len
< 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
385 ASET (spec
, FONT_REGISTRY_INDEX
, registry
);
386 list
= xfont_list_pattern (frame
, display
, name
);
387 if (NILP (list
) && NILP (registry
))
390 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
392 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
394 strcpy (r
, "iso10646-1");
395 list
= xfont_list_pattern (frame
, display
, name
);
398 if (NILP (list
) && ! NILP (registry
))
400 /* Try alternate registries. */
403 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
404 Vface_alternative_font_registry_alist
),
407 /* Pointer to REGISTRY-ENCODING field. */
408 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
410 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
411 if (STRINGP (XCAR (alter
))
412 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
414 strcpy (r
, (char *) SDATA (XCAR (alter
)));
415 list
= xfont_list_pattern (frame
, display
, name
);
424 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
425 if (CONSP (val
) && STRINGP (XCDR (val
)) && SBYTES (XCDR (val
)) < 512)
427 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
428 if (xfont_encode_coding_xlfd (name
) < 0)
430 list
= xfont_list_pattern (frame
, display
, name
);
438 xfont_match (frame
, spec
)
439 Lisp_Object frame
, spec
;
441 FRAME_PTR f
= XFRAME (frame
);
442 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
443 Lisp_Object extra
, val
, entity
;
448 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
449 val
= assq_no_quit (QCname
, extra
);
450 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
452 if (font_unparse_xlfd (spec
, 0, name
, 512) < 0)
455 else if (SBYTES (XCDR (val
)) < 512)
456 bcopy (SDATA (XCDR (val
)), name
, SBYTES (XCDR (val
)) + 1);
459 if (xfont_encode_coding_xlfd (name
) < 0)
464 xfont
= XLoadQueryFont (display
, name
);
467 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
472 s
= (char *) XGetAtomName (display
, (Atom
) value
);
475 /* If DXPC (a Differential X Protocol Compressor)
476 Ver.3.7 is running, XGetAtomName will return null
477 string. We must avoid such a name. */
480 entity
= font_make_entity ();
481 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
482 xfont_decode_coding_xlfd (s
, -1, name
);
483 if (font_parse_xlfd (name
, entity
) < 0)
488 XFreeFont (display
, xfont
);
492 font_add_log ("xfont-match", spec
, entity
);
497 xfont_list_family (frame
)
500 FRAME_PTR f
= XFRAME (frame
);
501 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
509 x_catch_errors (dpyinfo
->display
);
510 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
512 if (x_had_errors_p (dpyinfo
->display
))
514 /* This error is perhaps due to insufficient memory on X server.
515 Let's just ignore it. */
516 x_clear_errors (dpyinfo
->display
);
521 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
523 char *p0
= names
[i
], *p1
, buf
[512];
527 p0
++; /* skip the leading '-' */
528 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
532 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
533 if (! *p1
|| p1
== p0
)
535 if (last_len
== p1
- p0
536 && bcmp (last_family
, p0
, last_len
) == 0)
541 decoded_len
= xfont_decode_coding_xlfd (p0
, last_len
, buf
);
542 family
= font_intern_prop (p0
, decoded_len
, 1);
543 if (NILP (assq_no_quit (family
, list
)))
544 list
= Fcons (family
, list
);
547 XFreeFontNames (names
);
554 extern Lisp_Object QCavgwidth
;
557 xfont_open (f
, entity
, pixel_size
)
562 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
563 Display
*display
= dpyinfo
->display
;
567 Lisp_Object registry
;
568 struct charset
*encoding
, *repertory
;
569 Lisp_Object font_object
, fullname
;
574 /* At first, check if we know how to encode characters for this
576 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
577 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
579 font_add_log (" x:unknown registry", registry
, Qnil
);
583 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
584 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
585 else if (pixel_size
== 0)
588 pixel_size
= FRAME_FONT (f
)->pixel_size
;
592 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 512);
593 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
595 font_add_log (" x:unparse failed", entity
, Qnil
);
600 x_catch_errors (display
);
601 xfont
= XLoadQueryFont (display
, name
);
602 if (x_had_errors_p (display
))
604 /* This error is perhaps due to insufficient memory on X server.
605 Let's just ignore it. */
606 x_clear_errors (display
);
611 /* Some version of X lists:
612 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
613 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
615 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
617 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
618 So, we try again with wildcards in RESX and RESY. */
621 temp
= Fcopy_font_spec (entity
);
622 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
623 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 512);
624 if (len
<= 0 || (len
= xfont_encode_coding_xlfd (name
)) < 0)
626 font_add_log (" x:unparse failed", temp
, Qnil
);
629 xfont
= XLoadQueryFont (display
, name
);
630 if (x_had_errors_p (display
))
632 /* This error is perhaps due to insufficient memory on X server.
633 Let's just ignore it. */
634 x_clear_errors (display
);
639 /* Try to get the full name of FONT. */
640 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
645 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);
646 /* Count the number of dashes in the "full name".
647 If it is too few, this isn't really the font's full name,
649 In X11R4, the fonts did not come with their canonical names
660 len
= xfont_decode_coding_xlfd (p0
, -1, name
);
661 fullname
= Fdowncase (make_string (name
, len
));
670 font_add_log (" x:open failed", build_string (name
), Qnil
);
674 font_object
= font_make_object (VECSIZE (struct xfont_info
),
676 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
677 if (STRINGP (fullname
))
679 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
680 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
686 len
= xfont_decode_coding_xlfd (name
, -1, buf
);
687 ASET (font_object
, FONT_NAME_INDEX
, make_string (buf
, len
));
689 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
690 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
691 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
692 font
= XFONT_OBJECT (font_object
);
693 ((struct xfont_info
*) font
)->xfont
= xfont
;
694 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
695 font
->pixel_size
= pixel_size
;
696 font
->driver
= &xfont_driver
;
697 font
->encoding_charset
= encoding
->id
;
698 font
->repertory_charset
= repertory
? repertory
->id
: -1;
699 font
->ascent
= xfont
->ascent
;
700 font
->descent
= xfont
->descent
;
701 font
->height
= font
->ascent
+ font
->descent
;
702 font
->min_width
= xfont
->min_bounds
.width
;
703 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
705 /* Fixed width font. */
706 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
714 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
715 pcm
= xfont_get_pcm (xfont
, &char2b
);
717 font
->space_width
= pcm
->width
;
719 font
->space_width
= 0;
721 val
= Ffont_get (font_object
, QCavgwidth
);
723 font
->average_width
= XINT (val
);
724 if (font
->average_width
< 0)
725 font
->average_width
= - font
->average_width
;
726 if (font
->average_width
== 0
727 && encoding
->ascii_compatible_p
)
729 int width
= font
->space_width
, n
= pcm
!= NULL
;
731 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
732 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
733 width
+= pcm
->width
, n
++;
735 font
->average_width
= width
/ n
;
737 if (font
->average_width
== 0)
738 /* No easy way other than this to get a reasonable
741 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
745 font
->underline_thickness
746 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
748 font
->underline_position
749 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
750 ? (long) value
: -1);
751 font
->baseline_offset
752 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
754 font
->relative_compose
755 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
758 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
763 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
764 font
->vertical_centering
765 = (STRINGP (Vvertical_centering_font_regexp
)
766 && (fast_string_match_ignore_case
767 (Vvertical_centering_font_regexp
, fullname
) >= 0));
773 xfont_close (f
, font
)
778 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
783 xfont_prepare_face (f
, face
)
788 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
789 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
796 xfont_has_char (font
, c
)
800 Lisp_Object registry
= AREF (font
, FONT_REGISTRY_INDEX
);
801 struct charset
*encoding
;
802 struct charset
*repertory
= NULL
;
804 if (EQ (registry
, Qiso10646_1
))
806 /* We use a font of `ja' and `ko' adstyle only for a character
807 in JISX0208 and KSC5601 charsets respectively. */
808 if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qja
)
809 && charset_jisx0208
>= 0)
810 encoding
= repertory
= CHARSET_FROM_ID (charset_jisx0208
);
811 else if (EQ (AREF (font
, FONT_ADSTYLE_INDEX
), Qko
)
812 && charset_ksc5601
>= 0)
813 encoding
= repertory
= CHARSET_FROM_ID (charset_ksc5601
);
815 encoding
= CHARSET_FROM_ID (charset_unicode
);
817 else if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
818 /* Unknown REGISTRY, not usable. */
820 if (ASCII_CHAR_P (c
) && encoding
->ascii_compatible_p
)
824 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
828 xfont_encode_char (font
, c
)
832 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
833 struct charset
*charset
;
837 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
838 code
= ENCODE_CHAR (charset
, c
);
839 if (code
== CHARSET_INVALID_CODE (charset
))
840 return FONT_INVALID_CODE
;
841 if (font
->repertory_charset
>= 0)
843 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
844 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
845 ? code
: FONT_INVALID_CODE
);
847 char2b
.byte1
= code
>> 8;
848 char2b
.byte2
= code
& 0xFF;
849 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
853 xfont_text_extents (font
, code
, nglyphs
, metrics
)
857 struct font_metrics
*metrics
;
859 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
864 bzero (metrics
, sizeof (struct font_metrics
));
865 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
868 static XCharStruct
*pcm
;
870 if (code
[i
] >= 0x10000)
872 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
873 pcm
= xfont_get_pcm (xfont
, &char2b
);
880 metrics
->lbearing
= pcm
->lbearing
;
881 metrics
->rbearing
= pcm
->rbearing
;
882 metrics
->ascent
= pcm
->ascent
;
883 metrics
->descent
= pcm
->descent
;
891 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
892 metrics
->lbearing
= width
+ pcm
->lbearing
;
893 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
894 metrics
->rbearing
= width
+ pcm
->rbearing
;
895 if (metrics
->ascent
< pcm
->ascent
)
896 metrics
->ascent
= pcm
->ascent
;
897 if (metrics
->descent
< pcm
->descent
)
898 metrics
->descent
= pcm
->descent
;
904 metrics
->width
= width
;
909 xfont_draw (s
, from
, to
, x
, y
, with_background
)
910 struct glyph_string
*s
;
911 int from
, to
, x
, y
, with_background
;
913 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
918 if (s
->gc
!= s
->face
->gc
)
921 XSetFont (s
->display
, gc
, xfont
->fid
);
925 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
930 SAFE_ALLOCA (str
, char *, len
);
931 for (i
= 0; i
< len
; i
++)
932 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
934 if (with_background
> 0)
937 for (i
= 0; i
< len
; i
++)
938 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
939 gc
, x
+ i
, y
, str
+ i
, 1);
941 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
947 for (i
= 0; i
< len
; i
++)
948 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
949 gc
, x
+ i
, y
, str
+ i
, 1);
951 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
960 if (with_background
> 0)
963 for (i
= 0; i
< len
; i
++)
964 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
965 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
967 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
968 gc
, x
, y
, s
->char2b
+ from
, len
);
973 for (i
= 0; i
< len
; i
++)
974 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
975 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
977 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
978 gc
, x
, y
, s
->char2b
+ from
, len
);
986 xfont_check (f
, font
)
990 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
992 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
999 xfont_driver
.type
= Qx
;
1000 register_font_driver (&xfont_driver
, NULL
);
1003 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
1004 (do not change this comment) */