Coverage Report

Created: 2026-08-25 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontconfig/src/fcinit.c
Line
Count
Source
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
27
#include <stdlib.h>
28
29
#if defined(FC_ATOMIC_INT_NIL)
30
#  pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe.")
31
#endif
32
#if defined(FC_MUTEX_IMPL_NIL)
33
#  pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe.")
34
#endif
35
#if defined(FC_ATOMIC_INT_NIL) || defined(FC_MUTEX_IMPL_NIL)
36
#  pragma message("To suppress these warnings, define FC_NO_MT.")
37
#endif
38
39
static FcConfig *
40
FcInitFallbackConfig (const FcChar8 *sysroot)
41
0
{
42
0
    FcConfig      *config;
43
0
    const FcChar8 *fallback = (const FcChar8 *)
44
0
  ""
45
0
  "<fontconfig>" FC_DEFAULT_FONTS
46
0
  "  <dir prefix=\"xdg\">fonts</dir>"
47
0
  "  <cachedir>" FC_CACHEDIR
48
0
  "</cachedir>"
49
0
  "  <cachedir prefix=\"xdg\">fontconfig</cachedir>"
50
0
  "  <include ignore_missing=\"yes\">" CONFIGDIR
51
0
  "</include>"
52
0
  "  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/conf.d</include>"
53
0
  "  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/fonts.conf</include>"
54
0
  "</fontconfig>";
55
56
0
    config = FcConfigCreate();
57
0
    if (!config)
58
0
  goto bail0;
59
0
    FcConfigSetSysRoot (config, sysroot);
60
0
    if (!FcConfigParseAndLoadFromMemory (config, fallback, FcFalse))
61
0
  goto bail1;
62
63
0
    return config;
64
65
0
bail1:
66
0
    FcConfigDestroy (config);
67
0
bail0:
68
0
    return 0;
69
0
}
70
71
static FcConfig *
72
FcInitFallbackConfigWithFilter (FcConfig *config, const FcChar8 *sysroot)
73
0
{
74
0
    FcConfig *fallback = FcInitFallbackConfig (sysroot);
75
76
    /* Copy filter data */
77
0
    fallback->filter_func = config->filter_func;
78
0
    fallback->filter_data = config->filter_data;
79
0
    fallback->destroy_data_func = config->destroy_data_func;
80
0
    config->filter_func = NULL;
81
0
    config->filter_data = NULL;
82
0
    config->destroy_data_func = NULL;
83
    /* Rebuild fontset */
84
0
    FcConfigBuildFonts (fallback);
85
86
0
    FcConfigDestroy (config);
87
88
0
    return fallback;
89
0
}
90
91
int
92
FcGetVersion (void)
93
0
{
94
0
    return FC_VERSION;
95
0
}
96
97
/*
98
 * Load the configuration files
99
 */
