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
));
595 font
->font
.font
= xfont
;
596 font
->entity
= entity
;
597 font
->pixel_size
= pixel_size
;
598 font
->driver
= &xfont_driver
;
599 font
->font
.name
= malloc (len
+ 1);
600 if (! font
->font
.name
)
602 XFreeFont (display
, xfont
);
606 bcopy (name
, font
->font
.name
, len
+ 1);
607 font
->font
.charset
= encoding
->id
;
608 font
->encoding_charset
= encoding
->id
;
609 font
->repertory_charset
= repertory
? repertory
->id
: -1;
610 font
->ascent
= xfont
->ascent
;
611 font
->descent
= xfont
->descent
;
613 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
615 /* Fixed width font. */
616 font
->font
.average_width
= font
->font
.space_width
617 = xfont
->min_bounds
.width
;
624 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
625 pcm
= xfont_get_pcm (xfont
, &char2b
);
627 font
->font
.space_width
= pcm
->width
;
629 font
->font
.space_width
= xfont
->max_bounds
.width
;
631 font
->font
.average_width
632 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_AVERAGE_WIDTH
, &value
)
633 ? (long) value
/ 10 : 0);
634 if (font
->font
.average_width
< 0)
635 font
->font
.average_width
= - font
->font
.average_width
;
636 if (font
->font
.average_width
== 0)
640 int width
= pcm
->width
;
641 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
642 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
644 font
->font
.average_width
= width
/ 95;
647 font
->font
.average_width
= xfont
->max_bounds
.width
;
650 font
->min_width
= xfont
->min_bounds
.width
;
651 if (font
->min_width
<= 0)
652 font
->min_width
= font
->font
.space_width
;
655 /* Try to get the full name of FONT. Put it in FULL_NAME. */
656 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
658 char *full_name
= NULL
, *p0
, *p
;
661 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);;
662 /* Count the number of dashes in the "full name".
663 If it is too few, this isn't really the font's full name,
665 In X11R4, the fonts did not come with their canonical names
676 full_name
= (char *) malloc (p
- p0
+ 1);
678 bcopy (p0
, full_name
, p
- p0
+ 1);
683 font
->font
.full_name
= full_name
;
685 font
->font
.full_name
= font
->font
.name
;
687 font
->file_name
= NULL
;
689 font
->font
.size
= xfont
->max_bounds
.width
;
690 font
->font
.height
= xfont
->ascent
+ xfont
->descent
;
691 font
->font
.baseline_offset
692 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
694 font
->font
.relative_compose
695 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
697 font
->font
.default_ascent
698 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
700 font
->font
.vertical_centering
701 = (STRINGP (Vvertical_centering_font_regexp
)
702 && (fast_c_string_match_ignore_case
703 (Vvertical_centering_font_regexp
, font
->font
.full_name
) >= 0));
709 /* Set global flag fonts_changed_p to non-zero if the font loaded
710 has a character with a smaller width than any other character
711 before, or if the font loaded has a smaller height than any other
712 font loaded before. If this happens, it will make a glyph matrix
713 reallocation necessary. */
714 if (dpyinfo
->n_fonts
== 1)
716 dpyinfo
->smallest_font_height
= font
->font
.height
;
717 dpyinfo
->smallest_char_width
= font
->min_width
;
722 if (dpyinfo
->smallest_font_height
> font
->font
.height
)
723 dpyinfo
->smallest_font_height
= font
->font
.height
, fonts_changed_p
|= 1;
724 if (dpyinfo
->smallest_char_width
> font
->min_width
)
725 dpyinfo
->smallest_char_width
= font
->min_width
, fonts_changed_p
|= 1;
732 xfont_close (f
, font
)
737 XFreeFont (FRAME_X_DISPLAY (f
), font
->font
.font
);
740 if (font
->font
.name
!= font
->font
.full_name
)
741 free (font
->font
.full_name
);
742 free (font
->font
.name
);
744 FRAME_X_DISPLAY_INFO (f
)->n_fonts
--;
748 xfont_prepare_face (f
, face
)
753 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
, face
->font
->fid
);
761 xfont_done_face (f
, face
)
768 XFreeGC (FRAME_X_DISPLAY (f
), (GC
) face
->extra
);
776 xfont_has_char (entity
, c
)
780 Lisp_Object registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
781 struct charset
*repertory
;
783 if (xfont_registry_charsets (registry
, NULL
, &repertory
) < 0)
787 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
791 xfont_encode_char (font
, c
)
795 struct charset
*charset
;
799 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
800 code
= ENCODE_CHAR (charset
, c
);
801 if (code
== CHARSET_INVALID_CODE (charset
))
803 if (font
->repertory_charset
>= 0)
805 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
806 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
807 ? code
: 0xFFFFFFFF);
809 char2b
.byte1
= code
>> 8;
810 char2b
.byte2
= code
& 0xFF;
811 return (xfont_get_pcm (font
->font
.font
, &char2b
) ? code
: 0xFFFFFFFF);
815 xfont_text_extents (font
, code
, nglyphs
, metrics
)
819 struct font_metrics
*metrics
;
825 bzero (metrics
, sizeof (struct font_metrics
));
826 for (i
= 0, x
= 0; i
< nglyphs
; i
++)
829 static XCharStruct
*pcm
;
831 if (code
[i
] >= 0x10000)
833 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
834 pcm
= xfont_get_pcm (font
->font
.font
, &char2b
);
837 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
838 metrics
->lbearing
= width
+ pcm
->lbearing
;
839 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
840 metrics
->rbearing
= width
+ pcm
->rbearing
;
841 if (metrics
->ascent
< pcm
->ascent
)
842 metrics
->ascent
= pcm
->ascent
;
843 if (metrics
->descent
< pcm
->descent
)
844 metrics
->descent
= pcm
->descent
;
848 metrics
->width
= width
;
853 xfont_draw (s
, from
, to
, x
, y
, with_background
)
854 struct glyph_string
*s
;
855 int from
, to
, x
, y
, with_background
;
857 XFontStruct
*xfont
= s
->face
->font
;
861 if (gc
!= s
->face
->gc
)
864 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (s
->f
);
866 XGetGCValues (s
->display
, gc
, GCFont
, &xgcv
);
867 if (xgcv
.font
!= xfont
->fid
)
868 XSetFont (s
->display
, gc
, xfont
->fid
);
871 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
877 SAFE_ALLOCA (str
, char *, len
);
878 for (i
= 0; i
< len
; i
++)
879 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
880 if (with_background
> 0)
881 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
884 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
890 if (with_background
> 0)
891 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
892 gc
, x
, y
, s
->char2b
+ from
, len
);
894 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
895 gc
, x
, y
, s
->char2b
+ from
, len
);
905 staticpro (&x_font_charset_alist
);
906 x_font_charset_alist
= Qnil
;
909 xfont_driver
.type
= Qx
;
910 register_font_driver (&xfont_driver
, NULL
);
913 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
914 (do not change this comment) */