]> git.wh0rd.org - fontconfig.git/blob - src/fcfreetype.c
Clean up some coverage files; a few accidentally included PUA values and
[fontconfig.git] / src / fcfreetype.c
1 /*
2 * $XFree86: xc/lib/fontconfig/src/fcfreetype.c,v 1.7 2002/07/08 07:31:53 keithp Exp $
3 *
4 * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
15 *
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include "fcint.h"
29 #include <freetype/freetype.h>
30 #include <freetype/internal/ftobjs.h>
31 #include <freetype/tttables.h>
32
33 /*
34 * Keep Han languages separated by eliminating languages
35 * that the codePageRange bits says aren't supported
36 */
37
38 static const struct {
39 int bit;
40 const FcChar8 *lang;
41 } FcCodePageRange[] = {
42 { 17, (const FcChar8 *) "ja" },
43 { 18, (const FcChar8 *) "zh-cn" },
44 { 19, (const FcChar8 *) "ko" },
45 { 20, (const FcChar8 *) "zh-tw" },
46 };
47
48 #define NUM_CODE_PAGE_RANGE (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
49
50 FcBool
51 FcFreeTypeIsExclusiveLang (const FcChar8 *lang)
52 {
53 int i;
54
55 for (i = 0; i < NUM_CODE_PAGE_RANGE; i++)
56 {
57 if (FcLangCompare (lang, FcCodePageRange[i].lang) != FcLangDifferentLang)
58 return FcTrue;
59 }
60 return FcFalse;
61 }
62
63 FcPattern *
64 FcFreeTypeQuery (const FcChar8 *file,
65 int id,
66 FcBlanks *blanks,
67 int *count)
68 {
69 FT_Face face;
70 FcPattern *pat;
71 int slant;
72 int weight;
73 int i;
74 FcCharSet *cs;
75 FT_Library ftLibrary;
76 const FcChar8 *family;
77 TT_OS2 *os2;
78 const FcChar8 *exclusiveLang = 0;
79
80 if (FT_Init_FreeType (&ftLibrary))
81 return 0;
82
83 if (FT_New_Face (ftLibrary, (char *) file, id, &face))
84 goto bail;
85
86 *count = face->num_faces;
87
88 pat = FcPatternCreate ();
89 if (!pat)
90 goto bail0;
91
92 if (!FcPatternAddBool (pat, FC_OUTLINE,
93 (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0))
94 goto bail1;
95
96 if (!FcPatternAddBool (pat, FC_SCALABLE,
97 (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0))
98 goto bail1;
99
100
101 slant = FC_SLANT_ROMAN;
102 if (face->style_flags & FT_STYLE_FLAG_ITALIC)
103 slant = FC_SLANT_ITALIC;
104
105 if (!FcPatternAddInteger (pat, FC_SLANT, slant))
106 goto bail1;
107
108 weight = FC_WEIGHT_MEDIUM;
109 if (face->style_flags & FT_STYLE_FLAG_BOLD)
110 weight = FC_WEIGHT_BOLD;
111
112 if (!FcPatternAddInteger (pat, FC_WEIGHT, weight))
113 goto bail1;
114
115 family = (FcChar8 *) face->family_name;
116 if (!family)
117 {
118 family = (FcChar8 *) strrchr ((char *) file, '/');
119 if (family)
120 family++;
121 else
122 family = file;
123 }
124 if (!FcPatternAddString (pat, FC_FAMILY, family))
125 goto bail1;
126
127 if (face->style_name)
128 {
129 if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name))
130 goto bail1;
131 }
132
133 if (!FcPatternAddString (pat, FC_FILE, file))
134 goto bail1;
135
136 if (!FcPatternAddInteger (pat, FC_INDEX, id))
137 goto bail1;
138
139 if (!FcPatternAddString (pat, FC_SOURCE, (FcChar8 *) "FreeType"))
140 goto bail1;
141
142 #if 1
143 if ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0)
144 if (!FcPatternAddInteger (pat, FC_SPACING, FC_MONO))
145 goto bail1;
146 #endif
147
148 /*
149 * Get the OS/2 table and poke about
150 */
151 os2 = (TT_OS2 *) FT_Get_Sfnt_Table (face, ft_sfnt_os2);
152 if (os2 && os2->version >= 0x0001 && os2->version != 0xffff)
153 {
154 for (i = 0; i < NUM_CODE_PAGE_RANGE; i++)
155 {
156 FT_ULong bits;
157 int bit;
158 if (FcCodePageRange[i].bit < 32)
159 {
160 bits = os2->ulCodePageRange1;
161 bit = FcCodePageRange[i].bit;
162 }
163 else
164 {
165 bits = os2->ulCodePageRange2;
166 bit = FcCodePageRange[i].bit - 32;
167 }
168 if (bits & (1 << bit))
169 {
170 /*
171 * If the font advertises support for multiple
172 * "exclusive" languages, then include support
173 * for any language found to have coverage
174 */
175 if (exclusiveLang)
176 {
177 exclusiveLang = 0;
178 break;
179 }
180 exclusiveLang = FcCodePageRange[i].lang;
181 }
182 }
183 }
184
185 /*
186 * Compute the unicode coverage for the font
187 */
188 cs = FcFreeTypeCharSet (face, blanks);
189 if (!cs)
190 goto bail1;
191
192 /*
193 * Skip over PCF fonts that have no encoded characters; they're
194 * usually just Unicode fonts transcoded to some legacy encoding
195 */
196 if (FcCharSetCount (cs) == 0)
197 {
198 if (!strcmp(FT_MODULE_CLASS(&face->driver->root)->module_name, "pcf"))
199 goto bail2;
200 }
201
202 if (!FcPatternAddCharSet (pat, FC_CHARSET, cs))
203 goto bail2;
204
205 if (!FcFreeTypeSetLang (pat, cs, exclusiveLang))
206 goto bail2;
207
208 /*
209 * Drop our reference to the charset
210 */
211 FcCharSetDestroy (cs);
212
213 if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
214 {
215 for (i = 0; i < face->num_fixed_sizes; i++)
216 if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE,
217 (double) face->available_sizes[i].height))
218 goto bail1;
219 if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse))
220 goto bail1;
221 }
222
223 FT_Done_Face (face);
224 FT_Done_FreeType (ftLibrary);
225 return pat;
226
227 bail2:
228 FcCharSetDestroy (cs);
229 bail1:
230 FcPatternDestroy (pat);
231 bail0:
232 FT_Done_Face (face);
233 bail:
234 FT_Done_FreeType (ftLibrary);
235 return 0;
236 }