]> git.wh0rd.org - fontconfig.git/blame - src/fcdir.c
Regenerate x86 line in fcarch.tmpl.h to match change in cache data.
[fontconfig.git] / src / fcdir.c
CommitLineData
24330d27 1/*
4bd4418a 2 * $RCSId: xc/lib/fontconfig/src/fcdir.c,v 1.9 2002/08/31 22:17:32 keithp Exp $
24330d27 3 *
46b51147 4 * Copyright © 2000 Keith Packard
24330d27
KP
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
24330d27 25#include "fcint.h"
179c3995
KP
26#include <dirent.h>
27
2d9c79c0 28FcBool
179c3995
KP
29FcFileIsDir (const FcChar8 *file)
30{
31 struct stat statb;
24330d27 32
179c3995
KP
33 if (stat ((const char *) file, &statb) != 0)
34 return FcFalse;
35 return S_ISDIR(statb.st_mode);
36}
24330d27 37
00f059e9
KP
38static FcBool
39FcFileScanFontConfig (FcFontSet *set,
40 FcBlanks *blanks,
41 const FcChar8 *file,
42 FcConfig *config)
24330d27 43{
00f059e9
KP
44 FcPattern *font;
45 FcBool ret = FcTrue;
46 int id;
47 int count = 0;
24330d27
KP
48
49 id = 0;
50 do
51 {
327a7fd4
KP
52 font = 0;
53 /*
eb0cf671 54 * Nothing in the cache, scan the file
327a7fd4 55 */
eb0cf671 56 if (FcDebug () & FC_DBG_SCAN)
24330d27 57 {
eb0cf671
PL
58 printf ("\tScanning file %s...", file);
59 fflush (stdout);
24330d27 60 }
eb0cf671
PL
61 font = FcFreeTypeQuery (file, id, blanks, &count);
62 if (FcDebug () & FC_DBG_SCAN)
63 printf ("done\n");
327a7fd4
KP
64 /*
65 * Add the font
66 */
4f27c1c0 67 if (font && (!config || FcConfigAcceptFont (config, font)))
24330d27
KP
68 {
69 if (!FcFontSetAdd (set, font))
70 {
71 FcPatternDestroy (font);
72 font = 0;
73 ret = FcFalse;
74 }
75 }
47b49bf1
KP
76 else if (font)
77 FcPatternDestroy (font);
24330d27
KP
78 id++;
79 } while (font && ret && id < count);
80 return ret;
81}
82
00f059e9
KP
83FcBool
84FcFileScanConfig (FcFontSet *set,
85 FcStrSet *dirs,
86 FcBlanks *blanks,
87 const FcChar8 *file,
88 FcBool force,
89 FcConfig *config)
90{
91 if (config && !FcConfigAcceptFilename (config, file))
92 return FcTrue;
93
94 if (FcFileIsDir (file))
95 return FcStrSetAdd (dirs, file);
96 else
97 return FcFileScanFontConfig (set, blanks, file, config);
98}
99
d47c9d6e
KP
100FcBool
101FcFileScan (FcFontSet *set,
102 FcStrSet *dirs,
00f059e9 103 FcFileCache *cache, /* XXX unused */
d47c9d6e
KP
104 FcBlanks *blanks,
105 const FcChar8 *file,
106 FcBool force)
107{
00f059e9 108 return FcFileScanConfig (set, dirs, blanks, file, force, 0);
d47c9d6e
KP
109}
110
e3c6d336
PL
111/*
112 * Strcmp helper that takes pointers to pointers, copied from qsort(3) manpage
113 */
114
115static int
116cmpstringp(const void *p1, const void *p2)
117{
118 return strcmp(* (char **) p1, * (char **) p2);
119}
120
c8d5753c
KP
121/*
122 * Scan 'dir', adding font files to 'set' and
123 * subdirectories to 'dirs'
124 */
125
24330d27 126FcBool
d47c9d6e
KP
127FcDirScanConfig (FcFontSet *set,
128 FcStrSet *dirs,
d47c9d6e
KP
129 FcBlanks *blanks,
130 const FcChar8 *dir,
131 FcBool force,
132 FcConfig *config)
24330d27 133{
327a7fd4 134 DIR *d;
0d9e31c8 135 FcChar8 *canon_dir;
327a7fd4 136 struct dirent *e;
00f059e9 137 FcStrSet *dirlist, *filelist;
327a7fd4
KP
138 FcChar8 *file;
139 FcChar8 *base;
140 FcBool ret = FcTrue;
eb0cf671
PL
141 FcFontSet *tmpSet;
142 int i;
24330d27 143
0d9e31c8
KP
144 canon_dir = FcStrCanonFilename (dir);
145 if (!canon_dir) canon_dir = (FcChar8 *) dir;
0d9e31c8
KP
146
147 if (config && !FcConfigAcceptFilename (config, canon_dir)) {
148 ret = FcTrue;
149 goto bail;
150 }
d47c9d6e 151
327a7fd4
KP
152 if (!force)
153 {
0d9e31c8
KP
154 if (FcDirCacheRead (set, dirs, canon_dir, config)) {
155 ret = FcTrue;
156 goto bail;
157 }
327a7fd4
KP
158 }
159
00f059e9 160 if (FcDebug () & FC_DBG_FONTSET)
0d9e31c8 161 printf ("cache scan dir %s\n", canon_dir);
00f059e9 162
9dac3c59 163 /* freed below */
0d9e31c8
KP
164 file = (FcChar8 *) malloc (strlen ((char *) canon_dir) + 1 + FC_MAX_FILE_LEN + 1);
165 if (!file) {
166 ret = FcFalse;
167 goto bail;
168 }
24330d27 169
0d9e31c8 170 strcpy ((char *) file, (char *) canon_dir);
ccb3e93b
KP
171 strcat ((char *) file, "/");
172 base = file + strlen ((char *) file);
24330d27 173
a8386abc 174 if (FcDebug () & FC_DBG_SCAN)
0d9e31c8 175 printf ("\tScanning dir %s\n", canon_dir);
a8386abc 176
0d9e31c8 177 d = opendir ((char *) canon_dir);
24330d27
KP
178 if (!d)
179 {
179c3995
KP
180 /* Don't complain about missing directories */
181 if (errno == ENOENT)
0d9e31c8
KP
182 ret = FcTrue;
183 else
184 ret = FcFalse;
185 goto bail_1;
24330d27 186 }
eb0cf671
PL
187
188 tmpSet = FcFontSetCreate();
65448e8b
PL
189 if (!tmpSet)
190 {
191 ret = FcFalse;
192 goto bail0;
eb0cf671
PL
193 }
194
00f059e9 195 dirlist = FcStrSetCreate ();
65448e8b
PL
196 if (!dirlist)
197 {
198 ret = FcFalse;
199 goto bail1;
200 }
00f059e9
KP
201 filelist = FcStrSetCreate ();
202 if (!filelist)
203 {
204 ret = FcFalse;
205 goto bail2;
206 }
e3c6d336 207 while ((e = readdir (d)))
24330d27 208 {
179c3995 209 if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
24330d27 210 {
00f059e9
KP
211 strcpy ((char *) base, (char *) e->d_name);
212 if (FcFileIsDir (file)) {
213 if (!FcStrSetAdd (dirlist, file)) {
65448e8b 214 ret = FcFalse;
00f059e9
KP
215 goto bail3;
216 }
217 } else {
218 if (!FcStrSetAdd (filelist, file)) {
219 ret = FcFalse;
220 goto bail3;
65448e8b 221 }
65448e8b 222 }
24330d27
KP
223 }
224 }
00f059e9
KP
225 /*
226 * Sort files and dirs to make things prettier
227 */
228 qsort(dirlist->strs, dirlist->num, sizeof(FcChar8 *), cmpstringp);
229 qsort(filelist->strs, filelist->num, sizeof(FcChar8 *), cmpstringp);
230
231 for (i = 0; i < filelist->num; i++)
232 FcFileScanFontConfig (tmpSet, blanks, filelist->strs[i], config);
233
af180c40
KP
234 /*
235 * Now that the directory has been scanned,
236 * write out the cache file
237 */
0d9e31c8 238 FcDirCacheWrite (tmpSet, dirlist, canon_dir, config);
00f059e9 239
c8d5753c 240 /*
00f059e9 241 * Add the discovered fonts to our internal non-cache list
c8d5753c 242 */
eb0cf671
PL
243 for (i = 0; i < tmpSet->nfont; i++)
244 FcFontSetAdd (set, tmpSet->fonts[i]);
245
00f059e9
KP
246 /*
247 * the patterns in tmpset now belong to set; don't free them
248 */
249 tmpSet->nfont = 0;
65448e8b 250
00f059e9
KP
251 /*
252 * Add the discovered directories to the list to be scanned
253 */
254 for (i = 0; i < dirlist->num; i++)
255 if (!FcStrSetAdd (dirs, dirlist->strs[i])) {
256 ret = FcFalse;
257 goto bail3;
258 }
259
260 bail3:
261 FcStrSetDestroy (filelist);
65448e8b 262 bail2:
00f059e9 263 FcStrSetDestroy (dirlist);
65448e8b 264 bail1:
00f059e9 265 FcFontSetDestroy (tmpSet);
65448e8b
PL
266
267 bail0:
268 closedir (d);
269
0d9e31c8 270 bail_1:
65448e8b 271 free (file);
0d9e31c8
KP
272 bail:
273 if (canon_dir != dir) free (canon_dir);
24330d27
KP
274 return ret;
275}
276
d47c9d6e
KP
277FcBool
278FcDirScan (FcFontSet *set,
279 FcStrSet *dirs,
00f059e9 280 FcFileCache *cache, /* XXX unused */
d47c9d6e
KP
281 FcBlanks *blanks,
282 const FcChar8 *dir,
283 FcBool force)
284{
00f059e9 285 return FcDirScanConfig (set, dirs, blanks, dir, force, 0);
d47c9d6e
KP
286}
287
24330d27 288FcBool
2304e38f 289FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir)
24330d27 290{
7410e40b 291 return FcDirCacheWrite (set, dirs, dir, FcConfigGetCurrent ());
24330d27 292}