1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006 Free Software Foundation, Inc.
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 2, or (at your option)
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; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
29 #include "dispextern.h"
32 #include "blockinput.h"
33 #include "character.h"
39 /* X core font driver. */
43 /* Alist of font registry symbol and the corresponding charsets
44 information. The information is retrieved from
45 Vfont_encoding_alist on demand.
47 Eash element has the form:
48 (REGISTRY . (ENCODING-CHARSET-ID . REPERTORY-CHARSET-ID))
52 In the former form, ENCODING-CHARSET-ID is an ID of a charset that
53 encodes a character code to a glyph code of a font, and
54 REPERTORY-CHARSET-ID is an ID of a charset that tells if a
55 character is supported by a font.
57 The latter form means that the information for REGISTRY couldn't be
59 static Lisp_Object x_font_charset_alist
;
61 /* Prototypes of support functions. */
62 extern void x_clear_errors
P_ ((Display
*));
64 static char *xfont_query_font
P_ ((Display
*, char *, Lisp_Object
));
65 static XCharStruct
*xfont_get_pcm
P_ ((XFontStruct
*, XChar2b
*));
66 static int xfont_registry_charsets
P_ ((Lisp_Object
, struct charset
**,
70 xfont_query_font (display
, name
, spec
)
78 x_catch_errors (display
);
79 font
= XLoadQueryFont (display
, name
);
81 if (x_had_errors_p (display
))
83 /* This error is perhaps due to insufficient memory on X
84 server. Let's just ignore it. */
85 x_clear_errors (display
);
91 if (XGetFontProperty (font
, XA_FONT
, &value
))
93 char *n
= (char *) XGetAtomName (display
, (Atom
) value
);
95 if (font_parse_xlfd (n
, spec
) >= 0)
100 XFreeFont (display
, font
);
109 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
110 is not contained in the font. */
113 xfont_get_pcm (xfont
, char2b
)
117 /* The result metric information. */
118 XCharStruct
*pcm
= NULL
;
120 xassert (xfont
&& char2b
);
122 if (xfont
->per_char
!= NULL
)
124 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
126 /* min_char_or_byte2 specifies the linear character index
127 corresponding to the first element of the per_char array,
128 max_char_or_byte2 is the index of the last character. A
129 character with non-zero CHAR2B->byte1 is not in the font.
130 A character with byte2 less than min_char_or_byte2 or
131 greater max_char_or_byte2 is not in the font. */
132 if (char2b
->byte1
== 0
133 && char2b
->byte2
>= xfont
->min_char_or_byte2
134 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
135 pcm
= xfont
->per_char
+ char2b
->byte2
- xfont
->min_char_or_byte2
;
139 /* If either min_byte1 or max_byte1 are nonzero, both
140 min_char_or_byte2 and max_char_or_byte2 are less than
141 256, and the 2-byte character index values corresponding
142 to the per_char array element N (counting from 0) are:
144 byte1 = N/D + min_byte1
145 byte2 = N\D + min_char_or_byte2
149 D = max_char_or_byte2 - min_char_or_byte2 + 1
151 \ = integer modulus */
152 if (char2b
->byte1
>= xfont
->min_byte1
153 && char2b
->byte1
<= xfont
->max_byte1
154 && char2b
->byte2
>= xfont
->min_char_or_byte2
155 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
156 pcm
= (xfont
->per_char
157 + ((xfont
->max_char_or_byte2
- xfont
->min_char_or_byte2
+ 1)
158 * (char2b
->byte1
- xfont
->min_byte1
))
159 + (char2b
->byte2
- xfont
->min_char_or_byte2
));
164 /* If the per_char pointer is null, all glyphs between the first
165 and last character indexes inclusive have the same
166 information, as given by both min_bounds and max_bounds. */
167 if (char2b
->byte2
>= xfont
->min_char_or_byte2
168 && char2b
->byte2
<= xfont
->max_char_or_byte2
)
169 pcm
= &xfont
->max_bounds
;
173 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
177 extern Lisp_Object find_font_encoding
P_ ((Lisp_Object
));
179 /* Return encoding charset and repertory charset for REGISTRY in
180 ENCODING and REPERTORY correspondingly. If correct information for
181 REGISTRY is available, return 0. Otherwise return -1. */
184 xfont_registry_charsets (registry
, encoding
, repertory
)
185 Lisp_Object registry
;
186 struct charset
**encoding
, **repertory
;
189 int encoding_id
, repertory_id
;
191 val
= assq_no_quit (registry
, x_font_charset_alist
);
197 encoding_id
= XINT (XCAR (val
));
198 repertory_id
= XINT (XCDR (val
));
202 val
= find_font_encoding (SYMBOL_NAME (registry
));
203 if (SYMBOLP (val
) && CHARSETP (val
))
205 encoding_id
= repertory_id
= XINT (CHARSET_SYMBOL_ID (val
));
207 else if (CONSP (val
))
209 if (! CHARSETP (XCAR (val
)))
211 encoding_id
= XINT (CHARSET_SYMBOL_ID (XCAR (val
)));
212 if (NILP (XCDR (val
)))
216 if (! CHARSETP (XCDR (val
)))
218 repertory_id
= XINT (CHARSET_SYMBOL_ID (XCDR (val
)));
223 val
= Fcons (make_number (encoding_id
), make_number (repertory_id
));
225 = nconc2 (x_font_charset_alist
, Fcons (Fcons (registry
, val
), Qnil
));
229 *encoding
= CHARSET_FROM_ID (encoding_id
);
231 *repertory
= repertory_id
>= 0 ? CHARSET_FROM_ID (repertory_id
) : NULL
;
236 = nconc2 (x_font_charset_alist
, Fcons (Fcons (registry
, Qnil
), Qnil
));
240 static Lisp_Object xfont_get_cache
P_ ((Lisp_Object
));
241 static Lisp_Object xfont_list
P_ ((Lisp_Object
, Lisp_Object
));
242 static Lisp_Object xfont_match
P_ ((Lisp_Object
, Lisp_Object
));
243 static Lisp_Object xfont_list_family
P_ ((Lisp_Object
));
244 static struct font
*xfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
245 static void xfont_close
P_ ((FRAME_PTR
, struct font
*));
246 static int xfont_prepare_face
P_ ((FRAME_PTR
, struct face
*));
248 static void xfont_done_face
P_ ((FRAME_PTR
, struct face
*));
250 static int xfont_has_char
P_ ((Lisp_Object
, int));
251 static unsigned xfont_encode_char
P_ ((struct font
*, int));
252 static int xfont_text_extents
P_ ((struct font
*, unsigned *, int,
253 struct font_metrics
*));
254 static int xfont_draw
P_ ((struct glyph_string
*, int, int, int, int, int));
256 struct font_driver xfont_driver
=
258 (Lisp_Object
) NULL
, /* Qx */
267 NULL
/*xfont_done_face*/,
274 extern Lisp_Object QCname
;
277 xfont_get_cache (frame
)
280 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (frame
));
282 return (dpyinfo
->name_list_element
);
285 extern Lisp_Object Vface_alternative_font_registry_alist
;
288 xfont_list_pattern (frame
, display
, pattern
)
293 Lisp_Object list
= Qnil
;
294 int i
, limit
, num_fonts
;
298 x_catch_errors (display
);
300 for (limit
= 512; ; limit
*= 2)
302 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
303 if (x_had_errors_p (display
))
305 /* This error is perhaps due to insufficient memory on X
306 server. Let's just ignore it. */
307 x_clear_errors (display
);
311 if (num_fonts
< limit
)
313 XFreeFontNames (names
);
316 for (i
= 0; i
< num_fonts
; i
++)
318 Lisp_Object entity
= Fmake_vector (make_number (FONT_ENTITY_MAX
), Qnil
);
321 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
322 ASET (entity
, FONT_FRAME_INDEX
, frame
);
324 result
= font_parse_xlfd (names
[i
], entity
);
327 /* This may be an alias name. Try to get the full XLFD name
328 from XA_FONT property of the font. */
329 XFontStruct
*font
= XLoadQueryFont (display
, names
[i
]);
334 if (XGetFontProperty (font
, XA_FONT
, &value
))
336 char *name
= (char *) XGetAtomName (display
, (Atom
) value
);
337 int len
= strlen (name
);
339 /* If DXPC (a Differential X Protocol Compressor)
340 Ver.3.7 is running, XGetAtomName will return null
341 string. We must avoid such a name. */
343 result
= font_parse_xlfd (name
, entity
);
346 XFreeFont (display
, font
);
351 Lisp_Object val
= AREF (entity
, FONT_EXTRA_INDEX
);
352 char *p
= (char *) SDATA (SYMBOL_NAME (val
));
354 /* P == "RESX-RESY-SPACING-AVGWIDTH. We rejust this font if
355 it's an autoscaled one (i.e. RESX > 0 && AVGWIDTH == 0). */
358 p
+= SBYTES (SYMBOL_NAME (val
));
359 while (p
[-1] != '-') p
--;
363 list
= Fcons (entity
, list
);
374 xfont_list (frame
, spec
)
375 Lisp_Object frame
, spec
;
377 FRAME_PTR f
= XFRAME (frame
);
378 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
379 Lisp_Object list
, val
, extra
, font_name
;
383 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
387 val
= assq_no_quit (QCotf
, extra
);
390 val
= assq_no_quit (QCscript
, extra
);
393 val
= assq_no_quit (QClanguage
, extra
);
396 val
= assq_no_quit (QCname
, extra
);
398 font_name
= XCDR (val
);
401 if (STRINGP (font_name
)
402 && ! strchr ((char *) SDATA (font_name
), ':'))
403 list
= xfont_list_pattern (frame
, display
, (char *) SDATA (font_name
));
404 else if ((len
= font_unparse_xlfd (spec
, 0, name
, 256)) < 0)
408 list
= xfont_list_pattern (frame
, display
, name
);
411 Lisp_Object registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
414 if (! NILP (registry
)
415 && (alter
= Fassoc (SYMBOL_NAME (registry
),
416 Vface_alternative_font_registry_alist
))
419 /* Pointer to REGISTRY-ENCODING field. */
420 char *r
= name
+ len
- SBYTES (SYMBOL_NAME (registry
));
422 for (alter
= XCDR (alter
); CONSP (alter
); alter
= XCDR (alter
))
423 if (STRINGP (XCAR (alter
))
424 && ((r
- name
) + SBYTES (XCAR (alter
))) < 255)
426 strcpy (r
, (char *) SDATA (XCAR (alter
)));
427 list
= xfont_list_pattern (frame
, display
, name
);
435 return (NILP (list
) ? null_vector
: Fvconcat (1, &list
));
439 xfont_match (frame
, spec
)
440 Lisp_Object frame
, spec
;
442 FRAME_PTR f
= XFRAME (frame
);
443 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
444 Lisp_Object extra
, val
, entity
;
449 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
450 val
= assq_no_quit (QCname
, extra
);
451 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
456 name
= (char *) SDATA (XCDR (val
));
457 xfont
= XLoadQueryFont (display
, name
);
460 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
464 name
= (char *) XGetAtomName (display
, (Atom
) value
);
467 /* If DXPC (a Differential X Protocol Compressor)
468 Ver.3.7 is running, XGetAtomName will return null
469 string. We must avoid such a name. */
472 entity
= Fmake_vector (make_number (FONT_ENTITY_MAX
), Qnil
);
473 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
474 ASET (entity
, FONT_FRAME_INDEX
, frame
);
475 if (font_parse_xlfd (name
, entity
) < 0)
480 XFreeFont (display
, xfont
);
488 memq_no_quit (elt
, list
)
489 Lisp_Object elt
, list
;
491 while (CONSP (list
) && ! EQ (XCAR (list
), elt
))
493 return (CONSP (list
));
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
;
526 p0
++; /* skip the leading '-' */
527 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
531 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
532 if (! *p1
|| p1
== p0
)
534 if (last_len
== p1
- p0
535 && bcmp (last_family
, p0
, last_len
) == 0)
539 family
= intern_downcase (p0
, last_len
);
540 if (! memq_no_quit (family
, list
))
541 list
= Fcons (family
, list
);
544 XFreeFontNames (names
);
552 xfont_open (f
, entity
, pixel_size
)
557 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
558 Display
*display
= dpyinfo
->display
;
562 Lisp_Object registry
;
563 struct charset
*encoding
, *repertory
;
567 /* At first, check if we know how to encode characters for this
569 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
570 if (xfont_registry_charsets (registry
, &encoding
, &repertory
) < 0)
573 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
574 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
575 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 256);
580 x_catch_errors (display
);
581 xfont
= XLoadQueryFont (display
, name
);
582 if (x_had_errors_p (display
))
584 /* This error is perhaps due to insufficient memory on X server.
585 Let's just ignore it. */
586 x_clear_errors (display
);
594 font
= malloc (sizeof (struct font
));
596 font
->font
.font
= xfont
;
597 font
->entity
= entity
;
598 font
->pixel_size
= pixel_size
;
599 font
->driver
= &xfont_driver
;
600 font
->font
.name
= malloc (len
+ 1);
601 if (! font
->font
.name
)
603 XFreeFont (display
, xfont
);
607 bcopy (name
, font
->font
.name
, len
+ 1);
608 font
->font
.charset
= encoding
->id
;
609 font
->encoding_charset
= encoding
->id
;
610 font
->repertory_charset
= repertory
? repertory
->id
: -1;
611 font
->ascent
= xfont
->ascent
;
612 font
->descent
= xfont
->descent
;
614 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
616 /* Fixed width font. */
617 font
->font
.average_width
= font
->font
.space_width
618 = xfont
->min_bounds
.width
;
625 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
626 pcm
= xfont_get_pcm (xfont
, &char2b
);
628 font
->font
.space_width
= pcm
->width
;
630 font
->font
.space_width
= xfont
->max_bounds
.width
;
632 font
->font
.average_width
633 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_AVERAGE_WIDTH
, &value
)
634 ? (long) value
/ 10 : 0);
635 if (font
->font
.average_width
< 0)
636 font
->font
.average_width
= - font
->font
.average_width
;
637 if (font
->font
.average_width
== 0)
641 int width
= pcm
->width
;
642 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
643 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
645 font
->font
.average_width
= width
/ 95;
648 font
->font
.average_width
= xfont
->max_bounds
.width
;
651 font
->min_width
= xfont
->min_bounds
.width
;
652 if (font
->min_width
<= 0)
653 font
->min_width
= font
->font
.space_width
;
656 /* Try to get the full name of FONT. Put it in FULL_NAME. */
657 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
659 char *full_name
= NULL
, *p0
, *p
;
662 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);;
663 /* Count the number of dashes in the "full name".
664 If it is too few, this isn't really the font's full name,
666 In X11R4, the fonts did not come with their canonical names
677 full_name
= (char *) malloc (p
- p0
+ 1);
679 bcopy (p0
, full_name
, p
- p0
+ 1);
684 font
->font
.full_name
= full_name
;
686 font
->font
.full_name
= font
->font
.name
;
688 font
->file_name
= NULL
;
690 font
->font
.size
= xfont
->max_bounds
.width
;
691 font
->font
.height
= xfont
->ascent
+ xfont
->descent
;
692 font
->font
.baseline_offset
693 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
695 font
->font
.relative_compose
696 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
698 font
->font
.default_ascent
699 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
701 font
->font
.vertical_centering
702 = (STRINGP (Vvertical_centering_font_regexp
)
703 && (fast_c_string_match_ignore_case
704 (Vvertical_centering_font_regexp
, font
->font
.full_name
) >= 0));
710 /* Set global flag fonts_changed_p to non-zero if the font loaded
711 has a character with a smaller width than any other character
712 before, or if the font loaded has a smaller height than any other
713 font loaded before. If this happens, it will make a glyph matrix
714 reallocation necessary. */
715 if (dpyinfo
->n_fonts
== 1)
717 dpyinfo
->smallest_font_height
= font
->font
.height
;
718 dpyinfo
->smallest_char_width
= font
->min_width
;
723 if (dpyinfo
->smallest_font_height
> font
->font
.height
)
724 dpyinfo
->smallest_font_height
= font
->font
.height
, fonts_changed_p
|= 1;
725 if (dpyinfo
->smallest_char_width
> font
->min_width
)
726 dpyinfo
->smallest_char_width
= font
->min_width
, fonts_changed_p
|= 1;
733 xfont_close (f
, font
)
738 XFreeFont (FRAME_X_DISPLAY (f
), font
->font
.font
);
741 if (font
->font
.name
!= font
->font
.full_name
)
742 free (font
->font
.full_name
);
743 free (font
->font
.name
);
745 FRAME_X_DISPLAY_INFO (f
)->n_fonts
--;
749 xfont_prepare_face (f
, face
)
754 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
, face
->font
->fid
);
762 xfont_done_face (f
, face
)
769 XFreeGC (FRAME_X_DISPLAY (f
), (GC
) face
->extra
);
777 xfont_has_char (entity
, c
)
781 Lisp_Object registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
782 struct charset
*repertory
;
784 if (xfont_registry_charsets (registry
, NULL
, &repertory
) < 0)
788 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
792 xfont_encode_char (font
, c
)
796 struct charset
*charset
;
800 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
801 code
= ENCODE_CHAR (charset
, c
);
802 if (code
== CHARSET_INVALID_CODE (charset
))
804 if (font
->repertory_charset
>= 0)
806 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
807 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
808 ? code
: 0xFFFFFFFF);
810 char2b
.byte1
= code
>> 8;
811 char2b
.byte2
= code
& 0xFF;
812 return (xfont_get_pcm (font
->font
.font
, &char2b
) ? code
: 0xFFFFFFFF);
816 xfont_text_extents (font
, code
, nglyphs
, metrics
)
820 struct font_metrics
*metrics
;
826 bzero (metrics
, sizeof (struct font_metrics
));
827 for (i
= 0, x
= 0; i
< nglyphs
; i
++)
830 static XCharStruct
*pcm
;
832 if (code
[i
] >= 0x10000)
834 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
835 pcm
= xfont_get_pcm (font
->font
.font
, &char2b
);
838 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
839 metrics
->lbearing
= width
+ pcm
->lbearing
;
840 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
841 metrics
->rbearing
= width
+ pcm
->rbearing
;
842 if (metrics
->ascent
< pcm
->ascent
)
843 metrics
->ascent
= pcm
->ascent
;
844 if (metrics
->descent
< pcm
->descent
)
845 metrics
->descent
= pcm
->descent
;
849 metrics
->width
= width
;
854 xfont_draw (s
, from
, to
, x
, y
, with_background
)
855 struct glyph_string
*s
;
856 int from
, to
, x
, y
, with_background
;
858 XFontStruct
*xfont
= s
->face
->font
;
862 if (gc
!= s
->face
->gc
)
865 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (s
->f
);
867 XGetGCValues (s
->display
, gc
, GCFont
, &xgcv
);
868 if (xgcv
.font
!= xfont
->fid
)
869 XSetFont (s
->display
, gc
, xfont
->fid
);
872 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
878 SAFE_ALLOCA (str
, char *, len
);
879 for (i
= 0; i
< len
; i
++)
880 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
881 if (with_background
> 0)
882 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
885 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
891 if (with_background
> 0)
892 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
893 gc
, x
, y
, s
->char2b
+ from
, len
);
895 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
896 gc
, x
, y
, s
->char2b
+ from
, len
);
906 staticpro (&x_font_charset_alist
);
907 x_font_charset_alist
= Qnil
;
910 xfont_driver
.type
= Qx
;
911 register_font_driver (&xfont_driver
, NULL
);
914 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
915 (do not change this comment) */