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