fcinit.c revision ca08ab68
1/*
2 * fontconfig/src/fcinit.c
3 *
4 * Copyright © 2001 Keith Packard
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 the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission.  The authors make 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 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) 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 "fcint.h"
26#include <stdlib.h>
27
28static FcConfig *
29FcInitFallbackConfig (void)
30{
31    FcConfig	*config;
32
33    config = FcConfigCreate ();
34    if (!config)
35	goto bail0;
36    if (!FcConfigAddDir (config, (FcChar8 *) FC_DEFAULT_FONTS))
37	goto bail1;
38    if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR))
39	goto bail1;
40    return config;
41
42bail1:
43    FcConfigDestroy (config);
44bail0:
45    return 0;
46}
47
48int
49FcGetVersion (void)
50{
51    return FC_VERSION;
52}
53
54/*
55 * Load the configuration files
56 */
57FcConfig *
58FcInitLoadConfig (void)
59{
60    FcConfig	*config;
61
62    FcInitDebug ();
63    config = FcConfigCreate ();
64    if (!config)
65	return NULL;
66
67    if (!FcConfigParseAndLoad (config, 0, FcTrue))
68    {
69	FcConfigDestroy (config);
70	return FcInitFallbackConfig ();
71    }
72
73    if (config->cacheDirs && config->cacheDirs->num == 0)
74    {
75	FcChar8 *prefix;
76	size_t plen;
77
78	fprintf (stderr,
79		 "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
80	fprintf (stderr,
81		 "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
82		 FC_CACHEDIR);
83	prefix = FcConfigXdgCacheHome ();
84	plen = prefix ? strlen ((const char *)prefix) : 0;
85	if (!prefix)
86	    goto bail;
87	prefix = realloc (prefix, plen + 12);
88	if (!prefix)
89	    goto bail;
90	memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
91	prefix[plen + 11] = 0;
92	fprintf (stderr,
93		 "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
94
95	if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
96	    !FcConfigAddCacheDir (config, (FcChar8 *) prefix))
97	{
98	  bail:
99	    fprintf (stderr,
100		     "Fontconfig error: out of memory");
101	    free (prefix);
102	    FcConfigDestroy (config);
103	    return FcInitFallbackConfig ();
104	}
105	free (prefix);
106    }
107
108    return config;
109}
110
111/*
112 * Load the configuration files and scan for available fonts
113 */
114FcConfig *
115FcInitLoadConfigAndFonts (void)
116{
117    FcConfig	*config = FcInitLoadConfig ();
118
119    FcInitDebug ();
120    if (!config)
121	return 0;
122    if (!FcConfigBuildFonts (config))
123    {
124	FcConfigDestroy (config);
125	return 0;
126    }
127    return config;
128}
129
130/*
131 * Initialize the default library configuration
132 */
133FcBool
134FcInit (void)
135{
136    FcConfig	*config;
137
138    if (_fcConfig)
139	return FcTrue;
140    config = FcInitLoadConfigAndFonts ();
141    if (!config)
142	return FcFalse;
143    FcConfigSetCurrent (config);
144    if (FcDebug() & FC_DBG_MEMORY)
145	FcMemReport ();
146    return FcTrue;
147}
148
149/*
150 * Free all library-allocated data structures.
151 */
152void
153FcFini (void)
154{
155    if (_fcConfig)
156	FcConfigDestroy (_fcConfig);
157
158    FcObjectFini ();
159    FcCacheFini ();
160    if (FcDebug() & FC_DBG_MEMORY)
161	FcMemReport ();
162}
163
164/*
165 * Reread the configuration and available font lists
166 */
167FcBool
168FcInitReinitialize (void)
169{
170    FcConfig	*config;
171
172    config = FcInitLoadConfigAndFonts ();
173    if (!config)
174	return FcFalse;
175    FcConfigSetCurrent (config);
176    return FcTrue;
177}
178
179FcBool
180FcInitBringUptoDate (void)
181{
182    FcConfig	*config = FcConfigGetCurrent ();
183    time_t	now;
184
185    /*
186     * rescanInterval == 0 disables automatic up to date
187     */
188    if (config->rescanInterval == 0)
189	return FcTrue;
190    /*
191     * Check no more often than rescanInterval seconds
192     */
193    now = time (0);
194    if (config->rescanTime + config->rescanInterval - now > 0)
195	return FcTrue;
196    /*
197     * If up to date, don't reload configuration
198     */
199    if (FcConfigUptoDate (0))
200	return FcTrue;
201    return FcInitReinitialize ();
202}
203
204static struct {
205    char    name[16];
206    int	    alloc_count;
207    int	    alloc_mem;
208    int	    free_count;
209    int	    free_mem;
210} FcInUse[FC_MEM_NUM] = {
211    { "charset" },
212    { "charleaf" },
213    { "fontset" },
214    { "fontptr" },
215    { "objectset" },
216    { "objectptr" },
217    { "matrix" },
218    { "pattern" },
219    { "patelt" },
220    { "vallist" },
221    { "substate" },
222    { "string" },
223    { "listbuck" },
224    { "strset" },
225    { "strlist" },
226    { "config" },
227    { "langset" },
228    { "atomic" },
229    { "blanks" },
230    { "cache" },
231    { "strbuf" },
232    { "subst" },
233    { "objecttype" },
234    { "constant" },
235    { "test" },
236    { "expr" },
237    { "vstack" },
238    { "attr" },
239    { "pstack" },
240    { "sharedstr" },
241};
242
243static int  FcAllocCount, FcAllocMem;
244static int  FcFreeCount, FcFreeMem;
245
246static int  FcMemNotice = 1*1024*1024;
247
248static int  FcAllocNotify, FcFreeNotify;
249
250void
251FcMemReport (void)
252{
253    int	i;
254    printf ("Fc Memory Usage:\n");
255    printf ("\t   Which       Alloc           Free           Active\n");
256    printf ("\t           count   bytes   count   bytes   count   bytes\n");
257    for (i = 0; i < FC_MEM_NUM; i++)
258	printf ("%16.16s%8d%8d%8d%8d%8d%8d\n",
259		FcInUse[i].name,
260		FcInUse[i].alloc_count, FcInUse[i].alloc_mem,
261		FcInUse[i].free_count, FcInUse[i].free_mem,
262		FcInUse[i].alloc_count - FcInUse[i].free_count,
263		FcInUse[i].alloc_mem - FcInUse[i].free_mem);
264    printf ("%16.16s%8d%8d%8d%8d%8d%8d\n",
265	    "Total",
266	    FcAllocCount, FcAllocMem,
267	    FcFreeCount, FcFreeMem,
268	    FcAllocCount - FcFreeCount,
269	    FcAllocMem - FcFreeMem);
270    FcAllocNotify = 0;
271    FcFreeNotify = 0;
272}
273
274void
275FcMemAlloc (int kind, int size)
276{
277    if (FcDebug() & FC_DBG_MEMORY)
278    {
279	FcInUse[kind].alloc_count++;
280	FcInUse[kind].alloc_mem += size;
281	FcAllocCount++;
282	FcAllocMem += size;
283	FcAllocNotify += size;
284	if (FcAllocNotify > FcMemNotice)
285	    FcMemReport ();
286    }
287}
288
289void
290FcMemFree (int kind, int size)
291{
292    if (FcDebug() & FC_DBG_MEMORY)
293    {
294	FcInUse[kind].free_count++;
295	FcInUse[kind].free_mem += size;
296	FcFreeCount++;
297	FcFreeMem += size;
298	FcFreeNotify += size;
299	if (FcFreeNotify > FcMemNotice)
300	    FcMemReport ();
301    }
302}
303#define __fcinit__
304#include "fcaliastail.h"
305#undef __fcinit__
306