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
)
126 if (numeric
== FC_WEIGHT_REGULAR
)
128 ASET (entity
, FONT_WEIGHT_INDEX
, make_number (numeric
));
130 if (FcPatternGetInteger (p
, FC_SLANT
, 0, &numeric
) == FcResultMatch
)
131 ASET (entity
, FONT_SLANT_INDEX
, make_number (numeric
+ 100));
132 if (FcPatternGetInteger (p
, FC_WIDTH
, 0, &numeric
) == FcResultMatch
)
133 ASET (entity
, FONT_WIDTH_INDEX
, make_number (numeric
));
134 if (FcPatternGetDouble (p
, FC_PIXEL_SIZE
, 0, &dbl
) == FcResultMatch
)
135 ASET (entity
, FONT_SIZE_INDEX
, make_number (dbl
));
137 ASET (entity
, FONT_SIZE_INDEX
, make_number (0));
139 if (FcPatternGetInteger (p
, FC_SPACING
, 0, &numeric
) != FcResultMatch
)
141 file
= FcStrCopy (file
);
145 p
= FcPatternCreate ();
149 if (FcPatternAddString (p
, FC_FILE
, file
) == FcFalse
150 || (charset
&& FcPatternAddCharSet (p
, FC_CHARSET
, charset
) == FcFalse
)
151 || FcPatternAddInteger (p
, FC_SPACING
, numeric
) == FcFalse
)
153 FcPatternDestroy (p
);
156 ASET (entity
, FONT_EXTRA_INDEX
, make_save_value (p
, 0));
160 static Lisp_Object ftfont_generic_family_list
;
163 ftfont_list_generic_family (spec
, frame
, registry
)
164 Lisp_Object spec
, frame
, registry
;
166 Lisp_Object family
= AREF (spec
, FONT_FAMILY_INDEX
);
167 Lisp_Object slot
, list
, val
;
169 if (EQ (family
, Qmono
))
171 else if (EQ (family
, Qsans
) || EQ (family
, Qsans__serif
))
172 family
= Qsans_serif
;
173 slot
= assq_no_quit (family
, ftfont_generic_family_list
);
179 /* Not yet listed. */
180 FcObjectSet
*objset
= NULL
;
181 FcPattern
*pattern
= NULL
, *pat
= NULL
;
182 FcFontSet
*fontset
= NULL
;
186 objset
= FcObjectSetBuild (FC_FOUNDRY
, FC_FAMILY
, FC_WEIGHT
, FC_SLANT
,
187 FC_WIDTH
, FC_PIXEL_SIZE
, FC_SPACING
,
188 FC_CHARSET
, FC_FILE
, NULL
);
191 pattern
= FcPatternBuild (NULL
, FC_FAMILY
, FcTypeString
,
192 SYMBOL_FcChar8 (family
), (char *) 0);
195 pat
= FcPatternCreate ();
198 FcConfigSubstitute (NULL
, pattern
, FcMatchPattern
);
199 for (i
= 0, val
= Qnil
;
200 FcPatternGetString (pattern
, FC_FAMILY
, i
, &fam
) == FcResultMatch
;
203 if (strcmp ((char *) fam
, (char *) SYMBOL_FcChar8 (family
)) == 0)
205 if (! FcPatternAddString (pat
, FC_FAMILY
, fam
))
207 fontset
= FcFontList (NULL
, pat
, objset
);
210 /* Here we build the list in reverse order so that the last
211 loop in this function build a list in the correct
213 for (j
= 0; j
< fontset
->nfont
; j
++)
217 entity
= ftfont_pattern_entity (fontset
->fonts
[j
],
220 val
= Fcons (entity
, val
);
222 FcFontSetDestroy (fontset
);
224 FcPatternDel (pat
, FC_FAMILY
);
227 XSETCDR (slot
, list
);
229 if (pat
) FcPatternDestroy (pat
);
230 if (pattern
) FcPatternDestroy (pattern
);
231 if (fontset
) FcFontSetDestroy (fontset
);
232 if (objset
) FcObjectSetDestroy (objset
);
236 ASET (spec
, FONT_FAMILY_INDEX
, Qnil
);
237 for (val
= Qnil
; CONSP (list
); list
= XCDR (list
))
238 if (font_match_p (spec
, XCAR (list
)))
239 val
= Fcons (XCAR (list
), val
);
240 ASET (spec
, FONT_FAMILY_INDEX
, family
);
241 return Fvconcat (1, &val
);
245 static Lisp_Object ftfont_get_cache
P_ ((Lisp_Object
));
246 static Lisp_Object ftfont_list
P_ ((Lisp_Object
, Lisp_Object
));
247 static Lisp_Object ftfont_list_family
P_ ((Lisp_Object
));
248 static void ftfont_free_entity
P_ ((Lisp_Object
));
249 static struct font
*ftfont_open
P_ ((FRAME_PTR
, Lisp_Object
, int));
250 static void ftfont_close
P_ ((FRAME_PTR
, struct font
*));
251 static int ftfont_has_char
P_ ((Lisp_Object
, int));
252 static unsigned ftfont_encode_char
P_ ((struct font
*, int));
253 static int ftfont_text_extents
P_ ((struct font
*, unsigned *, int,
254 struct font_metrics
*));
255 static int ftfont_get_bitmap
P_ ((struct font
*, unsigned,
256 struct font_bitmap
*, int));
257 static int ftfont_anchor_point
P_ ((struct font
*, unsigned, int,
260 struct font_driver ftfont_driver
=
262 (Lisp_Object
) NULL
, /* Qfreetype */
269 /* We can't draw a text without device dependent functions. */
275 /* We can't draw a text without device dependent functions. */
290 #endif /* HAVE_LIBOTF */
293 extern Lisp_Object QCname
;
296 ftfont_get_cache (frame
)
299 return freetype_font_cache
;
303 ftfont_list (frame
, spec
)
304 Lisp_Object frame
, spec
;
306 Lisp_Object val
, tmp
, extra
, font_name
;
308 FcPattern
*pattern
= NULL
;
309 FcCharSet
*charset
= NULL
;
310 FcLangSet
*langset
= NULL
;
311 FcFontSet
*fontset
= NULL
;
312 FcObjectSet
*objset
= NULL
;
313 Lisp_Object registry
= Qunicode_bmp
;
317 if (! fc_initialized
)
323 if (! NILP (AREF (spec
, FONT_ADSTYLE_INDEX
)))
325 if (! NILP (AREF (spec
, FONT_REGISTRY_INDEX
)))
327 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
328 if (EQ (registry
, Qiso8859_1
))
331 && ftfont_build_basic_charsets () < 0)
333 charset
= cs_iso8859_1
;
335 else if (! EQ (registry
, Qiso10646_1
) && ! EQ (registry
, Qunicode_bmp
))
339 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
343 tmp
= Fassq (QCotf
, extra
);
346 tmp
= Fassq (QClanguage
, extra
);
349 langset
= FcLangSetCreate ();
355 if (! FcLangSetAdd (langset
, SYMBOL_FcChar8 (tmp
)))
361 if (SYMBOLP (XCAR (tmp
))
362 && ! FcLangSetAdd (langset
, SYMBOL_FcChar8 (XCAR (tmp
))))
367 tmp
= Fassq (QCname
, extra
);
369 font_name
= XCDR (tmp
);
370 tmp
= Fassq (QCscript
, extra
);
371 if (CONSP (tmp
) && ! charset
)
373 Lisp_Object script
= XCDR (tmp
);
374 Lisp_Object chars
= assq_no_quit (script
,
375 Vscript_representative_chars
);
379 charset
= FcCharSetCreate ();
382 for (chars
= XCDR (chars
); CONSP (chars
); chars
= XCDR (chars
))
383 if (CHARACTERP (XCAR (chars
))
384 && ! FcCharSetAddChar (charset
, XUINT (XCAR (chars
))))
390 if (STRINGP (font_name
))
392 pattern
= FcNameParse (SDATA (font_name
));
393 /* Ignore these values in listing. */
394 FcPatternDel (pattern
, FC_PIXEL_SIZE
);
395 FcPatternDel (pattern
, FC_SIZE
);
396 FcPatternDel (pattern
, FC_FAMILY
);
399 pattern
= FcPatternCreate ();
403 tmp
= AREF (spec
, FONT_FOUNDRY_INDEX
);
404 if (SYMBOLP (tmp
) && ! NILP (tmp
)
405 && ! FcPatternAddString (pattern
, FC_FOUNDRY
, SYMBOL_FcChar8 (tmp
)))
407 tmp
= AREF (spec
, FONT_FAMILY_INDEX
);
408 if (SYMBOLP (tmp
) && ! NILP (tmp
)
409 && ! FcPatternAddString (pattern
, FC_FAMILY
, SYMBOL_FcChar8 (tmp
)))
411 tmp
= AREF (spec
, FONT_WEIGHT_INDEX
);
413 && ! FcPatternAddInteger (pattern
, FC_WEIGHT
, XINT (tmp
)))
415 tmp
= AREF (spec
, FONT_SLANT_INDEX
);
418 && ! FcPatternAddInteger (pattern
, FC_SLANT
, XINT (tmp
) - 100))
420 tmp
= AREF (spec
, FONT_WIDTH_INDEX
);
422 && ! FcPatternAddInteger (pattern
, FC_WIDTH
, XINT (tmp
)))
425 if (! FcPatternAddBool (pattern
, FC_SCALABLE
, FcTrue
))
430 && ! FcPatternAddCharSet (pattern
, FC_CHARSET
, charset
))
433 && ! FcPatternAddLangSet (pattern
, FC_LANG
, langset
))
436 objset
= FcObjectSetBuild (FC_FOUNDRY
, FC_FAMILY
, FC_WEIGHT
, FC_SLANT
,
437 FC_WIDTH
, FC_PIXEL_SIZE
, FC_SPACING
,
438 FC_CHARSET
, FC_FILE
, NULL
);
442 fontset
= FcFontList (NULL
, pattern
, objset
);
446 if (fontset
->nfont
> 0)
450 if (NILP (AREF (spec
, FONT_SIZE_INDEX
)))
453 pixel_size
= XINT (AREF (spec
, FONT_SIZE_INDEX
));
455 for (i
= 0, val
= Qnil
; i
< fontset
->nfont
; i
++)
463 if (FcPatternGetDouble (fontset
->fonts
[i
], FC_PIXEL_SIZE
, 0,
464 &this) == FcResultMatch
465 && this != pixel_size
)
468 entity
= ftfont_pattern_entity (fontset
->fonts
[i
], frame
, registry
);
470 val
= Fcons (entity
, val
);
472 val
= Fvconcat (1, &val
);
474 else if (! NILP (AREF (spec
, FONT_FAMILY_INDEX
)))
475 val
= ftfont_list_generic_family (spec
, frame
, registry
);
479 /* We come here because of unexpected error in fontconfig API call
480 (usually insufficient memory). */
484 if (charset
&& charset
!= cs_iso8859_1
) FcCharSetDestroy (charset
);
485 if (objset
) FcObjectSetDestroy (objset
);
486 if (fontset
) FcFontSetDestroy (fontset
);
487 if (langset
) FcLangSetDestroy (langset
);
488 if (pattern
) FcPatternDestroy (pattern
);
494 ftfont_list_family (frame
)
498 FcPattern
*pattern
= NULL
;
499 FcFontSet
*fontset
= NULL
;
500 FcObjectSet
*objset
= NULL
;
503 if (! fc_initialized
)
509 pattern
= FcPatternCreate ();
512 objset
= FcObjectSetBuild (FC_FAMILY
, NULL
);
515 fontset
= FcFontList (NULL
, pattern
, objset
);
520 for (i
= 0; i
< fontset
->nfont
; i
++)
522 FcPattern
*pat
= fontset
->fonts
[i
];
525 if (FcPatternGetString (pat
, FC_FAMILY
, 0, &str
) == FcResultMatch
)
526 list
= Fcons (intern_downcase ((char *) str
, strlen ((char *) str
)),
531 if (objset
) FcObjectSetDestroy (objset
);
532 if (fontset
) FcFontSetDestroy (fontset
);
533 if (pattern
) FcPatternDestroy (pattern
);
540 ftfont_free_entity (entity
)
543 Lisp_Object val
= AREF (entity
, FONT_EXTRA_INDEX
);
544 FcPattern
*pattern
= XSAVE_VALUE (val
)->pointer
;
546 FcPatternDestroy (pattern
);
550 ftfont_open (f
, entity
, pixel_size
)
555 struct ftfont_info
*ftfont_info
;
565 val
= AREF (entity
, FONT_EXTRA_INDEX
);
566 if (XTYPE (val
) != Lisp_Misc
567 || XMISCTYPE (val
) != Lisp_Misc_Save_Value
)
569 pattern
= XSAVE_VALUE (val
)->pointer
;
570 if (XSAVE_VALUE (val
)->integer
== 0)
572 /* We have not yet created FT_Face for this font. */
574 && FT_Init_FreeType (&ft_library
) != 0)
576 if (FcPatternGetString (pattern
, FC_FILE
, 0, &file
) != FcResultMatch
)
578 if (FT_New_Face (ft_library
, (char *) file
, 0, &ft_face
) != 0)
580 FcPatternAddFTFace (pattern
, FC_FT_FACE
, ft_face
);
581 ft_size
= ft_face
->size
;
585 if (FcPatternGetFTFace (pattern
, FC_FT_FACE
, 0, &ft_face
)
588 if (FT_New_Size (ft_face
, &ft_size
) != 0)
590 if (FT_Activate_Size (ft_size
) != 0)
592 FT_Done_Size (ft_size
);
597 size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
600 if (FT_Set_Pixel_Sizes (ft_face
, size
, size
) != 0)
602 if (XSAVE_VALUE (val
)->integer
== 0)
603 FT_Done_Face (ft_face
);
607 ftfont_info
= malloc (sizeof (struct ftfont_info
));
610 ftfont_info
->ft_size
= ft_size
;
612 font
= (struct font
*) ftfont_info
;
613 font
->entity
= entity
;
614 font
->pixel_size
= size
;
615 font
->driver
= &ftfont_driver
;
616 font
->font
.name
= font
->font
.full_name
= NULL
;
617 font
->file_name
= (char *) file
;
618 font
->font
.size
= ft_face
->size
->metrics
.max_advance
>> 6;
619 font
->ascent
= ft_face
->size
->metrics
.ascender
>> 6;
620 font
->descent
= - ft_face
->size
->metrics
.descender
>> 6;
621 font
->font
.height
= ft_face
->size
->metrics
.height
>> 6;
622 if (FcPatternGetInteger (pattern
, FC_SPACING
, 0, &spacing
) != FcResultMatch
623 || spacing
!= FC_PROPORTIONAL
)
624 font
->font
.average_width
= font
->font
.space_width
= font
->font
.size
;
629 for (i
= 32; i
< 127; i
++)
631 if (FT_Load_Char (ft_face
, i
, FT_LOAD_DEFAULT
) != 0)
634 font
->font
.space_width
= ft_face
->glyph
->metrics
.horiAdvance
>> 6;
635 font
->font
.average_width
+= ft_face
->glyph
->metrics
.horiAdvance
>> 6;
639 /* The font contains all ASCII printable characters. */
640 font
->font
.average_width
/= 95;
645 font
->font
.space_width
= font
->font
.size
;
646 font
->font
.average_width
= font
->font
.size
;
650 font
->font
.baseline_offset
= 0;
651 font
->font
.relative_compose
= 0;
652 font
->font
.default_ascent
= 0;
653 font
->font
.vertical_centering
= 0;
655 (XSAVE_VALUE (val
)->integer
)++;
661 ftfont_close (f
, font
)
665 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
666 Lisp_Object entity
= font
->entity
;
667 Lisp_Object val
= AREF (entity
, FONT_EXTRA_INDEX
);
669 (XSAVE_VALUE (val
)->integer
)--;
670 if (XSAVE_VALUE (val
)->integer
== 0)
671 FT_Done_Face (ftfont_info
->ft_size
->face
);
673 FT_Done_Size (ftfont_info
->ft_size
);
679 ftfont_has_char (entity
, c
)
687 val
= AREF (entity
, FONT_EXTRA_INDEX
);
688 pattern
= XSAVE_VALUE (val
)->pointer
;
689 if (FcPatternGetCharSet (pattern
, FC_CHARSET
, 0, &charset
) != FcResultMatch
)
691 return (FcCharSetHasChar (charset
, (FcChar32
) c
) == FcTrue
);
695 ftfont_encode_char (font
, c
)
699 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
700 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
701 FT_ULong charcode
= c
;
702 FT_UInt code
= FT_Get_Char_Index (ft_face
, charcode
);
704 return (code
> 0 ? code
: 0xFFFFFFFF);
708 ftfont_text_extents (font
, code
, nglyphs
, metrics
)
712 struct font_metrics
*metrics
;
714 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
715 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
719 if (ftfont_info
->ft_size
!= ft_face
->size
)
720 FT_Activate_Size (ftfont_info
->ft_size
);
722 bzero (metrics
, sizeof (struct font_metrics
));
723 for (i
= 0; i
< nglyphs
; i
++)
725 if (FT_Load_Glyph (ft_face
, code
[i
], FT_LOAD_DEFAULT
) == 0)
727 FT_Glyph_Metrics
*m
= &ft_face
->glyph
->metrics
;
731 if (metrics
->lbearing
> width
+ (m
->horiBearingX
>> 6))
732 metrics
->lbearing
= width
+ (m
->horiBearingX
>> 6);
733 if (metrics
->rbearing
734 < width
+ ((m
->horiBearingX
+ m
->width
) >> 6))
736 = width
+ ((m
->horiBearingX
+ m
->width
) >> 6);
737 if (metrics
->ascent
< (m
->horiBearingY
>> 6))
738 metrics
->ascent
= m
->horiBearingY
>> 6;
739 if (metrics
->descent
> ((m
->horiBearingY
+ m
->height
) >> 6))
740 metrics
->descent
= (m
->horiBearingY
+ m
->height
) >> 6;
742 width
+= m
->horiAdvance
>> 6;
746 width
+= font
->font
.space_width
;
750 metrics
->width
= width
;
756 ftfont_get_bitmap (font
, code
, bitmap
, bits_per_pixel
)
759 struct font_bitmap
*bitmap
;
762 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
763 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
764 FT_Int32 load_flags
= FT_LOAD_RENDER
;
766 if (ftfont_info
->ft_size
!= ft_face
->size
)
767 FT_Activate_Size (ftfont_info
->ft_size
);
768 if (bits_per_pixel
== 1)
770 #ifdef FT_LOAD_TARGET_MONO
771 load_flags
|= FT_LOAD_TARGET_MONO
;
773 load_flags
|= FT_LOAD_MONOCHROME
;
776 else if (bits_per_pixel
!= 8)
777 /* We don't support such a rendering. */
780 if (FT_Load_Glyph (ft_face
, code
, load_flags
) != 0)
782 bitmap
->rows
= ft_face
->glyph
->bitmap
.rows
;
783 bitmap
->width
= ft_face
->glyph
->bitmap
.width
;
784 bitmap
->pitch
= ft_face
->glyph
->bitmap
.pitch
;
785 bitmap
->buffer
= ft_face
->glyph
->bitmap
.buffer
;
786 bitmap
->left
= ft_face
->glyph
->bitmap_left
;
787 bitmap
->top
= ft_face
->glyph
->bitmap_top
;
788 bitmap
->advance
= ft_face
->glyph
->metrics
.horiAdvance
>> 6;
789 bitmap
->extra
= NULL
;
795 ftfont_anchor_point (font
, code
, index
, x
, y
)
801 struct ftfont_info
*ftfont_info
= (struct ftfont_info
*) font
;
802 FT_Face ft_face
= ftfont_info
->ft_size
->face
;
804 if (ftfont_info
->ft_size
!= ft_face
->size
)
805 FT_Activate_Size (ftfont_info
->ft_size
);
806 if (FT_Load_Glyph (ft_face
, code
, FT_LOAD_DEFAULT
) != 0)
808 if (ft_face
->glyph
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
810 if (index
>= ft_face
->glyph
->outline
.n_points
)
812 *x
= ft_face
->glyph
->outline
.points
[index
].x
;
813 *y
= ft_face
->glyph
->outline
.points
[index
].y
;
821 DEFSYM (Qfreetype
, "freetype");
822 DEFSYM (Qmonospace
, "monospace");
823 DEFSYM (Qsans_serif
, "sans-serif");
824 DEFSYM (Qserif
, "serif");
825 DEFSYM (Qmono
, "mono");
826 DEFSYM (Qsans
, "sans");
827 DEFSYM (Qsans__serif
, "sans serif");
829 staticpro (&freetype_font_cache
);
830 freetype_font_cache
= Fcons (Qt
, Qnil
);
832 staticpro (&ftfont_generic_family_list
);
833 ftfont_generic_family_list
834 = Fcons (Fcons (Qmonospace
, Qt
),
835 Fcons (Fcons (Qsans_serif
, Qt
),
836 Fcons (Fcons (Qsans
, Qt
), Qnil
)));
838 ftfont_driver
.type
= Qfreetype
;
839 register_font_driver (&ftfont_driver
, NULL
);
842 /* arch-tag: 7cfa432c-33a6-4988-83d2-a82ed8604aca
843 (do not change this comment) */