100
FcConfig *
101
FcInitLoadOwnConfig (FcConfig *config)
102
0
{
103
0
    if (!config) {
104
0
  config = FcConfigCreate();
105
0
  if (!config)
106
0
      return NULL;
107
0
    }
108
109
0
    FcInitDebug();
110
111
0
    if (!FcConfigParseAndLoad (config, 0, FcTrue)) {
112
0
  const FcChar8 *sysroot = FcConfigGetSysRoot (config);
113
0
  FcConfig      *fallback = FcInitFallbackConfigWithFilter (config, sysroot);
114
115
0
  return fallback;
116
0
    }
117
0
    (void)FcConfigParseOnly (config, (const FcChar8 *)FC_TEMPLATEDIR, FcFalse);
118
119
0
    if (config->cacheDirs && config->cacheDirs->num == 0) {
120
0
  FcChar8 *prefix, *p;
121
0
  size_t   plen;
122
0
  FcBool   have_own = FcFalse;
123
0
  char    *env_file, *env_path;
124
125
0
  env_file = getenv ("FONTCONFIG_FILE");
126
0
  env_path = getenv ("FONTCONFIG_PATH");
127
0
  if ((env_file != NULL && env_file[0] != 0) ||
128
0
      (env_path != NULL && env_path[0] != 0))
129
0
      have_own = FcTrue;
130
131
0
  if (!have_own) {
132
0
      fprintf (stderr,
133
0
               "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
134
0
      fprintf (stderr,
135
0
               "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
136
0
               FC_CACHEDIR);
137
0
  }
138
0
  prefix = FcConfigXdgCacheHome();
139
0
  if (!prefix)
140
0
      goto bail;
141
0
  plen = strlen ((const char *)prefix);
142
0
  p = realloc (prefix, plen + 12);
143
0
  if (!p)
144
0
      goto bail;
145
0
  prefix = p;
146
0
  memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
147
0
  prefix[plen + 11] = 0;
148
0
  if (!have_own)
149
0
      fprintf (stderr,
150
0
               "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
151
152
0
  if (!FcConfigAddCacheDir (config, (FcChar8 *)FC_CACHEDIR) ||
153
0
      !FcConfigAddCacheDir (config, (FcChar8 *)prefix)) {
154
0
      FcConfig      *fallback;
155
0
      const FcChar8 *sysroot;
156
157
0
  bail:
158
0
      sysroot = FcConfigGetSysRoot (config);
159
0
      fprintf (stderr,
160
0
               "Fontconfig error: out of memory");
161
0
      if (prefix)
162
0
    FcStrFree (prefix);
163
0
      fallback = FcInitFallbackConfigWithFilter (config, sysroot);
164
165
0
      return fallback;
166
0
  }
167
0
  FcStrFree (prefix);
168
0
    }
169
170
0
    return config;
171
0
}
172
173
FcConfig *
174
FcInitLoadConfig (void)
175
0
{
176
0
    return FcInitLoadOwnConfig (NULL);
177
0
}
178
179
/*
180
 * Load the configuration files and scan for available fonts
181
 */
182
FcConfig *
183
FcInitLoadOwnConfigAndFonts (FcConfig *config)
184
0
{
185
0
    config = FcInitLoadOwnConfig (config);
186
0
    if (!config)
187
0
  return 0;
188
0
    if (!FcConfigBuildFonts (config)) {
189
0
  FcConfigDestroy (config);
190
0
  return 0;
191
0
    }
192
0
    return config;
193
0
}
194
195
FcConfig *
196
FcInitLoadConfigAndFonts (void)
197
0
{
198
0
    return FcInitLoadOwnConfigAndFonts (NULL);
199
0
}
200
201
/*
202
 * Initialize the default library configuration
203
 */
204
FcBool
205
FcInit (void)
206
0
{
207
0
    return FcConfigInit();
208
0
}
209
210
/*
211
 * Free all library-allocated data structures.
212
 */
213
void
214
FcFini (void)
215
0
{
216
0
    FcConfigFini();
217
0
    FcCacheFini();
218
0
}
219
220
/*
221
 * Reread the configuration and available font lists
222
 */
223
FcBool
224
FcInitReinitialize (void)
225
0
{
226
0
    FcConfig *config, *old_config;
227
0
    FcBool    ret;
228
229
0
    old_config = FcConfigReference (NULL);
230
0
    if (!old_config)
231
0
  return FcFalse;
232
0
    config = FcInitReinitializeWith (old_config);
233
0
    FcConfigDestroy (old_config);
234
0
    if (!config)
235
0
  return FcFalse;
236
0
    ret = FcConfigSetCurrent (config);
237
    /* FcConfigSetCurrent() increases the refcount.
238
     * decrease it here to avoid the memory leak.
239
     */
240
0
    FcConfigDestroy (config);
241
242
0
    return ret;
243
0
}
244
245
FcConfig *
246
FcInitReinitializeWith (FcConfig *config)
247
0
{
248
0
    FcConfig      *ret;
249
0
    FcStrList     *l;
250
0
    const FcChar8 *s;
251
252
0
    ret = FcInitLoadOwnConfig (NULL);
253
0
    if (!ret)
254
0
  return NULL;
255
0
    if (!FcConfigBuildFonts (ret)) {
256
0
  FcConfigDestroy (ret);
257
0
  return NULL;
258
0
    }
259
    /* inherit application specific fonts only */
260
0
    l = FcStrListCreate (config->appFonts);
261
0
    if (!l) {
262
0
  FcConfigDestroy (ret);
263
0
  return NULL;
264
0
    }
265
0
    while ((s = FcStrListNext (l))) {
266
0
  if (FcFileIsFile (s)) {
267
0
      if (!FcConfigAppFontAddFile (ret, s)) {
268
0
    fprintf (stderr, "Fontconfig warning: failed to re-add an application font: %s\n",
269
0
             (const char *)s);
270
0
      }
271
0
  } else if (FcFileIsDir (s)) {
272
0
      if (!FcConfigAppFontAddDir (ret, s)) {
273
0
    FcStrListDone (l);
274
0
    FcConfigDestroy (ret);
275
0
    return NULL;
276
0
      }
277
0
  } else {
278
0
      fprintf (stderr, "Fontconfig warning: failed to re-add an application font: %s\n",
279
0
               (const char *)s);
280
0
  }
281
0
    }
282
0
    FcStrListDone (l);
283
284
0
    return ret;
285
0
}
286
287
FcBool
288
FcInitBringUptoDate (void)
289
0
{
290
0
    FcConfig *config = FcConfigReference (NULL);
291
0
    FcBool    ret = FcTrue;
292
0
    time_t    now;
293
294
0
    if (!config)
295
0
  return FcFalse;
296
    /*
297
     * rescanInterval == 0 disables automatic up to date
298
     */
299
0
    if (config->rescanInterval == 0)
300
0
  goto bail;
301
    /*
302
     * Check no more often than rescanInterval seconds
303
     */
304
0
    now = time (0);
305
0
    if (config->rescanTime + config->rescanInterval - now > 0)
306
0
  goto bail;
307
    /*
308
     * If up to date, don't reload configuration
309
     */
310
0
    if (FcConfigUptoDate (0))
311
0
  goto bail;
312
0
    ret = FcInitReinitialize();
313
0
bail:
314
0
    FcConfigDestroy (config);
315
316
0
    return ret;
317
0
}
318
319
#define __fcinit__
320
#include "fcaliastail.h"
321
#undef __fcinit__