Mercurial > emacs
annotate src/ftfont.c @ 90450:5c96354daf9e
(ftfont_pattern_entity): Fix typo.
(ftfont_list): Enforce FC_LANG in PATTERN to cancel the effect of
locale.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 14 Jun 2006 00:38:48 +0000 |
parents | d63258b13d84 |
children | 4702b592db4c |
rev | line source |
---|---|
90400 | 1 /* ftfont.c -- FreeType font driver. |
2 Copyright (C) 2006 Free Software Foundation, Inc. | |
3 Copyright (C) 2006 | |
4 National Institute of Advanced Industrial Science and Technology (AIST) | |
5 Registration Number H13PRO009 | |
6 | |
7 This file is part of GNU Emacs. | |
8 | |
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) | |
12 any later version. | |
13 | |
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. | |
18 | |
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. */ | |
23 | |
24 #include <config.h> | |
25 #include <stdio.h> | |
26 | |
27 #include <ft2build.h> | |
28 #include FT_FREETYPE_H | |
29 #include FT_SIZES_H | |
30 #include <fontconfig/fontconfig.h> | |
31 #include <fontconfig/fcfreetype.h> | |
32 | |
33 #include "lisp.h" | |
34 #include "dispextern.h" | |
35 #include "frame.h" | |
36 #include "blockinput.h" | |
37 #include "character.h" | |
38 #include "charset.h" | |
39 #include "coding.h" | |
40 #include "fontset.h" | |
41 #include "font.h" | |
42 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
43 /* Symbolic type of this font-driver. */ |
90400 | 44 Lisp_Object Qfreetype; |
45 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
46 /* Flag to tell if FcInit is areadly called or not. */ |
90400 | 47 static int fc_initialized; |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
48 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
49 /* Handle to a FreeType library instance. */ |
90400 | 50 static FT_Library ft_library; |
51 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
52 /* Cache for FreeType fonts. */ |
90400 | 53 static Lisp_Object freetype_font_cache; |
54 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
55 /* Fontconfig's charset used for finding fonts of registry |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
56 "iso8859-1". */ |
90400 | 57 static FcCharSet *cs_iso8859_1; |
58 | |
59 /* The actual structure for FreeType font that can be casted to struct | |
60 font. */ | |
61 | |
62 struct ftfont_info | |
63 { | |
64 struct font font; | |
65 FT_Size ft_size; | |
66 }; | |
67 | |
68 static int | |
69 ftfont_build_basic_charsets () | |
70 { | |
71 FcChar32 c; | |
72 | |
73 cs_iso8859_1 = FcCharSetCreate (); | |
74 if (! cs_iso8859_1) | |
75 return -1; | |
76 for (c = ' '; c < 127; c++) | |
77 if (! FcCharSetAddChar (cs_iso8859_1, c)) | |
78 return -1; | |
79 for (c = 192; c < 256; c++) | |
80 if (! FcCharSetAddChar (cs_iso8859_1, c)) | |
81 return -1; | |
82 return 0; | |
83 } | |
84 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
85 Lisp_Object |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
86 ftfont_pattern_entity (p, frame, registry, name) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
87 FcPattern *p; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
88 Lisp_Object frame, registry, name; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
89 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
90 Lisp_Object entity; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
91 FcChar8 *file; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
92 FcCharSet *charset; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
93 char *str; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
94 int numeric; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
95 double dbl; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
96 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
97 if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
98 return Qnil; |
90450
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
99 if (FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) != FcResultMatch) |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
100 charset = NULL; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
101 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
102 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
103 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
104 ASET (entity, FONT_TYPE_INDEX, Qfreetype); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
105 ASET (entity, FONT_REGISTRY_INDEX, registry); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
106 ASET (entity, FONT_FRAME_INDEX, frame); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
107 ASET (entity, FONT_OBJLIST_INDEX, Qnil); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
108 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
109 if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
110 ASET (entity, FONT_FOUNDRY_INDEX, intern_downcase (str, strlen (str))); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
111 if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
112 ASET (entity, FONT_FAMILY_INDEX, intern_downcase (str, strlen (str))); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
113 if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
114 ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
115 if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
116 ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
117 if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
118 ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
119 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
120 ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
121 else |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
122 ASET (entity, FONT_SIZE_INDEX, make_number (0)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
123 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
124 if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
125 numeric = FC_MONO; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
126 file = FcStrCopy (file); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
127 if (! file) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
128 return Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
129 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
130 p = FcPatternCreate (); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
131 if (! p) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
132 return Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
133 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
134 if (FcPatternAddString (p, FC_FILE, file) == FcFalse |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
135 || (charset && FcPatternAddCharSet (p, FC_CHARSET, charset) == FcFalse) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
136 || FcPatternAddInteger (p, FC_SPACING, numeric) == FcFalse |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
137 || (! NILP (name) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
138 && (FcPatternAddString (p, FC_FILE, (FcChar8 *) SDATA (name)) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
139 == FcFalse))) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
140 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
141 FcPatternDestroy (p); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
142 return Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
143 } |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
144 ASET (entity, FONT_EXTRA_INDEX, make_save_value (p, 0)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
145 return entity; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
146 } |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
147 |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
148 |
90400 | 149 static Lisp_Object ftfont_get_cache P_ ((Lisp_Object)); |
150 static int ftfont_parse_name P_ ((FRAME_PTR, char *, Lisp_Object)); | |
151 static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); | |
152 static Lisp_Object ftfont_list_family P_ ((Lisp_Object)); | |
153 static void ftfont_free_entity P_ ((Lisp_Object)); | |
154 static struct font *ftfont_open P_ ((FRAME_PTR, Lisp_Object, int)); | |
155 static void ftfont_close P_ ((FRAME_PTR, struct font *)); | |
156 static int ftfont_has_char P_ ((Lisp_Object, int)); | |
157 static unsigned ftfont_encode_char P_ ((struct font *, int)); | |
158 static int ftfont_text_extents P_ ((struct font *, unsigned *, int, | |
159 struct font_metrics *)); | |
160 static int ftfont_get_bitmap P_ ((struct font *, unsigned, | |
161 struct font_bitmap *, int)); | |
162 static int ftfont_anchor_point P_ ((struct font *, unsigned, int, | |
163 int *, int *)); | |
164 | |
165 struct font_driver ftfont_driver = | |
166 { | |
167 (Lisp_Object) NULL, /* Qfreetype */ | |
168 ftfont_get_cache, | |
169 ftfont_parse_name, | |
170 ftfont_list, | |
171 ftfont_list_family, | |
172 ftfont_free_entity, | |
173 ftfont_open, | |
174 ftfont_close, | |
175 /* We can't draw a text without device dependent functions. */ | |
176 NULL, | |
177 NULL, | |
178 ftfont_has_char, | |
179 ftfont_encode_char, | |
180 ftfont_text_extents, | |
181 /* We can't draw a text without device dependent functions. */ | |
182 NULL, | |
183 ftfont_get_bitmap, | |
184 NULL, | |
185 NULL, | |
186 NULL, | |
187 ftfont_anchor_point, | |
188 #ifdef HAVE_LIBOTF | |
189 font_otf_capability, | |
190 font_otf_gsub, | |
191 font_otf_gpos | |
192 #else | |
193 NULL, | |
194 NULL, | |
195 NULL | |
196 #endif /* HAVE_LIBOTF */ | |
197 }; | |
198 | |
199 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) | |
200 | |
201 extern Lisp_Object QCname; | |
202 | |
203 static Lisp_Object | |
204 ftfont_get_cache (frame) | |
205 Lisp_Object frame; | |
206 { | |
207 return freetype_font_cache; | |
208 } | |
209 | |
210 static int | |
211 ftfont_parse_name (f, name, spec) | |
212 FRAME_PTR f; | |
213 char *name; | |
214 Lisp_Object spec; | |
215 { | |
216 FcPattern *p; | |
217 FcChar8 *str; | |
218 int numeric; | |
219 double dbl; | |
220 | |
221 if (name[0] == '-' || strchr (name, '*')) | |
222 /* It seems that NAME is XLFD. */ | |
223 return -1; | |
224 p = FcNameParse ((FcChar8 *) name); | |
225 if (! p) | |
226 return -1; | |
227 if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch) | |
228 ASET (spec, FONT_FOUNDRY_INDEX, | |
229 intern_downcase ((char *) str, strlen ((char *) str))); | |
230 if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch) | |
231 ASET (spec, FONT_FAMILY_INDEX, | |
232 intern_downcase ((char *) str, strlen ((char *) str))); | |
233 if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) | |
234 ASET (spec, FONT_WEIGHT_INDEX, make_number (numeric)); | |
235 if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) | |
236 ASET (spec, FONT_SLANT_INDEX, make_number (numeric + 100)); | |
237 if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) | |
238 ASET (spec, FONT_WIDTH_INDEX, make_number (numeric)); | |
239 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) | |
240 ASET (spec, FONT_SIZE_INDEX, make_number (dbl)); | |
241 else if (FcPatternGetDouble (p, FC_SIZE, 0, &dbl) == FcResultMatch) | |
242 ASET (spec, FONT_SIZE_INDEX, make_float (dbl)); | |
243 return 0; | |
244 } | |
245 | |
246 static Lisp_Object | |
247 ftfont_list (frame, spec) | |
248 Lisp_Object frame, spec; | |
249 { | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
250 Lisp_Object val, tmp, extra, font_name, file_name; |
90400 | 251 int i; |
252 FcPattern *pattern = NULL; | |
253 FcCharSet *charset = NULL; | |
254 FcLangSet *langset = NULL; | |
255 FcFontSet *fontset = NULL; | |
256 FcObjectSet *objset = NULL; | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
257 Lisp_Object registry = Qunicode_bmp; |
90400 | 258 |
259 val = null_vector; | |
260 | |
261 if (! fc_initialized) | |
262 { | |
263 FcInit (); | |
264 fc_initialized = 1; | |
265 } | |
266 | |
267 if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX))) | |
268 return val; | |
269 if (! NILP (AREF (spec, FONT_REGISTRY_INDEX))) | |
270 { | |
271 registry = AREF (spec, FONT_REGISTRY_INDEX); | |
272 if (EQ (registry, Qiso8859_1)) | |
273 { | |
274 if (! cs_iso8859_1 | |
275 && ftfont_build_basic_charsets () < 0) | |
276 goto err; | |
277 charset = cs_iso8859_1; | |
278 } | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
279 else if (! EQ (registry, Qiso10646_1) && ! EQ (registry, Qunicode_bmp)) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
280 goto finish; |
90400 | 281 } |
282 | |
283 extra = AREF (spec, FONT_EXTRA_INDEX); | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
284 font_name = file_name = Qnil; |
90400 | 285 if (CONSP (extra)) |
286 { | |
287 tmp = Fassq (QCotf, extra); | |
288 if (! NILP (tmp)) | |
289 return val; | |
290 tmp = Fassq (QClanguage, extra); | |
291 if (CONSP (tmp)) | |
292 { | |
293 langset = FcLangSetCreate (); | |
294 if (! langset) | |
295 goto err; | |
296 tmp = XCDR (tmp); | |
297 if (SYMBOLP (tmp)) | |
298 { | |
299 if (! FcLangSetAdd (langset, SYMBOL_FcChar8 (tmp))) | |
300 goto err; | |
301 } | |
302 else | |
303 while (CONSP (tmp)) | |
304 { | |
305 if (SYMBOLP (XCAR (tmp)) | |
306 && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (tmp)))) | |
307 goto err; | |
308 tmp = XCDR (tmp); | |
309 } | |
310 } | |
311 tmp = Fassq (QCname, extra); | |
312 if (CONSP (tmp)) | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
313 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
314 font_name = XCDR (tmp); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
315 if (SDATA (font_name)[0] == ':') |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
316 file_name = font_name, font_name = Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
317 } |
90400 | 318 tmp = Fassq (QCscript, extra); |
319 if (CONSP (tmp) && ! charset) | |
320 { | |
321 Lisp_Object script = XCDR (tmp); | |
322 Lisp_Object chars = assq_no_quit (script, | |
323 Vscript_representative_chars); | |
324 | |
325 if (CONSP (chars)) | |
326 { | |
327 charset = FcCharSetCreate (); | |
328 if (! charset) | |
329 goto err; | |
330 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) | |
331 if (CHARACTERP (XCAR (chars)) | |
332 && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) | |
333 goto err; | |
334 } | |
335 } | |
336 } | |
337 | |
338 if (STRINGP (font_name)) | |
339 { | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
340 if (SDATA (font_name)[0] == '-') |
90400 | 341 goto finish; |
342 pattern = FcNameParse (SDATA (font_name)); | |
343 if (! pattern) | |
344 goto err; | |
345 } | |
346 else | |
347 { | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
348 if (! NILP (file_name)) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
349 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
350 pattern = FcNameParse (SDATA (file_name)); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
351 FcPatternDel (pattern, FC_PIXEL_SIZE); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
352 } |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
353 else |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
354 pattern = FcPatternCreate (); |
90400 | 355 if (! pattern) |
356 goto err; | |
357 | |
358 tmp = AREF (spec, FONT_FOUNDRY_INDEX); | |
359 if (SYMBOLP (tmp) && ! NILP (tmp) | |
360 && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp))) | |
361 goto err; | |
362 tmp = AREF (spec, FONT_FAMILY_INDEX); | |
363 if (SYMBOLP (tmp) && ! NILP (tmp) | |
364 && ! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (tmp))) | |
365 goto err; | |
366 tmp = AREF (spec, FONT_WEIGHT_INDEX); | |
367 if (INTEGERP (tmp) | |
368 && ! FcPatternAddInteger (pattern, FC_WEIGHT, XINT (tmp))) | |
369 goto err; | |
370 tmp = AREF (spec, FONT_SLANT_INDEX); | |
371 if (INTEGERP (tmp) | |
372 && XINT (tmp) >= 100 | |
373 && ! FcPatternAddInteger (pattern, FC_SLANT, XINT (tmp) - 100)) | |
374 goto err; | |
375 tmp = AREF (spec, FONT_WIDTH_INDEX); | |
376 if (INTEGERP (tmp) | |
377 && ! FcPatternAddInteger (pattern, FC_WIDTH, XINT (tmp))) | |
378 goto err; | |
379 if (! FcPatternAddBool (pattern, FC_SCALABLE, FcTrue)) | |
380 goto err; | |
381 } | |
382 | |
383 if (charset | |
384 && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset)) | |
385 goto err; | |
386 if (langset | |
387 && ! FcPatternAddLangSet (pattern, FC_LANG, langset)) | |
388 goto err; | |
389 | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
390 if (STRINGP (font_name)) |
90400 | 391 { |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
392 FcPattern *pat; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
393 FcResult result; |
90450
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
394 FcValue v; |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
395 Lisp_Object entity; |
90400 | 396 |
90450
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
397 if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch) |
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
398 /* If no language is specified in PATTERN, fontconfig will use |
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
399 that of the current locale. This cancel that effect. */ |
5c96354daf9e
(ftfont_pattern_entity): Fix typo.
Kenichi Handa <handa@m17n.org>
parents:
90441
diff
changeset
|
400 FcPatternAddString (pattern, FC_LANG, (FcChar8 *) "en"); |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
401 FcConfigSubstitute (NULL, pattern, FcMatchPattern); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
402 FcDefaultSubstitute (pattern); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
403 pat = FcFontMatch (NULL, pattern, &result); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
404 entity = ftfont_pattern_entity (pat, frame, registry, font_name); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
405 FcPatternDestroy (pat); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
406 if (! NILP (entity)) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
407 val = Fmake_vector (make_number (1), entity); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
408 } |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
409 else |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
410 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
411 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
412 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
413 FC_CHARSET, FC_FILE, NULL); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
414 if (! objset) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
415 goto err; |
90400 | 416 |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
417 fontset = FcFontList (NULL, pattern, objset); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
418 if (! fontset) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
419 goto err; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
420 val = Qnil; |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
421 for (i = 0; i < fontset->nfont; i++) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
422 { |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
423 Lisp_Object entity = ftfont_pattern_entity (fontset->fonts[i], |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
424 frame, registry, Qnil); |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
425 if (! NILP (entity)) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
426 val = Fcons (entity, val); |
90400 | 427 } |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
428 val = Fvconcat (1, &val); |
90400 | 429 } |
430 goto finish; | |
431 | |
432 err: | |
433 /* We come here because of unexpected error in fontconfig API call | |
434 (usually insufficiency memory). */ | |
435 val = Qnil; | |
436 | |
437 finish: | |
438 if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset); | |
439 if (objset) FcObjectSetDestroy (objset); | |
440 if (fontset) FcFontSetDestroy (fontset); | |
441 if (langset) FcLangSetDestroy (langset); | |
442 if (pattern) FcPatternDestroy (pattern); | |
443 | |
444 return val; | |
445 } | |
446 | |
447 static Lisp_Object | |
448 ftfont_list_family (frame) | |
449 Lisp_Object frame; | |
450 { | |
451 Lisp_Object list; | |
452 FcPattern *pattern = NULL; | |
453 FcFontSet *fontset = NULL; | |
454 FcObjectSet *objset = NULL; | |
455 int i; | |
456 | |
457 if (! fc_initialized) | |
458 { | |
459 FcInit (); | |
460 fc_initialized = 1; | |
461 } | |
462 | |
463 pattern = FcPatternCreate (); | |
464 if (! pattern) | |
465 goto finish; | |
466 objset = FcObjectSetBuild (FC_FAMILY); | |
467 if (! objset) | |
468 goto finish; | |
469 fontset = FcFontList (NULL, pattern, objset); | |
470 if (! fontset) | |
471 goto finish; | |
472 | |
473 list = Qnil; | |
474 for (i = 0; i < fontset->nfont; i++) | |
475 { | |
476 FcPattern *pat = fontset->fonts[i]; | |
477 FcChar8 *str; | |
478 | |
479 if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch) | |
480 list = Fcons (intern_downcase ((char *) str, strlen ((char *) str)), | |
481 list); | |
482 } | |
483 | |
484 finish: | |
485 if (objset) FcObjectSetDestroy (objset); | |
486 if (fontset) FcFontSetDestroy (fontset); | |
487 if (pattern) FcPatternDestroy (pattern); | |
488 | |
489 return list; | |
490 } | |
491 | |
492 | |
493 static void | |
494 ftfont_free_entity (entity) | |
495 Lisp_Object entity; | |
496 { | |
497 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX); | |
498 FcPattern *pattern = XSAVE_VALUE (val)->pointer; | |
499 | |
500 FcPatternDestroy (pattern); | |
501 } | |
502 | |
503 static struct font * | |
504 ftfont_open (f, entity, pixel_size) | |
505 FRAME_PTR f; | |
506 Lisp_Object entity; | |
507 int pixel_size; | |
508 { | |
509 struct ftfont_info *ftfont_info; | |
510 struct font *font; | |
511 FT_Face ft_face; | |
512 FT_Size ft_size; | |
513 FT_UInt size; | |
514 Lisp_Object val; | |
515 FcPattern *pattern; | |
516 FcChar8 *file; | |
517 int spacing; | |
518 | |
519 val = AREF (entity, FONT_EXTRA_INDEX); | |
520 if (XTYPE (val) != Lisp_Misc | |
521 || XMISCTYPE (val) != Lisp_Misc_Save_Value) | |
522 return NULL; | |
523 pattern = XSAVE_VALUE (val)->pointer; | |
524 if (XSAVE_VALUE (val)->integer == 0) | |
525 { | |
526 /* We have not yet created FT_Face for this font. */ | |
527 if (! ft_library | |
528 && FT_Init_FreeType (&ft_library) != 0) | |
529 return NULL; | |
530 if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) | |
531 return NULL; | |
532 if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0) | |
533 return NULL; | |
534 FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face); | |
535 ft_size = ft_face->size; | |
536 } | |
537 else | |
538 { | |
539 if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face) | |
540 != FcResultMatch) | |
541 return NULL; | |
542 if (FT_New_Size (ft_face, &ft_size) != 0) | |
543 return NULL; | |
544 if (FT_Activate_Size (ft_size) != 0) | |
545 { | |
546 FT_Done_Size (ft_size); | |
547 return NULL; | |
548 } | |
549 } | |
550 | |
551 size = XINT (AREF (entity, FONT_SIZE_INDEX)); | |
552 if (size == 0) | |
553 size = pixel_size; | |
554 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) | |
555 { | |
556 if (XSAVE_VALUE (val)->integer == 0) | |
557 FT_Done_Face (ft_face); | |
558 return NULL; | |
559 } | |
560 | |
561 ftfont_info = malloc (sizeof (struct ftfont_info)); | |
562 if (! ftfont_info) | |
563 return NULL; | |
564 ftfont_info->ft_size = ft_size; | |
565 | |
566 font = (struct font *) ftfont_info; | |
567 font->entity = entity; | |
568 font->pixel_size = size; | |
569 font->driver = &ftfont_driver; | |
570 font->font.name = font->font.full_name = NULL; | |
571 font->file_name = (char *) file; | |
572 font->font.size = ft_face->size->metrics.max_advance >> 6; | |
573 font->ascent = ft_face->size->metrics.ascender >> 6; | |
574 font->descent = - ft_face->size->metrics.descender >> 6; | |
575 font->font.height = ft_face->size->metrics.height >> 6; | |
576 if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch | |
577 || spacing != FC_PROPORTIONAL) | |
578 font->font.average_width = font->font.space_width = font->font.size; | |
579 else | |
580 { | |
581 int i; | |
582 | |
583 for (i = 32; i < 127; i++) | |
584 { | |
585 if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) != 0) | |
586 break; | |
587 if (i == 32) | |
588 font->font.space_width = ft_face->glyph->metrics.horiAdvance >> 6; | |
589 font->font.average_width += ft_face->glyph->metrics.horiAdvance >> 6; | |
590 } | |
591 if (i == 127) | |
592 { | |
593 /* The font contains all ASCII printable characters. */ | |
594 font->font.average_width /= 95; | |
595 } | |
596 else | |
597 { | |
598 if (i == 32) | |
599 font->font.space_width = font->font.size; | |
600 font->font.average_width = font->font.size; | |
601 } | |
602 } | |
603 | |
604 font->font.baseline_offset = 0; | |
605 font->font.relative_compose = 0; | |
606 font->font.default_ascent = 0; | |
607 font->font.vertical_centering = 0; | |
608 | |
609 (XSAVE_VALUE (val)->integer)++; | |
610 | |
611 return font; | |
612 } | |
613 | |
614 static void | |
615 ftfont_close (f, font) | |
616 FRAME_PTR f; | |
617 struct font *font; | |
618 { | |
619 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
620 Lisp_Object entity = font->entity; | |
621 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX); | |
622 | |
623 (XSAVE_VALUE (val)->integer)--; | |
624 if (XSAVE_VALUE (val)->integer == 0) | |
625 FT_Done_Face (ftfont_info->ft_size->face); | |
626 else | |
627 FT_Done_Size (ftfont_info->ft_size); | |
628 | |
629 free (font); | |
630 } | |
631 | |
632 static int | |
633 ftfont_has_char (entity, c) | |
634 Lisp_Object entity; | |
635 int c; | |
636 { | |
637 Lisp_Object val; | |
638 FcPattern *pattern; | |
639 FcCharSet *charset; | |
640 | |
641 val = AREF (entity, FONT_EXTRA_INDEX); | |
642 pattern = XSAVE_VALUE (val)->pointer; | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
643 if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) |
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
644 return -1; |
90400 | 645 return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue); |
646 } | |
647 | |
648 static unsigned | |
649 ftfont_encode_char (font, c) | |
650 struct font *font; | |
651 int c; | |
652 { | |
653 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
654 FT_Face ft_face = ftfont_info->ft_size->face; | |
655 FT_ULong charcode = c; | |
656 FT_UInt code = FT_Get_Char_Index (ft_face, charcode); | |
657 | |
658 return (code > 0 ? code : 0xFFFFFFFF); | |
659 } | |
660 | |
661 static int | |
662 ftfont_text_extents (font, code, nglyphs, metrics) | |
663 struct font *font; | |
664 unsigned *code; | |
665 int nglyphs; | |
666 struct font_metrics *metrics; | |
667 { | |
668 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
669 FT_Face ft_face = ftfont_info->ft_size->face; | |
670 int width = 0; | |
671 int i; | |
672 | |
673 if (ftfont_info->ft_size != ft_face->size) | |
674 FT_Activate_Size (ftfont_info->ft_size); | |
675 if (metrics) | |
676 bzero (metrics, sizeof (struct font_metrics)); | |
677 for (i = 0; i < nglyphs; i++) | |
678 { | |
679 if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0) | |
680 { | |
681 FT_Glyph_Metrics *m = &ft_face->glyph->metrics; | |
682 | |
683 if (metrics) | |
684 { | |
685 if (metrics->lbearing > width + (m->horiBearingX >> 6)) | |
686 metrics->lbearing = width + (m->horiBearingX >> 6); | |
687 if (metrics->rbearing | |
688 < width + ((m->horiBearingX + m->width) >> 6)) | |
689 metrics->rbearing | |
690 = width + ((m->horiBearingX + m->width) >> 6); | |
691 if (metrics->ascent < (m->horiBearingY >> 6)) | |
692 metrics->ascent = m->horiBearingY >> 6; | |
693 if (metrics->descent > ((m->horiBearingY + m->height) >> 6)) | |
694 metrics->descent = (m->horiBearingY + m->height) >> 6; | |
695 } | |
696 width += m->horiAdvance >> 6; | |
697 } | |
698 else | |
699 { | |
700 width += font->font.space_width; | |
701 } | |
702 } | |
703 if (metrics) | |
704 metrics->width = width; | |
705 | |
706 return width; | |
707 } | |
708 | |
709 static int | |
710 ftfont_get_bitmap (font, code, bitmap, bits_per_pixel) | |
711 struct font *font; | |
712 unsigned code; | |
713 struct font_bitmap *bitmap; | |
714 int bits_per_pixel; | |
715 { | |
716 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
717 FT_Face ft_face = ftfont_info->ft_size->face; | |
718 FT_Int32 load_flags = FT_LOAD_RENDER; | |
719 | |
720 if (ftfont_info->ft_size != ft_face->size) | |
721 FT_Activate_Size (ftfont_info->ft_size); | |
722 if (bits_per_pixel == 1) | |
723 { | |
724 #ifdef FT_LOAD_TARGET_MONO | |
725 load_flags |= FT_LOAD_TARGET_MONO; | |
726 #else | |
727 load_flags |= FT_LOAD_MONOCHROME; | |
728 #endif | |
729 } | |
730 else if (bits_per_pixel != 8) | |
731 /* We don't support such a rendering. */ | |
732 return -1; | |
733 | |
734 if (FT_Load_Glyph (ft_face, code, load_flags) != 0) | |
735 return -1; | |
736 bitmap->rows = ft_face->glyph->bitmap.rows; | |
737 bitmap->width = ft_face->glyph->bitmap.width; | |
738 bitmap->pitch = ft_face->glyph->bitmap.pitch; | |
739 bitmap->buffer = ft_face->glyph->bitmap.buffer; | |
740 bitmap->left = ft_face->glyph->bitmap_left; | |
741 bitmap->top = ft_face->glyph->bitmap_top; | |
742 bitmap->advance = ft_face->glyph->metrics.horiAdvance >> 6; | |
743 bitmap->extra = NULL; | |
744 | |
745 return 0; | |
746 } | |
747 | |
748 static int | |
749 ftfont_anchor_point (font, code, index, x, y) | |
750 struct font *font; | |
751 unsigned code; | |
752 int index; | |
753 int *x, *y; | |
754 { | |
755 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | |
756 FT_Face ft_face = ftfont_info->ft_size->face; | |
757 | |
758 if (ftfont_info->ft_size != ft_face->size) | |
759 FT_Activate_Size (ftfont_info->ft_size); | |
760 if (FT_Load_Glyph (ft_face, code, FT_LOAD_DEFAULT) != 0) | |
761 return -1; | |
762 if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) | |
763 return -1; | |
764 if (index >= ft_face->glyph->outline.n_points) | |
765 return -1; | |
766 *x = ft_face->glyph->outline.points[index].x; | |
767 *y = ft_face->glyph->outline.points[index].y; | |
768 return 0; | |
769 } | |
770 | |
771 | |
772 void | |
773 syms_of_ftfont () | |
774 { | |
775 staticpro (&freetype_font_cache); | |
90441
d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
Kenichi Handa <handa@m17n.org>
parents:
90427
diff
changeset
|
776 freetype_font_cache = Fcons (Qt, Qnil); |
90400 | 777 |
778 DEFSYM (Qfreetype, "freetype"); | |
779 | |
780 ftfont_driver.type = Qfreetype; | |
781 register_font_driver (&ftfont_driver, NULL); | |
782 } | |
90427 | 783 |
784 /* arch-tag: 7cfa432c-33a6-4988-83d2-a82ed8604aca | |
785 (do not change this comment) */ |