]> git.wh0rd.org - fontconfig.git/blob - src/fcfreetype.c
fontconfig library: build fixes and compiler warning fixes
[fontconfig.git] / src / fcfreetype.c
1 /*
2 * $XFree86: $
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 #include <fontconfig/fcfreetype.h>
33
34 static const struct {
35 int bit;
36 FcChar8 *name;
37 } FcCodePageRange[] = {
38 { 0, (FcChar8 *) FC_LANG_LATIN_1 },
39 { 1, (FcChar8 *) FC_LANG_LATIN_2_EASTERN_EUROPE },
40 { 2, (FcChar8 *) FC_LANG_CYRILLIC },
41 { 3, (FcChar8 *) FC_LANG_GREEK },
42 { 4, (FcChar8 *) FC_LANG_TURKISH },
43 { 5, (FcChar8 *) FC_LANG_HEBREW },
44 { 6, (FcChar8 *) FC_LANG_ARABIC },
45 { 7, (FcChar8 *) FC_LANG_WINDOWS_BALTIC },
46 { 8, (FcChar8 *) FC_LANG_VIETNAMESE },
47 /* 9-15 reserved for Alternate ANSI */
48 { 16, (FcChar8 *) FC_LANG_THAI },
49 { 17, (FcChar8 *) FC_LANG_JAPANESE },
50 { 18, (FcChar8 *) FC_LANG_SIMPLIFIED_CHINESE },
51 { 19, (FcChar8 *) FC_LANG_KOREAN_WANSUNG },
52 { 20, (FcChar8 *) FC_LANG_TRADITIONAL_CHINESE },
53 { 21, (FcChar8 *) FC_LANG_KOREAN_JOHAB },
54 /* 22-28 reserved for Alternate ANSI & OEM */
55 { 29, (FcChar8 *) FC_LANG_MACINTOSH },
56 { 30, (FcChar8 *) FC_LANG_OEM },
57 { 31, (FcChar8 *) FC_LANG_SYMBOL },
58 /* 32-47 reserved for OEM */
59 { 48, (FcChar8 *) FC_LANG_IBM_GREEK },
60 { 49, (FcChar8 *) FC_LANG_MSDOS_RUSSIAN },
61 { 50, (FcChar8 *) FC_LANG_MSDOS_NORDIC },
62 { 51, (FcChar8 *) FC_LANG_ARABIC_864 },
63 { 52, (FcChar8 *) FC_LANG_MSDOS_CANADIAN_FRENCH },
64 { 53, (FcChar8 *) FC_LANG_HEBREW_862 },
65 { 54, (FcChar8 *) FC_LANG_MSDOS_ICELANDIC },
66 { 55, (FcChar8 *) FC_LANG_MSDOS_PORTUGUESE },
67 { 56, (FcChar8 *) FC_LANG_IBM_TURKISH },
68 { 57, (FcChar8 *) FC_LANG_IBM_CYRILLIC },
69 { 58, (FcChar8 *) FC_LANG_LATIN_2 },
70 { 59, (FcChar8 *) FC_LANG_MSDOS_BALTIC },
71 { 60, (FcChar8 *) FC_LANG_GREEK_437_G },
72 { 61, (FcChar8 *) FC_LANG_ARABIC_ASMO_708 },
73 { 62, (FcChar8 *) FC_LANG_WE_LATIN_1 },
74 { 63, (FcChar8 *) FC_LANG_US },
75 };
76
77 #define NUM_CODE_PAGE_RANGE (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
78
79 FcPattern *
80 FcFreeTypeQuery (const FcChar8 *file,
81 int id,
82 FcBlanks *blanks,
83 int *count)
84 {
85 FT_Face face;
86 FcPattern *pat;
87 int slant;
88 int weight;
89 int i;
90 FcCharSet *cs;
91 FT_Library ftLibrary;
92 const FcChar8 *family;
93 TT_OS2 *os2;
94
95 if (FT_Init_FreeType (&ftLibrary))
96 return 0;
97
98 if (FT_New_Face (ftLibrary, (char *) file, id, &face))
99 goto bail;
100
101 *count = face->num_faces;
102
103 pat = FcPatternCreate ();
104 if (!pat)
105 goto bail0;
106
107 if (!FcPatternAddBool (pat, FC_OUTLINE,
108 (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0))
109 goto bail1;
110
111 if (!FcPatternAddBool (pat, FC_SCALABLE,
112 (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0))
113 goto bail1;
114
115
116 slant = FC_SLANT_ROMAN;
117 if (face->style_flags & FT_STYLE_FLAG_ITALIC)
118 slant = FC_SLANT_ITALIC;
119
120 if (!FcPatternAddInteger (pat, FC_SLANT, slant))
121 goto bail1;
122
123 weight = FC_WEIGHT_MEDIUM;
124 if (face->style_flags & FT_STYLE_FLAG_BOLD)
125 weight = FC_WEIGHT_BOLD;
126
127 if (!FcPatternAddInteger (pat, FC_WEIGHT, weight))
128 goto bail1;
129
130 family = (FcChar8 *) face->family_name;
131 if (!family)
132 {
133 family = (FcChar8 *) strrchr ((char *) file, '/');
134 if (family)
135 family++;
136 else
137 family = file;
138 }
139 if (!FcPatternAddString (pat, FC_FAMILY, family))
140 goto bail1;
141
142 if (face->style_name)
143 {
144 if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name))
145 goto bail1;
146 }
147
148 if (!FcPatternAddString (pat, FC_FILE, file))
149 goto bail1;
150
151 if (!FcPatternAddInteger (pat, FC_INDEX, id))
152 goto bail1;
153
154 if (!FcPatternAddString (pat, FC_SOURCE, (FcChar8 *) "FreeType"))
155 goto bail1;
156
157 #if 0
158 if ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0)
159 if (!FcPatternAddInteger (pat, FC_SPACING, FC_MONO))
160 goto bail1;
161 #endif
162
163 cs = FcFreeTypeCharSet (face, blanks);
164 if (!cs)
165 goto bail1;
166
167 /*
168 * Skip over PCF fonts that have no encoded characters; they're
169 * usually just Unicode fonts transcoded to some legacy encoding
170 */
171 if (FcCharSetCount (cs) == 0)
172 {
173 if (!strcmp(FT_MODULE_CLASS(&face->driver->root)->module_name, "pcf"))
174 goto bail2;
175 }
176
177 if (!FcPatternAddCharSet (pat, FC_CHARSET, cs))
178 goto bail2;
179 /*
180 * Drop our reference to the charset
181 */
182 FcCharSetDestroy (cs);
183
184 if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
185 {
186 for (i = 0; i < face->num_fixed_sizes; i++)
187 if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE,
188 (double) face->available_sizes[i].height))
189 goto bail1;
190 if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse))
191 goto bail1;
192 }
193
194 /*
195 * Get the OS/2 table and poke about
196 */
197 os2 = (TT_OS2 *) FT_Get_Sfnt_Table (face, ft_sfnt_os2);
198 if (os2 && os2->version >= 0x0001 && os2->version != 0xffff)
199 {
200 for (i = 0; i < NUM_CODE_PAGE_RANGE; i++)
201 {
202 FT_ULong bits;
203 int bit;
204 if (FcCodePageRange[i].bit < 32)
205 {
206 bits = os2->ulCodePageRange1;
207 bit = FcCodePageRange[i].bit;
208 }
209 else
210 {
211 bits = os2->ulCodePageRange2;
212 bit = FcCodePageRange[i].bit - 32;
213 }
214 if (bits & (1 << bit))
215 {
216 if (!FcPatternAddString (pat, FC_LANG,
217 FcCodePageRange[i].name))
218 goto bail1;
219 }
220 }
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 }