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 static Lisp_Object xfont_list_pattern
P_ ((Lisp_Object
, Display
*, char *));
216 xfont_list_pattern (frame
, display
, pattern
)
221 Lisp_Object list
= Qnil
;
222 int i
, limit
, num_fonts
;
226 x_catch_errors (display
);
228 for (limit
= 512; ; limit
*= 2)
230 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
231 if (x_had_errors_p (display
))
233 /* This error is perhaps due to insufficient memory on X
234 server. Let's just ignore it. */
235 x_clear_errors (display
);
239 if (num_fonts
< limit
)
241 XFreeFontNames (names
);
246 char **indices
= alloca (sizeof (char *) * num_fonts
);
248 for (i
= 0; i
< num_fonts
; i
++)
249 indices
[i
] = names
[i
];
250 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
252 for (i
= 0; i
< num_fonts
; i
++)
257 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
260 entity
= font_make_entity ();
261 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
263 result
= font_parse_xlfd (indices
[i
], entity
);
266 /* This may be an alias name. Try to get the full XLFD name
267 from XA_FONT property of the font. */
268 XFontStruct
*font
= XLoadQueryFont (display
, indices
[i
]);
273 if (XGetFontProperty (font
, XA_FONT
, &value
))
275 char *name
= (char *) XGetAtomName (display
, (Atom
) value
);
276 int len
= strlen (name
);
278 /* If DXPC (a Differential X Protocol Compressor)
279 Ver.3.7 is running, XGetAtomName will return null
280 string. We must avoid such a name. */
282 result
= font_parse_xlfd (name
, entity
);
285 XFreeFont (display
, font
);
289 /* Avoid auto-scaled fonts. */
290 && (XINT (AREF (entity
, FONT_DPI_INDEX
)) == 0
291 || XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) > 0))
292 list
= Fcons (entity
, list
);
294 XFreeFontNames (names
);
300 font_add_log ("xfont-list", build_string (pattern
), list
);
305 xfont_list (frame
, spec
)
306 Lisp_Object frame
, spec
;
308 FRAME_PTR f
= XFRAME (frame
);
309 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
310 Lisp_Object registry
, list
, val
, extra
;
314 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
317 val
= assq_no_quit (QCotf
, extra
);
320 val
= assq_no_quit (QCscript
, extra
);
323 val
= assq_no_quit (QClang
, extra
);
328 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
329 len
= font_unparse_xlfd (spec
, 0, name
, 256);
330 ASET (spec
, FONT_REGISTRY_INDEX
, registry
);
333 list
= xfont_list_pattern (frame
, display
, name
);
334 if (NILP (list
) && NILP (registry
))
337 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
339 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
341 strcpy (r
, "iso10646-1");
342 list
= xfont_list_pattern (frame
, display
, name
);
345 if (NILP (list
) && ! NILP (registry
))
347 /* Try alternate registries. */
350 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
351 Vface_alternative_font_registry_alist
),
354 /* Pointer to REGISTRY-ENCODING field. */
355 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
357 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
358 if (STRINGP (XCAR (alter
))
359 && ((r
- name
) + SBYTES (XCAR (alter
))) < 256)
361 strcpy (r
, (char *) SDATA (XCAR (alter
)));
362 list
= xfont_list_pattern (frame
, display
, name
);
371 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
372 if (CONSP (val
) && STRINGP (XCDR (val
)))
373 list
= xfont_list_pattern (frame
, display
, (char *) SDATA (XCDR (val
)));
380 xfont_match (frame
, spec
)
381 Lisp_Object frame
, spec
;
383 FRAME_PTR f
= XFRAME (frame
);
384 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
385 Lisp_Object extra
, val
, entity
;
386 char buf
[256], *name
;
390 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
391 val
= assq_no_quit (QCname
, extra
);
392 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
394 if (font_unparse_xlfd (spec
, 0, buf
, 256) < 0)
399 name
= (char *) SDATA (XCDR (val
));
403 xfont
= XLoadQueryFont (display
, name
);
406 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
410 name
= (char *) XGetAtomName (display
, (Atom
) value
);
413 /* If DXPC (a Differential X Protocol Compressor)
414 Ver.3.7 is running, XGetAtomName will return null
415 string. We must avoid such a name. */
418 entity
= font_make_entity ();
419 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
420 if (font_parse_xlfd (name
, entity
) < 0)
425 XFreeFont (display
, xfont
);
429 font_add_log ("xfont-match", spec
, entity
);
434 xfont_list_family (frame
)
437 FRAME_PTR f
= XFRAME (frame
);
438 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
446 x_catch_errors (dpyinfo
->display
);
447 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
449 if (x_had_errors_p (dpyinfo
->display
))
451 /* This error is perhaps due to insufficient memory on X server.
452 Let's just ignore it. */
453 x_clear_errors (dpyinfo
->display
);
458 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
460 char *p0
= names
[i
], *p1
;
463 p0
++; /* skip the leading '-' */
464 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
468 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
469 if (! *p1
|| p1
== p0
)
471 if (last_len
== p1
- p0
472 && bcmp (last_family
, p0
, last_len
) == 0)
476 family
= font_intern_prop (p0
, last_len
, 1);
477 if (NILP (assq_no_quit (family
, list
)))
478 list
= Fcons (family
, list
);
481 XFreeFontNames (names
);
488 extern Lisp_Object QCavgwidth
;
491 xfont_open (f
, entity
, pixel_size
)
496 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
497 Display
*display
= dpyinfo
->display
;
501 Lisp_Object registry
;
502 struct charset
*encoding
, *repertory
;
503 Lisp_Object font_object
, fullname
;
508 /* At first, check if we know how to encode characters for this
510 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
511 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
513 font_add_log (" x:unknown registry", registry
, Qnil
);
517 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
518 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
519 else if (pixel_size
== 0)
522 pixel_size
= FRAME_FONT (f
)->pixel_size
;
526 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 256);
529 font_add_log (" x:unparse failed", entity
, Qnil
);
534 x_catch_errors (display
);
535 xfont
= XLoadQueryFont (display
, name
);
536 if (x_had_errors_p (display
))
538 /* This error is perhaps due to insufficient memory on X server.
539 Let's just ignore it. */
540 x_clear_errors (display
);
545 /* Some version of X lists:
546 -misc-fixed-medium-r-normal--20-*-75-75-c-100-iso8859-1
547 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
549 -misc-fixed-medium-r-normal--20-*-100-100-c-100-iso8859-1
551 -misc-fixed-medium-r-normal--20-*-*-*-c-100-iso8859-1
552 So, we try again with wildcards in RESX and RESY. */
555 temp
= Fcopy_font_spec (entity
);
556 ASET (temp
, FONT_DPI_INDEX
, Qnil
);
557 len
= font_unparse_xlfd (temp
, pixel_size
, name
, 256);
560 font_add_log (" x:unparse failed", temp
, Qnil
);
563 xfont
= XLoadQueryFont (display
, name
);
564 if (x_had_errors_p (display
))
566 /* This error is perhaps due to insufficient memory on X server.
567 Let's just ignore it. */
568 x_clear_errors (display
);
573 /* Try to get the full name of FONT. */
574 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
579 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);;
580 /* Count the number of dashes in the "full name".
581 If it is too few, this isn't really the font's full name,
583 In X11R4, the fonts did not come with their canonical names
593 fullname
= Fdowncase (make_unibyte_string (p0
, p
- p0
));
601 font_add_log (" x:open failed", build_string (name
), Qnil
);
605 font_object
= font_make_object (VECSIZE (struct xfont_info
),
607 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
608 if (STRINGP (fullname
))
609 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
610 if (STRINGP (fullname
))
611 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
613 ASET (font_object
, FONT_NAME_INDEX
, make_unibyte_string (name
, len
));
614 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
615 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
616 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
617 font
= XFONT_OBJECT (font_object
);
618 ((struct xfont_info
*) font
)->xfont
= xfont
;
619 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
620 font
->pixel_size
= pixel_size
;
621 font
->driver
= &xfont_driver
;
622 font
->encoding_charset
= encoding
->id
;
623 font
->repertory_charset
= repertory
? repertory
->id
: -1;
624 font
->ascent
= xfont
->ascent
;
625 font
->descent
= xfont
->descent
;
626 font
->height
= font
->ascent
+ font
->descent
;
627 font
->min_width
= xfont
->min_bounds
.width
;
628 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
630 /* Fixed width font. */
631 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
639 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
640 pcm
= xfont_get_pcm (xfont
, &char2b
);
642 font
->space_width
= pcm
->width
;
644 font
->space_width
= 0;
646 val
= Ffont_get (font_object
, QCavgwidth
);
648 font
->average_width
= XINT (val
);
649 if (font
->average_width
< 0)
650 font
->average_width
= - font
->average_width
;
651 if (font
->average_width
== 0
652 && encoding
->ascii_compatible_p
)
654 int width
= font
->space_width
, n
= pcm
!= NULL
;
656 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
657 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
658 width
+= pcm
->width
, n
++;
660 font
->average_width
= width
/ n
;
662 if (font
->average_width
== 0)
663 /* No easy way other than this to get a reasonable
666 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
670 font
->underline_thickness
671 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
673 font
->underline_position
674 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
675 ? (long) value
: -1);
676 font
->baseline_offset
677 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
679 font
->relative_compose
680 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
683 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
688 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
689 font
->vertical_centering
690 = (STRINGP (Vvertical_centering_font_regexp
)
691 && (fast_string_match_ignore_case
692 (Vvertical_centering_font_regexp
, fullname
) >= 0));
698 xfont_close (f
, font
)
703 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
708 xfont_prepare_face (f
, face
)
713 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
714 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
721 xfont_has_char (entity
, c
)
725 Lisp_Object registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
726 struct charset
*repertory
;
728 if (font_registry_charsets (registry
, NULL
, &repertory
) < 0)
732 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
736 xfont_encode_char (font
, c
)
740 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
741 struct charset
*charset
;
745 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
746 code
= ENCODE_CHAR (charset
, c
);
747 if (code
== CHARSET_INVALID_CODE (charset
))
748 return FONT_INVALID_CODE
;
749 if (font
->repertory_charset
>= 0)
751 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
752 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
753 ? code
: FONT_INVALID_CODE
);
755 char2b
.byte1
= code
>> 8;
756 char2b
.byte2
= code
& 0xFF;
757 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
761 xfont_text_extents (font
, code
, nglyphs
, metrics
)
765 struct font_metrics
*metrics
;
767 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
772 bzero (metrics
, sizeof (struct font_metrics
));
773 for (i
= 0, x
= 0, first
= 1; i
< nglyphs
; i
++)
776 static XCharStruct
*pcm
;
778 if (code
[i
] >= 0x10000)
780 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
781 pcm
= xfont_get_pcm (xfont
, &char2b
);
788 metrics
->lbearing
= pcm
->lbearing
;
789 metrics
->rbearing
= pcm
->rbearing
;
790 metrics
->ascent
= pcm
->ascent
;
791 metrics
->descent
= pcm
->descent
;
799 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
800 metrics
->lbearing
= width
+ pcm
->lbearing
;
801 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
802 metrics
->rbearing
= width
+ pcm
->rbearing
;
803 if (metrics
->ascent
< pcm
->ascent
)
804 metrics
->ascent
= pcm
->ascent
;
805 if (metrics
->descent
< pcm
->descent
)
806 metrics
->descent
= pcm
->descent
;
812 metrics
->width
= width
;
817 xfont_draw (s
, from
, to
, x
, y
, with_background
)
818 struct glyph_string
*s
;
819 int from
, to
, x
, y
, with_background
;
821 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
826 if (s
->gc
!= s
->face
->gc
)
829 XSetFont (s
->display
, gc
, xfont
->fid
);
833 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
838 SAFE_ALLOCA (str
, char *, len
);
839 for (i
= 0; i
< len
; i
++)
840 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
842 if (with_background
> 0)
845 for (i
= 0; i
< len
; i
++)
846 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
847 gc
, x
+ i
, y
, str
+ i
, 1);
849 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
855 for (i
= 0; i
< len
; i
++)
856 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
857 gc
, x
+ i
, y
, str
+ i
, 1);
859 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
868 if (with_background
> 0)
871 for (i
= 0; i
< len
; i
++)
872 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
873 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
875 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
876 gc
, x
, y
, s
->char2b
+ from
, len
);
881 for (i
= 0; i
< len
; i
++)
882 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
883 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
885 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
886 gc
, x
, y
, s
->char2b
+ from
, len
);
894 xfont_check (f
, font
)
898 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
900 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
907 xfont_driver
.type
= Qx
;
908 register_font_driver (&xfont_driver
, NULL
);
911 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
912 (do not change this comment) */