1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008
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 (entity
, c
)
800 Lisp_Object registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
801 struct charset
*repertory
;
803 if (font_registry_charsets (registry
, NULL
, &repertory
) < 0)
807 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
811 xfont_encode_char (font
, c
)
815 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
816 struct charset
*charset
;
820 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
821 code
= ENCODE_CHAR (charset
, c
);
822 if (code
== CHARSET_INVALID_CODE (charset
))
823 return FONT_INVALID_CODE
;
824 if (font
->repertory_charset
>= 0)
826 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
827 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
828 ? code
: FONT_INVALID_CODE
);
830 char2b
.byte1
= code
>> 8;
831 char2b
.byte2
= code
& 0xFF;
832 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
836 xfont_text_extents (font
, code
, nglyphs
, metrics
)
840 struct font_metrics
*metrics
;
842 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
847 bzero (metrics
, sizeof (struct font_metrics
));
848 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
851 static XCharStruct
*pcm
;
853 if (code
[i
] >= 0x10000)
855 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
856 pcm
= xfont_get_pcm (xfont
, &char2b
);
863 metrics
->lbearing
= pcm
->lbearing
;
864 metrics
->rbearing
= pcm
->rbearing
;
865 metrics
->ascent
= pcm
->ascent
;
866 metrics
->descent
= pcm
->descent
;
874 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
875 metrics
->lbearing
= width
+ pcm
->lbearing
;
876 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
877 metrics
->rbearing
= width
+ pcm
->rbearing
;
878 if (metrics
->ascent
< pcm
->ascent
)
879 metrics
->ascent
= pcm
->ascent
;
880 if (metrics
->descent
< pcm
->descent
)
881 metrics
->descent
= pcm
->descent
;
887 metrics
->width
= width
;
892 xfont_draw (s
, from
, to
, x
, y
, with_background
)
893 struct glyph_string
*s
;
894 int from
, to
, x
, y
, with_background
;
896 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
901 if (s
->gc
!= s
->face
->gc
)
904 XSetFont (s
->display
, gc
, xfont
->fid
);
908 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
913 SAFE_ALLOCA (str
, char *, len
);
914 for (i
= 0; i
< len
; i
++)
915 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
917 if (with_background
> 0)
920 for (i
= 0; i
< len
; i
++)
921 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
922 gc
, x
+ i
, y
, str
+ i
, 1);
924 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
930 for (i
= 0; i
< len
; i
++)
931 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
932 gc
, x
+ i
, y
, str
+ i
, 1);
934 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
943 if (with_background
> 0)
946 for (i
= 0; i
< len
; i
++)
947 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
948 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
950 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
951 gc
, x
, y
, s
->char2b
+ from
, len
);
956 for (i
= 0; i
< len
; i
++)
957 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
958 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
960 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
961 gc
, x
, y
, s
->char2b
+ from
, len
);
969 xfont_check (f
, font
)
973 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
975 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
982 xfont_driver
.type
= Qx
;
983 register_font_driver (&xfont_driver
, NULL
);
986 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
987 (do not change this comment) */