1 /* ftfont.c -- FreeType 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. */
28 #include FT_FREETYPE_H
30 #include <fontconfig/fontconfig.h>
31 #include <fontconfig/fcfreetype.h>
34 #include "dispextern.h"
36 #include "blockinput.h"
37 #include "character.h"
43 /* Symbolic type of this font-driver. */
44 Lisp_Object Qfreetype
;
46 /* Fontconfig's generic families and their aliases. */
47 static Lisp_Object Qmonospace
, Qsans_serif
, Qserif
, Qmono
, Qsans
, Qsans__serif
;
49 /* Flag to tell if FcInit is areadly called or not. */
50 static int fc_initialized
;
52 /* Handle to a FreeType library instance. */
53 static FT_Library ft_library
;
55 /* Cache for FreeType fonts. */
56 static Lisp_Object freetype_font_cache
;
58 /* Fontconfig's charset used for finding fonts of registry
60 static FcCharSet
*cs_iso8859_1
;
62 /* The actual structure for FreeType font that can be casted to struct
71 static int ftfont_build_basic_charsets
P_ ((void));
72 static Lisp_Object ftfont_pattern_entity
P_ ((FcPattern
*,
73 Lisp_Object
, Lisp_Object
));
74 static Lisp_Object ftfont_list_generic_family
P_ ((Lisp_Object
, Lisp_Object
,
77 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
80 ftfont_build_basic_charsets ()
84 cs_iso8859_1
= FcCharSetCreate ();
87 for (c
= ' '; c
< 127; c
++)
88 if (! FcCharSetAddChar (cs_iso8859_1
, c
))
90 for (c
= 192; c
< 256; c
++)
91 if (! FcCharSetAddChar (cs_iso8859_1
, c
))
97 ftfont_pattern_entity (p
, frame
, registry
)
99 Lisp_Object frame
, registry
;
108 if (FcPatternGetString (p
, FC_FILE
, 0, &file
) != FcResultMatch
)
110 if (FcPatternGetCharSet (p
, FC_CHARSET
, 0, &charset
) != FcResultMatch
)
113 entity
= Fmake_vector (make_number (FONT_ENTITY_MAX
), null_string
);
115 ASET (entity
, FONT_TYPE_INDEX
, Qfreetype
);
116 ASET (entity
, FONT_REGISTRY_INDEX
, registry
);
117 ASET (entity
, FONT_FRAME_INDEX
, frame
);
118 ASET (entity
, FONT_OBJLIST_INDEX
, Qnil
);
120 if (FcPatternGetString (p
, FC_FOUNDRY
, 0, (FcChar8
**) &str
) == FcResultMatch
)
121 ASET (entity
, FONT_FOUNDRY_INDEX
, intern_downcase (str
, strlen (str
)));
122 if (FcPatternGetString (p
, FC_FAMILY
, 0, (FcChar8
**) &str
) == FcResultMatch
)
123 ASET (entity
, FONT_FAMILY_INDEX
, intern_downcase (str
, strlen (str
)));
124 if (FcPatternGetInteger (p
, FC_WEIGHT
, 0, &numeric
) == FcResultMatch
)
125 ASET (entity
, FONT_WEIGHT_INDEX
, make_number (numeric
));
126 if (FcPatternGetInteger (p
, FC_SLANT
, 0, &numeric
) == FcResultMatch
)
127 ASET (entity
, FONT_SLANT_INDEX
, make_number (numeric
+ 100));
128 if (FcPatternGetInteger (p
, FC_WIDTH
, 0, &numeric
) == FcResultMatch
)
129 ASET (entity
, FONT_WIDTH_INDEX
, make_number (numeric
));
130 if (FcPatternGetDouble (p
, FC_PIXEL_SIZE
, 0, &dbl
) == FcResultMatch
)
131 ASET (entity
, FONT_SIZE_INDEX
, make_number (dbl
));
133 ASET (entity
, FONT_SIZE_INDEX
, make_number (0));
135 if (FcPatternGetInteger (p
, FC_SPACING
, 0, &numeric
) != FcResultMatch
)
137 file
= FcStrCopy (file
);
141 p
= FcPatternCreate ();
145 if (FcPatternAddString (p
, FC_FILE
, file
) == FcFalse
146 || (charset
&& FcPatternAddCharSet (p
, FC_CHARSET
, charset
) == FcFalse
)
147 || FcPatternAddInteger (p
, FC_SPACING
, numeric
) == FcFalse
)
149 FcPatternDestroy (p
);
152 ASET (entity
, FONT_EXTRA_INDEX
, make_save_value (p
, 0));
156 static Lisp_Object ftfont_generic_family_list
;
159 ftfont_list_generic_family (spec
, frame
, registry
)
160 Lisp_Object spec
, frame
, registry
;
162 Lisp_Object family
= AREF (spec
, FONT_FAMILY_INDEX
);
163 Lisp_Object slot
, list
, val
;
165 if (EQ (family
, Qmono
))
167 else if (EQ (family
, Qsans
) || EQ (family
, Qsans__serif
))
168 family
= Qsans_serif
;
169 slot
= assq_no_quit (family
, ftfont_generic_family_list
);
175 /* Not yet listed. */
176 FcObjectSet
*objset
= NULL
;
177 FcPattern
*pattern
= NULL
, *pat
= NULL
;
178 FcFontSet
*fontset
= NULL
;
182 objset
= FcObjectSetBuild (FC_FOUNDRY
, FC_FAMILY
, FC_WEIGHT
, FC_SLANT
,
183 FC_WIDTH
, FC_PIXEL_SIZE
, FC_SPACING
,
184 FC_CHARSET
, FC_FILE
, NULL
);
187 pattern
= FcPatternBuild (NULL
, FC_FAMILY
, FcTypeString
,
188 SYMBOL_FcChar8 (family
), (char *) 0);
191 pat
= FcPatternCreate ();
194 FcConfigSubstitute (NULL
, pattern
, FcMatchPattern
);
195 for (i
= 0, val
= Qnil
;
196 FcPatternGetString (pattern
, FC_FAMILY
, i
, &fam
) == FcResultMatch
;
199 if (strcmp ((char *) fam
, (char *) SYMBOL_FcChar8 (family
)) == 0)
201 if (! FcPatternAddString (pat
, FC_FAMILY
, fam
))
203 fontset
= FcFontList (NULL
, pat
, objset
);
206 /* Here we build the list in reverse order so that the last
207 loop in this function build a list in the correct
209 for (j
= 0; j
< fontset
->nfont
; j
++)
213 entity
= ftfont_pattern_entity (fontset
->fonts
[j
],
216 val
= Fcons (entity
, val
);
218 FcFontSetDestroy (fontset
);
220 FcPatternDel (pat
, FC_FAMILY
);
223 XSETCDR (slot
, list
);
225 if (pat
) FcPatternDestroy (pat
);
226 if (pattern
) FcPatternDestroy (pattern
);
227 if (fontset
) FcFontSetDestroy (fontset
);
228 if (objset
) FcObjectSetDestroy (objset
);
232 ASET (spec
, FONT_FAMILY_INDEX
, Qnil
);
233 for (val
= Qnil
; CONSP (list
); list
= XCDR (list
))
234 if (font_match_p (spec
, XCAR (list
)))
235 val
= Fcons (XCAR (list
), val
);
236 ASET (spec
, FONT_FAMILY_INDEX
, family
);
237 return Fvconcat (1, &val
);
241 static Lisp_Object ftfont_get_cache
P_ ((Lisp_Object
));
242 static Lisp_Object ftfont_list
P_ ((Lisp_Object
, Lisp_Object
));
243 static Lisp_Object ftfont_list_family
P_ ((Lisp_Object
));
244 static void ftfont_free_entity
P_ ((Lisp_Object
));
245 static struct font
*ftfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
246 static void ftfont_close
P_ ((FRAME_PTR
, struct font
*));
247 static int ftfont_has_char
P_ ((Lisp_Object
, int));
248 static unsigned ftfont_encode_char
P_ ((struct font
*, int));
249 static int ftfont_text_extents
P_ ((struct font
*, unsigned *, int,
250 struct font_metrics
*));
251 static int ftfont_get_bitmap
P_ ((struct font
*, unsigned,
252 struct font_bitmap
*, int));
253 static int ftfont_anchor_point
P_ ((struct font
*, unsigned, int,
256 struct font_driver ftfont_driver
=
258 (Lisp_Object
) NULL
, /* Qfreetype */
265 /* We can't draw a text without device dependent functions. */
271 /* We can't draw a text without device dependent functions. */
286 #endif /* HAVE_LIBOTF */
289 extern Lisp_Object QCname
;
292 ftfont_get_cache (frame
)
295 return freetype_font_cache
;
299 ftfont_list (frame
, spec
)
300 Lisp_Object frame
, spec
;
302 Lisp_Object val
, tmp
, extra
, font_name
;
304 FcPattern
*pattern
= NULL
;
305 FcCharSet
*charset
= NULL
;
306 FcLangSet
*langset
= NULL
;
307 FcFontSet
*fontset
= NULL
;
308 FcObjectSet
*objset
= NULL
;
309 Lisp_Object registry
= Qunicode_bmp
;
313 if (! fc_initialized
)
319 if (! NILP (AREF (spec
, FONT_ADSTYLE_INDEX
)))
321 if (! NILP (AREF (spec
, FONT_REGISTRY_INDEX
)))
323 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
324 if (EQ (registry
, Qiso8859_1
))
327 && ftfont_build_basic_charsets () < 0)
329 charset
= cs_iso8859_1
;
331 else if (! EQ (registry
, Qiso10646_1
) && ! EQ (registry
, Qunicode_bmp
))
335 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
339 tmp
= Fassq (QCotf
, extra
);
342 tmp
= Fassq (QClanguage
, extra
);
345 langset
= FcLangSetCreate ();
351 if (! FcLangSetAdd (langset
, SYMBOL_FcChar8 (tmp
)))
357 if (SYMBOLP (XCAR (tmp
))
358 && ! FcLangSetAdd (langset
, SYMBOL_FcChar8 (XCAR (tmp
))))
363 tmp
= Fassq (QCname
, extra
);
365 font_name
= XCDR (tmp
);
366 tmp
= Fassq (QCscript
, extra
);
367 if (CONSP (tmp
) && ! charset
)
369 Lisp_Object script
= XCDR (tmp
);
370 Lisp_Object chars
= assq_no_quit (script
,
371 Vscript_representative_chars
);
375 charset
= FcCharSetCreate ();
378 for (chars
= XCDR (chars
); CONSP (chars
); chars
= XCDR (chars
))
379 if (CHARACTERP (XCAR (chars
))
380 && ! FcCharSetAddChar (charset
, XUINT (XCAR (chars
))))
386 if (STRINGP (font_name
))
387 pattern
= FcNameParse (SDATA (font_name
));
389 pattern
= FcPatternCreate ();
393 tmp
= AREF (spec
, FONT_FOUNDRY_INDEX
);
394 if (SYMBOLP (tmp
) && ! NILP (tmp
)
395 && ! FcPatternAddString (pattern
, FC_FOUNDRY
, SYMBOL_FcChar8 (tmp
)))
397 tmp
= AREF (spec
, FONT_FAMILY_INDEX
);
398 if (SYMBOLP (tmp
) && ! NILP (tmp
)
399 && ! FcPatternAddString (pattern
, FC_FAMILY
, SYMBOL_FcChar8 (tmp
)))
401 tmp
= AREF (spec
, FONT_WEIGHT_INDEX
);
403 && ! FcPatternAddInteger (pattern
, FC_WEIGHT
, XINT (tmp
)))
405 tmp
= AREF (spec
, FONT_SLANT_INDEX
);
408 && ! FcPatternAddInteger (pattern
, FC_SLANT
, XINT (tmp
) - 100))
410 tmp
= AREF (spec
, FONT_WIDTH_INDEX
);
412 && ! FcPatternAddInteger (pattern
, FC_WIDTH
, XINT (tmp
)))
414 if (! FcPatternAddBool (pattern
, FC_SCALABLE
, FcTrue
))
418 && ! FcPatternAddCharSet (pattern
, FC_CHARSET
, charset
))
421 && ! FcPatternAddLangSet (pattern
, FC_LANG
, langset
))
424 objset
= FcObjectSetBuild (FC_FOUNDRY
, FC_FAMILY
, FC_WEIGHT
, FC_SLANT
,
425 FC_WIDTH
, FC_PIXEL_SIZE
, FC_SPACING
,
426 FC_CHARSET
, FC_FILE
, NULL
);
429 fontset
= FcFontList (NULL
, pattern
, objset
);
433 if (fontset
->nfont
> 0)
435 for (i
= 0, val
= Qnil
; i
< fontset
->nfont
; i
++)
437 Lisp_Object entity
= ftfont_pattern_entity (fontset
->fonts
[i
],
440 val
= Fcons (entity
, val
);
442 val
= Fvconcat (1, &val
);
444 else if (! NILP (AREF (spec
, FONT_FAMILY_INDEX
)))
445 val
= ftfont_list_generic_family (spec
, frame
, registry
);
449 /* We come here because of unexpected error in fontconfig API call
450 (usually insufficient memory). */
454 if (charset
&& charset
!= cs_iso8859_1
) FcCharSetDestroy (charset
);
455 if (objset
) FcObjectSetDestroy (objset
);
456 if (fontset
) FcFontSetDestroy (fontset
);
457 if (langset
) FcLangSetDestroy (langset
);
458 if (pattern
) FcPatternDestroy (pattern
);
464 ftfont_list_family (frame
)
468 FcPattern
*pattern
= NULL
;
469 FcFontSet
*fontset
= NULL
;
470 FcObjectSet
*objset
= NULL
;
473 if (! fc_initialized
)
479 pattern
= FcPatternCreate ();
482 objset
= FcObjectSetBuild (FC_FAMILY
, NULL
);
485 fontset
= FcFontList (NULL
, pattern
, objset
);
490 for (i
= 0; i
< fontset
->nfont
; i
++)
492 FcPattern
*pat
= fontset
->fonts
[i
];
495 if (FcPatternGetString (pat
, FC_FAMILY
, 0, &str
) == FcResultMatch
)
496 list
= Fcons (intern_downcase ((char *) str
, strlen ((char *) str
)),
501 if (objset
) FcObjectSetDestroy (objset
);
502 if (fontset
) FcFontSetDestroy (fontset
);
503 if (pattern
) FcPatternDestroy (pattern
);
510 ftfont_free_entity (entity
)
513 Lisp_Object val
= AREF (entity
, FONT_EXTRA_INDEX
);
514 FcPattern
*pattern
= XSAVE_VALUE (val
)->pointer
;
516 FcPatternDestroy (pattern
);
520 ftfont_open (f
, entity
, pixel_size
)
525 struct ftfont_info
*ftfont_info
;
535 val
= AREF (entity
, FONT_EXTRA_INDEX
);
536 if (XTYPE (val
) != Lisp_Misc
537 || XMISCTYPE (val
) != Lisp_Misc_Save_Value
)
539 pattern
= XSAVE_VALUE (val
)->pointer
;
540 if (XSAVE_VALUE (val
)->integer
== 0)
542 /* We have not yet created FT_Face for this font. */
544 && FT_Init_FreeType (&ft_library
) != 0)
546 if (FcPatternGetString (pattern
, FC_FILE
, 0, &file
) != FcResultMatch
)
548 if (FT_New_Face (ft_library
, (char *) file
, 0, &ft_face
) != 0)
550 FcPatternAddFTFace (pattern
, FC_FT_FACE
, ft_face
);
551 ft_size
= ft_face
->size
;
555 if (FcPatternGetFTFace (pattern
, FC_FT_FACE
, 0, &ft_face
)
558 if (FT_New_Size (ft_face
, &ft_size
) != 0)
560 if (FT_Activate_Size (ft_size
) != 0)
562 FT_Done_Size (ft_size
);
567 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
570 if (FT_Set_Pixel_Sizes (ft_face
, size
, size
) != 0)
572 if (XSAVE_VALUE (val
)->integer
== 0)
573 FT_Done_Face (ft_face
);
577 ftfont_info
= malloc (sizeof (struct ftfont_info
));
580 ftfont_info
->ft_size
= ft_size
;
582 font
= (struct font
*) ftfont_info
;
583 font
->entity
= entity
;
584 font
->pixel_size
= size
;
585 font
->driver
= &ftfont_driver
;
586 font
->font
.name
= font
->font
.full_name
= NULL
;
587 font
->file_name
= (char *) file
;
588 font
->font
.size
= ft_face
->size
->metrics
.max_advance
>> 6;
589 font
->ascent
= ft_face
->size
->metrics
.ascender
>> 6;
590 font
->descent
= - ft_face
->size
->metrics
.descender
>> 6;
591 font
->font
.height
= ft_face
->size
->metrics
.height
>> 6;
592 if (FcPatternGetInteger (pattern
, FC_SPACING
, 0, &spacing
) != FcResultMatch
593 || spacing
!= FC_PROPORTIONAL
)
594 font
->font
.average_width
= font
->font
.space_width
= font
->font
.size
;
599 for (i
= 32; i
< 127; i
++)
601 if (FT_Load_Char (ft_face
, i
, FT_LOAD_DEFAULT
) != 0)
604 font
->font
.space_width
= ft_face
->glyph
->metrics
.horiAdvance
>> 6;
605 font
->font
.average_width
+= ft_face
->glyph
->metrics
.horiAdvance
>> 6;
609 /* The font contains all ASCII printable characters. */
610 font
->font
.average_width
/= 95;
615 font
->font
.space_width
= font
->font
.size
;
616 font
->font
.average_width
= font
->font
.size
;
620 font
->font
.baseline_offset
= 0;
621 font
->font
.relative_compose
= 0;
622 font
->font
.default_ascent
= 0;
623 font
->font
.vertical_centering
= 0;
625 (XSAVE_VALUE (val
)->integer
)++;
631 ftfont_close (f
, font
)
635 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
636 Lisp_Object entity
= font
->entity
;
637 Lisp_Object val
= AREF (entity
, FONT_EXTRA_INDEX
);
639 (XSAVE_VALUE (val
)->integer
)--;
640 if (XSAVE_VALUE (val
)->integer
== 0)
641 FT_Done_Face (ftfont_info
->ft_size
->face
);
643 FT_Done_Size (ftfont_info
->ft_size
);
649 ftfont_has_char (entity
, c
)
657 val
= AREF (entity
, FONT_EXTRA_INDEX
);
658 pattern
= XSAVE_VALUE (val
)->pointer
;
659 if (FcPatternGetCharSet (pattern
, FC_CHARSET
, 0, &charset
) != FcResultMatch
)
661 return (FcCharSetHasChar (charset
, (FcChar32
) c
) == FcTrue
);
665 ftfont_encode_char (font
, c
)
669 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
670 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
671 FT_ULong charcode
= c
;
672 FT_UInt code
= FT_Get_Char_Index (ft_face
, charcode
);
674 return (code
> 0 ? code
: 0xFFFFFFFF);
678 ftfont_text_extents (font
, code
, nglyphs
, metrics
)
682 struct font_metrics
*metrics
;
684 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
685 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
689 if (ftfont_info
->ft_size
!= ft_face
->size
)
690 FT_Activate_Size (ftfont_info
->ft_size
);
692 bzero (metrics
, sizeof (struct font_metrics
));
693 for (i
= 0; i
< nglyphs
; i
++)
695 if (FT_Load_Glyph (ft_face
, code
[i
], FT_LOAD_DEFAULT
) == 0)
697 FT_Glyph_Metrics
*m
= &ft_face
->glyph
->metrics
;
701 if (metrics
->lbearing
> width
+ (m
->horiBearingX
>> 6))
702 metrics
->lbearing
= width
+ (m
->horiBearingX
>> 6);
703 if (metrics
->rbearing
704 < width
+ ((m
->horiBearingX
+ m
->width
) >> 6))
706 = width
+ ((m
->horiBearingX
+ m
->width
) >> 6);
707 if (metrics
->ascent
< (m
->horiBearingY
>> 6))
708 metrics
->ascent
= m
->horiBearingY
>> 6;
709 if (metrics
->descent
> ((m
->horiBearingY
+ m
->height
) >> 6))
710 metrics
->descent
= (m
->horiBearingY
+ m
->height
) >> 6;
712 width
+= m
->horiAdvance
>> 6;
716 width
+= font
->font
.space_width
;
720 metrics
->width
= width
;
726 ftfont_get_bitmap (font
, code
, bitmap
, bits_per_pixel
)
729 struct font_bitmap
*bitmap
;
732 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
733 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
734 FT_Int32 load_flags
= FT_LOAD_RENDER
;
736 if (ftfont_info
->ft_size
!= ft_face
->size
)
737 FT_Activate_Size (ftfont_info
->ft_size
);
738 if (bits_per_pixel
== 1)
740 #ifdef FT_LOAD_TARGET_MONO
741 load_flags
|= FT_LOAD_TARGET_MONO
;
743 load_flags
|= FT_LOAD_MONOCHROME
;
746 else if (bits_per_pixel
!= 8)
747 /* We don't support such a rendering. */
750 if (FT_Load_Glyph (ft_face
, code
, load_flags
) != 0)
752 bitmap
->rows
= ft_face
->glyph
->bitmap
.rows
;
753 bitmap
->width
= ft_face
->glyph
->bitmap
.width
;
754 bitmap
->pitch
= ft_face
->glyph
->bitmap
.pitch
;
755 bitmap
->buffer
= ft_face
->glyph
->bitmap
.buffer
;
756 bitmap
->left
= ft_face
->glyph
->bitmap_left
;
757 bitmap
->top
= ft_face
->glyph
->bitmap_top
;
758 bitmap
->advance
= ft_face
->glyph
->metrics
.horiAdvance
>> 6;
759 bitmap
->extra
= NULL
;
765 ftfont_anchor_point (font
, code
, index
, x
, y
)
771 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
772 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
774 if (ftfont_info
->ft_size
!= ft_face
->size
)
775 FT_Activate_Size (ftfont_info
->ft_size
);
776 if (FT_Load_Glyph (ft_face
, code
, FT_LOAD_DEFAULT
) != 0)
778 if (ft_face
->glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
780 if (index
>= ft_face
->glyph
->outline
.n_points
)
782 *x
= ft_face
->glyph
->outline
.points
[index
].x
;
783 *y
= ft_face
->glyph
->outline
.points
[index
].y
;
791 DEFSYM (Qfreetype
, "freetype");
792 DEFSYM (Qmonospace
, "monospace");
793 DEFSYM (Qsans_serif
, "sans-serif");
794 DEFSYM (Qserif
, "serif");
795 DEFSYM (Qmono
, "mono");
796 DEFSYM (Qsans
, "sans");
797 DEFSYM (Qsans__serif
, "sans serif");
799 staticpro (&freetype_font_cache
);
800 freetype_font_cache
= Fcons (Qt
, Qnil
);
802 staticpro (&ftfont_generic_family_list
);
803 ftfont_generic_family_list
804 = Fcons (Fcons (Qmonospace
, Qt
),
805 Fcons (Fcons (Qsans_serif
, Qt
),
806 Fcons (Fcons (Qsans
, Qt
), Qnil
)));
808 ftfont_driver
.type
= Qfreetype
;
809 register_font_driver (&ftfont_driver
, NULL
);
812 /* arch-tag: 7cfa432c-33a6-4988-83d2-a82ed8604aca
813 (do not change this comment) */