cf0b154e338c842fcf37138c47ce3304f08ae632
[platform/upstream/fontconfig.git] / src / fcdir.c
1 /*
2  * $XFree86: xc/lib/fontconfig/src/fcdir.c,v 1.2 2002/02/15 06:01:28 keithp Exp $
3  *
4  * Copyright © 2000 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 <sys/types.h>
26 #include <dirent.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "fcint.h"
30
31 #define FC_INVALID_FONT_FILE "."
32
33 FcBool
34 FcFileScan (FcFontSet       *set,
35             FcFileCache     *cache,
36             FcBlanks        *blanks,
37             const FcChar8   *file,
38             FcBool          force)
39 {
40     int             id;
41     FcChar8         *name;
42     FcPattern       *font;
43     FcBool          ret = FcTrue;
44     int             count;
45     
46     id = 0;
47     do
48     {
49         if (!force && cache)
50             name = FcFileCacheFind (cache, file, id, &count);
51         else
52             name = 0;
53         if (name)
54         {
55             /* "." means the file doesn't contain a font */
56             if (strcmp ((const char *) name, FC_INVALID_FONT_FILE) != 0)
57             {
58                 font = FcNameParse (name);
59                 if (font)
60                     FcPatternAddString (font, FC_FILE, file);
61             }
62             else
63                 font = 0;
64         }
65         else
66         {
67             if (FcDebug () & FC_DBG_SCAN)
68             {
69                 printf ("\tScanning file %s...", file);
70                 fflush (stdout);
71             }
72             font = FcFreeTypeQuery (file, id, blanks, &count);
73             if (FcDebug () & FC_DBG_SCAN)
74                 printf ("done\n");
75             if (!force && cache)
76             {
77                 if (font)
78                 {
79                     FcChar8     *unparse;
80
81                     unparse = FcNameUnparse (font);
82                     if (unparse)
83                     {
84                         (void) FcFileCacheUpdate (cache, file, id, unparse);
85                         free (unparse);
86                     }
87                 }
88                 else
89                 {
90                     /* negative cache files not containing fonts */
91                     FcFileCacheUpdate (cache, file, id, (FcChar8 *) FC_INVALID_FONT_FILE);
92                 }
93             }
94         }
95         if (font)
96         {
97             if (!FcFontSetAdd (set, font))
98             {
99                 FcPatternDestroy (font);
100                 font = 0;
101                 ret = FcFalse;
102             }
103         }
104         id++;
105     } while (font && ret && id < count);
106     return ret;
107 }
108
109 FcBool
110 FcDirScan (FcFontSet        *set,
111            FcFileCache      *cache,
112            FcBlanks         *blanks,
113            const FcChar8    *dir,
114            FcBool           force)
115 {
116     DIR             *d;
117     struct dirent   *e;
118     FcChar8         *file;
119     FcChar8         *base;
120     FcBool          ret = FcTrue;
121
122     file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + 256 + 1);
123     if (!file)
124         return FcFalse;
125
126     strcpy ((char *) file, (char *) dir);
127     strcat ((char *) file, "/");
128     base = file + strlen ((char *) file);
129     if (!force)
130     {
131         strcpy ((char *) base, FC_DIR_CACHE_FILE);
132         
133         if (FcFileCacheReadDir (set, file))
134         {
135             free (file);
136             return FcTrue;
137         }
138     }
139     
140     d = opendir ((char *) dir);
141     if (!d)
142     {
143         free (file);
144         return FcFalse;
145     }
146     while (ret && (e = readdir (d)))
147     {
148         if (e->d_name[0] != '.')
149         {
150             strcpy ((char *) base, (char *) e->d_name);
151             FcFileScan (set, cache, blanks, file, force);
152         }
153     }
154     free (file);
155     closedir (d);
156     return ret;
157 }
158
159 FcBool
160 FcDirSave (FcFontSet *set, const FcChar8 *dir)
161 {
162     FcChar8         *file;
163     FcChar8         *base;
164     FcBool          ret;
165     
166     file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + 256 + 1);
167     if (!file)
168         return FcFalse;
169
170     strcpy ((char *) file, (char *) dir);
171     strcat ((char *) file, "/");
172     base = file + strlen ((char *) file);
173     strcpy ((char *) base, FC_DIR_CACHE_FILE);
174     ret = FcFileCacheWriteDir (set, file);
175     free (file);
176     return ret;
177 }
178