merge fontconfig 2.10.2diff -r1.1.1.1 -r0 xsrc/external/mit/fontconfig/dist/acinclude.m4
(mrg)
--- xsrc/external/mit/fontconfig/dist/fc-cache/fc-cache.c 2011/02/18 00:26:24 1.2
+++ xsrc/external/mit/fontconfig/dist/fc-cache/fc-cache.c 2013/06/03 06:04:33 1.3
@@ -1,39 +1,37 @@ | @@ -1,39 +1,37 @@ | |||
1 | /* | 1 | /* | |
2 | * fontconfig/fc-cache/fc-cache.c | 2 | * fontconfig/fc-cache/fc-cache.c | |
3 | * | 3 | * | |
4 | * Copyright © 2002 Keith Packard | 4 | * Copyright © 2002 Keith Packard | |
5 | * | 5 | * | |
6 | * Permission to use, copy, modify, distribute, and sell this software and its | 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 | 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 | 8 | * the above copyright notice appear in all copies and that both that | |
9 | * copyright notice and this permission notice appear in supporting | 9 | * copyright notice and this permission notice appear in supporting | |
10 | * documentation, and that the name of Keith Packard not be used in | 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 | 11 | * advertising or publicity pertaining to distribution of the software without | |
12 | * specific, written prior permission. Keith Packard makes no | 12 | * specific, written prior permission. The authors make no | |
13 | * representations about the suitability of this software for any purpose. It | 13 | * representations about the suitability of this software for any purpose. It | |
14 | * is provided "as is" without express or implied warranty. | 14 | * is provided "as is" without express or implied warranty. | |
15 | * | 15 | * | |
16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | 16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | 17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
18 | * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR | 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, | 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 | 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 | 21 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
22 | * PERFORMANCE OF THIS SOFTWARE. | 22 | * PERFORMANCE OF THIS SOFTWARE. | |
23 | */ | 23 | */ | |
24 | 24 | |||
25 | #include "../fc-arch/fcarch.h" | |||
26 | ||||
27 | #ifdef HAVE_CONFIG_H | 25 | #ifdef HAVE_CONFIG_H | |
28 | #include <config.h> | 26 | #include <config.h> | |
29 | #else | 27 | #else | |
30 | #ifdef linux | 28 | #ifdef linux | |
31 | #define HAVE_GETOPT_LONG 1 | 29 | #define HAVE_GETOPT_LONG 1 | |
32 | #endif | 30 | #endif | |
33 | #define HAVE_GETOPT 1 | 31 | #define HAVE_GETOPT 1 | |
34 | #endif | 32 | #endif | |
35 | 33 | |||
36 | #include <fontconfig/fontconfig.h> | 34 | #include <fontconfig/fontconfig.h> | |
37 | #include <stdio.h> | 35 | #include <stdio.h> | |
38 | #include <stdlib.h> | 36 | #include <stdlib.h> | |
39 | #include <unistd.h> | 37 | #include <unistd.h> | |
@@ -110,27 +108,27 @@ usage (char *program, int error) | @@ -110,27 +108,27 @@ usage (char *program, int error) | |||
110 | fprintf (file, " -q (quick) don't sleep before exiting\n"); | 108 | fprintf (file, " -q (quick) don't sleep before exiting\n"); | |
111 | fprintf (file, " -r, (really force) erase all existing caches, then rescan\n"); | 109 | fprintf (file, " -r, (really force) erase all existing caches, then rescan\n"); | |
112 | fprintf (file, " -s (system) scan system-wide directories only\n"); | 110 | fprintf (file, " -s (system) scan system-wide directories only\n"); | |
113 | fprintf (file, " -v (verbose) display status information while busy\n"); | 111 | fprintf (file, " -v (verbose) display status information while busy\n"); | |
114 | fprintf (file, " -V (version) display font config version and exit\n"); | 112 | fprintf (file, " -V (version) display font config version and exit\n"); | |
115 | fprintf (file, " -h (help) display this help and exit\n"); | 113 | fprintf (file, " -h (help) display this help and exit\n"); | |
116 | #endif | 114 | #endif | |
117 | exit (error); | 115 | exit (error); | |
118 | } | 116 | } | |
119 | 117 | |||
120 | static FcStrSet *processed_dirs; | 118 | static FcStrSet *processed_dirs; | |
121 | 119 | |||
122 | static int | 120 | static int | |
123 | scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose) | 121 | scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, int *changed) | |
124 | { | 122 | { | |
125 | int ret = 0; | 123 | int ret = 0; | |
126 | const FcChar8 *dir; | 124 | const FcChar8 *dir; | |
127 | FcStrSet *subdirs; | 125 | FcStrSet *subdirs; | |
128 | FcStrList *sublist; | 126 | FcStrList *sublist; | |
129 | FcCache *cache; | 127 | FcCache *cache; | |
130 | struct stat statb; | 128 | struct stat statb; | |
131 | FcBool was_valid; | 129 | FcBool was_valid; | |
132 | int i; | 130 | int i; | |
133 | 131 | |||
134 | /* | 132 | /* | |
135 | * Now scan all of the directories into separate databases | 133 | * Now scan all of the directories into separate databases | |
136 | * and write out the results | 134 | * and write out the results | |
@@ -183,26 +181,27 @@ scanDirs (FcStrList *list, FcConfig *con | @@ -183,26 +181,27 @@ scanDirs (FcStrList *list, FcConfig *con | |||
183 | if (really_force) | 181 | if (really_force) | |
184 | FcDirCacheUnlink (dir, config); | 182 | FcDirCacheUnlink (dir, config); | |
185 | 183 | |||
186 | cache = NULL; | 184 | cache = NULL; | |
187 | was_valid = FcFalse; | 185 | was_valid = FcFalse; | |
188 | if (!force) { | 186 | if (!force) { | |
189 | cache = FcDirCacheLoad (dir, config, NULL); | 187 | cache = FcDirCacheLoad (dir, config, NULL); | |
190 | if (cache) | 188 | if (cache) | |
191 | was_valid = FcTrue; | 189 | was_valid = FcTrue; | |
192 | } | 190 | } | |
193 | 191 | |||
194 | if (!cache) | 192 | if (!cache) | |
195 | { | 193 | { | |
194 | (*changed)++; | |||
196 | cache = FcDirCacheRead (dir, FcTrue, config); | 195 | cache = FcDirCacheRead (dir, FcTrue, config); | |
197 | if (!cache) | 196 | if (!cache) | |
198 | { | 197 | { | |
199 | fprintf (stderr, "%s: error scanning\n", dir); | 198 | fprintf (stderr, "%s: error scanning\n", dir); | |
200 | ret++; | 199 | ret++; | |
201 | continue; | 200 | continue; | |
202 | } | 201 | } | |
203 | } | 202 | } | |
204 | 203 | |||
205 | if (was_valid) | 204 | if (was_valid) | |
206 | { | 205 | { | |
207 | if (verbose) | 206 | if (verbose) | |
208 | printf ("skipping, existing cache is valid: %d fonts, %d dirs\n", | 207 | printf ("skipping, existing cache is valid: %d fonts, %d dirs\n", | |
@@ -234,155 +233,66 @@ scanDirs (FcStrList *list, FcConfig *con | @@ -234,155 +233,66 @@ scanDirs (FcStrList *list, FcConfig *con | |||
234 | FcStrSetAdd (subdirs, FcCacheSubdir (cache, i)); | 233 | FcStrSetAdd (subdirs, FcCacheSubdir (cache, i)); | |
235 | 234 | |||
236 | FcDirCacheUnload (cache); | 235 | FcDirCacheUnload (cache); | |
237 | 236 | |||
238 | sublist = FcStrListCreate (subdirs); | 237 | sublist = FcStrListCreate (subdirs); | |
239 | FcStrSetDestroy (subdirs); | 238 | FcStrSetDestroy (subdirs); | |
240 | if (!sublist) | 239 | if (!sublist) | |
241 | { | 240 | { | |
242 | fprintf (stderr, "%s: Can't create subdir list\n", dir); | 241 | fprintf (stderr, "%s: Can't create subdir list\n", dir); | |
243 | ret++; | 242 | ret++; | |
244 | continue; | 243 | continue; | |
245 | } | 244 | } | |
246 | FcStrSetAdd (processed_dirs, dir); | 245 | FcStrSetAdd (processed_dirs, dir); | |
247 | ret += scanDirs (sublist, config, force, really_force, verbose); | 246 | ret += scanDirs (sublist, config, force, really_force, verbose, changed); | |
248 | } | 247 | } | |
249 | FcStrListDone (list); | 248 | FcStrListDone (list); | |
250 | return ret; | 249 | return ret; | |
251 | } | 250 | } | |
252 | 251 | |||
253 | static FcBool | 252 | static FcBool | |
254 | cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose) | |||
255 | { | |||
256 | DIR *d; | |||
257 | struct dirent *ent; | |||
258 | FcChar8 *dir_base; | |||
259 | FcBool ret = FcTrue; | |||
260 | FcBool remove; | |||
261 | FcCache *cache; | |||
262 | struct stat target_stat; | |||
263 | ||||
264 | dir_base = FcStrPlus (dir, (FcChar8 *) "/"); | |||
265 | if (!dir_base) | |||
266 | { | |||
267 | fprintf (stderr, "%s: out of memory\n", dir); | |||
268 | return FcFalse; | |||
269 | } | |||
270 | if (access ((char *) dir, W_OK) != 0) | |||
271 | { | |||
272 | if (verbose) | |||
273 | printf ("%s: not cleaning %s cache directory\n", dir, | |||
274 | access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent"); | |||
275 | FcStrFree (dir_base); | |||
276 | return FcTrue; | |||
277 | } | |||
278 | if (verbose) | |||
279 | printf ("%s: cleaning cache directory\n", dir); | |||
280 | d = opendir ((char *) dir); | |||
281 | if (!d) | |||
282 | { | |||
283 | perror ((char *) dir); | |||
284 | FcStrFree (dir_base); | |||
285 | return FcFalse; | |||
286 | } | |||
287 | while ((ent = readdir (d))) | |||
288 | { | |||
289 | FcChar8 *file_name; | |||
290 | const FcChar8 *target_dir; | |||
291 | ||||
292 | if (ent->d_name[0] == '.') | |||
293 | continue; | |||
294 | /* skip cache files for different architectures and */ | |||
295 | /* files which are not cache files at all */ | |||
296 | if (strlen(ent->d_name) != 32 + strlen ("-" FC_ARCHITECTURE FC_CACHE_SUFFIX) || | |||
297 | strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) | |||
298 | continue; | |||
299 | ||||
300 | file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); | |||
301 | if (!file_name) | |||
302 | { | |||
303 | fprintf (stderr, "%s: allocation failure\n", dir); | |||
304 | ret = FcFalse; | |||
305 | break; | |||
306 | } | |||
307 | remove = FcFalse; | |||
308 | cache = FcDirCacheLoadFile (file_name, NULL); | |||
309 | if (!cache) | |||
310 | { | |||
311 | if (verbose) | |||
312 | printf ("%s: invalid cache file: %s\n", dir, ent->d_name); | |||
313 | remove = FcTrue; | |||
314 | } | |||
315 | else | |||
316 | { | |||
317 | target_dir = FcCacheDir (cache); | |||
318 | if (stat ((char *) target_dir, &target_stat) < 0) | |||
319 | { | |||
320 | if (verbose) | |||
321 | printf ("%s: %s: missing directory: %s \n", | |||
322 | dir, ent->d_name, target_dir); | |||
323 | remove = FcTrue; | |||
324 | } | |||
325 | } | |||
326 | if (remove) | |||
327 | { | |||
328 | if (unlink ((char *) file_name) < 0) | |||
329 | { | |||
330 | perror ((char *) file_name); | |||
331 | ret = FcFalse; | |||
332 | } | |||
333 | } | |||
334 | FcDirCacheUnload (cache); | |||
335 | FcStrFree (file_name); | |||
336 | } | |||
337 | ||||
338 | closedir (d); | |||
339 | FcStrFree (dir_base); | |||
340 | return ret; | |||
341 | } | |||
342 | ||||
343 | static FcBool | |||
344 | cleanCacheDirectories (FcConfig *config, FcBool verbose) | 253 | cleanCacheDirectories (FcConfig *config, FcBool verbose) | |
345 | { | 254 | { | |
346 | FcStrList *cache_dirs = FcConfigGetCacheDirs (config); | 255 | FcStrList *cache_dirs = FcConfigGetCacheDirs (config); | |
347 | FcChar8 *cache_dir; | 256 | FcChar8 *cache_dir; | |
348 | FcBool ret = FcTrue; | 257 | FcBool ret = FcTrue; | |
349 | 258 | |||
350 | if (!cache_dirs) | 259 | if (!cache_dirs) | |
351 | return FcFalse; | 260 | return FcFalse; | |
352 | while ((cache_dir = FcStrListNext (cache_dirs))) | 261 | while ((cache_dir = FcStrListNext (cache_dirs))) | |
353 | { | 262 | { | |
354 | if (!cleanCacheDirectory (config, cache_dir, verbose)) | 263 | if (!FcDirCacheClean (cache_dir, verbose)) | |
355 | { | 264 | { | |
356 | ret = FcFalse; | 265 | ret = FcFalse; | |
357 | break; | 266 | break; | |
358 | } | 267 | } | |
359 | } | 268 | } | |
360 | FcStrListDone (cache_dirs); | 269 | FcStrListDone (cache_dirs); | |
361 | return ret; | 270 | return ret; | |
362 | } | 271 | } | |
363 | 272 | |||
364 | int | 273 | int | |
365 | main (int argc, char **argv) | 274 | main (int argc, char **argv) | |
366 | { | 275 | { | |
367 | FcStrSet *dirs; | 276 | FcStrSet *dirs; | |
368 | FcStrList *list; | 277 | FcStrList *list; | |
369 | FcBool verbose = FcFalse; | 278 | FcBool verbose = FcFalse; | |
370 | FcBool quick = FcFalse; | 279 | FcBool quick = FcFalse; | |
371 | FcBool force = FcFalse; | 280 | FcBool force = FcFalse; | |
372 | FcBool really_force = FcFalse; | 281 | FcBool really_force = FcFalse; | |
373 | FcBool systemOnly = FcFalse; | 282 | FcBool systemOnly = FcFalse; | |
374 | FcConfig *config; | 283 | FcConfig *config; | |
375 | int i; | 284 | int i; | |
285 | int changed; | |||
376 | int ret; | 286 | int ret; | |
377 | #if HAVE_GETOPT_LONG || HAVE_GETOPT | 287 | #if HAVE_GETOPT_LONG || HAVE_GETOPT | |
378 | int c; | 288 | int c; | |
379 | 289 | |||
380 | #if HAVE_GETOPT_LONG | 290 | #if HAVE_GETOPT_LONG | |
381 | while ((c = getopt_long (argc, argv, "fqrsVvh", longopts, NULL)) != -1) | 291 | while ((c = getopt_long (argc, argv, "fqrsVvh", longopts, NULL)) != -1) | |
382 | #else | 292 | #else | |
383 | while ((c = getopt (argc, argv, "fqrsVvh")) != -1) | 293 | while ((c = getopt (argc, argv, "fqrsVvh")) != -1) | |
384 | #endif | 294 | #endif | |
385 | { | 295 | { | |
386 | switch (c) { | 296 | switch (c) { | |
387 | case 'r': | 297 | case 'r': | |
388 | really_force = FcTrue; | 298 | really_force = FcTrue; | |
@@ -443,34 +353,42 @@ main (int argc, char **argv) | @@ -443,34 +353,42 @@ main (int argc, char **argv) | |||
443 | i++; | 353 | i++; | |
444 | } | 354 | } | |
445 | list = FcStrListCreate (dirs); | 355 | list = FcStrListCreate (dirs); | |
446 | FcStrSetDestroy (dirs); | 356 | FcStrSetDestroy (dirs); | |
447 | } | 357 | } | |
448 | else | 358 | else | |
449 | list = FcConfigGetConfigDirs (config); | 359 | list = FcConfigGetConfigDirs (config); | |
450 | 360 | |||
451 | if ((processed_dirs = FcStrSetCreate()) == NULL) { | 361 | if ((processed_dirs = FcStrSetCreate()) == NULL) { | |
452 | fprintf(stderr, "Cannot malloc\n"); | 362 | fprintf(stderr, "Cannot malloc\n"); | |
453 | return 1; | 363 | return 1; | |
454 | } | 364 | } | |
455 | 365 | |||
456 | ret = scanDirs (list, config, force, really_force, verbose); | 366 | changed = 0; | |
367 | ret = scanDirs (list, config, force, really_force, verbose, &changed); | |||
368 | ||||
369 | /* | |||
370 | * Try to create CACHEDIR.TAG anyway. | |||
371 | * This expects the fontconfig cache directory already exists. | |||
372 | * If it doesn't, it won't be simply created. | |||
373 | */ | |||
374 | FcCacheCreateTagFile (config); | |||
457 | 375 | |||
458 | FcStrSetDestroy (processed_dirs); | 376 | FcStrSetDestroy (processed_dirs); | |
459 | 377 | |||
460 | cleanCacheDirectories (config, verbose); | 378 | cleanCacheDirectories (config, verbose); | |
461 | 379 | |||
462 | /* | 380 | /* | |
463 | * Now we need to sleep a second (or two, to be extra sure), to make | 381 | * Now we need to sleep a second (or two, to be extra sure), to make | |
464 | * sure that timestamps for changes after this run of fc-cache are later | 382 | * sure that timestamps for changes after this run of fc-cache are later | |
465 | * then any timestamps we wrote. We don't use gettimeofday() because | 383 | * then any timestamps we wrote. We don't use gettimeofday() because | |
466 | * sleep(3) can't be interrupted by a signal here -- this isn't in the | 384 | * sleep(3) can't be interrupted by a signal here -- this isn't in the | |
467 | * library, and there aren't any signals flying around here. | 385 | * library, and there aren't any signals flying around here. | |
468 | */ | 386 | */ | |
469 | FcConfigDestroy (config); | 387 | FcConfigDestroy (config); | |
470 | FcFini (); | 388 | FcFini (); | |
471 | if (!quick) | 389 | if (!quick && changed) | |
472 | sleep (2); | 390 | sleep (2); | |
473 | if (verbose) | 391 | if (verbose) | |
474 | printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded"); | 392 | printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded"); | |
475 | return ret; | 393 | return ret; | |
476 | } | 394 | } |
--- xsrc/external/mit/fontconfig/dist/src/fccache.c 2011/08/11 21:59:46 1.2
+++ xsrc/external/mit/fontconfig/dist/src/fccache.c 2013/06/03 06:04:33 1.3
@@ -1,147 +1,95 @@ | @@ -1,147 +1,95 @@ | |||
1 | /* | 1 | /* | |
2 | * Copyright © 2000 Keith Packard | 2 | * Copyright © 2000 Keith Packard | |
3 | * Copyright © 2005 Patrick Lam | 3 | * Copyright © 2005 Patrick Lam | |
4 | * | 4 | * | |
5 | * Permission to use, copy, modify, distribute, and sell this software and its | 5 | * Permission to use, copy, modify, distribute, and sell this software and its | |
6 | * documentation for any purpose is hereby granted without fee, provided that | 6 | * documentation for any purpose is hereby granted without fee, provided that | |
7 | * the above copyright notice appear in all copies and that both that | 7 | * the above copyright notice appear in all copies and that both that | |
8 | * copyright notice and this permission notice appear in supporting | 8 | * copyright notice and this permission notice appear in supporting | |
9 | * documentation, and that the name of Keith Packard not be used in | 9 | * documentation, and that the name of the author(s) not be used in | |
10 | * advertising or publicity pertaining to distribution of the software without | 10 | * advertising or publicity pertaining to distribution of the software without | |
11 | * specific, written prior permission. Keith Packard makes no | 11 | * specific, written prior permission. The authors make no | |
12 | * representations about the suitability of this software for any purpose. It | 12 | * representations about the suitability of this software for any purpose. It | |
13 | * is provided "as is" without express or implied warranty. | 13 | * is provided "as is" without express or implied warranty. | |
14 | * | 14 | * | |
15 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | 15 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
17 | * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR | 17 | * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
21 | * PERFORMANCE OF THIS SOFTWARE. | 21 | * PERFORMANCE OF THIS SOFTWARE. | |
22 | */ | 22 | */ | |
23 | 23 | #ifdef HAVE_CONFIG_H | ||
24 | #include "config.h" | |||
25 | #endif | |||
24 | #include "fcint.h" | 26 | #include "fcint.h" | |
25 | #include "../fc-arch/fcarch.h" | 27 | #include "fcarch.h" | |
26 | #include <stdio.h> | 28 | #include <stdio.h> | |
29 | #include <stdlib.h> | |||
27 | #include <fcntl.h> | 30 | #include <fcntl.h> | |
28 | #include <dirent.h> | 31 | #include <dirent.h> | |
29 | #include <string.h> | 32 | #include <string.h> | |
30 | #include <sys/types.h> | 33 | #include <sys/types.h> | |
34 | #include <time.h> | |||
31 | #include <assert.h> | 35 | #include <assert.h> | |
32 | #if defined(HAVE_MMAP) || defined(__CYGWIN__) | 36 | #if defined(HAVE_MMAP) || defined(__CYGWIN__) | |
33 | # include <unistd.h> | 37 | # include <unistd.h> | |
34 | # include <sys/mman.h> | 38 | # include <sys/mman.h> | |
35 | #elif defined(_WIN32) | |||
36 | # define _WIN32_WINNT 0x0500 | |||
37 | # include <windows.h> | |||
38 | #endif | 39 | #endif | |
39 | 40 | |||
40 | #ifndef O_BINARY | 41 | #ifndef O_BINARY | |
41 | #define O_BINARY 0 | 42 | #define O_BINARY 0 | |
42 | #endif | 43 | #endif | |
43 | 44 | |||
45 | ||||
44 | struct MD5Context { | 46 | struct MD5Context { | |
45 | FcChar32 buf[4]; | 47 | FcChar32 buf[4]; | |
46 | FcChar32 bits[2]; | 48 | FcChar32 bits[2]; | |
47 | unsigned char in[64]; | 49 | unsigned char in[64]; | |
48 | }; | 50 | }; | |
49 | 51 | |||
50 | static void MD5Init(struct MD5Context *ctx); | 52 | static void MD5Init(struct MD5Context *ctx); | |
51 | static void MD5Update(struct MD5Context *ctx, const unsigned char *buf, unsigned len); | 53 | static void MD5Update(struct MD5Context *ctx, const unsigned char *buf, unsigned len); | |
52 | static void MD5Final(unsigned char digest[16], struct MD5Context *ctx); | 54 | static void MD5Final(unsigned char digest[16], struct MD5Context *ctx); | |
53 | static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]); | 55 | static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]); | |
54 | 56 | |||
55 | #define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX)) | 57 | #define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX)) | |
56 | 58 | |||
57 | #ifdef _WIN32 | 59 | static FcBool | |
58 | 60 | FcCacheIsMmapSafe (int fd) | ||
59 | #include <windows.h> | |||
60 | ||||
61 | #ifdef __GNUC__ | |||
62 | typedef long long INT64; | |||
63 | #define EPOCH_OFFSET 11644473600ll | |||
64 | #else | |||
65 | #define EPOCH_OFFSET 11644473600i64 | |||
66 | typedef __int64 INT64; | |||
67 | #endif | |||
68 | ||||
69 | /* Workaround for problems in the stat() in the Microsoft C library: | |||
70 | * | |||
71 | * 1) stat() uses FindFirstFile() to get the file | |||
72 | * attributes. Unfortunately this API doesn't return correct values | |||
73 | * for modification time of a directory until some time after a file | |||
74 | * or subdirectory has been added to the directory. (This causes | |||
75 | * run-test.sh to fail, for instance.) GetFileAttributesEx() is | |||
76 | * better, it returns the updated timestamp right away. | |||
77 | * | |||
78 | * 2) stat() does some strange things related to backward | |||
79 | * compatibility with the local time timestamps on FAT volumes and | |||
80 | * daylight saving time. This causes problems after the switches | |||
81 | * to/from daylight saving time. See | |||
82 | * http://bugzilla.gnome.org/show_bug.cgi?id=154968 , especially | |||
83 | * comment #30, and http://www.codeproject.com/datetime/dstbugs.asp . | |||
84 | * We don't need any of that, FAT and Win9x are as good as dead. So | |||
85 | * just use the UTC timestamps from NTFS, converted to the Unix epoch. | |||
86 | */ | |||
87 | ||||
88 | int | |||
89 | FcStat (const char *file, struct stat *statb) | |||
90 | { | 61 | { | |
91 | WIN32_FILE_ATTRIBUTE_DATA wfad; | 62 | static FcBool is_initialized = FcFalse; | |
92 | char full_path_name[MAX_PATH]; | 63 | static FcBool is_env_available = FcFalse; | |
93 | char *basename; | 64 | static FcBool use_mmap = FcFalse; | |
94 | DWORD rc; | |||
95 | ||||
96 | if (!GetFileAttributesEx (file, GetFileExInfoStandard, &wfad)) | |||
97 | return -1; | |||
98 | ||||
99 | statb->st_dev = 0; | |||
100 | 65 | |||
101 | /* Calculate a pseudo inode number as a hash of the full path name. | 66 | if (!is_initialized) | |
102 | * Call GetLongPathName() to get the spelling of the path name as it | 67 | { | |
103 | * is on disk. | 68 | const char *env; | |
104 | */ | |||
105 | rc = GetFullPathName (file, sizeof (full_path_name), full_path_name, &basename); | |||
106 | if (rc == 0 || rc > sizeof (full_path_name)) | |||
107 | return -1; | |||
108 | 69 | |||
109 | rc = GetLongPathName (full_path_name, full_path_name, sizeof (full_path_name)); | 70 | env = getenv ("FONTCONFIG_USE_MMAP"); | |
110 | statb->st_ino = FcStringHash (full_path_name); | 71 | if (env) | |
111 | 72 | { | ||
112 | statb->st_mode = _S_IREAD | _S_IWRITE; | 73 | if (FcNameBool ((const FcChar8 *)env, &use_mmap)) | |
113 | statb->st_mode |= (statb->st_mode >> 3) | (statb->st_mode >> 6); | 74 | is_env_available = FcTrue; | |
75 | } | |||
76 | is_initialized = FcTrue; | |||
77 | } | |||
78 | if (is_env_available) | |||
79 | return use_mmap; | |||
114 | 80 | |||
115 | if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | 81 | return FcIsFsMmapSafe (fd); | |
116 | statb->st_mode |= _S_IFDIR; | |||
117 | else | |||
118 | statb->st_mode |= _S_IFREG; | |||
119 | ||||
120 | statb->st_nlink = 1; | |||
121 | statb->st_uid = statb->st_gid = 0; | |||
122 | statb->st_rdev = 0; | |||
123 | ||||
124 | if (wfad.nFileSizeHigh > 0) | |||
125 | return -1; | |||
126 | statb->st_size = wfad.nFileSizeLow; | |||
127 | ||||
128 | statb->st_atime = (*(INT64 *)&wfad.ftLastAccessTime)/10000000 - EPOCH_OFFSET; | |||
129 | statb->st_mtime = (*(INT64 *)&wfad.ftLastWriteTime)/10000000 - EPOCH_OFFSET; | |||
130 | statb->st_ctime = statb->st_mtime; | |||
131 | ||||
132 | return 0; | |||
133 | } | 82 | } | |
134 | #endif | |||
135 | 83 | |||
136 | static const char bin2hex[] = { '0', '1', '2', '3', | 84 | static const char bin2hex[] = { '0', '1', '2', '3', | |
137 | '4', '5', '6', '7', | 85 | '4', '5', '6', '7', | |
138 | '8', '9', 'a', 'b', | 86 | '8', '9', 'a', 'b', | |
139 | 'c', 'd', 'e', 'f' }; | 87 | 'c', 'd', 'e', 'f' }; | |
140 | 88 | |||
141 | static FcChar8 * | 89 | static FcChar8 * | |
142 | FcDirCacheBasename (const FcChar8 * dir, FcChar8 cache_base[CACHEBASE_LEN]) | 90 | FcDirCacheBasename (const FcChar8 * dir, FcChar8 cache_base[CACHEBASE_LEN]) | |
143 | { | 91 | { | |
144 | unsigned char hash[16]; | 92 | unsigned char hash[16]; | |
145 | FcChar8 *hex_hash; | 93 | FcChar8 *hex_hash; | |
146 | int cnt; | 94 | int cnt; | |
147 | struct MD5Context ctx; | 95 | struct MD5Context ctx; | |
@@ -205,45 +153,45 @@ FcDirCacheOpenFile (const FcChar8 *cache | @@ -205,45 +153,45 @@ FcDirCacheOpenFile (const FcChar8 *cache | |||
205 | fd = open((char *) cache_file, O_RDONLY | O_BINARY); | 153 | fd = open((char *) cache_file, O_RDONLY | O_BINARY); | |
206 | if (fd < 0) | 154 | if (fd < 0) | |
207 | return fd; | 155 | return fd; | |
208 | #ifndef _WIN32 | 156 | #ifndef _WIN32 | |
209 | if (fstat (fd, file_stat) < 0) | 157 | if (fstat (fd, file_stat) < 0) | |
210 | { | 158 | { | |
211 | close (fd); | 159 | close (fd); | |
212 | return -1; | 160 | return -1; | |
213 | } | 161 | } | |
214 | #endif | 162 | #endif | |
215 | return fd; | 163 | return fd; | |
216 | } | 164 | } | |
217 | 165 | |||
218 | /* | 166 | /* | |
219 | * Look for a cache file for the specified dir. Attempt | 167 | * Look for a cache file for the specified dir. Attempt | |
220 | * to use each one we find, stopping when the callback | 168 | * to use each one we find, stopping when the callback | |
221 | * indicates success | 169 | * indicates success | |
222 | */ | 170 | */ | |
223 | static FcBool | 171 | static FcBool | |
224 | FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, | 172 | FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, | |
225 | FcBool (*callback) (int fd, struct stat *fd_stat, | 173 | FcBool (*callback) (int fd, struct stat *fd_stat, | |
226 | struct stat *dir_stat, void *closure), | 174 | struct stat *dir_stat, void *closure), | |
227 | void *closure, FcChar8 **cache_file_ret) | 175 | void *closure, FcChar8 **cache_file_ret) | |
228 | { | 176 | { | |
229 | int fd = -1; | 177 | int fd = -1; | |
230 | FcChar8 cache_base[CACHEBASE_LEN]; | 178 | FcChar8 cache_base[CACHEBASE_LEN]; | |
231 | FcStrList *list; | 179 | FcStrList *list; | |
232 | FcChar8 *cache_dir; | 180 | FcChar8 *cache_dir; | |
233 | struct stat file_stat, dir_stat; | 181 | struct stat file_stat, dir_stat; | |
234 | FcBool ret = FcFalse; | 182 | FcBool ret = FcFalse; | |
235 | 183 | |||
236 | if (FcStat ((char *) dir, &dir_stat) < 0) | 184 | if (FcStatChecksum (dir, &dir_stat) < 0) | |
237 | return FcFalse; | 185 | return FcFalse; | |
238 | 186 | |||
239 | FcDirCacheBasename (dir, cache_base); | 187 | FcDirCacheBasename (dir, cache_base); | |
240 | 188 | |||
241 | list = FcStrListCreate (config->cacheDirs); | 189 | list = FcStrListCreate (config->cacheDirs); | |
242 | if (!list) | 190 | if (!list) | |
243 | return FcFalse; | 191 | return FcFalse; | |
244 | 192 | |||
245 | while ((cache_dir = FcStrListNext (list))) | 193 | while ((cache_dir = FcStrListNext (list))) | |
246 | { | 194 | { | |
247 | FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base); | 195 | FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base); | |
248 | if (!cache_hashed) | 196 | if (!cache_hashed) | |
249 | break; | 197 | break; | |
@@ -253,27 +201,27 @@ FcDirCacheProcess (FcConfig *config, con | @@ -253,27 +201,27 @@ FcDirCacheProcess (FcConfig *config, con | |||
253 | close (fd); | 201 | close (fd); | |
254 | if (ret) | 202 | if (ret) | |
255 | { | 203 | { | |
256 | if (cache_file_ret) | 204 | if (cache_file_ret) | |
257 | *cache_file_ret = cache_hashed; | 205 | *cache_file_ret = cache_hashed; | |
258 | else | 206 | else | |
259 | FcStrFree (cache_hashed); | 207 | FcStrFree (cache_hashed); | |
260 | break; | 208 | break; | |
261 | } | 209 | } | |
262 | } | 210 | } | |
263 | FcStrFree (cache_hashed); | 211 | FcStrFree (cache_hashed); | |
264 | } | 212 | } | |
265 | FcStrListDone (list); | 213 | FcStrListDone (list); | |
266 | 214 | |||
267 | return ret; | 215 | return ret; | |
268 | } | 216 | } | |
269 | 217 | |||
270 | #define FC_CACHE_MIN_MMAP 1024 | 218 | #define FC_CACHE_MIN_MMAP 1024 | |
271 | 219 | |||
272 | /* | 220 | /* | |
273 | * Skip list element, make sure the 'next' pointer is the last thing | 221 | * Skip list element, make sure the 'next' pointer is the last thing | |
274 | * in the structure, it will be allocated large enough to hold all | 222 | * in the structure, it will be allocated large enough to hold all | |
275 | * of the necessary pointers | 223 | * of the necessary pointers | |
276 | */ | 224 | */ | |
277 | 225 | |||
278 | typedef struct _FcCacheSkip FcCacheSkip; | 226 | typedef struct _FcCacheSkip FcCacheSkip; | |
279 | 227 | |||
@@ -287,37 +235,82 @@ struct _FcCacheSkip { | @@ -287,37 +235,82 @@ struct _FcCacheSkip { | |||
287 | FcCacheSkip *next[1]; | 235 | FcCacheSkip *next[1]; | |
288 | }; | 236 | }; | |
289 | 237 | |||
290 | /* | 238 | /* | |
291 | * The head of the skip list; pointers for every possible level | 239 | * The head of the skip list; pointers for every possible level | |
292 | * in the skip list, plus the largest level in the list | 240 | * in the skip list, plus the largest level in the list | |
293 | */ | 241 | */ | |
294 | 242 | |||
295 | #define FC_CACHE_MAX_LEVEL 16 | 243 | #define FC_CACHE_MAX_LEVEL 16 | |
296 | 244 | |||
297 | static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL]; | 245 | static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL]; | |
298 | static int fcCacheMaxLevel; | 246 | static int fcCacheMaxLevel; | |
299 | 247 | |||
300 | #if HAVE_RANDOM | 248 | ||
301 | # define FcRandom() random() | 249 | static int32_t | |
250 | FcRandom(void) | |||
251 | { | |||
252 | int32_t result; | |||
253 | ||||
254 | #if HAVE_RANDOM_R | |||
255 | static struct random_data fcrandbuf; | |||
256 | static char statebuf[256]; | |||
257 | static FcBool initialized = FcFalse; | |||
258 | ||||
259 | if (initialized != FcTrue) | |||
260 | { | |||
261 | initstate_r(time(NULL), statebuf, 256, &fcrandbuf); | |||
262 | initialized = FcTrue; | |||
263 | } | |||
264 | ||||
265 | random_r(&fcrandbuf, &result); | |||
266 | #elif HAVE_RANDOM | |||
267 | static char statebuf[256]; | |||
268 | char *state; | |||
269 | static FcBool initialized = FcFalse; | |||
270 | ||||
271 | if (initialized != FcTrue) | |||
272 | { | |||
273 | state = initstate(time(NULL), statebuf, 256); | |||
274 | initialized = FcTrue; | |||
275 | } | |||
276 | else | |||
277 | state = setstate(statebuf); | |||
278 | ||||
279 | result = random(); | |||
280 | ||||
281 | setstate(state); | |||
282 | #elif HAVE_LRAND48 | |||
283 | result = lrand48(); | |||
284 | #elif HAVE_RAND_R | |||
285 | static unsigned int seed = time(NULL); | |||
286 | ||||
287 | result = rand_r(&seed); | |||
288 | #elif HAVE_RAND | |||
289 | static FcBool initialized = FcFalse; | |||
290 | ||||
291 | if (initialized != FcTrue) | |||
292 | { | |||
293 | srand(time(NULL)); | |||
294 | initialized = FcTrue; | |||
295 | } | |||
296 | result = rand(); | |||
302 | #else | 297 | #else | |
303 | # if HAVE_LRAND48 | 298 | # error no random number generator function available. | |
304 | # define FcRandom() lrand48() | |||
305 | # else | |||
306 | # if HAVE_RAND | |||
307 | # define FcRandom() rand() | |||
308 | # endif | |||
309 | # endif | |||
310 | #endif | 299 | #endif | |
300 | ||||
301 | return result; | |||
302 | } | |||
303 | ||||
311 | /* | 304 | /* | |
312 | * Generate a random level number, distributed | 305 | * Generate a random level number, distributed | |
313 | * so that each level is 1/4 as likely as the one before | 306 | * so that each level is 1/4 as likely as the one before | |
314 | * | 307 | * | |
315 | * Note that level numbers run 1 <= level <= MAX_LEVEL | 308 | * Note that level numbers run 1 <= level <= MAX_LEVEL | |
316 | */ | 309 | */ | |
317 | static int | 310 | static int | |
318 | random_level (void) | 311 | random_level (void) | |
319 | { | 312 | { | |
320 | /* tricky bit -- each bit is '1' 75% of the time */ | 313 | /* tricky bit -- each bit is '1' 75% of the time */ | |
321 | long int bits = FcRandom () | FcRandom (); | 314 | long int bits = FcRandom () | FcRandom (); | |
322 | int level = 0; | 315 | int level = 0; | |
323 | 316 | |||
@@ -352,47 +345,47 @@ FcCacheInsert (FcCache *cache, struct st | @@ -352,47 +345,47 @@ FcCacheInsert (FcCache *cache, struct st | |||
352 | update[i] = &next[i]; | 345 | update[i] = &next[i]; | |
353 | } | 346 | } | |
354 | 347 | |||
355 | /* | 348 | /* | |
356 | * Create new list element | 349 | * Create new list element | |
357 | */ | 350 | */ | |
358 | level = random_level (); | 351 | level = random_level (); | |
359 | if (level > fcCacheMaxLevel) | 352 | if (level > fcCacheMaxLevel) | |
360 | { | 353 | { | |
361 | level = fcCacheMaxLevel + 1; | 354 | level = fcCacheMaxLevel + 1; | |
362 | update[fcCacheMaxLevel] = &fcCacheChains[fcCacheMaxLevel]; | 355 | update[fcCacheMaxLevel] = &fcCacheChains[fcCacheMaxLevel]; | |
363 | fcCacheMaxLevel = level; | 356 | fcCacheMaxLevel = level; | |
364 | } | 357 | } | |
365 | 358 | |||
366 | s = malloc (sizeof (FcCacheSkip) + (level - 1) * sizeof (FcCacheSkip *)); | 359 | s = malloc (sizeof (FcCacheSkip) + (level - 1) * sizeof (FcCacheSkip *)); | |
367 | if (!s) | 360 | if (!s) | |
368 | return FcFalse; | 361 | return FcFalse; | |
369 | 362 | |||
370 | s->cache = cache; | 363 | s->cache = cache; | |
371 | s->size = cache->size; | 364 | s->size = cache->size; | |
372 | s->ref = 1; | 365 | s->ref = 1; | |
373 | if (cache_stat) | 366 | if (cache_stat) | |
374 | { | 367 | { | |
375 | s->cache_dev = cache_stat->st_dev; | 368 | s->cache_dev = cache_stat->st_dev; | |
376 | s->cache_ino = cache_stat->st_ino; | 369 | s->cache_ino = cache_stat->st_ino; | |
377 | s->cache_mtime = cache_stat->st_mtime; | 370 | s->cache_mtime = cache_stat->st_mtime; | |
378 | } | 371 | } | |
379 | else | 372 | else | |
380 | { | 373 | { | |
381 | s->cache_dev = 0; | 374 | s->cache_dev = 0; | |
382 | s->cache_ino = 0; | 375 | s->cache_ino = 0; | |
383 | s->cache_mtime = 0; | 376 | s->cache_mtime = 0; | |
384 | } | 377 | } | |
385 | 378 | |||
386 | /* | 379 | /* | |
387 | * Insert into all fcCacheChains | 380 | * Insert into all fcCacheChains | |
388 | */ | 381 | */ | |
389 | for (i = 0; i < level; i++) | 382 | for (i = 0; i < level; i++) | |
390 | { | 383 | { | |
391 | s->next[i] = *update[i]; | 384 | s->next[i] = *update[i]; | |
392 | *update[i] = s; | 385 | *update[i] = s; | |
393 | } | 386 | } | |
394 | return FcTrue; | 387 | return FcTrue; | |
395 | } | 388 | } | |
396 | 389 | |||
397 | static FcCacheSkip * | 390 | static FcCacheSkip * | |
398 | FcCacheFindByAddr (void *object) | 391 | FcCacheFindByAddr (void *object) | |
@@ -505,96 +498,99 @@ FcCacheFini (void) | @@ -505,96 +498,99 @@ FcCacheFini (void) | |||
505 | 498 | |||
506 | for (i = 0; i < FC_CACHE_MAX_LEVEL; i++) | 499 | for (i = 0; i < FC_CACHE_MAX_LEVEL; i++) | |
507 | assert (fcCacheChains[i] == NULL); | 500 | assert (fcCacheChains[i] == NULL); | |
508 | assert (fcCacheMaxLevel == 0); | 501 | assert (fcCacheMaxLevel == 0); | |
509 | } | 502 | } | |
510 | 503 | |||
511 | static FcBool | 504 | static FcBool | |
512 | FcCacheTimeValid (FcCache *cache, struct stat *dir_stat) | 505 | FcCacheTimeValid (FcCache *cache, struct stat *dir_stat) | |
513 | { | 506 | { | |
514 | struct stat dir_static; | 507 | struct stat dir_static; | |
515 | 508 | |||
516 | if (!dir_stat) | 509 | if (!dir_stat) | |
517 | { | 510 | { | |
518 | if (FcStat ((const char *) FcCacheDir (cache), &dir_static) < 0) | 511 | if (FcStatChecksum (FcCacheDir (cache), &dir_static) < 0) | |
519 | return FcFalse; | 512 | return FcFalse; | |
520 | dir_stat = &dir_static; | 513 | dir_stat = &dir_static; | |
521 | } | 514 | } | |
522 | if (FcDebug () & FC_DBG_CACHE) | 515 | if (FcDebug () & FC_DBG_CACHE) | |
523 | printf ("FcCacheTimeValid dir \"%s\" cache time %d dir time %d\n", | 516 | printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", | |
524 | FcCacheDir (cache), cache->mtime, (int) dir_stat->st_mtime); | 517 | FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); | |
525 | return cache->mtime == (int) dir_stat->st_mtime; | 518 | return cache->checksum == (int) dir_stat->st_mtime; | |
526 | } | 519 | } | |
527 | 520 | |||
528 | /* | 521 | /* | |
529 | * Map a cache file into memory | 522 | * Map a cache file into memory | |
530 | */ | 523 | */ | |
531 | static FcCache * | 524 | static FcCache * | |
532 | FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) | 525 | FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) | |
533 | { | 526 | { | |
534 | FcCache *cache; | 527 | FcCache *cache; | |
535 | FcBool allocated = FcFalse; | 528 | FcBool allocated = FcFalse; | |
536 | 529 | |||
537 | if (fd_stat->st_size < sizeof (FcCache)) | 530 | if (fd_stat->st_size < sizeof (FcCache)) | |
538 | return NULL; | 531 | return NULL; | |
539 | cache = FcCacheFindByStat (fd_stat); | 532 | cache = FcCacheFindByStat (fd_stat); | |
540 | if (cache) | 533 | if (cache) | |
541 | { | 534 | { | |
542 | if (FcCacheTimeValid (cache, dir_stat)) | 535 | if (FcCacheTimeValid (cache, dir_stat)) | |
543 | return cache; | 536 | return cache; | |
544 | FcDirCacheUnload (cache); | 537 | FcDirCacheUnload (cache); | |
545 | cache = NULL; | 538 | cache = NULL; | |
546 | } | 539 | } | |
547 | 540 | |||
548 | /* | 541 | /* | |
549 | * Lage cache files are mmap'ed, smaller cache files are read. This | 542 | * Large cache files are mmap'ed, smaller cache files are read. This | |
550 | * balances the system cost of mmap against per-process memory usage. | 543 | * balances the system cost of mmap against per-process memory usage. | |
551 | */ | 544 | */ | |
552 | if (fd_stat->st_size >= FC_CACHE_MIN_MMAP) | 545 | if (FcCacheIsMmapSafe (fd) && fd_stat->st_size >= FC_CACHE_MIN_MMAP) | |
553 | { | 546 | { | |
554 | #if defined(HAVE_MMAP) || defined(__CYGWIN__) | 547 | #if defined(HAVE_MMAP) || defined(__CYGWIN__) | |
555 | cache = mmap (0, fd_stat->st_size, PROT_READ, MAP_SHARED, fd, 0); | 548 | cache = mmap (0, fd_stat->st_size, PROT_READ, MAP_SHARED, fd, 0); | |
549 | #ifdef HAVE_POSIX_FADVISE | |||
550 | posix_fadvise (fd, 0, fd_stat->st_size, POSIX_FADV_WILLNEED); | |||
551 | #endif | |||
556 | if (cache == MAP_FAILED) | 552 | if (cache == MAP_FAILED) | |
557 | cache = NULL; | 553 | cache = NULL; | |
558 | #elif defined(_WIN32) | 554 | #elif defined(_WIN32) | |
559 | { | 555 | { | |
560 | HANDLE hFileMap; | 556 | HANDLE hFileMap; | |
561 | 557 | |||
562 | cache = NULL; | 558 | cache = NULL; | |
563 | hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, | 559 | hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, | |
564 | PAGE_READONLY, 0, 0, NULL); | 560 | PAGE_READONLY, 0, 0, NULL); | |
565 | if (hFileMap != NULL) | 561 | if (hFileMap != NULL) | |
566 | { | 562 | { | |
567 | cache = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, | 563 | cache = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, | |
568 | fd_stat->st_size); | 564 | fd_stat->st_size); | |
569 | CloseHandle (hFileMap); | 565 | CloseHandle (hFileMap); | |
570 | } | 566 | } | |
571 | } | 567 | } | |
572 | #endif | 568 | #endif | |
573 | } | 569 | } | |
574 | if (!cache) | 570 | if (!cache) | |
575 | { | 571 | { | |
576 | cache = malloc (fd_stat->st_size); | 572 | cache = malloc (fd_stat->st_size); | |
577 | if (!cache) | 573 | if (!cache) | |
578 | return NULL; | 574 | return NULL; | |
579 | 575 | |||
580 | if (read (fd, cache, fd_stat->st_size) != fd_stat->st_size) | 576 | if (read (fd, cache, fd_stat->st_size) != fd_stat->st_size) | |
581 | { | 577 | { | |
582 | free (cache); | 578 | free (cache); | |
583 | return NULL; | 579 | return NULL; | |
584 | } | 580 | } | |
585 | allocated = FcTrue; | 581 | allocated = FcTrue; | |
586 | } | 582 | } | |
587 | if (cache->magic != FC_CACHE_MAGIC_MMAP || | 583 | if (cache->magic != FC_CACHE_MAGIC_MMAP || | |
588 | cache->version < FC_CACHE_CONTENT_VERSION || | 584 | cache->version < FC_CACHE_CONTENT_VERSION || | |
589 | cache->size != fd_stat->st_size || | 585 | cache->size != fd_stat->st_size || | |
590 | !FcCacheTimeValid (cache, dir_stat) || | 586 | !FcCacheTimeValid (cache, dir_stat) || | |
591 | !FcCacheInsert (cache, fd_stat)) | 587 | !FcCacheInsert (cache, fd_stat)) | |
592 | { | 588 | { | |
593 | if (allocated) | 589 | if (allocated) | |
594 | free (cache); | 590 | free (cache); | |
595 | else | 591 | else | |
596 | { | 592 | { | |
597 | #if defined(HAVE_MMAP) || defined(__CYGWIN__) | 593 | #if defined(HAVE_MMAP) || defined(__CYGWIN__) | |
598 | munmap (cache, fd_stat->st_size); | 594 | munmap (cache, fd_stat->st_size); | |
599 | #elif defined(_WIN32) | 595 | #elif defined(_WIN32) | |
600 | UnmapViewOfFile (cache); | 596 | UnmapViewOfFile (cache); | |
@@ -664,173 +660,171 @@ FcDirCacheLoadFile (const FcChar8 *cache | @@ -664,173 +660,171 @@ FcDirCacheLoadFile (const FcChar8 *cache | |||
664 | close (fd); | 660 | close (fd); | |
665 | return cache; | 661 | return cache; | |
666 | } | 662 | } | |
667 | 663 | |||
668 | /* | 664 | /* | |
669 | * Validate a cache file by reading the header and checking | 665 | * Validate a cache file by reading the header and checking | |
670 | * the magic number and the size field | 666 | * the magic number and the size field | |
671 | */ | 667 | */ | |
672 | static FcBool | 668 | static FcBool | |
673 | FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) | 669 | FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) | |
674 | { | 670 | { | |
675 | FcBool ret = FcTrue; | 671 | FcBool ret = FcTrue; | |
676 | FcCache c; | 672 | FcCache c; | |
677 | 673 | |||
678 | if (read (fd, &c, sizeof (FcCache)) != sizeof (FcCache)) | 674 | if (read (fd, &c, sizeof (FcCache)) != sizeof (FcCache)) | |
679 | ret = FcFalse; | 675 | ret = FcFalse; | |
680 | else if (c.magic != FC_CACHE_MAGIC_MMAP) | 676 | else if (c.magic != FC_CACHE_MAGIC_MMAP) | |
681 | ret = FcFalse; | 677 | ret = FcFalse; | |
682 | else if (c.version < FC_CACHE_CONTENT_VERSION) | 678 | else if (c.version < FC_CACHE_CONTENT_VERSION) | |
683 | ret = FcFalse; | 679 | ret = FcFalse; | |
684 | else if (fd_stat->st_size != c.size) | 680 | else if (fd_stat->st_size != c.size) | |
685 | ret = FcFalse; | 681 | ret = FcFalse; | |
686 | else if (c.mtime != (int) dir_stat->st_mtime) | 682 | else if (c.checksum != (int) dir_stat->st_mtime) | |
687 | ret = FcFalse; | 683 | ret = FcFalse; | |
688 | return ret; | 684 | return ret; | |
689 | } | 685 | } | |
690 | 686 | |||
691 | static FcBool | 687 | static FcBool | |
692 | FcDirCacheValidConfig (const FcChar8 *dir, FcConfig *config) | 688 | FcDirCacheValidConfig (const FcChar8 *dir, FcConfig *config) | |
693 | { | 689 | { | |
694 | return FcDirCacheProcess (config, dir, | 690 | return FcDirCacheProcess (config, dir, | |
695 | FcDirCacheValidateHelper, | 691 | FcDirCacheValidateHelper, | |
696 | NULL, NULL); | 692 | NULL, NULL); | |
697 | } | 693 | } | |
698 | 694 | |||
699 | FcBool | 695 | FcBool | |
700 | FcDirCacheValid (const FcChar8 *dir) | 696 | FcDirCacheValid (const FcChar8 *dir) | |
701 | { | 697 | { | |
702 | FcConfig *config; | 698 | FcConfig *config; | |
703 | 699 | |||
704 | config = FcConfigGetCurrent (); | 700 | config = FcConfigGetCurrent (); | |
705 | if (!config) | 701 | if (!config) | |
706 | return FcFalse; | 702 | return FcFalse; | |
707 | 703 | |||
708 | return FcDirCacheValidConfig (dir, config); | 704 | return FcDirCacheValidConfig (dir, config); | |
709 | } | 705 | } | |
710 | 706 | |||
711 | /* | 707 | /* | |
712 | * Build a cache structure from the given contents | 708 | * Build a cache structure from the given contents | |
713 | */ | 709 | */ | |
714 | FcCache * | 710 | FcCache * | |
715 | FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs) | 711 | FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs) | |
716 | { | 712 | { | |
717 | FcSerialize *serialize = FcSerializeCreate (); | 713 | FcSerialize *serialize = FcSerializeCreate (); | |
718 | FcCache *cache; | 714 | FcCache *cache; | |
719 | int i; | 715 | int i; | |
720 | intptr_t cache_offset; | |||
721 | intptr_t dirs_offset; | |||
722 | FcChar8 *dir_serialize; | 716 | FcChar8 *dir_serialize; | |
723 | intptr_t *dirs_serialize; | 717 | intptr_t *dirs_serialize; | |
724 | FcFontSet *set_serialize; | 718 | FcFontSet *set_serialize; | |
725 | 719 | |||
726 | if (!serialize) | 720 | if (!serialize) | |
727 | return NULL; | 721 | return NULL; | |
728 | /* | 722 | /* | |
729 | * Space for cache structure | 723 | * Space for cache structure | |
730 | */ | 724 | */ | |
731 | cache_offset = FcSerializeReserve (serialize, sizeof (FcCache)); | 725 | FcSerializeReserve (serialize, sizeof (FcCache)); | |
732 | /* | 726 | /* | |
733 | * Directory name | 727 | * Directory name | |
734 | */ | 728 | */ | |
735 | if (!FcStrSerializeAlloc (serialize, dir)) | 729 | if (!FcStrSerializeAlloc (serialize, dir)) | |
736 | goto bail1; | 730 | goto bail1; | |
737 | /* | 731 | /* | |
738 | * Subdirs | 732 | * Subdirs | |
739 | */ | 733 | */ | |
740 | dirs_offset = FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *)); | 734 | FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *)); | |
741 | for (i = 0; i < dirs->num; i++) | 735 | for (i = 0; i < dirs->num; i++) | |
742 | if (!FcStrSerializeAlloc (serialize, dirs->strs[i])) | 736 | if (!FcStrSerializeAlloc (serialize, dirs->strs[i])) | |
743 | goto bail1; | 737 | goto bail1; | |
744 | 738 | |||
745 | /* | 739 | /* | |
746 | * Patterns | 740 | * Patterns | |
747 | */ | 741 | */ | |
748 | if (!FcFontSetSerializeAlloc (serialize, set)) | 742 | if (!FcFontSetSerializeAlloc (serialize, set)) | |
749 | goto bail1; | 743 | goto bail1; | |
750 | 744 | |||
751 | /* Serialize layout complete. Now allocate space and fill it */ | 745 | /* Serialize layout complete. Now allocate space and fill it */ | |
752 | cache = malloc (serialize->size); | 746 | cache = malloc (serialize->size); | |
753 | if (!cache) | 747 | if (!cache) | |
754 | goto bail1; | 748 | goto bail1; | |
755 | /* shut up valgrind */ | 749 | /* shut up valgrind */ | |
756 | memset (cache, 0, serialize->size); | 750 | memset (cache, 0, serialize->size); | |
757 | 751 | |||
758 | serialize->linear = cache; | 752 | serialize->linear = cache; | |
759 | 753 | |||
760 | cache->magic = FC_CACHE_MAGIC_ALLOC; | 754 | cache->magic = FC_CACHE_MAGIC_ALLOC; | |
761 | cache->version = FC_CACHE_CONTENT_VERSION; | 755 | cache->version = FC_CACHE_CONTENT_VERSION; | |
762 | cache->size = serialize->size; | 756 | cache->size = serialize->size; | |
763 | cache->mtime = (int) dir_stat->st_mtime; | 757 | cache->checksum = (int) dir_stat->st_mtime; | |
764 | 758 | |||
765 | /* | 759 | /* | |
766 | * Serialize directory name | 760 | * Serialize directory name | |
767 | */ | 761 | */ | |
768 | dir_serialize = FcStrSerialize (serialize, dir); | 762 | dir_serialize = FcStrSerialize (serialize, dir); | |
769 | if (!dir_serialize) | 763 | if (!dir_serialize) | |
770 | goto bail2; | 764 | goto bail2; | |
771 | cache->dir = FcPtrToOffset (cache, dir_serialize); | 765 | cache->dir = FcPtrToOffset (cache, dir_serialize); | |
772 | 766 | |||
773 | /* | 767 | /* | |
774 | * Serialize sub dirs | 768 | * Serialize sub dirs | |
775 | */ | 769 | */ | |
776 | dirs_serialize = FcSerializePtr (serialize, dirs); | 770 | dirs_serialize = FcSerializePtr (serialize, dirs); | |
777 | if (!dirs_serialize) | 771 | if (!dirs_serialize) | |
778 | goto bail2; | 772 | goto bail2; | |
779 | cache->dirs = FcPtrToOffset (cache, dirs_serialize); | 773 | cache->dirs = FcPtrToOffset (cache, dirs_serialize); | |
780 | cache->dirs_count = dirs->num; | 774 | cache->dirs_count = dirs->num; | |
781 | for (i = 0; i < dirs->num; i++) | 775 | for (i = 0; i < dirs->num; i++) | |
782 | { | 776 | { | |
783 | FcChar8 *d_serialize = FcStrSerialize (serialize, dirs->strs[i]); | 777 | FcChar8 *d_serialize = FcStrSerialize (serialize, dirs->strs[i]); | |
784 | if (!d_serialize) | 778 | if (!d_serialize) | |
785 | goto bail2; | 779 | goto bail2; | |
786 | dirs_serialize[i] = FcPtrToOffset (dirs_serialize, d_serialize); | 780 | dirs_serialize[i] = FcPtrToOffset (dirs_serialize, d_serialize); | |
787 | } | 781 | } | |
788 | 782 | |||
789 | /* | 783 | /* | |
790 | * Serialize font set | 784 | * Serialize font set | |
791 | */ | 785 | */ | |
792 | set_serialize = FcFontSetSerialize (serialize, set); | 786 | set_serialize = FcFontSetSerialize (serialize, set); | |
793 | if (!set_serialize) | 787 | if (!set_serialize) | |
794 | goto bail2; | 788 | goto bail2; | |
795 | cache->set = FcPtrToOffset (cache, set_serialize); | 789 | cache->set = FcPtrToOffset (cache, set_serialize); | |
796 | 790 | |||
797 | FcSerializeDestroy (serialize); | 791 | FcSerializeDestroy (serialize); | |
798 | 792 | |||
799 | FcCacheInsert (cache, NULL); | 793 | FcCacheInsert (cache, NULL); | |
800 | 794 | |||
801 | return cache; | 795 | return cache; | |
802 | 796 | |||
803 | bail2: | 797 | bail2: | |
804 | free (cache); | 798 | free (cache); | |
805 | bail1: | 799 | bail1: | |
806 | FcSerializeDestroy (serialize); | 800 | FcSerializeDestroy (serialize); | |
807 | return NULL; | 801 | return NULL; | |
808 | } | 802 | } | |
809 | 803 | |||
810 | 804 | |||
811 | #ifdef _WIN32 | 805 | #ifdef _WIN32 | |
812 | #define mkdir(path,mode) _mkdir(path) | 806 | #define mkdir(path,mode) _mkdir(path) | |
813 | #endif | 807 | #endif | |
814 | 808 | |||
815 | static FcBool | 809 | static FcBool | |
816 | FcMakeDirectory (const FcChar8 *dir) | 810 | FcMakeDirectory (const FcChar8 *dir) | |
817 | { | 811 | { | |
818 | FcChar8 *parent; | 812 | FcChar8 *parent; | |
819 | FcBool ret; | 813 | FcBool ret; | |
820 | 814 | |||
821 | if (strlen ((char *) dir) == 0) | 815 | if (strlen ((char *) dir) == 0) | |
822 | return FcFalse; | 816 | return FcFalse; | |
823 | 817 | |||
824 | parent = FcStrDirname (dir); | 818 | parent = FcStrDirname (dir); | |
825 | if (!parent) | 819 | if (!parent) | |
826 | return FcFalse; | 820 | return FcFalse; | |
827 | if (access ((char *) parent, F_OK) == 0) | 821 | if (access ((char *) parent, F_OK) == 0) | |
828 | ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; | 822 | ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0; | |
829 | else if (access ((char *) parent, F_OK) == -1) | 823 | else if (access ((char *) parent, F_OK) == -1) | |
830 | ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; | 824 | ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0; | |
831 | else | 825 | else | |
832 | ret = FcFalse; | 826 | ret = FcFalse; | |
833 | FcStrFree (parent); | 827 | FcStrFree (parent); | |
834 | return ret; | 828 | return ret; | |
835 | } | 829 | } | |
836 | 830 | |||
@@ -844,54 +838,58 @@ FcDirCacheWrite (FcCache *cache, FcConfi | @@ -844,54 +838,58 @@ FcDirCacheWrite (FcCache *cache, FcConfi | |||
844 | int fd; | 838 | int fd; | |
845 | FcAtomic *atomic; | 839 | FcAtomic *atomic; | |
846 | FcStrList *list; | 840 | FcStrList *list; | |
847 | FcChar8 *cache_dir = NULL; | 841 | FcChar8 *cache_dir = NULL; | |
848 | FcChar8 *test_dir; | 842 | FcChar8 *test_dir; | |
849 | FcCacheSkip *skip; | 843 | FcCacheSkip *skip; | |
850 | struct stat cache_stat; | 844 | struct stat cache_stat; | |
851 | int magic; | 845 | int magic; | |
852 | int written; | 846 | int written; | |
853 | 847 | |||
854 | /* | 848 | /* | |
855 | * Write it to the first directory in the list which is writable | 849 | * Write it to the first directory in the list which is writable | |
856 | */ | 850 | */ | |
857 | 851 | |||
858 | list = FcStrListCreate (config->cacheDirs); | 852 | list = FcStrListCreate (config->cacheDirs); | |
859 | if (!list) | 853 | if (!list) | |
860 | return FcFalse; | 854 | return FcFalse; | |
861 | while ((test_dir = FcStrListNext (list))) { | 855 | while ((test_dir = FcStrListNext (list))) { | |
862 | if (access ((char *) test_dir, W_OK|X_OK) == 0) | 856 | if (access ((char *) test_dir, W_OK) == 0) | |
863 | { | 857 | { | |
864 | cache_dir = test_dir; | 858 | cache_dir = test_dir; | |
865 | break; | 859 | break; | |
866 | } | 860 | } | |
867 | else | 861 | else | |
868 | { | 862 | { | |
869 | /* | 863 | /* | |
870 | * If the directory doesn't exist, try to create it | 864 | * If the directory doesn't exist, try to create it | |
871 | */ | 865 | */ | |
872 | if (access ((char *) test_dir, F_OK) == -1) { | 866 | if (access ((char *) test_dir, F_OK) == -1) { | |
873 | if (FcMakeDirectory (test_dir)) | 867 | if (FcMakeDirectory (test_dir)) | |
874 | { | 868 | { | |
875 | cache_dir = test_dir; | 869 | cache_dir = test_dir; | |
870 | /* Create CACHEDIR.TAG */ | |||
871 | FcDirCacheCreateTagFile (cache_dir); | |||
876 | break; | 872 | break; | |
877 | } | 873 | } | |
878 | } | 874 | } | |
879 | /* | 875 | /* | |
880 | * Otherwise, try making it writable | 876 | * Otherwise, try making it writable | |
881 | */ | 877 | */ | |
882 | else if (chmod ((char *) test_dir, 0755) == 0) | 878 | else if (chmod ((char *) test_dir, 0755) == 0) | |
883 | { | 879 | { | |
884 | cache_dir = test_dir; | 880 | cache_dir = test_dir; | |
881 | /* Try to create CACHEDIR.TAG too */ | |||
882 | FcDirCacheCreateTagFile (cache_dir); | |||
885 | break; | 883 | break; | |
886 | } | 884 | } | |
887 | } | 885 | } | |
888 | } | 886 | } | |
889 | FcStrListDone (list); | 887 | FcStrListDone (list); | |
890 | if (!cache_dir) | 888 | if (!cache_dir) | |
891 | return FcFalse; | 889 | return FcFalse; | |
892 | 890 | |||
893 | FcDirCacheBasename (dir, cache_base); | 891 | FcDirCacheBasename (dir, cache_base); | |
894 | cache_hashed = FcStrPlus (cache_dir, cache_base); | 892 | cache_hashed = FcStrPlus (cache_dir, cache_base); | |
895 | if (!cache_hashed) | 893 | if (!cache_hashed) | |
896 | return FcFalse; | 894 | return FcFalse; | |
897 | 895 | |||
@@ -899,41 +897,41 @@ FcDirCacheWrite (FcCache *cache, FcConfi | @@ -899,41 +897,41 @@ FcDirCacheWrite (FcCache *cache, FcConfi | |||
899 | printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n", | 897 | printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n", | |
900 | dir, cache_hashed); | 898 | dir, cache_hashed); | |
901 | 899 | |||
902 | atomic = FcAtomicCreate ((FcChar8 *)cache_hashed); | 900 | atomic = FcAtomicCreate ((FcChar8 *)cache_hashed); | |
903 | if (!atomic) | 901 | if (!atomic) | |
904 | goto bail1; | 902 | goto bail1; | |
905 | 903 | |||
906 | if (!FcAtomicLock (atomic)) | 904 | if (!FcAtomicLock (atomic)) | |
907 | goto bail3; | 905 | goto bail3; | |
908 | 906 | |||
909 | fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); | 907 | fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666); | |
910 | if (fd == -1) | 908 | if (fd == -1) | |
911 | goto bail4; | 909 | goto bail4; | |
912 | 910 | |||
913 | /* Temporarily switch magic to MMAP while writing to file */ | 911 | /* Temporarily switch magic to MMAP while writing to file */ | |
914 | magic = cache->magic; | 912 | magic = cache->magic; | |
915 | if (magic != FC_CACHE_MAGIC_MMAP) | 913 | if (magic != FC_CACHE_MAGIC_MMAP) | |
916 | cache->magic = FC_CACHE_MAGIC_MMAP; | 914 | cache->magic = FC_CACHE_MAGIC_MMAP; | |
917 | 915 | |||
918 | /* | 916 | /* | |
919 | * Write cache contents to file | 917 | * Write cache contents to file | |
920 | */ | 918 | */ | |
921 | written = write (fd, cache, cache->size); | 919 | written = write (fd, cache, cache->size); | |
922 | 920 | |||
923 | /* Switch magic back */ | 921 | /* Switch magic back */ | |
924 | if (magic != FC_CACHE_MAGIC_MMAP) | 922 | if (magic != FC_CACHE_MAGIC_MMAP) | |
925 | cache->magic = magic; | 923 | cache->magic = magic; | |
926 | 924 | |||
927 | if (written != cache->size) | 925 | if (written != cache->size) | |
928 | { | 926 | { | |
929 | perror ("write cache"); | 927 | perror ("write cache"); | |
930 | goto bail5; | 928 | goto bail5; | |
931 | } | 929 | } | |
932 | 930 | |||
933 | close(fd); | 931 | close(fd); | |
934 | if (!FcAtomicReplaceOrig(atomic)) | 932 | if (!FcAtomicReplaceOrig(atomic)) | |
935 | goto bail4; | 933 | goto bail4; | |
936 | 934 | |||
937 | /* If the file is small, update the cache chain entry such that the | 935 | /* If the file is small, update the cache chain entry such that the | |
938 | * new cache file is not read again. If it's large, we don't do that | 936 | * new cache file is not read again. If it's large, we don't do that | |
939 | * such that we reload it, using mmap, which is shared across processes. | 937 | * such that we reload it, using mmap, which is shared across processes. | |
@@ -953,46 +951,137 @@ FcDirCacheWrite (FcCache *cache, FcConfi | @@ -953,46 +951,137 @@ FcDirCacheWrite (FcCache *cache, FcConfi | |||
953 | return FcTrue; | 951 | return FcTrue; | |
954 | 952 | |||
955 | bail5: | 953 | bail5: | |
956 | close (fd); | 954 | close (fd); | |
957 | bail4: | 955 | bail4: | |
958 | FcAtomicUnlock (atomic); | 956 | FcAtomicUnlock (atomic); | |
959 | bail3: | 957 | bail3: | |
960 | FcAtomicDestroy (atomic); | 958 | FcAtomicDestroy (atomic); | |
961 | bail1: | 959 | bail1: | |
962 | FcStrFree (cache_hashed); | 960 | FcStrFree (cache_hashed); | |
963 | return FcFalse; | 961 | return FcFalse; | |
964 | } | 962 | } | |
965 | 963 | |||
964 | FcBool | |||
965 | FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) | |||
966 | { | |||
967 | DIR *d; | |||
968 | struct dirent *ent; | |||
969 | FcChar8 *dir_base; | |||
970 | FcBool ret = FcTrue; | |||
971 | FcBool remove; | |||
972 | FcCache *cache; | |||
973 | struct stat target_stat; | |||
974 | ||||
975 | dir_base = FcStrPlus (cache_dir, (FcChar8 *) FC_DIR_SEPARATOR_S); | |||
976 | if (!dir_base) | |||
977 | { | |||
978 | fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir); | |||
979 | return FcFalse; | |||
980 | } | |||
981 | if (access ((char *) cache_dir, W_OK) != 0) | |||
982 | { | |||
983 | if (verbose || FcDebug () & FC_DBG_CACHE) | |||
984 | printf ("%s: not cleaning %s cache directory\n", cache_dir, | |||
985 | access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); | |||
986 | goto bail0; | |||
987 | } | |||
988 | if (verbose || FcDebug () & FC_DBG_CACHE) | |||
989 | printf ("%s: cleaning cache directory\n", cache_dir); | |||
990 | d = opendir ((char *) cache_dir); | |||
991 | if (!d) | |||
992 | { | |||
993 | perror ((char *) cache_dir); | |||
994 | ret = FcFalse; | |||
995 | goto bail0; | |||
996 | } | |||
997 | while ((ent = readdir (d))) | |||
998 | { | |||
999 | FcChar8 *file_name; | |||
1000 | const FcChar8 *target_dir; | |||
1001 | ||||
1002 | if (ent->d_name[0] == '.') | |||
1003 | continue; | |||
1004 | /* skip cache files for different architectures and */ | |||
1005 | /* files which are not cache files at all */ | |||
1006 | if (strlen(ent->d_name) != 32 + strlen ("-" FC_ARCHITECTURE FC_CACHE_SUFFIX) || | |||
1007 | strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) | |||
1008 | continue; | |||
1009 | ||||
1010 | file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); | |||
1011 | if (!file_name) | |||
1012 | { | |||
1013 | fprintf (stderr, "Fontconfig error: %s: allocation failure\n", cache_dir); | |||
1014 | ret = FcFalse; | |||
1015 | break; | |||
1016 | } | |||
1017 | remove = FcFalse; | |||
1018 | cache = FcDirCacheLoadFile (file_name, NULL); | |||
1019 | if (!cache) | |||
1020 | { | |||
1021 | if (verbose || FcDebug () & FC_DBG_CACHE) | |||
1022 | printf ("%s: invalid cache file: %s\n", cache_dir, ent->d_name); | |||
1023 | remove = FcTrue; | |||
1024 | } | |||
1025 | else | |||
1026 | { | |||
1027 | target_dir = FcCacheDir (cache); | |||
1028 | if (stat ((char *) target_dir, &target_stat) < 0) | |||
1029 | { | |||
1030 | if (verbose || FcDebug () & FC_DBG_CACHE) | |||
1031 | printf ("%s: %s: missing directory: %s \n", | |||
1032 | cache_dir, ent->d_name, target_dir); | |||
1033 | remove = FcTrue; | |||
1034 | } | |||
1035 | } | |||
1036 | if (remove) | |||
1037 | { | |||
1038 | if (unlink ((char *) file_name) < 0) | |||
1039 | { | |||
1040 | perror ((char *) file_name); | |||
1041 | ret = FcFalse; | |||
1042 | } | |||
1043 | } | |||
1044 | FcDirCacheUnload (cache); | |||
1045 | FcStrFree (file_name); | |||
1046 | } | |||
1047 | ||||
1048 | closedir (d); | |||
1049 | bail0: | |||
1050 | FcStrFree (dir_base); | |||
1051 | ||||
1052 | return ret; | |||
1053 | } | |||
1054 | ||||
966 | /* | 1055 | /* | |
967 | * Hokey little macro trick to permit the definitions of C functions | 1056 | * Hokey little macro trick to permit the definitions of C functions | |
968 | * with the same name as CPP macros | 1057 | * with the same name as CPP macros | |
969 | */ | 1058 | */ | |
970 | #define args1(x) (x) | 1059 | #define args1(x) (x) | |
971 | #define args2(x,y) (x,y) | 1060 | #define args2(x,y) (x,y) | |
972 | 1061 | |||
973 | const FcChar8 * | 1062 | const FcChar8 * | |
974 | FcCacheDir args1(const FcCache *c) | 1063 | FcCacheDir args1(const FcCache *c) | |
975 | { | 1064 | { | |
976 | return FcCacheDir (c); | 1065 | return FcCacheDir (c); | |
977 | } | 1066 | } | |
978 | 1067 | |||
979 | FcFontSet * | 1068 | FcFontSet * | |
980 | FcCacheCopySet args1(const FcCache *c) | 1069 | FcCacheCopySet args1(const FcCache *c) | |
981 | { | 1070 | { | |
982 | FcFontSet *old = FcCacheSet (c); | 1071 | FcFontSet *old = FcCacheSet (c); | |
983 | FcFontSet *new = FcFontSetCreate (); | 1072 | FcFontSet *new = FcFontSetCreate (); | |
984 | int i; | 1073 | int i; | |
985 | 1074 | |||
986 | if (!new) | 1075 | if (!new) | |
987 | return NULL; | 1076 | return NULL; | |
988 | for (i = 0; i < old->nfont; i++) | 1077 | for (i = 0; i < old->nfont; i++) | |
989 | { | 1078 | { | |
990 | FcPattern *font = FcFontSetFont (old, i); | 1079 | FcPattern *font = FcFontSetFont (old, i); | |
991 | 1080 | |||
992 | FcPatternReference (font); | 1081 | FcPatternReference (font); | |
993 | if (!FcFontSetAdd (new, font)) | 1082 | if (!FcFontSetAdd (new, font)) | |
994 | { | 1083 | { | |
995 | FcFontSetDestroy (new); | 1084 | FcFontSetDestroy (new); | |
996 | return NULL; | 1085 | return NULL; | |
997 | } | 1086 | } | |
998 | } | 1087 | } | |
@@ -1106,27 +1195,27 @@ static void MD5Update(struct MD5Context | @@ -1106,27 +1195,27 @@ static void MD5Update(struct MD5Context | |||
1106 | memcpy(ctx->in, buf, 64); | 1195 | memcpy(ctx->in, buf, 64); | |
1107 | byteReverse(ctx->in, 16); | 1196 | byteReverse(ctx->in, 16); | |
1108 | MD5Transform(ctx->buf, (FcChar32 *) ctx->in); | 1197 | MD5Transform(ctx->buf, (FcChar32 *) ctx->in); | |
1109 | buf += 64; | 1198 | buf += 64; | |
1110 | len -= 64; | 1199 | len -= 64; | |
1111 | } | 1200 | } | |
1112 | 1201 | |||
1113 | /* Handle any remaining bytes of data. */ | 1202 | /* Handle any remaining bytes of data. */ | |
1114 | 1203 | |||
1115 | memcpy(ctx->in, buf, len); | 1204 | memcpy(ctx->in, buf, len); | |
1116 | } | 1205 | } | |
1117 | 1206 | |||
1118 | /* | 1207 | /* | |
1119 | * Final wrapup - pad to 64-byte boundary with the bit pattern | 1208 | * Final wrapup - pad to 64-byte boundary with the bit pattern | |
1120 | * 1 0* (64-bit count of bits processed, MSB-first) | 1209 | * 1 0* (64-bit count of bits processed, MSB-first) | |
1121 | */ | 1210 | */ | |
1122 | static void MD5Final(unsigned char digest[16], struct MD5Context *ctx) | 1211 | static void MD5Final(unsigned char digest[16], struct MD5Context *ctx) | |
1123 | { | 1212 | { | |
1124 | unsigned count; | 1213 | unsigned count; | |
1125 | unsigned char *p; | 1214 | unsigned char *p; | |
1126 | 1215 | |||
1127 | /* Compute number of bytes mod 64 */ | 1216 | /* Compute number of bytes mod 64 */ | |
1128 | count = (ctx->bits[0] >> 3) & 0x3F; | 1217 | count = (ctx->bits[0] >> 3) & 0x3F; | |
1129 | 1218 | |||
1130 | /* Set the first char of padding to 0x80. This is safe since there is | 1219 | /* Set the first char of padding to 0x80. This is safe since there is | |
1131 | always at least one byte free */ | 1220 | always at least one byte free */ | |
1132 | p = ctx->in + count; | 1221 | p = ctx->in + count; | |
@@ -1250,16 +1339,97 @@ static void MD5Transform(FcChar32 buf[4] | @@ -1250,16 +1339,97 @@ static void MD5Transform(FcChar32 buf[4] | |||
1250 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | 1339 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | |
1251 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | 1340 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | |
1252 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | 1341 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | |
1253 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | 1342 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | |
1254 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | 1343 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | |
1255 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | 1344 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | |
1256 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | 1345 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | |
1257 | 1346 | |||
1258 | buf[0] += a; | 1347 | buf[0] += a; | |
1259 | buf[1] += b; | 1348 | buf[1] += b; | |
1260 | buf[2] += c; | 1349 | buf[2] += c; | |
1261 | buf[3] += d; | 1350 | buf[3] += d; | |
1262 | } | 1351 | } | |
1352 | ||||
1353 | FcBool | |||
1354 | FcDirCacheCreateTagFile (const FcChar8 *cache_dir) | |||
1355 | { | |||
1356 | FcChar8 *cache_tag; | |||
1357 | int fd; | |||
1358 | FILE *fp; | |||
1359 | FcAtomic *atomic; | |||
1360 | static const FcChar8 cache_tag_contents[] = | |||
1361 | "Signature: 8a477f597d28d172789f06886806bc55\n" | |||
1362 | "# This file is a cache directory tag created by fontconfig.\n" | |||
1363 | "# For information about cache directory tags, see:\n" | |||
1364 | "# http://www.brynosaurus.com/cachedir/\n"; | |||
1365 | static size_t cache_tag_contents_size = sizeof (cache_tag_contents) - 1; | |||
1366 | FcBool ret = FcFalse; | |||
1367 | ||||
1368 | if (!cache_dir) | |||
1369 | return FcFalse; | |||
1370 | ||||
1371 | if (access ((char *) cache_dir, W_OK) == 0) | |||
1372 | { | |||
1373 | /* Create CACHEDIR.TAG */ | |||
1374 | cache_tag = FcStrPlus (cache_dir, (const FcChar8 *) FC_DIR_SEPARATOR_S "CACHEDIR.TAG"); | |||
1375 | if (!cache_tag) | |||
1376 | return FcFalse; | |||
1377 | atomic = FcAtomicCreate ((FcChar8 *)cache_tag); | |||
1378 | if (!atomic) | |||
1379 | goto bail1; | |||
1380 | if (!FcAtomicLock (atomic)) | |||
1381 | goto bail2; | |||
1382 | fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT, 0644); | |||
1383 | if (fd == -1) | |||
1384 | goto bail3; | |||
1385 | fp = fdopen(fd, "wb"); | |||
1386 | if (fp == NULL) | |||
1387 | goto bail3; | |||
1388 | ||||
1389 | fwrite(cache_tag_contents, cache_tag_contents_size, sizeof (FcChar8), fp); | |||
1390 | fclose(fp); | |||
1391 | ||||
1392 | if (!FcAtomicReplaceOrig(atomic)) | |||
1393 | goto bail3; | |||
1394 | ||||
1395 | ret = FcTrue; | |||
1396 | bail3: | |||
1397 | FcAtomicUnlock (atomic); | |||
1398 | bail2: | |||
1399 | FcAtomicDestroy (atomic); | |||
1400 | bail1: | |||
1401 | FcStrFree (cache_tag); | |||
1402 | } | |||
1403 | ||||
1404 | if (FcDebug () & FC_DBG_CACHE) | |||
1405 | { | |||
1406 | if (ret) | |||
1407 | printf ("Created CACHEDIR.TAG at %s\n", cache_dir); | |||
1408 | else | |||
1409 | printf ("Unable to create CACHEDIR.TAG at %s\n", cache_dir); | |||
1410 | } | |||
1411 | ||||
1412 | return ret; | |||
1413 | } | |||
1414 | ||||
1415 | void | |||
1416 | FcCacheCreateTagFile (const FcConfig *config) | |||
1417 | { | |||
1418 | FcChar8 *cache_dir = NULL; | |||
1419 | FcStrList *list; | |||
1420 | ||||
1421 | list = FcConfigGetCacheDirs (config); | |||
1422 | if (!list) | |||
1423 | return; | |||
1424 | ||||
1425 | while ((cache_dir = FcStrListNext (list))) | |||
1426 | { | |||
1427 | if (FcDirCacheCreateTagFile (cache_dir)) | |||
1428 | break; | |||
1429 | } | |||
1430 | FcStrListDone (list); | |||
1431 | } | |||
1432 | ||||
1263 | #define __fccache__ | 1433 | #define __fccache__ | |
1264 | #include "fcaliastail.h" | 1434 | #include "fcaliastail.h" | |
1265 | #undef __fccache__ | 1435 | #undef __fccache__ |
--- xsrc/external/mit/fontconfig/dist/src/fcmatch.c 2012/02/13 16:59:51 1.2
+++ xsrc/external/mit/fontconfig/dist/src/fcmatch.c 2013/06/03 06:04:33 1.3
@@ -1,48 +1,49 @@ | @@ -1,48 +1,49 @@ | |||
1 | /* | 1 | /* | |
2 | * fontconfig/src/fcmatch.c | 2 | * fontconfig/src/fcmatch.c | |
3 | * | 3 | * | |
4 | * Copyright © 2000 Keith Packard | 4 | * Copyright © 2000 Keith Packard | |
5 | * | 5 | * | |
6 | * Permission to use, copy, modify, distribute, and sell this software and its | 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 | 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 | 8 | * the above copyright notice appear in all copies and that both that | |
9 | * copyright notice and this permission notice appear in supporting | 9 | * copyright notice and this permission notice appear in supporting | |
10 | * documentation, and that the name of Keith Packard not be used in | 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 | 11 | * advertising or publicity pertaining to distribution of the software without | |
12 | * specific, written prior permission. Keith Packard makes no | 12 | * specific, written prior permission. The authors make no | |
13 | * representations about the suitability of this software for any purpose. It | 13 | * representations about the suitability of this software for any purpose. It | |
14 | * is provided "as is" without express or implied warranty. | 14 | * is provided "as is" without express or implied warranty. | |
15 | * | 15 | * | |
16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | 16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | 17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
18 | * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR | 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, | 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 | 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 | 21 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
22 | * PERFORMANCE OF THIS SOFTWARE. | 22 | * PERFORMANCE OF THIS SOFTWARE. | |
23 | */ | 23 | */ | |
24 | 24 | |||
25 | #include "fcint.h" | 25 | #include "fcint.h" | |
26 | #include <assert.h> | |||
26 | #include <string.h> | 27 | #include <string.h> | |
27 | #include <ctype.h> | 28 | #include <ctype.h> | |
28 | #include <stdio.h> | 29 | #include <stdio.h> | |
29 | #include <float.h> | 30 | #include <float.h> | |
30 | 31 | |||
31 | static double | 32 | static double | |
32 | FcCompareNumber (FcValue *value1, FcValue *value2) | 33 | FcCompareNumber (FcValue *value1, FcValue *value2) | |
33 | { | 34 | { | |
34 | double v1, v2, v; | 35 | double v1, v2, v; | |
35 | 36 | |||
36 | switch (value1->type) { | 37 | switch (value1->type) { | |
37 | case FcTypeInteger: | 38 | case FcTypeInteger: | |
38 | v1 = (double) value1->u.i; | 39 | v1 = (double) value1->u.i; | |
39 | break; | 40 | break; | |
40 | case FcTypeDouble: | 41 | case FcTypeDouble: | |
41 | v1 = value1->u.d; | 42 | v1 = value1->u.d; | |
42 | break; | 43 | break; | |
43 | default: | 44 | default: | |
44 | return -1.0; | 45 | return -1.0; | |
45 | } | 46 | } | |
46 | switch (value2->type) { | 47 | switch (value2->type) { | |
47 | case FcTypeInteger: | 48 | case FcTypeInteger: | |
48 | v2 = (double) value2->u.i; | 49 | v2 = (double) value2->u.i; | |
@@ -58,65 +59,65 @@ FcCompareNumber (FcValue *value1, FcValu | @@ -58,65 +59,65 @@ FcCompareNumber (FcValue *value1, FcValu | |||
58 | v = -v; | 59 | v = -v; | |
59 | return v; | 60 | return v; | |
60 | } | 61 | } | |
61 | 62 | |||
62 | static double | 63 | static double | |
63 | FcCompareString (FcValue *v1, FcValue *v2) | 64 | FcCompareString (FcValue *v1, FcValue *v2) | |
64 | { | 65 | { | |
65 | return (double) FcStrCmpIgnoreCase (FcValueString(v1), FcValueString(v2)) != 0; | 66 | return (double) FcStrCmpIgnoreCase (FcValueString(v1), FcValueString(v2)) != 0; | |
66 | } | 67 | } | |
67 | 68 | |||
68 | static double | 69 | static double | |
69 | FcCompareFamily (FcValue *v1, FcValue *v2) | 70 | FcCompareFamily (FcValue *v1, FcValue *v2) | |
70 | { | 71 | { | |
71 | /* rely on the guarantee in FcPatternAddWithBinding that | 72 | /* rely on the guarantee in FcPatternObjectAddWithBinding that | |
72 | * families are always FcTypeString. */ | 73 | * families are always FcTypeString. */ | |
73 | const FcChar8* v1_string = FcValueString(v1); | 74 | const FcChar8* v1_string = FcValueString(v1); | |
74 | const FcChar8* v2_string = FcValueString(v2); | 75 | const FcChar8* v2_string = FcValueString(v2); | |
75 | 76 | |||
76 | if (FcToLower(*v1_string) != FcToLower(*v2_string) && | 77 | if (FcToLower(*v1_string) != FcToLower(*v2_string) && | |
77 | *v1_string != ' ' && *v2_string != ' ') | 78 | *v1_string != ' ' && *v2_string != ' ') | |
78 | return 1.0; | 79 | return 1.0; | |
79 | 80 | |||
80 | return (double) FcStrCmpIgnoreBlanksAndCase (v1_string, v2_string) != 0; | 81 | return (double) FcStrCmpIgnoreBlanksAndCase (v1_string, v2_string) != 0; | |
81 | } | 82 | } | |
82 | 83 | |||
83 | static double | 84 | static double | |
84 | FcCompareLang (FcValue *v1, FcValue *v2) | 85 | FcCompareLang (FcValue *v1, FcValue *v2) | |
85 | { | 86 | { | |
86 | FcLangResult result; | 87 | FcLangResult result; | |
87 | FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2); | 88 | FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2); | |
88 | 89 | |||
89 | switch (value1.type) { | 90 | switch (value1.type) { | |
90 | case FcTypeLangSet: | 91 | case FcTypeLangSet: | |
91 | switch (value2.type) { | 92 | switch (value2.type) { | |
92 | case FcTypeLangSet: | 93 | case FcTypeLangSet: | |
93 | result = FcLangSetCompare (value1.u.l, value2.u.l); | 94 | result = FcLangSetCompare (value1.u.l, value2.u.l); | |
94 | break; | 95 | break; | |
95 | case FcTypeString: | 96 | case FcTypeString: | |
96 | result = FcLangSetHasLang (value1.u.l, | 97 | result = FcLangSetHasLang (value1.u.l, | |
97 | value2.u.s); | 98 | value2.u.s); | |
98 | break; | 99 | break; | |
99 | default: | 100 | default: | |
100 | return -1.0; | 101 | return -1.0; | |
101 | } | 102 | } | |
102 | break; | 103 | break; | |
103 | case FcTypeString: | 104 | case FcTypeString: | |
104 | switch (value2.type) { | 105 | switch (value2.type) { | |
105 | case FcTypeLangSet: | 106 | case FcTypeLangSet: | |
106 | result = FcLangSetHasLang (value2.u.l, value1.u.s); | 107 | result = FcLangSetHasLang (value2.u.l, value1.u.s); | |
107 | break; | 108 | break; | |
108 | case FcTypeString: | 109 | case FcTypeString: | |
109 | result = FcLangCompare (value1.u.s, | 110 | result = FcLangCompare (value1.u.s, | |
110 | value2.u.s); | 111 | value2.u.s); | |
111 | break; | 112 | break; | |
112 | default: | 113 | default: | |
113 | return -1.0; | 114 | return -1.0; | |
114 | } | 115 | } | |
115 | break; | 116 | break; | |
116 | default: | 117 | default: | |
117 | return -1.0; | 118 | return -1.0; | |
118 | } | 119 | } | |
119 | switch (result) { | 120 | switch (result) { | |
120 | case FcLangEqual: | 121 | case FcLangEqual: | |
121 | return 0; | 122 | return 0; | |
122 | case FcLangDifferentCountry: | 123 | case FcLangDifferentCountry: | |
@@ -164,80 +165,101 @@ FcCompareSize (FcValue *value1, FcValue | @@ -164,80 +165,101 @@ FcCompareSize (FcValue *value1, FcValue | |||
164 | v2 = value2->u.d; | 165 | v2 = value2->u.d; | |
165 | break; | 166 | break; | |
166 | default: | 167 | default: | |
167 | return -1; | 168 | return -1; | |
168 | } | 169 | } | |
169 | if (v2 == 0) | 170 | if (v2 == 0) | |
170 | return 0; | 171 | return 0; | |
171 | v = v2 - v1; | 172 | v = v2 - v1; | |
172 | if (v < 0) | 173 | if (v < 0) | |
173 | v = -v; | 174 | v = -v; | |
174 | return v; | 175 | return v; | |
175 | } | 176 | } | |
176 | 177 | |||
178 | static double | |||
179 | FcCompareFilename (FcValue *v1, FcValue *v2) | |||
180 | { | |||
181 | const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2); | |||
182 | if (FcStrCmp (s1, s2) == 0) | |||
183 | return 0.0; | |||
184 | else if (FcStrCmpIgnoreCase (s1, s2) == 0) | |||
185 | return 1.0; | |||
186 | else if (FcStrRegexCmp (s2, s1)) | |||
187 | return 2.0; | |||
188 | else if (FcStrRegexCmpIgnoreCase (s2, s1)) | |||
189 | return 3.0; | |||
190 | else | |||
191 | return 4.0; | |||
192 | } | |||
193 | ||||
177 | typedef struct _FcMatcher { | 194 | typedef struct _FcMatcher { | |
178 | FcObject object; | 195 | FcObject object; | |
179 | double (*compare) (FcValue *value1, FcValue *value2); | 196 | double (*compare) (FcValue *value1, FcValue *value2); | |
180 | int strong, weak; | 197 | int strong, weak; | |
181 | } FcMatcher; | 198 | } FcMatcher; | |
182 | 199 | |||
183 | /* | 200 | /* | |
184 | * Order is significant, it defines the precedence of | 201 | * Order is significant, it defines the precedence of | |
185 | * each value, earlier values are more significant than | 202 | * each value, earlier values are more significant than | |
186 | * later values | 203 | * later values | |
187 | */ | 204 | */ | |
188 | static const FcMatcher _FcMatchers [] = { | 205 | static const FcMatcher _FcMatchers [] = { | |
189 | { FC_FOUNDRY_OBJECT, FcCompareString, 0, 0 }, | 206 | { FC_FILE_OBJECT, FcCompareFilename, 0, 0 }, | |
190 | #define MATCH_FOUNDRY 0 | 207 | #define MATCH_FILE 0 | |
191 | { FC_CHARSET_OBJECT, FcCompareCharSet, 1, 1 }, | 208 | { FC_FOUNDRY_OBJECT, FcCompareString, 1, 1 }, | |
192 | #define MATCH_CHARSET 1 | 209 | #define MATCH_FOUNDRY 1 | |
193 | { FC_FAMILY_OBJECT, FcCompareFamily, 2, 4 }, | 210 | { FC_CHARSET_OBJECT, FcCompareCharSet, 2, 2 }, | |
194 | #define MATCH_FAMILY 2 | 211 | #define MATCH_CHARSET 2 | |
195 | { FC_LANG_OBJECT, FcCompareLang, 3, 3 }, | 212 | { FC_FAMILY_OBJECT, FcCompareFamily, 3, 5 }, | |
196 | #define MATCH_LANG 3 | 213 | #define MATCH_FAMILY 3 | |
197 | #define MATCH_LANG_INDEX 3 | 214 | { FC_LANG_OBJECT, FcCompareLang, 4, 4 }, | |
198 | { FC_SPACING_OBJECT, FcCompareNumber, 5, 5 }, | 215 | #define MATCH_LANG 4 | |
199 | #define MATCH_SPACING 4 | 216 | #define MATCH_LANG_INDEX 4 | |
200 | { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 6, 6 }, | 217 | { FC_SPACING_OBJECT, FcCompareNumber, 6, 6 }, | |
201 | #define MATCH_PIXEL_SIZE 5 | 218 | #define MATCH_SPACING 5 | |
202 | { FC_STYLE_OBJECT, FcCompareString, 7, 7 }, | 219 | { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 7, 7 }, | |
203 | #define MATCH_STYLE 6 | 220 | #define MATCH_PIXEL_SIZE 6 | |
204 | { FC_SLANT_OBJECT, FcCompareNumber, 8, 8 }, | 221 | { FC_STYLE_OBJECT, FcCompareString, 8, 8 }, | |
205 | #define MATCH_SLANT 7 | 222 | #define MATCH_STYLE 7 | |
206 | { FC_WEIGHT_OBJECT, FcCompareNumber, 9, 9 }, | 223 | { FC_SLANT_OBJECT, FcCompareNumber, 9, 9 }, | |
207 | #define MATCH_WEIGHT 8 | 224 | #define MATCH_SLANT 8 | |
208 | { FC_WIDTH_OBJECT, FcCompareNumber, 10, 10 }, | 225 | { FC_WEIGHT_OBJECT, FcCompareNumber, 10, 10 }, | |
209 | #define MATCH_WIDTH 9 | 226 | #define MATCH_WEIGHT 9 | |
210 | { FC_DECORATIVE_OBJECT, FcCompareBool, 11, 11 }, | 227 | { FC_WIDTH_OBJECT, FcCompareNumber, 11, 11 }, | |
211 | #define MATCH_DECORATIVE 10 | 228 | #define MATCH_WIDTH 10 | |
212 | { FC_ANTIALIAS_OBJECT, FcCompareBool, 12, 12 }, | 229 | { FC_DECORATIVE_OBJECT, FcCompareBool, 12, 12 }, | |
213 | #define MATCH_ANTIALIAS 11 | 230 | #define MATCH_DECORATIVE 11 | |
214 | { FC_RASTERIZER_OBJECT, FcCompareString, 13, 13 }, | 231 | { FC_ANTIALIAS_OBJECT, FcCompareBool, 13, 13 }, | |
215 | #define MATCH_RASTERIZER 12 | 232 | #define MATCH_ANTIALIAS 12 | |
216 | { FC_OUTLINE_OBJECT, FcCompareBool, 14, 14 }, | 233 | { FC_RASTERIZER_OBJECT, FcCompareString, 14, 14 }, | |
217 | #define MATCH_OUTLINE 13 | 234 | #define MATCH_RASTERIZER 13 | |
218 | { FC_FONTVERSION_OBJECT, FcCompareNumber, 15, 15 }, | 235 | { FC_OUTLINE_OBJECT, FcCompareBool, 15, 15 }, | |
219 | #define MATCH_FONTVERSION 14 | 236 | #define MATCH_OUTLINE 14 | |
237 | { FC_FONTVERSION_OBJECT, FcCompareNumber, 16, 16 }, | |||
238 | #define MATCH_FONTVERSION 15 | |||
220 | }; | 239 | }; | |
221 | 240 | |||
222 | #define NUM_MATCH_VALUES 16 | 241 | #define NUM_MATCH_VALUES 17 | |
223 | 242 | |||
224 | static const FcMatcher* | 243 | static const FcMatcher* | |
225 | FcObjectToMatcher (FcObject object) | 244 | FcObjectToMatcher (FcObject object, | |
245 | FcBool include_lang) | |||
226 | { | 246 | { | |
227 | int i; | 247 | int i; | |
228 | 248 | |||
229 | i = -1; | 249 | i = -1; | |
230 | switch (object) { | 250 | switch (object) { | |
251 | case FC_FILE_OBJECT: | |||
252 | i = MATCH_FILE; break; | |||
231 | case FC_FOUNDRY_OBJECT: | 253 | case FC_FOUNDRY_OBJECT: | |
232 | i = MATCH_FOUNDRY; break; | 254 | i = MATCH_FOUNDRY; break; | |
233 | case FC_FONTVERSION_OBJECT: | 255 | case FC_FONTVERSION_OBJECT: | |
234 | i = MATCH_FONTVERSION; break; | 256 | i = MATCH_FONTVERSION; break; | |
235 | case FC_FAMILY_OBJECT: | 257 | case FC_FAMILY_OBJECT: | |
236 | i = MATCH_FAMILY; break; | 258 | i = MATCH_FAMILY; break; | |
237 | case FC_CHARSET_OBJECT: | 259 | case FC_CHARSET_OBJECT: | |
238 | i = MATCH_CHARSET; break; | 260 | i = MATCH_CHARSET; break; | |
239 | case FC_ANTIALIAS_OBJECT: | 261 | case FC_ANTIALIAS_OBJECT: | |
240 | i = MATCH_ANTIALIAS; break; | 262 | i = MATCH_ANTIALIAS; break; | |
241 | case FC_LANG_OBJECT: | 263 | case FC_LANG_OBJECT: | |
242 | i = MATCH_LANG; break; | 264 | i = MATCH_LANG; break; | |
243 | case FC_SPACING_OBJECT: | 265 | case FC_SPACING_OBJECT: | |
@@ -248,74 +270,88 @@ FcObjectToMatcher (FcObject object) | @@ -248,74 +270,88 @@ FcObjectToMatcher (FcObject object) | |||
248 | i = MATCH_SLANT; break; | 270 | i = MATCH_SLANT; break; | |
249 | case FC_PIXEL_SIZE_OBJECT: | 271 | case FC_PIXEL_SIZE_OBJECT: | |
250 | i = MATCH_PIXEL_SIZE; break; | 272 | i = MATCH_PIXEL_SIZE; break; | |
251 | case FC_WIDTH_OBJECT: | 273 | case FC_WIDTH_OBJECT: | |
252 | i = MATCH_WIDTH; break; | 274 | i = MATCH_WIDTH; break; | |
253 | case FC_WEIGHT_OBJECT: | 275 | case FC_WEIGHT_OBJECT: | |
254 | i = MATCH_WEIGHT; break; | 276 | i = MATCH_WEIGHT; break; | |
255 | case FC_RASTERIZER_OBJECT: | 277 | case FC_RASTERIZER_OBJECT: | |
256 | i = MATCH_RASTERIZER; break; | 278 | i = MATCH_RASTERIZER; break; | |
257 | case FC_OUTLINE_OBJECT: | 279 | case FC_OUTLINE_OBJECT: | |
258 | i = MATCH_OUTLINE; break; | 280 | i = MATCH_OUTLINE; break; | |
259 | case FC_DECORATIVE_OBJECT: | 281 | case FC_DECORATIVE_OBJECT: | |
260 | i = MATCH_DECORATIVE; break; | 282 | i = MATCH_DECORATIVE; break; | |
283 | default: | |||
284 | if (include_lang) | |||
285 | { | |||
286 | switch (object) { | |||
287 | case FC_FAMILYLANG_OBJECT: | |||
288 | case FC_STYLELANG_OBJECT: | |||
289 | case FC_FULLNAMELANG_OBJECT: | |||
290 | i = MATCH_LANG; break; | |||
291 | } | |||
292 | } | |||
261 | } | 293 | } | |
262 | 294 | |||
263 | if (i < 0) | 295 | if (i < 0) | |
264 | return NULL; | 296 | return NULL; | |
265 | 297 | |||
266 | return _FcMatchers+i; | 298 | return _FcMatchers+i; | |
267 | } | 299 | } | |
268 | 300 | |||
269 | static FcBool | 301 | static FcBool | |
270 | FcCompareValueList (FcObject object, | 302 | FcCompareValueList (FcObject object, | |
271 | FcValueListPtr v1orig, /* pattern */ | 303 | const FcMatcher *match, | |
272 | FcValueListPtr v2orig, /* target */ | 304 | FcValueListPtr v1orig, /* pattern */ | |
273 | FcValue *bestValue, | 305 | FcValueListPtr v2orig, /* target */ | |
274 | double *value, | 306 | FcValue *bestValue, | |
275 | FcResult *result) | 307 | double *value, | |
308 | int *n, | |||
309 | FcResult *result) | |||
276 | { | 310 | { | |
277 | FcValueListPtr v1, v2; | 311 | FcValueListPtr v1, v2; | |
278 | double v, best, bestStrong, bestWeak; | 312 | double v, best, bestStrong, bestWeak; | |
279 | int j; | 313 | int j, k, pos = 0; | |
280 | const FcMatcher *match = FcObjectToMatcher(object); | |||
281 | 314 | |||
282 | if (!match) | 315 | if (!match) | |
283 | { | 316 | { | |
284 | if (bestValue) | 317 | if (bestValue) | |
285 | *bestValue = FcValueCanonicalize(&v2orig->value); | 318 | *bestValue = FcValueCanonicalize(&v2orig->value); | |
319 | if (n) | |||
320 | *n = 0; | |||
286 | return FcTrue; | 321 | return FcTrue; | |
287 | } | 322 | } | |
288 | 323 | |||
289 | best = DBL_MAX; | 324 | best = DBL_MAX; | |
290 | bestStrong = DBL_MAX; | 325 | bestStrong = DBL_MAX; | |
291 | bestWeak = DBL_MAX; | 326 | bestWeak = DBL_MAX; | |
292 | j = 1; | 327 | j = 1; | |
293 | for (v1 = v1orig; v1; v1 = FcValueListNext(v1)) | 328 | for (v1 = v1orig; v1; v1 = FcValueListNext(v1)) | |
294 | { | 329 | { | |
295 | for (v2 = v2orig; v2; v2 = FcValueListNext(v2)) | 330 | for (v2 = v2orig, k = 0; v2; v2 = FcValueListNext(v2), k++) | |
296 | { | 331 | { | |
297 | v = (match->compare) (&v1->value, &v2->value); | 332 | v = (match->compare) (&v1->value, &v2->value); | |
298 | if (v < 0) | 333 | if (v < 0) | |
299 | { | 334 | { | |
300 | *result = FcResultTypeMismatch; | 335 | *result = FcResultTypeMismatch; | |
301 | return FcFalse; | 336 | return FcFalse; | |
302 | } | 337 | } | |
303 | v = v * 1000 + j; | 338 | v = v * 1000 + j; | |
304 | if (v < best) | 339 | if (v < best) | |
305 | { | 340 | { | |
306 | if (bestValue) | 341 | if (bestValue) | |
307 | *bestValue = FcValueCanonicalize(&v2->value); | 342 | *bestValue = FcValueCanonicalize(&v2->value); | |
308 | best = v; | 343 | best = v; | |
344 | pos = k; | |||
309 | } | 345 | } | |
310 | if (v1->binding == FcValueBindingStrong) | 346 | if (v1->binding == FcValueBindingStrong) | |
311 | { | 347 | { | |
312 | if (v < bestStrong) | 348 | if (v < bestStrong) | |
313 | bestStrong = v; | 349 | bestStrong = v; | |
314 | } | 350 | } | |
315 | else | 351 | else | |
316 | { | 352 | { | |
317 | if (v < bestWeak) | 353 | if (v < bestWeak) | |
318 | bestWeak = v; | 354 | bestWeak = v; | |
319 | } | 355 | } | |
320 | } | 356 | } | |
321 | j++; | 357 | j++; | |
@@ -330,100 +366,196 @@ FcCompareValueList (FcObject object, | @@ -330,100 +366,196 @@ FcCompareValueList (FcObject object, | |||
330 | } | 366 | } | |
331 | if (value) | 367 | if (value) | |
332 | { | 368 | { | |
333 | int weak = match->weak; | 369 | int weak = match->weak; | |
334 | int strong = match->strong; | 370 | int strong = match->strong; | |
335 | if (weak == strong) | 371 | if (weak == strong) | |
336 | value[strong] += best; | 372 | value[strong] += best; | |
337 | else | 373 | else | |
338 | { | 374 | { | |
339 | value[weak] += bestWeak; | 375 | value[weak] += bestWeak; | |
340 | value[strong] += bestStrong; | 376 | value[strong] += bestStrong; | |
341 | } | 377 | } | |
342 | } | 378 | } | |
379 | if (n) | |||
380 | *n = pos; | |||
381 | ||||
343 | return FcTrue; | 382 | return FcTrue; | |
344 | } | 383 | } | |
345 | 384 | |||
346 | /* | 385 | /* | |
347 | * Return a value indicating the distance between the two lists of | 386 | * Return a value indicating the distance between the two lists of | |
348 | * values | 387 | * values | |
349 | */ | 388 | */ | |
350 | 389 | |||
351 | static FcBool | 390 | static FcBool | |
352 | FcCompare (FcPattern *pat, | 391 | FcCompare (FcPattern *pat, | |
353 | FcPattern *fnt, | 392 | FcPattern *fnt, | |
354 | double *value, | 393 | double *value, | |
355 | FcResult *result) | 394 | FcResult *result) | |
356 | { | 395 | { | |
357 | int i, i1, i2; | 396 | int i, i1, i2; | |
358 | 397 | |||
359 | for (i = 0; i < NUM_MATCH_VALUES; i++) | 398 | for (i = 0; i < NUM_MATCH_VALUES; i++) | |
360 | value[i] = 0.0; | 399 | value[i] = 0.0; | |
361 | 400 | |||
362 | i1 = 0; | 401 | i1 = 0; | |
363 | i2 = 0; | 402 | i2 = 0; | |
364 | while (i1 < pat->num && i2 < fnt->num) | 403 | while (i1 < pat->num && i2 < fnt->num) | |
365 | { | 404 | { | |
366 | FcPatternElt *elt_i1 = &FcPatternElts(pat)[i1]; | 405 | FcPatternElt *elt_i1 = &FcPatternElts(pat)[i1]; | |
367 | FcPatternElt *elt_i2 = &FcPatternElts(fnt)[i2]; | 406 | FcPatternElt *elt_i2 = &FcPatternElts(fnt)[i2]; | |
368 | 407 | |||
369 | i = FcObjectCompare(elt_i1->object, elt_i2->object); | 408 | i = FcObjectCompare(elt_i1->object, elt_i2->object); | |
370 | if (i > 0) | 409 | if (i > 0) | |
371 | i2++; | 410 | i2++; | |
372 | else if (i < 0) | 411 | else if (i < 0) | |
373 | i1++; | 412 | i1++; | |
374 | else | 413 | else | |
375 | { | 414 | { | |
376 | if (!FcCompareValueList (elt_i1->object, | 415 | const FcMatcher *match = FcObjectToMatcher (elt_i1->object, FcFalse); | |
416 | if (!FcCompareValueList (elt_i1->object, match, | |||
377 | FcPatternEltValues(elt_i1), | 417 | FcPatternEltValues(elt_i1), | |
378 | FcPatternEltValues(elt_i2), | 418 | FcPatternEltValues(elt_i2), | |
379 | 0, value, result)) | 419 | NULL, value, NULL, result)) | |
380 | return FcFalse; | 420 | return FcFalse; | |
381 | i1++; | 421 | i1++; | |
382 | i2++; | 422 | i2++; | |
383 | } | 423 | } | |
384 | } | 424 | } | |
385 | return FcTrue; | 425 | return FcTrue; | |
386 | } | 426 | } | |
387 | 427 | |||
388 | FcPattern * | 428 | FcPattern * | |
389 | FcFontRenderPrepare (FcConfig *config, | 429 | FcFontRenderPrepare (FcConfig *config, | |
390 | FcPattern *pat, | 430 | FcPattern *pat, | |
391 | FcPattern *font) | 431 | FcPattern *font) | |
392 | { | 432 | { | |
393 | FcPattern *new; | 433 | FcPattern *new; | |
394 | int i; | 434 | int i; | |
395 | FcPatternElt *fe, *pe; | 435 | FcPatternElt *fe, *pe, *fel, *pel; | |
396 | FcValue v; | 436 | FcValue v; | |
397 | FcResult result; | 437 | FcResult result; | |
398 | 438 | |||
439 | assert (pat != NULL); | |||
440 | assert (font != NULL); | |||
441 | ||||
399 | new = FcPatternCreate (); | 442 | new = FcPatternCreate (); | |
400 | if (!new) | 443 | if (!new) | |
401 | return 0; | 444 | return NULL; | |
402 | for (i = 0; i < font->num; i++) | 445 | for (i = 0; i < font->num; i++) | |
403 | { | 446 | { | |
404 | fe = &FcPatternElts(font)[i]; | 447 | fe = &FcPatternElts(font)[i]; | |
448 | if (fe->object == FC_FAMILYLANG_OBJECT || | |||
449 | fe->object == FC_STYLELANG_OBJECT || | |||
450 | fe->object == FC_FULLNAMELANG_OBJECT) | |||
451 | { | |||
452 | /* ignore those objects. we need to deal with them | |||
453 | * another way */ | |||
454 | continue; | |||
455 | } | |||
456 | if (fe->object == FC_FAMILY_OBJECT || | |||
457 | fe->object == FC_STYLE_OBJECT || | |||
458 | fe->object == FC_FULLNAME_OBJECT) | |||
459 | { | |||
460 | FC_ASSERT_STATIC ((FC_FAMILY_OBJECT + 1) == FC_FAMILYLANG_OBJECT); | |||
461 | FC_ASSERT_STATIC ((FC_STYLE_OBJECT + 1) == FC_STYLELANG_OBJECT); | |||
462 | FC_ASSERT_STATIC ((FC_FULLNAME_OBJECT + 1) == FC_FULLNAMELANG_OBJECT); | |||
463 | ||||
464 | fel = FcPatternObjectFindElt (font, fe->object + 1); | |||
465 | pel = FcPatternObjectFindElt (pat, fe->object + 1); | |||
466 | } | |||
467 | else | |||
468 | { | |||
469 | fel = NULL; | |||
470 | pel = NULL; | |||
471 | } | |||
405 | pe = FcPatternObjectFindElt (pat, fe->object); | 472 | pe = FcPatternObjectFindElt (pat, fe->object); | |
406 | if (pe) | 473 | if (pe) | |
407 | { | 474 | { | |
408 | if (!FcCompareValueList (pe->object, FcPatternEltValues(pe), | 475 | const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse); | |
409 | FcPatternEltValues(fe), &v, 0, &result)) | 476 | ||
477 | if (!FcCompareValueList (pe->object, match, | |||
478 | FcPatternEltValues(pe), | |||
479 | FcPatternEltValues(fe), &v, NULL, NULL, &result)) | |||
410 | { | 480 | { | |
411 | FcPatternDestroy (new); | 481 | FcPatternDestroy (new); | |
412 | return 0; | 482 | return NULL; | |
483 | } | |||
484 | if (fel && pel) | |||
485 | { | |||
486 | int n = 1, j; | |||
487 | FcValueListPtr l1, l2, ln = NULL, ll = NULL; | |||
488 | ||||
489 | match = FcObjectToMatcher (pel->object, FcTrue); | |||
490 | if (!FcCompareValueList (pel->object, match, | |||
491 | FcPatternEltValues (pel), | |||
492 | FcPatternEltValues (fel), NULL, NULL, &n, &result)) | |||
493 | { | |||
494 | FcPatternDestroy (new); | |||
495 | return NULL; | |||
496 | } | |||
497 | ||||
498 | for (j = 0, l1 = FcPatternEltValues (fe), l2 = FcPatternEltValues (fel); | |||
499 | l1 != NULL || l2 != NULL; | |||
500 | j++, l1 = l1 ? FcValueListNext (l1) : NULL, l2 = l2 ? FcValueListNext (l2) : NULL) | |||
501 | { | |||
502 | if (j == n) | |||
503 | { | |||
504 | if (l1) | |||
505 | ln = FcValueListPrepend (ln, | |||
506 | FcValueCanonicalize (&l1->value), | |||
507 | FcValueBindingStrong); | |||
508 | if (l2) | |||
509 | ll = FcValueListPrepend (ll, | |||
510 | FcValueCanonicalize (&l2->value), | |||
511 | FcValueBindingStrong); | |||
512 | } | |||
513 | else | |||
514 | { | |||
515 | if (l1) | |||
516 | ln = FcValueListAppend (ln, | |||
517 | FcValueCanonicalize (&l1->value), | |||
518 | FcValueBindingStrong); | |||
519 | if (l2) | |||
520 | ll = FcValueListAppend (ll, | |||
521 | FcValueCanonicalize (&l2->value), | |||
522 | FcValueBindingStrong); | |||
523 | } | |||
524 | } | |||
525 | FcPatternObjectListAdd (new, fe->object, ln, FcFalse); | |||
526 | FcPatternObjectListAdd (new, fel->object, ll, FcFalse); | |||
527 | ||||
528 | continue; | |||
529 | } | |||
530 | else if (fel) | |||
531 | { | |||
532 | FcValueListPtr l1, l2; | |||
533 | ||||
534 | copy_lang: | |||
535 | l1 = FcValueListDuplicate (FcPatternEltValues (fe)); | |||
536 | l2 = FcValueListDuplicate (FcPatternEltValues (fel)); | |||
537 | FcPatternObjectListAdd (new, fe->object, l1, FcFalse); | |||
538 | FcPatternObjectListAdd (new, fel->object, l2, FcFalse); | |||
539 | ||||
540 | continue; | |||
413 | } | 541 | } | |
414 | } | 542 | } | |
415 | else | 543 | else | |
544 | { | |||
545 | if (fel) | |||
546 | goto copy_lang; | |||
416 | v = FcValueCanonicalize(&FcPatternEltValues (fe)->value); | 547 | v = FcValueCanonicalize(&FcPatternEltValues (fe)->value); | |
548 | } | |||
417 | FcPatternObjectAdd (new, fe->object, v, FcFalse); | 549 | FcPatternObjectAdd (new, fe->object, v, FcFalse); | |
418 | } | 550 | } | |
419 | for (i = 0; i < pat->num; i++) | 551 | for (i = 0; i < pat->num; i++) | |
420 | { | 552 | { | |
421 | pe = &FcPatternElts(pat)[i]; | 553 | pe = &FcPatternElts(pat)[i]; | |
422 | fe = FcPatternObjectFindElt (font, pe->object); | 554 | fe = FcPatternObjectFindElt (font, pe->object); | |
423 | if (!fe) | 555 | if (!fe) | |
424 | { | 556 | { | |
425 | v = FcValueCanonicalize(&FcPatternEltValues(pe)->value); | 557 | v = FcValueCanonicalize(&FcPatternEltValues(pe)->value); | |
426 | FcPatternObjectAdd (new, pe->object, v, FcTrue); | 558 | FcPatternObjectAdd (new, pe->object, v, FcTrue); | |
427 | } | 559 | } | |
428 | } | 560 | } | |
429 | 561 | |||
@@ -488,65 +620,76 @@ FcFontSetMatchInternal (FcConfig *con | @@ -488,65 +620,76 @@ FcFontSetMatchInternal (FcConfig *con | |||
488 | break; | 620 | break; | |
489 | } | 621 | } | |
490 | } | 622 | } | |
491 | } | 623 | } | |
492 | } | 624 | } | |
493 | if (FcDebug () & FC_DBG_MATCH) | 625 | if (FcDebug () & FC_DBG_MATCH) | |
494 | { | 626 | { | |
495 | printf ("Best score"); | 627 | printf ("Best score"); | |
496 | for (i = 0; i < NUM_MATCH_VALUES; i++) | 628 | for (i = 0; i < NUM_MATCH_VALUES; i++) | |
497 | printf (" %g", bestscore[i]); | 629 | printf (" %g", bestscore[i]); | |
498 | printf ("\n"); | 630 | printf ("\n"); | |
499 | FcPatternPrint (best); | 631 | FcPatternPrint (best); | |
500 | } | 632 | } | |
501 | if (!best) | 633 | /* assuming that 'result' is initialized with FcResultNoMatch | |
502 | { | 634 | * outside this function */ | |
503 | *result = FcResultNoMatch; | 635 | if (best) | |
504 | return 0; | 636 | *result = FcResultMatch; | |
505 | } | 637 | ||
506 | return best; | 638 | return best; | |
507 | } | 639 | } | |
508 | 640 | |||
509 | FcPattern * | 641 | FcPattern * | |
510 | FcFontSetMatch (FcConfig *config, | 642 | FcFontSetMatch (FcConfig *config, | |
511 | FcFontSet **sets, | 643 | FcFontSet **sets, | |
512 | int nsets, | 644 | int nsets, | |
513 | FcPattern *p, | 645 | FcPattern *p, | |
514 | FcResult *result) | 646 | FcResult *result) | |
515 | { | 647 | { | |
516 | FcPattern *best; | 648 | FcPattern *best; | |
517 | 649 | |||
650 | assert (sets != NULL); | |||
651 | assert (p != NULL); | |||
652 | assert (result != NULL); | |||
653 | ||||
654 | *result = FcResultNoMatch; | |||
655 | ||||
518 | if (!config) | 656 | if (!config) | |
519 | { | 657 | { | |
520 | config = FcConfigGetCurrent (); | 658 | config = FcConfigGetCurrent (); | |
521 | if (!config) | 659 | if (!config) | |
522 | return 0; | 660 | return 0; | |
523 | } | 661 | } | |
524 | best = FcFontSetMatchInternal (config, sets, nsets, p, result); | 662 | best = FcFontSetMatchInternal (config, sets, nsets, p, result); | |
525 | if (best) | 663 | if (best) | |
526 | return FcFontRenderPrepare (config, p, best); | 664 | return FcFontRenderPrepare (config, p, best); | |
527 | else | 665 | else | |
528 | return NULL; | 666 | return NULL; | |
529 | } | 667 | } | |
530 | 668 | |||
531 | FcPattern * | 669 | FcPattern * | |
532 | FcFontMatch (FcConfig *config, | 670 | FcFontMatch (FcConfig *config, | |
533 | FcPattern *p, | 671 | FcPattern *p, | |
534 | FcResult *result) | 672 | FcResult *result) | |
535 | { | 673 | { | |
536 | FcFontSet *sets[2]; | 674 | FcFontSet *sets[2]; | |
537 | int nsets; | 675 | int nsets; | |
538 | FcPattern *best; | 676 | FcPattern *best; | |
539 | 677 | |||
678 | assert (p != NULL); | |||
679 | assert (result != NULL); | |||
680 | ||||
681 | *result = FcResultNoMatch; | |||
682 | ||||
540 | if (!config) | 683 | if (!config) | |
541 | { | 684 | { | |
542 | config = FcConfigGetCurrent (); | 685 | config = FcConfigGetCurrent (); | |
543 | if (!config) | 686 | if (!config) | |
544 | return 0; | 687 | return 0; | |
545 | } | 688 | } | |
546 | nsets = 0; | 689 | nsets = 0; | |
547 | if (config->fonts[FcSetSystem]) | 690 | if (config->fonts[FcSetSystem]) | |
548 | sets[nsets++] = config->fonts[FcSetSystem]; | 691 | sets[nsets++] = config->fonts[FcSetSystem]; | |
549 | if (config->fonts[FcSetApplication]) | 692 | if (config->fonts[FcSetApplication]) | |
550 | sets[nsets++] = config->fonts[FcSetApplication]; | 693 | sets[nsets++] = config->fonts[FcSetApplication]; | |
551 | 694 | |||
552 | best = FcFontSetMatchInternal (config, sets, nsets, p, result); | 695 | best = FcFontSetMatchInternal (config, sets, nsets, p, result); | |
@@ -663,56 +806,69 @@ FcFontSetSort (FcConfig *config, | @@ -663,56 +806,69 @@ FcFontSetSort (FcConfig *config, | |||
663 | FcFontSet *ret; | 806 | FcFontSet *ret; | |
664 | FcFontSet *s; | 807 | FcFontSet *s; | |
665 | FcSortNode *nodes; | 808 | FcSortNode *nodes; | |
666 | FcSortNode **nodeps, **nodep; | 809 | FcSortNode **nodeps, **nodep; | |
667 | int nnodes; | 810 | int nnodes; | |
668 | FcSortNode *new; | 811 | FcSortNode *new; | |
669 | int set; | 812 | int set; | |
670 | int f; | 813 | int f; | |
671 | int i; | 814 | int i; | |
672 | int nPatternLang; | 815 | int nPatternLang; | |
673 | FcBool *patternLangSat; | 816 | FcBool *patternLangSat; | |
674 | FcValue patternLang; | 817 | FcValue patternLang; | |
675 | 818 | |||
819 | assert (sets != NULL); | |||
820 | assert (p != NULL); | |||
821 | assert (result != NULL); | |||
822 | ||||
823 | /* There are some implementation that relying on the result of | |||
824 | * "result" to check if the return value of FcFontSetSort | |||
825 | * is valid or not. | |||
826 | * So we should initialize it to the conservative way since | |||
827 | * this function doesn't return NULL anymore. | |||
828 | */ | |||
829 | if (result) | |||
830 | *result = FcResultNoMatch; | |||
831 | ||||
676 | if (FcDebug () & FC_DBG_MATCH) | 832 | if (FcDebug () & FC_DBG_MATCH) | |
677 | { | 833 | { | |
678 | printf ("Sort "); | 834 | printf ("Sort "); | |
679 | FcPatternPrint (p); | 835 | FcPatternPrint (p); | |
680 | } | 836 | } | |
681 | nnodes = 0; | 837 | nnodes = 0; | |
682 | for (set = 0; set < nsets; set++) | 838 | for (set = 0; set < nsets; set++) | |
683 | { | 839 | { | |
684 | s = sets[set]; | 840 | s = sets[set]; | |
685 | if (!s) | 841 | if (!s) | |
686 | continue; | 842 | continue; | |
687 | nnodes += s->nfont; | 843 | nnodes += s->nfont; | |
688 | } | 844 | } | |
689 | if (!nnodes) | 845 | if (!nnodes) | |
690 | goto bail0; | 846 | return FcFontSetCreate (); | |
691 | 847 | |||
692 | for (nPatternLang = 0; | 848 | for (nPatternLang = 0; | |
693 | FcPatternGet (p, FC_LANG, nPatternLang, &patternLang) == FcResultMatch; | 849 | FcPatternGet (p, FC_LANG, nPatternLang, &patternLang) == FcResultMatch; | |
694 | nPatternLang++) | 850 | nPatternLang++) | |
695 | ; | 851 | ; | |
696 | 852 | |||
697 | /* freed below */ | 853 | /* freed below */ | |
698 | nodes = malloc (nnodes * sizeof (FcSortNode) + | 854 | nodes = malloc (nnodes * sizeof (FcSortNode) + | |
699 | nnodes * sizeof (FcSortNode *) + | 855 | nnodes * sizeof (FcSortNode *) + | |
700 | nPatternLang * sizeof (FcBool)); | 856 | nPatternLang * sizeof (FcBool)); | |
701 | if (!nodes) | 857 | if (!nodes) | |
702 | goto bail0; | 858 | goto bail0; | |
703 | nodeps = (FcSortNode **) (nodes + nnodes); | 859 | nodeps = (FcSortNode **) (nodes + nnodes); | |
704 | patternLangSat = (FcBool *) (nodeps + nnodes); | 860 | patternLangSat = (FcBool *) (nodeps + nnodes); | |
705 | 861 | |||
706 | new = nodes; | 862 | new = nodes; | |
707 | nodep = nodeps; | 863 | nodep = nodeps; | |
708 | for (set = 0; set < nsets; set++) | 864 | for (set = 0; set < nsets; set++) | |
709 | { | 865 | { | |
710 | s = sets[set]; | 866 | s = sets[set]; | |
711 | if (!s) | 867 | if (!s) | |
712 | continue; | 868 | continue; | |
713 | for (f = 0; f < s->nfont; f++) | 869 | for (f = 0; f < s->nfont; f++) | |
714 | { | 870 | { | |
715 | if (FcDebug () & FC_DBG_MATCHV) | 871 | if (FcDebug () & FC_DBG_MATCHV) | |
716 | { | 872 | { | |
717 | printf ("Font %d ", f); | 873 | printf ("Font %d ", f); | |
718 | FcPatternPrint (s->fonts[f]); | 874 | FcPatternPrint (s->fonts[f]); | |
@@ -726,41 +882,41 @@ FcFontSetSort (FcConfig *config, | @@ -726,41 +882,41 @@ FcFontSetSort (FcConfig *config, | |||
726 | for (i = 0; i < NUM_MATCH_VALUES; i++) | 882 | for (i = 0; i < NUM_MATCH_VALUES; i++) | |
727 | { | 883 | { | |
728 | printf (" %g", new->score[i]); | 884 | printf (" %g", new->score[i]); | |
729 | } | 885 | } | |
730 | printf ("\n"); | 886 | printf ("\n"); | |
731 | } | 887 | } | |
732 | *nodep = new; | 888 | *nodep = new; | |
733 | new++; | 889 | new++; | |
734 | nodep++; | 890 | nodep++; | |
735 | } | 891 | } | |
736 | } | 892 | } | |
737 | 893 | |||
738 | nnodes = new - nodes; | 894 | nnodes = new - nodes; | |
739 | 895 | |||
740 | qsort (nodeps, nnodes, sizeof (FcSortNode *), | 896 | qsort (nodeps, nnodes, sizeof (FcSortNode *), | |
741 | FcSortCompare); | 897 | FcSortCompare); | |
742 | 898 | |||
743 | for (i = 0; i < nPatternLang; i++) | 899 | for (i = 0; i < nPatternLang; i++) | |
744 | patternLangSat[i] = FcFalse; | 900 | patternLangSat[i] = FcFalse; | |
745 | 901 | |||
746 | for (f = 0; f < nnodes; f++) | 902 | for (f = 0; f < nnodes; f++) | |
747 | { | 903 | { | |
748 | FcBool satisfies = FcFalse; | 904 | FcBool satisfies = FcFalse; | |
749 | /* | 905 | /* | |
750 | * If this node matches any language, go check | 906 | * If this node matches any language, go check | |
751 | * which ones and satisfy those entries | 907 | * which ones and satisfy those entries | |
752 | */ | 908 | */ | |
753 | if (nodeps[f]->score[MATCH_LANG_INDEX] < 200) | 909 | if (nodeps[f]->score[MATCH_LANG_INDEX] < 2000) | |
754 | { | 910 | { | |
755 | for (i = 0; i < nPatternLang; i++) | 911 | for (i = 0; i < nPatternLang; i++) | |
756 | { | 912 | { | |
757 | FcValue nodeLang; | 913 | FcValue nodeLang; | |
758 | 914 | |||
759 | if (!patternLangSat[i] && | 915 | if (!patternLangSat[i] && | |
760 | FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch && | 916 | FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch && | |
761 | FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch) | 917 | FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch) | |
762 | { | 918 | { | |
763 | double compare = FcCompareLang (&patternLang, &nodeLang); | 919 | double compare = FcCompareLang (&patternLang, &nodeLang); | |
764 | if (compare >= 0 && compare < 2) | 920 | if (compare >= 0 && compare < 2) | |
765 | { | 921 | { | |
766 | if (FcDebug () & FC_DBG_MATCHV) | 922 | if (FcDebug () & FC_DBG_MATCHV) | |
@@ -793,46 +949,54 @@ FcFontSetSort (FcConfig *config, | @@ -793,46 +949,54 @@ FcFontSetSort (FcConfig *config, | |||
793 | if (!ret) | 949 | if (!ret) | |
794 | goto bail1; | 950 | goto bail1; | |
795 | 951 | |||
796 | if (!FcSortWalk (nodeps, nnodes, ret, csp, trim)) | 952 | if (!FcSortWalk (nodeps, nnodes, ret, csp, trim)) | |
797 | goto bail2; | 953 | goto bail2; | |
798 | 954 | |||
799 | free (nodes); | 955 | free (nodes); | |
800 | 956 | |||
801 | if (FcDebug() & FC_DBG_MATCH) | 957 | if (FcDebug() & FC_DBG_MATCH) | |
802 | { | 958 | { | |
803 | printf ("First font "); | 959 | printf ("First font "); | |
804 | FcPatternPrint (ret->fonts[0]); | 960 | FcPatternPrint (ret->fonts[0]); | |
805 | } | 961 | } | |
962 | if (ret->nfont > 0) | |||
963 | *result = FcResultMatch; | |||
964 | ||||
806 | return ret; | 965 | return ret; | |
807 | 966 | |||
808 | bail2: | 967 | bail2: | |
809 | FcFontSetDestroy (ret); | 968 | FcFontSetDestroy (ret); | |
810 | bail1: | 969 | bail1: | |
811 | free (nodes); | 970 | free (nodes); | |
812 | bail0: | 971 | bail0: | |
813 | return 0; | 972 | return 0; | |
814 | } | 973 | } | |
815 | 974 | |||
816 | FcFontSet * | 975 | FcFontSet * | |
817 | FcFontSort (FcConfig *config, | 976 | FcFontSort (FcConfig *config, | |
818 | FcPattern *p, | 977 | FcPattern *p, | |
819 | FcBool trim, | 978 | FcBool trim, | |
820 | FcCharSet **csp, | 979 | FcCharSet **csp, | |
821 | FcResult *result) | 980 | FcResult *result) | |
822 | { | 981 | { | |
823 | FcFontSet *sets[2]; | 982 | FcFontSet *sets[2]; | |
824 | int nsets; | 983 | int nsets; | |
825 | 984 | |||
985 | assert (p != NULL); | |||
986 | assert (result != NULL); | |||
987 | ||||
988 | *result = FcResultNoMatch; | |||
989 | ||||
826 | if (!config) | 990 | if (!config) | |
827 | { | 991 | { | |
828 | config = FcConfigGetCurrent (); | 992 | config = FcConfigGetCurrent (); | |
829 | if (!config) | 993 | if (!config) | |
830 | return 0; | 994 | return 0; | |
831 | } | 995 | } | |
832 | nsets = 0; | 996 | nsets = 0; | |
833 | if (config->fonts[FcSetSystem]) | 997 | if (config->fonts[FcSetSystem]) | |
834 | sets[nsets++] = config->fonts[FcSetSystem]; | 998 | sets[nsets++] = config->fonts[FcSetSystem]; | |
835 | if (config->fonts[FcSetApplication]) | 999 | if (config->fonts[FcSetApplication]) | |
836 | sets[nsets++] = config->fonts[FcSetApplication]; | 1000 | sets[nsets++] = config->fonts[FcSetApplication]; | |
837 | return FcFontSetSort (config, sets, nsets, p, trim, csp, result); | 1001 | return FcFontSetSort (config, sets, nsets, p, trim, csp, result); | |
838 | } | 1002 | } |
--- xsrc/external/mit/fontconfig/dist/src/fcname.c 2013/01/31 08:24:32 1.2
+++ xsrc/external/mit/fontconfig/dist/src/fcname.c 2013/06/03 06:04:33 1.3
@@ -1,91 +1,92 @@ | @@ -1,91 +1,92 @@ | |||
1 | /* | 1 | /* | |
2 | * fontconfig/src/fcname.c | 2 | * fontconfig/src/fcname.c | |
3 | * | 3 | * | |
4 | * Copyright © 2000 Keith Packard | 4 | * Copyright © 2000 Keith Packard | |
5 | * | 5 | * | |
6 | * Permission to use, copy, modify, distribute, and sell this software and its | 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 | 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 | 8 | * the above copyright notice appear in all copies and that both that | |
9 | * copyright notice and this permission notice appear in supporting | 9 | * copyright notice and this permission notice appear in supporting | |
10 | * documentation, and that the name of Keith Packard not be used in | 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 | 11 | * advertising or publicity pertaining to distribution of the software without | |
12 | * specific, written prior permission. Keith Packard makes no | 12 | * specific, written prior permission. The authors make no | |
13 | * representations about the suitability of this software for any purpose. It | 13 | * representations about the suitability of this software for any purpose. It | |
14 | * is provided "as is" without express or implied warranty. | 14 | * is provided "as is" without express or implied warranty. | |
15 | * | 15 | * | |
16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | 16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | 17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
18 | * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR | 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, | 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 | 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 | 21 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
22 | * PERFORMANCE OF THIS SOFTWARE. | 22 | * PERFORMANCE OF THIS SOFTWARE. | |
23 | */ | 23 | */ | |
24 | 24 | |||
25 | #include "fcint.h" | 25 | #include "fcint.h" | |
26 | #include <ctype.h> | 26 | #include <ctype.h> | |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> | |
28 | #include <string.h> | 28 | #include <string.h> | |
29 | #include <stdio.h> | 29 | #include <stdio.h> | |
30 | 30 | |||
31 | /* | 31 | /* | |
32 | * Please do not change this list, it is used to initialize the object | 32 | * Please do not change this list, it is used to initialize the object | |
33 | * list in this order to match the FC_foo_OBJECT constants. Those | 33 | * list in this order to match the FC_foo_OBJECT constants. Those | |
34 | * constants are written into cache files. | 34 | * constants are written into cache files. | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | static const FcObjectType _FcBaseObjectTypes[] = { | 37 | static const FcObjectType _FcBaseObjectTypes[] = { | |
38 | { FC_FAMILY, FcTypeString, }, /* 1 */ | 38 | { FC_FAMILY, FcTypeString, }, /* 1 */ | |
39 | { FC_FAMILYLANG, FcTypeString, }, | 39 | { FC_FAMILYLANG, FcTypeString, }, | |
40 | { FC_STYLE, FcTypeString, }, | 40 | { FC_STYLE, FcTypeString, }, | |
41 | { FC_STYLELANG, FcTypeString, }, | 41 | { FC_STYLELANG, FcTypeString, }, | |
42 | { FC_FULLNAME, FcTypeString, }, | 42 | { FC_FULLNAME, FcTypeString, }, | |
43 | { FC_FULLNAMELANG, FcTypeString, }, | 43 | { FC_FULLNAMELANG, FcTypeString, }, | |
44 | { FC_SLANT, FcTypeInteger, }, | 44 | { FC_SLANT, FcTypeInteger, }, | |
45 | { FC_WEIGHT, FcTypeInteger, }, | 45 | { FC_WEIGHT, FcTypeInteger, }, | |
46 | { FC_WIDTH, FcTypeInteger, }, | 46 | { FC_WIDTH, FcTypeInteger, }, | |
47 | { FC_SIZE, FcTypeDouble, }, | 47 | { FC_SIZE, FcTypeDouble, }, | |
48 | { FC_ASPECT, FcTypeDouble, }, | 48 | { FC_ASPECT, FcTypeDouble, }, | |
49 | { FC_PIXEL_SIZE, FcTypeDouble, }, | 49 | { FC_PIXEL_SIZE, FcTypeDouble, }, | |
50 | { FC_SPACING, FcTypeInteger, }, | 50 | { FC_SPACING, FcTypeInteger, }, | |
51 | { FC_FOUNDRY, FcTypeString, }, | 51 | { FC_FOUNDRY, FcTypeString, }, | |
52 | { FC_ANTIALIAS, FcTypeBool, }, | 52 | { FC_ANTIALIAS, FcTypeBool, }, | |
53 | { FC_HINT_STYLE, FcTypeInteger, }, | 53 | { FC_HINT_STYLE, FcTypeInteger, }, | |
54 | { FC_HINTING, FcTypeBool, }, | 54 | { FC_HINTING, FcTypeBool, }, | |
55 | { FC_VERTICAL_LAYOUT, FcTypeBool, }, | 55 | { FC_VERTICAL_LAYOUT, FcTypeBool, }, | |
56 | { FC_AUTOHINT, FcTypeBool, }, | 56 | { FC_AUTOHINT, FcTypeBool, }, | |
57 | { FC_GLOBAL_ADVANCE, FcTypeBool, }, | 57 | { FC_GLOBAL_ADVANCE, FcTypeBool, }, /* deprecated */ | |
58 | { FC_FILE, FcTypeString, }, | 58 | { FC_FILE, FcTypeString, }, | |
59 | { FC_INDEX, FcTypeInteger, }, | 59 | { FC_INDEX, FcTypeInteger, }, | |
60 | { FC_RASTERIZER, FcTypeString, }, | 60 | { FC_RASTERIZER, FcTypeString, }, | |
61 | { FC_OUTLINE, FcTypeBool, }, | 61 | { FC_OUTLINE, FcTypeBool, }, | |
62 | { FC_SCALABLE, FcTypeBool, }, | 62 | { FC_SCALABLE, FcTypeBool, }, | |
63 | { FC_DPI, FcTypeDouble }, | 63 | { FC_DPI, FcTypeDouble }, | |
64 | { FC_RGBA, FcTypeInteger, }, | 64 | { FC_RGBA, FcTypeInteger, }, | |
65 | { FC_SCALE, FcTypeDouble, }, | 65 | { FC_SCALE, FcTypeDouble, }, | |
66 | { FC_MINSPACE, FcTypeBool, }, | 66 | { FC_MINSPACE, FcTypeBool, }, | |
67 | { FC_CHAR_WIDTH, FcTypeInteger }, | 67 | { FC_CHAR_WIDTH, FcTypeInteger }, | |
68 | { FC_CHAR_HEIGHT, FcTypeInteger }, | 68 | { FC_CHAR_HEIGHT, FcTypeInteger }, | |
69 | { FC_MATRIX, FcTypeMatrix }, | 69 | { FC_MATRIX, FcTypeMatrix }, | |
70 | { FC_CHARSET, FcTypeCharSet }, | 70 | { FC_CHARSET, FcTypeCharSet }, | |
71 | { FC_LANG, FcTypeLangSet }, | 71 | { FC_LANG, FcTypeLangSet }, | |
72 | { FC_FONTVERSION, FcTypeInteger }, | 72 | { FC_FONTVERSION, FcTypeInteger }, | |
73 | { FC_CAPABILITY, FcTypeString }, | 73 | { FC_CAPABILITY, FcTypeString }, | |
74 | { FC_FONTFORMAT, FcTypeString }, | 74 | { FC_FONTFORMAT, FcTypeString }, | |
75 | { FC_EMBOLDEN, FcTypeBool }, | 75 | { FC_EMBOLDEN, FcTypeBool }, | |
76 | { FC_EMBEDDED_BITMAP, FcTypeBool }, | 76 | { FC_EMBEDDED_BITMAP, FcTypeBool }, | |
77 | { FC_DECORATIVE, FcTypeBool }, | 77 | { FC_DECORATIVE, FcTypeBool }, | |
78 | { FC_LCD_FILTER, FcTypeInteger }, /* 41 */ | 78 | { FC_LCD_FILTER, FcTypeInteger }, /* 41 */ | |
79 | { FC_NAMELANG, FcTypeString }, /* 42 */ | |||
79 | }; | 80 | }; | |
80 | 81 | |||
81 | #define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) | 82 | #define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) | |
82 | 83 | |||
83 | typedef struct _FcObjectTypeList FcObjectTypeList; | 84 | typedef struct _FcObjectTypeList FcObjectTypeList; | |
84 | 85 | |||
85 | struct _FcObjectTypeList { | 86 | struct _FcObjectTypeList { | |
86 | const FcObjectTypeList *next; | 87 | const FcObjectTypeList *next; | |
87 | const FcObjectType *types; | 88 | const FcObjectType *types; | |
88 | int ntypes; | 89 | int ntypes; | |
89 | }; | 90 | }; | |
90 | 91 | |||
91 | static const FcObjectTypeList _FcBaseObjectTypesList = { | 92 | static const FcObjectTypeList _FcBaseObjectTypesList = { | |
@@ -159,27 +160,27 @@ FcObjectFindByName (const char *object, | @@ -159,27 +160,27 @@ FcObjectFindByName (const char *object, | |||
159 | FcObjectInit (); | 160 | FcObjectInit (); | |
160 | for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) | 161 | for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) | |
161 | { | 162 | { | |
162 | o = FcObjects + b->id - 1; | 163 | o = FcObjects + b->id - 1; | |
163 | if (b->hash == hash && !strcmp (object, (o->object))) | 164 | if (b->hash == hash && !strcmp (object, (o->object))) | |
164 | return o; | 165 | return o; | |
165 | } | 166 | } | |
166 | if (!insert) | 167 | if (!insert) | |
167 | return NULL; | 168 | return NULL; | |
168 | /* | 169 | /* | |
169 | * Hook it into the hash chain | 170 | * Hook it into the hash chain | |
170 | */ | 171 | */ | |
171 | b = malloc (sizeof(FcObjectBucket)); | 172 | b = malloc (sizeof(FcObjectBucket)); | |
172 | if (!b) | 173 | if (!b) | |
173 | return NULL; | 174 | return NULL; | |
174 | object = (const char *) FcStrCopy ((FcChar8 *) object); | 175 | object = (const char *) FcStrCopy ((FcChar8 *) object); | |
175 | if (!object) { | 176 | if (!object) { | |
176 | free (b); | 177 | free (b); | |
177 | return NULL; | 178 | return NULL; | |
178 | } | 179 | } | |
179 | o = FcObjectInsert (object, -1); | 180 | o = FcObjectInsert (object, -1); | |
180 | b->next = NULL; | 181 | b->next = NULL; | |
181 | b->hash = hash; | 182 | b->hash = hash; | |
182 | b->id = FcObjectId (o); | 183 | b->id = FcObjectId (o); | |
183 | *p = b; | 184 | *p = b; | |
184 | return o; | 185 | return o; | |
185 | } | 186 | } | |
@@ -202,27 +203,27 @@ FcObjectHashInsert (const FcObjectType * | @@ -202,27 +203,27 @@ FcObjectHashInsert (const FcObjectType * | |||
202 | 203 | |||
203 | if (!FcObjectsInited) | 204 | if (!FcObjectsInited) | |
204 | FcObjectInit (); | 205 | FcObjectInit (); | |
205 | for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) | 206 | for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)) | |
206 | { | 207 | { | |
207 | o = FcObjects + b->id - 1; | 208 | o = FcObjects + b->id - 1; | |
208 | if (b->hash == hash && !strcmp (object->object, o->object)) | 209 | if (b->hash == hash && !strcmp (object->object, o->object)) | |
209 | return FcFalse; | 210 | return FcFalse; | |
210 | } | 211 | } | |
211 | /* | 212 | /* | |
212 | * Hook it into the hash chain | 213 | * Hook it into the hash chain | |
213 | */ | 214 | */ | |
214 | b = malloc (sizeof(FcObjectBucket)); | 215 | b = malloc (sizeof(FcObjectBucket)); | |
215 | if (!b) | 216 | if (!b) | |
216 | return FcFalse; | 217 | return FcFalse; | |
217 | if (copy) | 218 | if (copy) | |
218 | { | 219 | { | |
219 | o = FcObjectInsert (object->object, object->type); | 220 | o = FcObjectInsert (object->object, object->type); | |
220 | if (!o) | 221 | if (!o) | |
221 | { | 222 | { | |
222 | free (b); | 223 | free (b); | |
223 | return FcFalse; | 224 | return FcFalse; | |
224 | } | 225 | } | |
225 | } | 226 | } | |
226 | else | 227 | else | |
227 | o = (FcObjectType *) object; | 228 | o = (FcObjectType *) object; | |
228 | b->next = NULL; | 229 | b->next = NULL; | |
@@ -286,39 +287,37 @@ FcNameUnregisterObjectTypes (const FcObj | @@ -286,39 +287,37 @@ FcNameUnregisterObjectTypes (const FcObj | |||
286 | const FcObjectType * | 287 | const FcObjectType * | |
287 | FcNameGetObjectType (const char *object) | 288 | FcNameGetObjectType (const char *object) | |
288 | { | 289 | { | |
289 | return FcObjectFindByName (object, FcFalse); | 290 | return FcObjectFindByName (object, FcFalse); | |
290 | } | 291 | } | |
291 | 292 | |||
292 | FcBool | 293 | FcBool | |
293 | FcObjectValidType (FcObject object, FcType type) | 294 | FcObjectValidType (FcObject object, FcType type) | |
294 | { | 295 | { | |
295 | FcObjectType *t = FcObjectFindById (object); | 296 | FcObjectType *t = FcObjectFindById (object); | |
296 | 297 | |||
297 | if (t) { | 298 | if (t) { | |
298 | switch (t->type) { | 299 | switch (t->type) { | |
299 | case -1: | |||
300 | return FcTrue; | |||
301 | case FcTypeDouble: | 300 | case FcTypeDouble: | |
302 | case FcTypeInteger: | 301 | case FcTypeInteger: | |
303 | if (type == FcTypeDouble || type == FcTypeInteger) | 302 | if (type == FcTypeDouble || type == FcTypeInteger) | |
304 | return FcTrue; | 303 | return FcTrue; | |
305 | break; | 304 | break; | |
306 | case FcTypeLangSet: | 305 | case FcTypeLangSet: | |
307 | if (type == FcTypeLangSet || type == FcTypeString) | 306 | if (type == FcTypeLangSet || type == FcTypeString) | |
308 | return FcTrue; | 307 | return FcTrue; | |
309 | break; | 308 | break; | |
310 | default: | 309 | default: | |
311 | if (type == t->type) | 310 | if (t->type == -1 || type == t->type) | |
312 | return FcTrue; | 311 | return FcTrue; | |
313 | break; | 312 | break; | |
314 | } | 313 | } | |
315 | return FcFalse; | 314 | return FcFalse; | |
316 | } | 315 | } | |
317 | return FcTrue; | 316 | return FcTrue; | |
318 | } | 317 | } | |
319 | 318 | |||
320 | FcObject | 319 | FcObject | |
321 | FcObjectFromName (const char * name) | 320 | FcObjectFromName (const char * name) | |
322 | { | 321 | { | |
323 | FcObjectType *o = FcObjectFindByName (name, FcTrue); | 322 | FcObjectType *o = FcObjectFindByName (name, FcTrue); | |
324 | 323 | |||
@@ -411,49 +410,49 @@ static const FcConstant _FcBaseConstants | @@ -411,49 +410,49 @@ static const FcConstant _FcBaseConstants | |||
411 | { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, | 410 | { (FcChar8 *) "roman", "slant", FC_SLANT_ROMAN, }, | |
412 | { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, | 411 | { (FcChar8 *) "italic", "slant", FC_SLANT_ITALIC, }, | |
413 | { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, | 412 | { (FcChar8 *) "oblique", "slant", FC_SLANT_OBLIQUE, }, | |
414 | 413 | |||
415 | { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, | 414 | { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, | |
416 | { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, | 415 | { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, | |
417 | { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, | 416 | { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, | |
418 | { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, | 417 | { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, | |
419 | { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, | 418 | { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, | |
420 | { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, | 419 | { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, | |
421 | { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, | 420 | { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, | |
422 | { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, | 421 | { (FcChar8 *) "extraexpanded", "width", FC_WIDTH_EXTRAEXPANDED }, | |
423 | { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, | 422 | { (FcChar8 *) "ultraexpanded", "width", FC_WIDTH_ULTRAEXPANDED }, | |
424 | 423 | |||
425 | { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, | 424 | { (FcChar8 *) "proportional", "spacing", FC_PROPORTIONAL, }, | |
426 | { (FcChar8 *) "dual", "spacing", FC_DUAL, }, | 425 | { (FcChar8 *) "dual", "spacing", FC_DUAL, }, | |
427 | { (FcChar8 *) "mono", "spacing", FC_MONO, }, | 426 | { (FcChar8 *) "mono", "spacing", FC_MONO, }, | |
428 | { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, | 427 | { (FcChar8 *) "charcell", "spacing", FC_CHARCELL, }, | |
429 | 428 | |||
430 | { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, | 429 | { (FcChar8 *) "unknown", "rgba", FC_RGBA_UNKNOWN }, | |
431 | { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, | 430 | { (FcChar8 *) "rgb", "rgba", FC_RGBA_RGB, }, | |
432 | { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, | 431 | { (FcChar8 *) "bgr", "rgba", FC_RGBA_BGR, }, | |
433 | { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, | 432 | { (FcChar8 *) "vrgb", "rgba", FC_RGBA_VRGB }, | |
434 | { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, | 433 | { (FcChar8 *) "vbgr", "rgba", FC_RGBA_VBGR }, | |
435 | { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, | 434 | { (FcChar8 *) "none", "rgba", FC_RGBA_NONE }, | |
436 | 435 | |||
437 | { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, | 436 | { (FcChar8 *) "hintnone", "hintstyle", FC_HINT_NONE }, | |
438 | { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, | 437 | { (FcChar8 *) "hintslight", "hintstyle", FC_HINT_SLIGHT }, | |
439 | { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, | 438 | { (FcChar8 *) "hintmedium", "hintstyle", FC_HINT_MEDIUM }, | |
440 | { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, | 439 | { (FcChar8 *) "hintfull", "hintstyle", FC_HINT_FULL }, | |
441 | 440 | |||
442 | { (FcChar8 *) "antialias", "antialias", FcTrue }, | 441 | { (FcChar8 *) "antialias", "antialias", FcTrue }, | |
443 | { (FcChar8 *) "hinting", "hinting", FcTrue }, | 442 | { (FcChar8 *) "hinting", "hinting", FcTrue }, | |
444 | { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, | 443 | { (FcChar8 *) "verticallayout", "verticallayout", FcTrue }, | |
445 | { (FcChar8 *) "autohint", "autohint", FcTrue }, | 444 | { (FcChar8 *) "autohint", "autohint", FcTrue }, | |
446 | { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, | 445 | { (FcChar8 *) "globaladvance", "globaladvance", FcTrue }, /* deprecated */ | |
447 | { (FcChar8 *) "outline", "outline", FcTrue }, | 446 | { (FcChar8 *) "outline", "outline", FcTrue }, | |
448 | { (FcChar8 *) "scalable", "scalable", FcTrue }, | 447 | { (FcChar8 *) "scalable", "scalable", FcTrue }, | |
449 | { (FcChar8 *) "minspace", "minspace", FcTrue }, | 448 | { (FcChar8 *) "minspace", "minspace", FcTrue }, | |
450 | { (FcChar8 *) "embolden", "embolden", FcTrue }, | 449 | { (FcChar8 *) "embolden", "embolden", FcTrue }, | |
451 | { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, | 450 | { (FcChar8 *) "embeddedbitmap", "embeddedbitmap", FcTrue }, | |
452 | { (FcChar8 *) "decorative", "decorative", FcTrue }, | 451 | { (FcChar8 *) "decorative", "decorative", FcTrue }, | |
453 | { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, | 452 | { (FcChar8 *) "lcdnone", "lcdfilter", FC_LCD_NONE }, | |
454 | { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, | 453 | { (FcChar8 *) "lcddefault", "lcdfilter", FC_LCD_DEFAULT }, | |
455 | { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, | 454 | { (FcChar8 *) "lcdlight", "lcdfilter", FC_LCD_LIGHT }, | |
456 | { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, | 455 | { (FcChar8 *) "lcdlegacy", "lcdfilter", FC_LCD_LEGACY }, | |
457 | }; | 456 | }; | |
458 | 457 | |||
459 | #define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) | 458 | #define NUM_FC_CONSTANTS (sizeof _FcBaseConstants/sizeof _FcBaseConstants[0]) | |
@@ -485,58 +484,58 @@ FcNameRegisterConstants (const FcConstan | @@ -485,58 +484,58 @@ FcNameRegisterConstants (const FcConstan | |||
485 | FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); | 484 | FcMemAlloc (FC_MEM_CONSTANT, sizeof (FcConstantList)); | |
486 | l->consts = consts; | 485 | l->consts = consts; | |
487 | l->nconsts = nconsts; | 486 | l->nconsts = nconsts; | |
488 | l->next = _FcConstants; | 487 | l->next = _FcConstants; | |
489 | _FcConstants = l; | 488 | _FcConstants = l; | |
490 | return FcTrue; | 489 | return FcTrue; | |
491 | } | 490 | } | |
492 | 491 | |||
493 | FcBool | 492 | FcBool | |
494 | FcNameUnregisterConstants (const FcConstant *consts, int nconsts) | 493 | FcNameUnregisterConstants (const FcConstant *consts, int nconsts) | |
495 | { | 494 | { | |
496 | const FcConstantList *l, **prev; | 495 | const FcConstantList *l, **prev; | |
497 | 496 | |||
498 | for (prev = &_FcConstants; | 497 | for (prev = &_FcConstants; | |
499 | (l = *prev); | 498 | (l = *prev); | |
500 | prev = (const FcConstantList **) &(l->next)) | 499 | prev = (const FcConstantList **) &(l->next)) | |
501 | { | 500 | { | |
502 | if (l->consts == consts && l->nconsts == nconsts) | 501 | if (l->consts == consts && l->nconsts == nconsts) | |
503 | { | 502 | { | |
504 | *prev = l->next; | 503 | *prev = l->next; | |
505 | FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); | 504 | FcMemFree (FC_MEM_CONSTANT, sizeof (FcConstantList)); | |
506 | free ((void *) l); | 505 | free ((void *) l); | |
507 | return FcTrue; | 506 | return FcTrue; | |
508 | } | 507 | } | |
509 | } | 508 | } | |
510 | return FcFalse; | 509 | return FcFalse; | |
511 | } | 510 | } | |
512 | 511 | |||
513 | const FcConstant * | 512 | const FcConstant * | |
514 | FcNameGetConstant (FcChar8 *string) | 513 | FcNameGetConstant (const FcChar8 *string) | |
515 | { | 514 | { | |
516 | const FcConstantList *l; | 515 | const FcConstantList *l; | |
517 | int i; | 516 | int i; | |
518 | 517 | |||
519 | for (l = _FcConstants; l; l = l->next) | 518 | for (l = _FcConstants; l; l = l->next) | |
520 | { | 519 | { | |
521 | for (i = 0; i < l->nconsts; i++) | 520 | for (i = 0; i < l->nconsts; i++) | |
522 | if (!FcStrCmpIgnoreCase (string, l->consts[i].name)) | 521 | if (!FcStrCmpIgnoreCase (string, l->consts[i].name)) | |
523 | return &l->consts[i]; | 522 | return &l->consts[i]; | |
524 | } | 523 | } | |
525 | return 0; | 524 | return 0; | |
526 | } | 525 | } | |
527 | 526 | |||
528 | FcBool | 527 | FcBool | |
529 | FcNameConstant (FcChar8 *string, int *result) | 528 | FcNameConstant (const FcChar8 *string, int *result) | |
530 | { | 529 | { | |
531 | const FcConstant *c; | 530 | const FcConstant *c; | |
532 | 531 | |||
533 | if ((c = FcNameGetConstant(string))) | 532 | if ((c = FcNameGetConstant(string))) | |
534 | { | 533 | { | |
535 | *result = c->value; | 534 | *result = c->value; | |
536 | return FcTrue; | 535 | return FcTrue; | |
537 | } | 536 | } | |
538 | return FcFalse; | 537 | return FcFalse; | |
539 | } | 538 | } | |
540 | 539 | |||
541 | FcBool | 540 | FcBool | |
542 | FcNameBool (const FcChar8 *v, FcBool *result) | 541 | FcNameBool (const FcChar8 *v, FcBool *result) | |
@@ -564,73 +563,74 @@ FcNameBool (const FcChar8 *v, FcBool *re | @@ -564,73 +563,74 @@ FcNameBool (const FcChar8 *v, FcBool *re | |||
564 | *result = FcTrue; | 563 | *result = FcTrue; | |
565 | return FcTrue; | 564 | return FcTrue; | |
566 | } | 565 | } | |
567 | if (c1 == 'f') | 566 | if (c1 == 'f') | |
568 | { | 567 | { | |
569 | *result = FcFalse; | 568 | *result = FcFalse; | |
570 | return FcTrue; | 569 | return FcTrue; | |
571 | } | 570 | } | |
572 | } | 571 | } | |
573 | return FcFalse; | 572 | return FcFalse; | |
574 | } | 573 | } | |
575 | 574 | |||
576 | static FcValue | 575 | static FcValue | |
577 | FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m) | 576 | FcNameConvert (FcType type, FcChar8 *string) | |
578 | { | 577 | { | |
579 | FcValue v; | 578 | FcValue v; | |
579 | FcMatrix m; | |||
580 | 580 | |||
581 | v.type = type; | 581 | v.type = type; | |
582 | switch (v.type) { | 582 | switch (v.type) { | |
583 | case FcTypeInteger: | 583 | case FcTypeInteger: | |
584 | if (!FcNameConstant (string, &v.u.i)) | 584 | if (!FcNameConstant (string, &v.u.i)) | |
585 | v.u.i = atoi ((char *) string); | 585 | v.u.i = atoi ((char *) string); | |
586 | break; | 586 | break; | |
587 | case FcTypeString: | 587 | case FcTypeString: | |
588 | v.u.s = FcStrStaticName(string); | 588 | v.u.s = FcSharedStr (string); | |
589 | if (!v.u.s) | 589 | if (!v.u.s) | |
590 | v.type = FcTypeVoid; | 590 | v.type = FcTypeVoid; | |
591 | break; | 591 | break; | |
592 | case FcTypeBool: | 592 | case FcTypeBool: | |
593 | if (!FcNameBool (string, &v.u.b)) | 593 | if (!FcNameBool (string, &v.u.b)) | |
594 | v.u.b = FcFalse; | 594 | v.u.b = FcFalse; | |
595 | break; | 595 | break; | |
596 | case FcTypeDouble: | 596 | case FcTypeDouble: | |
597 | v.u.d = strtod ((char *) string, 0); | 597 | v.u.d = strtod ((char *) string, 0); | |
598 | break; | 598 | break; | |
599 | case FcTypeMatrix: | 599 | case FcTypeMatrix: | |
600 | v.u.m = m; | 600 | sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy); | |
601 | sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy); | 601 | v.u.m = FcMatrixCopy (&m); | |
602 | break; | 602 | break; | |
603 | case FcTypeCharSet: | 603 | case FcTypeCharSet: | |
604 | v.u.c = FcNameParseCharSet (string); | 604 | v.u.c = FcNameParseCharSet (string); | |
605 | if (!v.u.c) | 605 | if (!v.u.c) | |
606 | v.type = FcTypeVoid; | 606 | v.type = FcTypeVoid; | |
607 | break; | 607 | break; | |
608 | case FcTypeLangSet: | 608 | case FcTypeLangSet: | |
609 | v.u.l = FcNameParseLangSet (string); | 609 | v.u.l = FcNameParseLangSet (string); | |
610 | if (!v.u.l) | 610 | if (!v.u.l) | |
611 | v.type = FcTypeVoid; | 611 | v.type = FcTypeVoid; | |
612 | break; | 612 | break; | |
613 | default: | 613 | default: | |
614 | break; | 614 | break; | |
615 | } | 615 | } | |
616 | return v; | 616 | return v; | |
617 | } | 617 | } | |
618 | 618 | |||
619 | static const FcChar8 * | 619 | static const FcChar8 * | |
620 | FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) | 620 | FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) | |
621 | { | 621 | { | |
622 | FcChar8 c; | 622 | FcChar8 c; | |
623 | 623 | |||
624 | while ((c = *cur)) | 624 | while ((c = *cur)) | |
625 | { | 625 | { | |
626 | if (c == '\\') | 626 | if (c == '\\') | |
627 | { | 627 | { | |
628 | ++cur; | 628 | ++cur; | |
629 | if (!(c = *cur)) | 629 | if (!(c = *cur)) | |
630 | break; | 630 | break; | |
631 | } | 631 | } | |
632 | else if (strchr (delim, c)) | 632 | else if (strchr (delim, c)) | |
633 | break; | 633 | break; | |
634 | ++cur; | 634 | ++cur; | |
635 | *save++ = c; | 635 | *save++ = c; | |
636 | } | 636 | } | |
@@ -640,27 +640,26 @@ FcNameFindNext (const FcChar8 *cur, cons | @@ -640,27 +640,26 @@ FcNameFindNext (const FcChar8 *cur, cons | |||
640 | cur++; | 640 | cur++; | |
641 | return cur; | 641 | return cur; | |
642 | } | 642 | } | |
643 | 643 | |||
644 | FcPattern * | 644 | FcPattern * | |
645 | FcNameParse (const FcChar8 *name) | 645 | FcNameParse (const FcChar8 *name) | |
646 | { | 646 | { | |
647 | FcChar8 *save; | 647 | FcChar8 *save; | |
648 | FcPattern *pat; | 648 | FcPattern *pat; | |
649 | double d; | 649 | double d; | |
650 | FcChar8 *e; | 650 | FcChar8 *e; | |
651 | FcChar8 delim; | 651 | FcChar8 delim; | |
652 | FcValue v; | 652 | FcValue v; | |
653 | FcMatrix m; | |||
654 | const FcObjectType *t; | 653 | const FcObjectType *t; | |
655 | const FcConstant *c; | 654 | const FcConstant *c; | |
656 | 655 | |||
657 | /* freed below */ | 656 | /* freed below */ | |
658 | save = malloc (strlen ((char *) name) + 1); | 657 | save = malloc (strlen ((char *) name) + 1); | |
659 | if (!save) | 658 | if (!save) | |
660 | goto bail0; | 659 | goto bail0; | |
661 | pat = FcPatternCreate (); | 660 | pat = FcPatternCreate (); | |
662 | if (!pat) | 661 | if (!pat) | |
663 | goto bail1; | 662 | goto bail1; | |
664 | 663 | |||
665 | for (;;) | 664 | for (;;) | |
666 | { | 665 | { | |
@@ -691,51 +690,33 @@ FcNameParse (const FcChar8 *name) | @@ -691,51 +690,33 @@ FcNameParse (const FcChar8 *name) | |||
691 | while (delim == ':') | 690 | while (delim == ':') | |
692 | { | 691 | { | |
693 | name = FcNameFindNext (name, "=_:", save, &delim); | 692 | name = FcNameFindNext (name, "=_:", save, &delim); | |
694 | if (save[0]) | 693 | if (save[0]) | |
695 | { | 694 | { | |
696 | if (delim == '=' || delim == '_') | 695 | if (delim == '=' || delim == '_') | |
697 | { | 696 | { | |
698 | t = FcNameGetObjectType ((char *) save); | 697 | t = FcNameGetObjectType ((char *) save); | |
699 | for (;;) | 698 | for (;;) | |
700 | { | 699 | { | |
701 | name = FcNameFindNext (name, ":,", save, &delim); | 700 | name = FcNameFindNext (name, ":,", save, &delim); | |
702 | if (t) | 701 | if (t) | |
703 | { | 702 | { | |
704 | v = FcNameConvert (t->type, save, &m); | 703 | v = FcNameConvert (t->type, save); | |
705 | if (!FcPatternAdd (pat, t->object, v, FcTrue)) | 704 | if (!FcPatternAdd (pat, t->object, v, FcTrue)) | |
706 | { | 705 | { | |
707 | switch (v.type) { | 706 | FcValueDestroy (v); | |
708 | case FcTypeCharSet: | |||
709 | FcCharSetDestroy ((FcCharSet *) v.u.c); | |||
710 | break; | |||
711 | case FcTypeLangSet: | |||
712 | FcLangSetDestroy ((FcLangSet *) v.u.l); | |||
713 | break; | |||
714 | default: | |||
715 | break; | |||
716 | } | |||
717 | goto bail2; | 707 | goto bail2; | |
718 | } | 708 | } | |
719 | switch (v.type) { | 709 | FcValueDestroy (v); | |
720 | case FcTypeCharSet: | |||
721 | FcCharSetDestroy ((FcCharSet *) v.u.c); | |||
722 | break; | |||
723 | case FcTypeLangSet: | |||
724 | FcLangSetDestroy ((FcLangSet *) v.u.l); | |||
725 | break; | |||
726 | default: | |||
727 | break; | |||
728 | } | |||
729 | } | 710 | } | |
730 | if (delim != ',') | 711 | if (delim != ',') | |
731 | break; | 712 | break; | |
732 | } | 713 | } | |
733 | } | 714 | } | |
734 | else | 715 | else | |
735 | { | 716 | { | |
736 | if ((c = FcNameGetConstant (save))) | 717 | if ((c = FcNameGetConstant (save))) | |
737 | { | 718 | { | |
738 | t = FcNameGetObjectType ((char *) c->object); | 719 | t = FcNameGetObjectType ((char *) c->object); | |
739 | switch (t->type) { | 720 | switch (t->type) { | |
740 | case FcTypeInteger: | 721 | case FcTypeInteger: | |
741 | case FcTypeDouble: | 722 | case FcTypeDouble: | |
@@ -755,67 +736,67 @@ FcNameParse (const FcChar8 *name) | @@ -755,67 +736,67 @@ FcNameParse (const FcChar8 *name) | |||
755 | } | 736 | } | |
756 | 737 | |||
757 | free (save); | 738 | free (save); | |
758 | return pat; | 739 | return pat; | |
759 | 740 | |||
760 | bail2: | 741 | bail2: | |
761 | FcPatternDestroy (pat); | 742 | FcPatternDestroy (pat); | |
762 | bail1: | 743 | bail1: | |
763 | free (save); | 744 | free (save); | |
764 | bail0: | 745 | bail0: | |
765 | return 0; | 746 | return 0; | |
766 | } | 747 | } | |
767 | static FcBool | 748 | static FcBool | |
768 | FcNameUnparseString (FcStrBuf *buf, | 749 | FcNameUnparseString (FcStrBuf *buf, | |
769 | const FcChar8 *string, | 750 | const FcChar8 *string, | |
770 | const FcChar8 *escape) | 751 | const FcChar8 *escape) | |
771 | { | 752 | { | |
772 | FcChar8 c; | 753 | FcChar8 c; | |
773 | while ((c = *string++)) | 754 | while ((c = *string++)) | |
774 | { | 755 | { | |
775 | if (escape && strchr ((char *) escape, (char) c)) | 756 | if (escape && strchr ((char *) escape, (char) c)) | |
776 | { | 757 | { | |
777 | if (!FcStrBufChar (buf, escape[0])) | 758 | if (!FcStrBufChar (buf, escape[0])) | |
778 | return FcFalse; | 759 | return FcFalse; | |
779 | } | 760 | } | |
780 | if (!FcStrBufChar (buf, c)) | 761 | if (!FcStrBufChar (buf, c)) | |
781 | return FcFalse; | 762 | return FcFalse; | |
782 | } | 763 | } | |
783 | return FcTrue; | 764 | return FcTrue; | |
784 | } | 765 | } | |
785 | 766 | |||
786 | FcBool | 767 | FcBool | |
787 | FcNameUnparseValue (FcStrBuf *buf, | 768 | FcNameUnparseValue (FcStrBuf *buf, | |
788 | FcValue *v0, | 769 | FcValue *v0, | |
789 | FcChar8 *escape) | 770 | FcChar8 *escape) | |
790 | { | 771 | { | |
791 | FcChar8 temp[1024]; | 772 | FcChar8 temp[1024]; | |
792 | FcValue v = FcValueCanonicalize(v0); | 773 | FcValue v = FcValueCanonicalize(v0); | |
793 | 774 | |||
794 | switch (v.type) { | 775 | switch (v.type) { | |
795 | case FcTypeVoid: | 776 | case FcTypeVoid: | |
796 | return FcTrue; | 777 | return FcTrue; | |
797 | case FcTypeInteger: | 778 | case FcTypeInteger: | |
798 | sprintf ((char *) temp, "%d", v.u.i); | 779 | sprintf ((char *) temp, "%d", v.u.i); | |
799 | return FcNameUnparseString (buf, temp, 0); | 780 | return FcNameUnparseString (buf, temp, 0); | |
800 | case FcTypeDouble: | 781 | case FcTypeDouble: | |
801 | sprintf ((char *) temp, "%g", v.u.d); | 782 | sprintf ((char *) temp, "%g", v.u.d); | |
802 | return FcNameUnparseString (buf, temp, 0); | 783 | return FcNameUnparseString (buf, temp, 0); | |
803 | case FcTypeString: | 784 | case FcTypeString: | |
804 | return FcNameUnparseString (buf, v.u.s, escape); | 785 | return FcNameUnparseString (buf, v.u.s, escape); | |
805 | case FcTypeBool: | 786 | case FcTypeBool: | |
806 | return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0); | 787 | return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0); | |
807 | case FcTypeMatrix: | 788 | case FcTypeMatrix: | |
808 | sprintf ((char *) temp, "%g %g %g %g", | 789 | sprintf ((char *) temp, "%g %g %g %g", | |
809 | v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); | 790 | v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); | |
810 | return FcNameUnparseString (buf, temp, 0); | 791 | return FcNameUnparseString (buf, temp, 0); | |
811 | case FcTypeCharSet: | 792 | case FcTypeCharSet: | |
812 | return FcNameUnparseCharSet (buf, v.u.c); | 793 | return FcNameUnparseCharSet (buf, v.u.c); | |
813 | case FcTypeLangSet: | 794 | case FcTypeLangSet: | |
814 | return FcNameUnparseLangSet (buf, v.u.l); | 795 | return FcNameUnparseLangSet (buf, v.u.l); | |
815 | case FcTypeFTFace: | 796 | case FcTypeFTFace: | |
816 | return FcTrue; | 797 | return FcTrue; | |
817 | } | 798 | } | |
818 | return FcFalse; | 799 | return FcFalse; | |
819 | } | 800 | } | |
820 | 801 | |||
821 | FcBool | 802 | FcBool | |
@@ -863,41 +844,40 @@ FcNameUnparseEscaped (FcPattern *pat, Fc | @@ -863,41 +844,40 @@ FcNameUnparseEscaped (FcPattern *pat, Fc | |||
863 | e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); | 844 | e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); | |
864 | if (e) | 845 | if (e) | |
865 | { | 846 | { | |
866 | if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) | 847 | if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) | |
867 | goto bail0; | 848 | goto bail0; | |
868 | if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) | 849 | if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) | |
869 | goto bail0; | 850 | goto bail0; | |
870 | } | 851 | } | |
871 | for (l = _FcObjectTypes; l; l = l->next) | 852 | for (l = _FcObjectTypes; l; l = l->next) | |
872 | { | 853 | { | |
873 | for (i = 0; i < l->ntypes; i++) | 854 | for (i = 0; i < l->ntypes; i++) | |
874 | { | 855 | { | |
875 | o = &l->types[i]; | 856 | o = &l->types[i]; | |
876 | if (!strcmp (o->object, FC_FAMILY) || | 857 | if (!strcmp (o->object, FC_FAMILY) || | |
877 | !strcmp (o->object, FC_SIZE) || | 858 | !strcmp (o->object, FC_SIZE)) | |
878 | !strcmp (o->object, FC_FILE)) | |||
879 | continue; | 859 | continue; | |
880 | 860 | |||
881 | e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); | 861 | e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); | |
882 | if (e) | 862 | if (e) | |
883 | { | 863 | { | |
884 | if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) | 864 | if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) | |
885 | goto bail0; | 865 | goto bail0; | |
886 | if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) | 866 | if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) | |
887 | goto bail0; | 867 | goto bail0; | |
888 | if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) | 868 | if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0)) | |
889 | goto bail0; | 869 | goto bail0; | |
890 | if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? | 870 | if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? | |
891 | (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) | 871 | (FcChar8 *) FC_ESCAPE_VARIABLE : 0)) | |
892 | goto bail0; | 872 | goto bail0; | |
893 | } | 873 | } | |
894 | } | 874 | } | |
895 | } | 875 | } | |
896 | return FcStrBufDone (&buf); | 876 | return FcStrBufDone (&buf); | |
897 | bail0: | 877 | bail0: | |
898 | FcStrBufDestroy (&buf); | 878 | FcStrBufDestroy (&buf); | |
899 | return 0; | 879 | return 0; | |
900 | } | 880 | } | |
901 | #define __fcname__ | 881 | #define __fcname__ | |
902 | #include "fcaliastail.h" | 882 | #include "fcaliastail.h" | |
903 | #undef __fcname__ | 883 | #undef __fcname__ |
--- xsrc/external/mit/fontconfig/dist/src/fcint.h 2010/11/21 06:50:47 1.3
+++ xsrc/external/mit/fontconfig/dist/src/fcint.h 2013/06/03 06:04:33 1.4
@@ -1,25 +1,25 @@ | @@ -1,25 +1,25 @@ | |||
1 | /* | 1 | /* | |
2 | * fontconfig/src/fcint.h | 2 | * fontconfig/src/fcint.h | |
3 | * | 3 | * | |
4 | * Copyright © 2000 Keith Packard | 4 | * Copyright © 2000 Keith Packard | |
5 | * | 5 | * | |
6 | * Permission to use, copy, modify, distribute, and sell this software and its | 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 | 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 | 8 | * the above copyright notice appear in all copies and that both that | |
9 | * copyright notice and this permission notice appear in supporting | 9 | * copyright notice and this permission notice appear in supporting | |
10 | * documentation, and that the name of Keith Packard not be used in | 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 | 11 | * advertising or publicity pertaining to distribution of the software without | |
12 | * specific, written prior permission. Keith Packard makes no | 12 | * specific, written prior permission. The authors make no | |
13 | * representations about the suitability of this software for any purpose. It | 13 | * representations about the suitability of this software for any purpose. It | |
14 | * is provided "as is" without express or implied warranty. | 14 | * is provided "as is" without express or implied warranty. | |
15 | * | 15 | * | |
16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | 16 | * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | 17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
18 | * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR | 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, | 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 | 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 | 21 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
22 | * PERFORMANCE OF THIS SOFTWARE. | 22 | * PERFORMANCE OF THIS SOFTWARE. | |
23 | */ | 23 | */ | |
24 | 24 | |||
25 | #ifndef _FCINT_H_ | 25 | #ifndef _FCINT_H_ | |
@@ -60,29 +60,43 @@ | @@ -60,29 +60,43 @@ | |||
60 | #include <stddef.h> | 60 | #include <stddef.h> | |
61 | #include <sys/types.h> | 61 | #include <sys/types.h> | |
62 | #include <sys/stat.h> | 62 | #include <sys/stat.h> | |
63 | #include <time.h> | 63 | #include <time.h> | |
64 | #include <fontconfig/fontconfig.h> | 64 | #include <fontconfig/fontconfig.h> | |
65 | #include <fontconfig/fcprivate.h> | 65 | #include <fontconfig/fcprivate.h> | |
66 | #include "fcdeprecate.h" | 66 | #include "fcdeprecate.h" | |
67 | 67 | |||
68 | #ifndef FC_CONFIG_PATH | 68 | #ifndef FC_CONFIG_PATH | |
69 | #define FC_CONFIG_PATH "fonts.conf" | 69 | #define FC_CONFIG_PATH "fonts.conf" | |
70 | #endif | 70 | #endif | |
71 | 71 | |||
72 | #ifdef _WIN32 | 72 | #ifdef _WIN32 | |
73 | #define FC_SEARCH_PATH_SEPARATOR ';' | 73 | # ifndef _WIN32_WINNT | |
74 | # define _WIN32_WINNT 0x0500 | |||
75 | # endif | |||
76 | # define WIN32_LEAN_AND_MEAN | |||
77 | # define STRICT | |||
78 | # include <windows.h> | |||
79 | typedef UINT (WINAPI *pfnGetSystemWindowsDirectory)(LPSTR, UINT); | |||
80 | typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR); | |||
81 | extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory; | |||
82 | extern pfnSHGetFolderPathA pSHGetFolderPathA; | |||
83 | # define FC_SEARCH_PATH_SEPARATOR ';' | |||
84 | # define FC_DIR_SEPARATOR '\\' | |||
85 | # define FC_DIR_SEPARATOR_S "\\" | |||
74 | #else | 86 | #else | |
75 | #define FC_SEARCH_PATH_SEPARATOR ':' | 87 | # define FC_SEARCH_PATH_SEPARATOR ':' | |
88 | # define FC_DIR_SEPARATOR '/' | |||
89 | # define FC_DIR_SEPARATOR_S "/" | |||
76 | #endif | 90 | #endif | |
77 | 91 | |||
78 | #define FC_DBG_MATCH 1 | 92 | #define FC_DBG_MATCH 1 | |
79 | #define FC_DBG_MATCHV 2 | 93 | #define FC_DBG_MATCHV 2 | |
80 | #define FC_DBG_EDIT 4 | 94 | #define FC_DBG_EDIT 4 | |
81 | #define FC_DBG_FONTSET 8 | 95 | #define FC_DBG_FONTSET 8 | |
82 | #define FC_DBG_CACHE 16 | 96 | #define FC_DBG_CACHE 16 | |
83 | #define FC_DBG_CACHEV 32 | 97 | #define FC_DBG_CACHEV 32 | |
84 | #define FC_DBG_PARSE 64 | 98 | #define FC_DBG_PARSE 64 | |
85 | #define FC_DBG_SCAN 128 | 99 | #define FC_DBG_SCAN 128 | |
86 | #define FC_DBG_SCANV 256 | 100 | #define FC_DBG_SCANV 256 | |
87 | #define FC_DBG_MEMORY 512 | 101 | #define FC_DBG_MEMORY 512 | |
88 | #define FC_DBG_CONFIG 1024 | 102 | #define FC_DBG_CONFIG 1024 | |
@@ -108,54 +122,58 @@ | @@ -108,54 +122,58 @@ | |||
108 | #define FC_MEM_LANGSET 16 | 122 | #define FC_MEM_LANGSET 16 | |
109 | #define FC_MEM_ATOMIC 17 | 123 | #define FC_MEM_ATOMIC 17 | |
110 | #define FC_MEM_BLANKS 18 | 124 | #define FC_MEM_BLANKS 18 | |
111 | #define FC_MEM_CACHE 19 | 125 | #define FC_MEM_CACHE 19 | |
112 | #define FC_MEM_STRBUF 20 | 126 | #define FC_MEM_STRBUF 20 | |
113 | #define FC_MEM_SUBST 21 | 127 | #define FC_MEM_SUBST 21 | |
114 | #define FC_MEM_OBJECTTYPE 22 | 128 | #define FC_MEM_OBJECTTYPE 22 | |
115 | #define FC_MEM_CONSTANT 23 | 129 | #define FC_MEM_CONSTANT 23 | |
116 | #define FC_MEM_TEST 24 | 130 | #define FC_MEM_TEST 24 | |
117 | #define FC_MEM_EXPR 25 | 131 | #define FC_MEM_EXPR 25 | |
118 | #define FC_MEM_VSTACK 26 | 132 | #define FC_MEM_VSTACK 26 | |
119 | #define FC_MEM_ATTR 27 | 133 | #define FC_MEM_ATTR 27 | |
120 | #define FC_MEM_PSTACK 28 | 134 | #define FC_MEM_PSTACK 28 | |
121 | #define FC_MEM_STATICSTR 29 | 135 | #define FC_MEM_SHAREDSTR 29 | |
122 | 136 | |||
123 | #define FC_MEM_NUM 30 | 137 | #define FC_MEM_NUM 30 | |
124 | 138 | |||
139 | #define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] | |||
140 | #define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) | |||
141 | #define FC_ASSERT_STATIC(_cond) _FC_ASSERT_STATIC0 (__LINE__, (_cond)) | |||
142 | ||||
125 | #define FC_MIN(a,b) ((a) < (b) ? (a) : (b)) | 143 | #define FC_MIN(a,b) ((a) < (b) ? (a) : (b)) | |
126 | #define FC_MAX(a,b) ((a) > (b) ? (a) : (b)) | 144 | #define FC_MAX(a,b) ((a) > (b) ? (a) : (b)) | |
127 | #define FC_ABS(a) ((a) < 0 ? -(a) : (a)) | 145 | #define FC_ABS(a) ((a) < 0 ? -(a) : (a)) | |
128 | 146 | |||
129 | /* slim_internal.h */ | 147 | /* slim_internal.h */ | |
130 | #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun) | 148 | #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun) | |
131 | #define FcPrivate __attribute__((__visibility__("hidden"))) | 149 | #define FcPrivate __attribute__((__visibility__("hidden"))) | |
132 | #define HAVE_GNUC_ATTRIBUTE 1 | 150 | #define HAVE_GNUC_ATTRIBUTE 1 | |
133 | #include "fcalias.h" | 151 | #include "fcalias.h" | |
134 | #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) | 152 | #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) | |
135 | #define FcPrivate __hidden | 153 | #define FcPrivate __hidden | |
136 | #else /* not gcc >= 3.3 and not Sun Studio >= 8 */ | 154 | #else /* not gcc >= 3.3 and not Sun Studio >= 8 */ | |
137 | #define FcPrivate | 155 | #define FcPrivate | |
138 | #endif | 156 | #endif | |
139 | 157 | |||
140 | typedef enum _FcValueBinding { | 158 | typedef enum _FcValueBinding { | |
141 | FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame | 159 | FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame | |
142 | } FcValueBinding; | 160 | } FcValueBinding; | |
143 | 161 | |||
144 | /* | 162 | /* | |
145 | * Serialized data structures use only offsets instead of pointers | 163 | * Serialized data structures use only offsets instead of pointers | |
146 | * A low bit of 1 indicates an offset. | 164 | * A low bit of 1 indicates an offset. | |
147 | */ | 165 | */ | |
148 | 166 | |||
149 | /* Is the provided pointer actually an offset? */ | 167 | /* Is the provided pointer actually an offset? */ | |
150 | #define FcIsEncodedOffset(p) ((((intptr_t) (p)) & 1) != 0) | 168 | #define FcIsEncodedOffset(p) ((((intptr_t) (p)) & 1) != 0) | |
151 | 169 | |||
152 | /* Encode offset in a pointer of type t */ | 170 | /* Encode offset in a pointer of type t */ | |
153 | #define FcOffsetEncode(o,t) ((t *) ((o) | 1)) | 171 | #define FcOffsetEncode(o,t) ((t *) ((o) | 1)) | |
154 | 172 | |||
155 | /* Decode a pointer into an offset */ | 173 | /* Decode a pointer into an offset */ | |
156 | #define FcOffsetDecode(p) (((intptr_t) (p)) & ~1) | 174 | #define FcOffsetDecode(p) (((intptr_t) (p)) & ~1) | |
157 | 175 | |||
158 | /* Compute pointer offset */ | 176 | /* Compute pointer offset */ | |
159 | #define FcPtrToOffset(b,p) ((intptr_t) (p) - (intptr_t) (b)) | 177 | #define FcPtrToOffset(b,p) ((intptr_t) (p) - (intptr_t) (b)) | |
160 | 178 | |||
161 | /* Given base address, offset and type, return a pointer */ | 179 | /* Given base address, offset and type, return a pointer */ | |
@@ -186,33 +204,33 @@ typedef enum _FcValueBinding { | @@ -186,33 +204,33 @@ typedef enum _FcValueBinding { | |||
186 | #define FcValueString(v) FcPointerMember(v,u.s,FcChar8) | 204 | #define FcValueString(v) FcPointerMember(v,u.s,FcChar8) | |
187 | #define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet) | 205 | #define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet) | |
188 | #define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet) | 206 | #define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet) | |
189 | 207 | |||
190 | typedef struct _FcValueList *FcValueListPtr; | 208 | typedef struct _FcValueList *FcValueListPtr; | |
191 | 209 | |||
192 | typedef struct _FcValueList { | 210 | typedef struct _FcValueList { | |
193 | struct _FcValueList *next; | 211 | struct _FcValueList *next; | |
194 | FcValue value; | 212 | FcValue value; | |
195 | FcValueBinding binding; | 213 | FcValueBinding binding; | |
196 | } FcValueList; | 214 | } FcValueList; | |
197 | 215 | |||
198 | #define FcValueListNext(vl) FcPointerMember(vl,next,FcValueList) | 216 | #define FcValueListNext(vl) FcPointerMember(vl,next,FcValueList) | |
199 | 217 | |||
200 | typedef int FcObject; | 218 | typedef int FcObject; | |
201 | 219 | |||
202 | typedef struct _FcPatternElt *FcPatternEltPtr; | 220 | typedef struct _FcPatternElt *FcPatternEltPtr; | |
203 | 221 | |||
204 | /* | 222 | /* | |
205 | * Pattern elts are stuck in a structure connected to the pattern, | 223 | * Pattern elts are stuck in a structure connected to the pattern, | |
206 | * so they get moved around when the pattern is resized. Hence, the | 224 | * so they get moved around when the pattern is resized. Hence, the | |
207 | * values field must be a pointer/offset instead of just an offset | 225 | * values field must be a pointer/offset instead of just an offset | |
208 | */ | 226 | */ | |
209 | typedef struct _FcPatternElt { | 227 | typedef struct _FcPatternElt { | |
210 | FcObject object; | 228 | FcObject object; | |
211 | FcValueList *values; | 229 | FcValueList *values; | |
212 | } FcPatternElt; | 230 | } FcPatternElt; | |
213 | 231 | |||
214 | #define FcPatternEltValues(pe) FcPointerMember(pe,values,FcValueList) | 232 | #define FcPatternEltValues(pe) FcPointerMember(pe,values,FcValueList) | |
215 | 233 | |||
216 | struct _FcPattern { | 234 | struct _FcPattern { | |
217 | int num; | 235 | int num; | |
218 | int size; | 236 | int size; | |
@@ -221,64 +239,73 @@ struct _FcPattern { | @@ -221,64 +239,73 @@ struct _FcPattern { | |||
221 | }; | 239 | }; | |
222 | 240 | |||
223 | #define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt) | 241 | #define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt) | |
224 | 242 | |||
225 | #define FcFontSetFonts(fs) FcPointerMember(fs,fonts,FcPattern *) | 243 | #define FcFontSetFonts(fs) FcPointerMember(fs,fonts,FcPattern *) | |
226 | 244 | |||
227 | #define FcFontSetFont(fs,i) (FcIsEncodedOffset((fs)->fonts) ? \ | 245 | #define FcFontSetFont(fs,i) (FcIsEncodedOffset((fs)->fonts) ? \ | |
228 | FcEncodedOffsetToPtr(fs, \ | 246 | FcEncodedOffsetToPtr(fs, \ | |
229 | FcFontSetFonts(fs)[i], \ | 247 | FcFontSetFonts(fs)[i], \ | |
230 | FcPattern) : \ | 248 | FcPattern) : \ | |
231 | fs->fonts[i]) | 249 | fs->fonts[i]) | |
232 | 250 | |||
233 | typedef enum _FcOp { | 251 | typedef enum _FcOp { | |
234 | FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet, | 252 | FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet, FcOpLangSet, | |
235 | FcOpNil, | 253 | FcOpNil, | |
236 | FcOpField, FcOpConst, | 254 | FcOpField, FcOpConst, | |
237 | FcOpAssign, FcOpAssignReplace, | 255 | FcOpAssign, FcOpAssignReplace, | |
238 | FcOpPrependFirst, FcOpPrepend, FcOpAppend, FcOpAppendLast, | 256 | FcOpPrependFirst, FcOpPrepend, FcOpAppend, FcOpAppendLast, | |
239 | FcOpQuest, | 257 | FcOpQuest, | |
240 | FcOpOr, FcOpAnd, FcOpEqual, FcOpNotEqual, | 258 | FcOpOr, FcOpAnd, FcOpEqual, FcOpNotEqual, | |
241 | FcOpContains, FcOpListing, FcOpNotContains, | 259 | FcOpContains, FcOpListing, FcOpNotContains, | |
242 | FcOpLess, FcOpLessEqual, FcOpMore, FcOpMoreEqual, | 260 | FcOpLess, FcOpLessEqual, FcOpMore, FcOpMoreEqual, | |
243 | FcOpPlus, FcOpMinus, FcOpTimes, FcOpDivide, | 261 | FcOpPlus, FcOpMinus, FcOpTimes, FcOpDivide, | |
244 | FcOpNot, FcOpComma, FcOpFloor, FcOpCeil, FcOpRound, FcOpTrunc, | 262 | FcOpNot, FcOpComma, FcOpFloor, FcOpCeil, FcOpRound, FcOpTrunc, | |
245 | FcOpInvalid | 263 | FcOpInvalid | |
246 | } FcOp; | 264 | } FcOp; | |
247 | 265 | |||
266 | typedef enum _FcOpFlags { | |||
267 | FcOpFlagIgnoreBlanks = 1 << 0 | |||
268 | } FcOpFlags; | |||
269 | ||||
270 | #define FC_OP_GET_OP(_x_) ((_x_) & 0xffff) | |||
271 | #define FC_OP_GET_FLAGS(_x_) (((_x_) & 0xffff0000) >> 16) | |||
272 | #define FC_OP(_x_,_f_) (FC_OP_GET_OP (_x_) | ((_f_) << 16)) | |||
273 | ||||
248 | typedef struct _FcExpr { | 274 | typedef struct _FcExpr { | |
249 | FcOp op; | 275 | FcOp op; | |
250 | union { | 276 | union { | |
251 | int ival; | 277 | int ival; | |
252 | double dval; | 278 | double dval; | |
253 | FcChar8 *sval; | 279 | const FcChar8 *sval; | |
254 | FcMatrix *mval; | 280 | FcMatrix *mval; | |
255 | FcBool bval; | 281 | FcBool bval; | |
256 | FcCharSet *cval; | 282 | FcCharSet *cval; | |
283 | FcLangSet *lval; | |||
257 | FcObject object; | 284 | FcObject object; | |
258 | FcChar8 *constant; | 285 | const FcChar8 *constant; | |
259 | struct { | 286 | struct { | |
260 | struct _FcExpr *left, *right; | 287 | struct _FcExpr *left, *right; | |
261 | } tree; | 288 | } tree; | |
262 | } u; | 289 | } u; | |
263 | } FcExpr; | 290 | } FcExpr; | |
264 | 291 | |||
265 | typedef struct _FcExprPage FcExprPage; | 292 | typedef struct _FcExprPage FcExprPage; | |
266 | 293 | |||
267 | struct _FcExprPage { | 294 | struct _FcExprPage { | |
268 | FcExprPage *next_page; | 295 | FcExprPage *next_page; | |
269 | FcExpr *next; | 296 | FcExpr *next; | |
270 | FcExpr exprs[(1024 - 2/* two pointers */ - 2/* malloc overhead */) * sizeof (void *) / sizeof (FcExpr)]; | 297 | FcExpr exprs[(1024 - 2/* two pointers */ - 2/* malloc overhead */) * sizeof (void *) / sizeof (FcExpr)]; | |
271 | FcExpr end[0]; | 298 | FcExpr end[FLEXIBLE_ARRAY_MEMBER]; | |
272 | }; | 299 | }; | |
273 | 300 | |||
274 | typedef enum _FcQual { | 301 | typedef enum _FcQual { | |
275 | FcQualAny, FcQualAll, FcQualFirst, FcQualNotFirst | 302 | FcQualAny, FcQualAll, FcQualFirst, FcQualNotFirst | |
276 | } FcQual; | 303 | } FcQual; | |
277 | 304 | |||
278 | #define FcMatchDefault ((FcMatchKind) -1) | 305 | #define FcMatchDefault ((FcMatchKind) -1) | |
279 | 306 | |||
280 | typedef struct _FcTest { | 307 | typedef struct _FcTest { | |
281 | struct _FcTest *next; | 308 | struct _FcTest *next; | |
282 | FcMatchKind kind; | 309 | FcMatchKind kind; | |
283 | FcQual qual; | 310 | FcQual qual; | |
284 | FcObject object; | 311 | FcObject object; | |
@@ -338,27 +365,27 @@ typedef struct _FcStrBuf { | @@ -338,27 +365,27 @@ typedef struct _FcStrBuf { | |||
338 | int len; | 365 | int len; | |
339 | int size; | 366 | int size; | |
340 | FcChar8 buf_static[16 * sizeof (void *)]; | 367 | FcChar8 buf_static[16 * sizeof (void *)]; | |
341 | } FcStrBuf; | 368 | } FcStrBuf; | |
342 | 369 | |||
343 | struct _FcCache { | 370 | struct _FcCache { | |
344 | int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ | 371 | int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ | |
345 | int version; /* FC_CACHE_CONTENT_VERSION */ | 372 | int version; /* FC_CACHE_CONTENT_VERSION */ | |
346 | intptr_t size; /* size of file */ | 373 | intptr_t size; /* size of file */ | |
347 | intptr_t dir; /* offset to dir name */ | 374 | intptr_t dir; /* offset to dir name */ | |
348 | intptr_t dirs; /* offset to subdirs */ | 375 | intptr_t dirs; /* offset to subdirs */ | |
349 | int dirs_count; /* number of subdir strings */ | 376 | int dirs_count; /* number of subdir strings */ | |
350 | intptr_t set; /* offset to font set */ | 377 | intptr_t set; /* offset to font set */ | |
351 | int mtime; /* low bits of directory mtime */ | 378 | int checksum; /* checksum of directory state */ | |
352 | }; | 379 | }; | |
353 | 380 | |||
354 | #undef FcCacheDir | 381 | #undef FcCacheDir | |
355 | #undef FcCacheSubdir | 382 | #undef FcCacheSubdir | |
356 | #define FcCacheDir(c) FcOffsetMember(c,dir,FcChar8) | 383 | #define FcCacheDir(c) FcOffsetMember(c,dir,FcChar8) | |
357 | #define FcCacheDirs(c) FcOffsetMember(c,dirs,intptr_t) | 384 | #define FcCacheDirs(c) FcOffsetMember(c,dirs,intptr_t) | |
358 | #define FcCacheSet(c) FcOffsetMember(c,set,FcFontSet) | 385 | #define FcCacheSet(c) FcOffsetMember(c,set,FcFontSet) | |
359 | #define FcCacheSubdir(c,i) FcOffsetToPtr (FcCacheDirs(c),\ | 386 | #define FcCacheSubdir(c,i) FcOffsetToPtr (FcCacheDirs(c),\ | |
360 | FcCacheDirs(c)[i], \ | 387 | FcCacheDirs(c)[i], \ | |
361 | FcChar8) | 388 | FcChar8) | |
362 | 389 | |||
363 | /* | 390 | /* | |
364 | * Used while constructing a directory cache object | 391 | * Used while constructing a directory cache object | |
@@ -378,48 +405,48 @@ typedef struct _FcSerializeBucket { | @@ -378,48 +405,48 @@ typedef struct _FcSerializeBucket { | |||
378 | struct _FcSerializeBucket *next; | 405 | struct _FcSerializeBucket *next; | |
379 | const void *object; | 406 | const void *object; | |
380 | intptr_t offset; | 407 | intptr_t offset; | |
381 | } FcSerializeBucket; | 408 | } FcSerializeBucket; | |
382 | 409 | |||
383 | typedef struct _FcCharSetFreezer FcCharSetFreezer; | 410 | typedef struct _FcCharSetFreezer FcCharSetFreezer; | |
384 | 411 | |||
385 | typedef struct _FcSerialize { | 412 | typedef struct _FcSerialize { | |
386 | intptr_t size; | 413 | intptr_t size; | |
387 | FcCharSetFreezer *cs_freezer; | 414 | FcCharSetFreezer *cs_freezer; | |
388 | void *linear; | 415 | void *linear; | |
389 | FcSerializeBucket *buckets[FC_SERIALIZE_HASH_SIZE]; | 416 | FcSerializeBucket *buckets[FC_SERIALIZE_HASH_SIZE]; | |
390 | } FcSerialize; | 417 | } FcSerialize; | |
391 | 418 | |||
392 | /* | 419 | /* | |
393 | * To map adobe glyph names to unicode values, a precomputed hash | 420 | * To map adobe glyph names to unicode values, a precomputed hash | |
394 | * table is used | 421 | * table is used | |
395 | */ | 422 | */ | |
396 | 423 | |||
397 | typedef struct _FcGlyphName { | 424 | typedef struct _FcGlyphName { | |
398 | FcChar32 ucs; /* unicode value */ | 425 | FcChar32 ucs; /* unicode value */ | |
399 | FcChar8 name[1]; /* name extends beyond struct */ | 426 | FcChar8 name[1]; /* name extends beyond struct */ | |
400 | } FcGlyphName; | 427 | } FcGlyphName; | |
401 | 428 | |||
402 | /* | 429 | /* | |
403 | * To perform case-insensitive string comparisons, a table | 430 | * To perform case-insensitive string comparisons, a table | |
404 | * is used which holds three different kinds of folding data. | 431 | * is used which holds three different kinds of folding data. | |
405 | * | 432 | * | |
406 | * The first is a range of upper case values mapping to a range | 433 | * The first is a range of upper case values mapping to a range | |
407 | * of their lower case equivalents. Within each range, the offset | 434 | * of their lower case equivalents. Within each range, the offset | |
408 | * between upper and lower case is constant. | 435 | * between upper and lower case is constant. | |
409 | * | 436 | * | |
410 | * The second is a range of upper case values which are interleaved | 437 | * The second is a range of upper case values which are interleaved | |
411 | * with their lower case equivalents. | 438 | * with their lower case equivalents. | |
412 | * | 439 | * | |
413 | * The third is a set of raw unicode values mapping to a list | 440 | * The third is a set of raw unicode values mapping to a list | |
414 | * of unicode values for comparison purposes. This allows conversion | 441 | * of unicode values for comparison purposes. This allows conversion | |
415 | * of ß to "ss" so that SS, ss and ß all match. A separate array | 442 | * of ß to "ss" so that SS, ss and ß all match. A separate array | |
416 | * holds the list of unicode values for each entry. | 443 | * holds the list of unicode values for each entry. | |
417 | * | 444 | * | |
418 | * These are packed into a single table. Using a binary search, | 445 | * These are packed into a single table. Using a binary search, | |
419 | * the appropriate entry can be located. | 446 | * the appropriate entry can be located. | |
420 | */ | 447 | */ | |
421 | 448 | |||
422 | #define FC_CASE_FOLD_RANGE 0 | 449 | #define FC_CASE_FOLD_RANGE 0 | |
423 | #define FC_CASE_FOLD_EVEN_ODD 1 | 450 | #define FC_CASE_FOLD_EVEN_ODD 1 | |
424 | #define FC_CASE_FOLD_FULL 2 | 451 | #define FC_CASE_FOLD_FULL 2 | |
425 | 452 | |||
@@ -453,27 +480,27 @@ struct _FcConfig { | @@ -453,27 +480,27 @@ struct _FcConfig { | |||
453 | /* | 480 | /* | |
454 | * File names loaded from the configuration -- saved here as the | 481 | * File names loaded from the configuration -- saved here as the | |
455 | * cache file must be consulted before the directories are scanned, | 482 | * cache file must be consulted before the directories are scanned, | |
456 | * and those directives may occur in any order | 483 | * and those directives may occur in any order | |
457 | */ | 484 | */ | |
458 | FcStrSet *configDirs; /* directories to scan for fonts */ | 485 | FcStrSet *configDirs; /* directories to scan for fonts */ | |
459 | /* | 486 | /* | |
460 | * Set of allowed blank chars -- used to | 487 | * Set of allowed blank chars -- used to | |
461 | * trim fonts of bogus glyphs | 488 | * trim fonts of bogus glyphs | |
462 | */ | 489 | */ | |
463 | FcBlanks *blanks; | 490 | FcBlanks *blanks; | |
464 | /* | 491 | /* | |
465 | * List of directories containing fonts, | 492 | * List of directories containing fonts, | |
466 | * built by recursively scanning the set | 493 | * built by recursively scanning the set | |
467 | * of configured directories | 494 | * of configured directories | |
468 | */ | 495 | */ | |
469 | FcStrSet *fontDirs; | 496 | FcStrSet *fontDirs; | |
470 | /* | 497 | /* | |
471 | * List of directories containing cache files. | 498 | * List of directories containing cache files. | |
472 | */ | 499 | */ | |
473 | FcStrSet *cacheDirs; | 500 | FcStrSet *cacheDirs; | |
474 | /* | 501 | /* | |
475 | * Names of all of the configuration files used | 502 | * Names of all of the configuration files used | |
476 | * to create this configuration | 503 | * to create this configuration | |
477 | */ | 504 | */ | |
478 | FcStrSet *configFiles; /* config files loaded */ | 505 | FcStrSet *configFiles; /* config files loaded */ | |
479 | /* | 506 | /* | |
@@ -502,70 +529,89 @@ struct _FcConfig { | @@ -502,70 +529,89 @@ struct _FcConfig { | |||
502 | /* | 529 | /* | |
503 | * Fontconfig can periodically rescan the system configuration | 530 | * Fontconfig can periodically rescan the system configuration | |
504 | * and font directories. This rescanning occurs when font | 531 | * and font directories. This rescanning occurs when font | |
505 | * listing requests are made, but no more often than rescanInterval | 532 | * listing requests are made, but no more often than rescanInterval | |
506 | * seconds apart. | 533 | * seconds apart. | |
507 | */ | 534 | */ | |
508 | time_t rescanTime; /* last time information was scanned */ | 535 | time_t rescanTime; /* last time information was scanned */ | |
509 | int rescanInterval; /* interval between scans */ | 536 | int rescanInterval; /* interval between scans */ | |
510 | 537 | |||
511 | int ref; /* reference count */ | 538 | int ref; /* reference count */ | |
512 | 539 | |||
513 | FcExprPage *expr_pool; /* pool of FcExpr's */ | 540 | FcExprPage *expr_pool; /* pool of FcExpr's */ | |
514 | }; | 541 | }; | |
515 | 542 | |||
516 | extern FcPrivate FcConfig *_fcConfig; | 543 | extern FcPrivate FcConfig *_fcConfig; | |
517 | 544 | |||
518 | typedef struct _FcFileTime { | 545 | typedef struct _FcFileTime { | |
519 | time_t time; | 546 | time_t time; | |
520 | FcBool set; | 547 | FcBool set; | |
521 | } FcFileTime; | 548 | } FcFileTime; | |
522 | 549 | |||
523 | typedef struct _FcCharMap FcCharMap; | 550 | typedef struct _FcCharMap FcCharMap; | |
524 | 551 | |||
552 | typedef struct _FcRange FcRange; | |||
553 | ||||
554 | struct _FcRange { | |||
555 | FcChar32 begin; | |||
556 | FcChar32 end; | |||
557 | }; | |||
558 | ||||
559 | typedef struct _FcStatFS FcStatFS; | |||
560 | ||||
561 | struct _FcStatFS { | |||
562 | FcBool is_remote_fs; | |||
563 | FcBool is_mtime_broken; | |||
564 | }; | |||
565 | ||||
525 | /* fcblanks.c */ | 566 | /* fcblanks.c */ | |
526 | 567 | |||
527 | /* fccache.c */ | 568 | /* fccache.c */ | |
528 | 569 | |||
529 | FcPrivate FcCache * | 570 | FcPrivate FcCache * | |
530 | FcDirCacheScan (const FcChar8 *dir, FcConfig *config); | 571 | FcDirCacheScan (const FcChar8 *dir, FcConfig *config); | |
531 | 572 | |||
532 | FcPrivate FcCache * | 573 | FcPrivate FcCache * | |
533 | FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs); | 574 | FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs); | |
534 | 575 | |||
535 | FcPrivate FcBool | 576 | FcPrivate FcBool | |
536 | FcDirCacheWrite (FcCache *cache, FcConfig *config); | 577 | FcDirCacheWrite (FcCache *cache, FcConfig *config); | |
537 | 578 | |||
579 | FcPrivate FcBool | |||
580 | FcDirCacheCreateTagFile (const FcChar8 *cache_dir); | |||
581 | ||||
538 | FcPrivate void | 582 | FcPrivate void | |
539 | FcCacheObjectReference (void *object); | 583 | FcCacheObjectReference (void *object); | |
540 | 584 | |||
541 | FcPrivate void | 585 | FcPrivate void | |
542 | FcCacheObjectDereference (void *object); | 586 | FcCacheObjectDereference (void *object); | |
543 | 587 | |||
544 | FcPrivate void | 588 | FcPrivate void | |
545 | FcCacheFini (void); | 589 | FcCacheFini (void); | |
546 | 590 | |||
547 | FcPrivate void | 591 | FcPrivate void | |
548 | FcDirCacheReference (FcCache *cache, int nref); | 592 | FcDirCacheReference (FcCache *cache, int nref); | |
549 | 593 | |||
550 | #ifdef _WIN32 | |||
551 | FcPrivate int | |||
552 | FcStat (const char *file, struct stat *statb); | |||
553 | #else | |||
554 | #define FcStat stat | |||
555 | #endif | |||
556 | ||||
557 | /* fccfg.c */ | 594 | /* fccfg.c */ | |
558 | 595 | |||
596 | FcPrivate FcChar8 * | |||
597 | FcConfigXdgCacheHome (void); | |||
598 | ||||
599 | FcPrivate FcChar8 * | |||
600 | FcConfigXdgConfigHome (void); | |||
601 | ||||
602 | FcPrivate FcChar8 * | |||
603 | FcConfigXdgDataHome (void); | |||
604 | ||||
559 | FcPrivate FcExpr * | 605 | FcPrivate FcExpr * | |
560 | FcConfigAllocExpr (FcConfig *config); | 606 | FcConfigAllocExpr (FcConfig *config); | |
561 | 607 | |||
562 | FcPrivate FcBool | 608 | FcPrivate FcBool | |
563 | FcConfigAddConfigDir (FcConfig *config, | 609 | FcConfigAddConfigDir (FcConfig *config, | |
564 | const FcChar8 *d); | 610 | const FcChar8 *d); | |
565 | 611 | |||
566 | FcPrivate FcBool | 612 | FcPrivate FcBool | |
567 | FcConfigAddFontDir (FcConfig *config, | 613 | FcConfigAddFontDir (FcConfig *config, | |
568 | const FcChar8 *d); | 614 | const FcChar8 *d); | |
569 | 615 | |||
570 | FcPrivate FcBool | 616 | FcPrivate FcBool | |
571 | FcConfigAddDir (FcConfig *config, | 617 | FcConfigAddDir (FcConfig *config, | |
@@ -611,33 +657,33 @@ FcConfigAcceptFilename (FcConfig *config | @@ -611,33 +657,33 @@ FcConfigAcceptFilename (FcConfig *config | |||
611 | FcPrivate FcBool | 657 | FcPrivate FcBool | |
612 | FcConfigPatternsAdd (FcConfig *config, | 658 | FcConfigPatternsAdd (FcConfig *config, | |
613 | FcPattern *pattern, | 659 | FcPattern *pattern, | |
614 | FcBool accept); | 660 | FcBool accept); | |
615 | 661 | |||
616 | FcPrivate FcBool | 662 | FcPrivate FcBool | |
617 | FcConfigAcceptFont (FcConfig *config, | 663 | FcConfigAcceptFont (FcConfig *config, | |
618 | const FcPattern *font); | 664 | const FcPattern *font); | |
619 | 665 | |||
620 | FcPrivate FcFileTime | 666 | FcPrivate FcFileTime | |
621 | FcConfigModifiedTime (FcConfig *config); | 667 | FcConfigModifiedTime (FcConfig *config); | |
622 | 668 | |||
623 | FcPrivate FcBool | 669 | FcPrivate FcBool | |
624 | FcConfigAddCache (FcConfig *config, FcCache *cache, | 670 | FcConfigAddCache (FcConfig *config, FcCache *cache, | |
625 | FcSetName set, FcStrSet *dirSet); | 671 | FcSetName set, FcStrSet *dirSet); | |
626 | 672 | |||
627 | /* fcserialize.c */ | 673 | /* fcserialize.c */ | |
628 | FcPrivate intptr_t | 674 | FcPrivate intptr_t | |
629 | FcAlignSize (intptr_t size); | 675 | FcAlignSize (intptr_t size); | |
630 | 676 | |||
631 | FcPrivate FcSerialize * | 677 | FcPrivate FcSerialize * | |
632 | FcSerializeCreate (void); | 678 | FcSerializeCreate (void); | |
633 | 679 | |||
634 | FcPrivate void | 680 | FcPrivate void | |
635 | FcSerializeDestroy (FcSerialize *serialize); | 681 | FcSerializeDestroy (FcSerialize *serialize); | |
636 | 682 | |||
637 | FcPrivate FcBool | 683 | FcPrivate FcBool | |
638 | FcSerializeAlloc (FcSerialize *serialize, const void *object, int size); | 684 | FcSerializeAlloc (FcSerialize *serialize, const void *object, int size); | |
639 | 685 | |||
640 | FcPrivate intptr_t | 686 | FcPrivate intptr_t | |
641 | FcSerializeReserve (FcSerialize *serialize, int size); | 687 | FcSerializeReserve (FcSerialize *serialize, int size); | |
642 | 688 | |||
643 | FcPrivate intptr_t | 689 | FcPrivate intptr_t | |
@@ -685,49 +731,55 @@ FcPrivate FcCharLeaf * | @@ -685,49 +731,55 @@ FcPrivate FcCharLeaf * | |||
685 | FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4); | 731 | FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4); | |
686 | 732 | |||
687 | FcPrivate FcBool | 733 | FcPrivate FcBool | |
688 | FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs); | 734 | FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs); | |
689 | 735 | |||
690 | FcPrivate FcCharSet * | 736 | FcPrivate FcCharSet * | |
691 | FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs); | 737 | FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs); | |
692 | 738 | |||
693 | FcPrivate FcChar16 * | 739 | FcPrivate FcChar16 * | |
694 | FcCharSetGetNumbers(const FcCharSet *c); | 740 | FcCharSetGetNumbers(const FcCharSet *c); | |
695 | 741 | |||
696 | /* fcdbg.c */ | 742 | /* fcdbg.c */ | |
697 | FcPrivate void | 743 | FcPrivate void | |
698 | FcValueListPrint (const FcValueListPtr l); | 744 | FcValuePrintWithPosition (const FcValue v, FcBool show_pos_mark); | |
745 | ||||
746 | FcPrivate void | |||
747 | FcValueListPrintWithPosition (FcValueListPtr l, const FcValueListPtr pos); | |||
748 | ||||
749 | FcPrivate void | |||
750 | FcValueListPrint (FcValueListPtr l); | |||
699 | 751 | |||
700 | FcPrivate void | 752 | FcPrivate void | |
701 | FcLangSetPrint (const FcLangSet *ls); | 753 | FcLangSetPrint (const FcLangSet *ls); | |
702 | 754 | |||
703 | FcPrivate void | 755 | FcPrivate void | |
704 | FcOpPrint (FcOp op); | 756 | FcOpPrint (FcOp op); | |
705 | 757 | |||
706 | FcPrivate void | 758 | FcPrivate void | |
707 | FcTestPrint (const FcTest *test); | 759 | FcTestPrint (const FcTest *test); | |
708 | 760 | |||
709 | FcPrivate void | 761 | FcPrivate void | |
710 | FcExprPrint (const FcExpr *expr); | 762 | FcExprPrint (const FcExpr *expr); | |
711 | 763 | |||
712 | FcPrivate void | 764 | FcPrivate void | |
713 | FcEditPrint (const FcEdit *edit); | 765 | FcEditPrint (const FcEdit *edit); | |
714 | 766 | |||
715 | FcPrivate void | 767 | FcPrivate void | |
716 | FcSubstPrint (const FcSubst *subst); | 768 | FcSubstPrint (const FcSubst *subst); | |
717 | 769 | |||
718 | FcPrivate void | 770 | FcPrivate void | |
719 | FcCharSetPrint (const FcCharSet *c); | 771 | FcCharSetPrint (const FcCharSet *c); | |
720 | 772 | |||
721 | extern FcPrivate int FcDebugVal; | 773 | extern FcPrivate int FcDebugVal; | |
722 | 774 | |||
723 | #define FcDebug() (FcDebugVal) | 775 | #define FcDebug() (FcDebugVal) | |
724 | 776 | |||
725 | FcPrivate void | 777 | FcPrivate void | |
726 | FcInitDebug (void); | 778 | FcInitDebug (void); | |
727 | 779 | |||
728 | /* fcdefault.c */ | 780 | /* fcdefault.c */ | |
729 | FcPrivate FcChar8 * | 781 | FcPrivate FcChar8 * | |
730 | FcGetDefaultLang (void); | 782 | FcGetDefaultLang (void); | |
731 | 783 | |||
732 | /* fcdir.c */ | 784 | /* fcdir.c */ | |
733 | 785 | |||
@@ -768,32 +820,35 @@ FcEditDestroy (FcEdit *e); | @@ -768,32 +820,35 @@ FcEditDestroy (FcEdit *e); | |||
768 | /* fcinit.c */ | 820 | /* fcinit.c */ | |
769 | 821 | |||
770 | FcPrivate void | 822 | FcPrivate void | |
771 | FcMemReport (void); | 823 | FcMemReport (void); | |
772 | 824 | |||
773 | FcPrivate void | 825 | FcPrivate void | |
774 | FcMemAlloc (int kind, int size); | 826 | FcMemAlloc (int kind, int size); | |
775 | 827 | |||
776 | FcPrivate void | 828 | FcPrivate void | |
777 | FcMemFree (int kind, int size); | 829 | FcMemFree (int kind, int size); | |
778 | 830 | |||
779 | /* fclang.c */ | 831 | /* fclang.c */ | |
780 | FcPrivate FcLangSet * | 832 | FcPrivate FcLangSet * | |
781 | FcFreeTypeLangSet (const FcCharSet *charset, | 833 | FcFreeTypeLangSet (const FcCharSet *charset, | |
782 | const FcChar8 *exclusiveLang); | 834 | const FcChar8 *exclusiveLang); | |
783 | 835 | |||
836 | FcPrivate FcChar8 * | |||
837 | FcLangNormalize (const FcChar8 *lang); | |||
838 | ||||
784 | FcPrivate FcLangResult | 839 | FcPrivate FcLangResult | |
785 | FcLangCompare (const FcChar8 *s1, const FcChar8 *s2); | 840 | FcLangCompare (const FcChar8 *s1, const FcChar8 *s2); | |
786 | 841 | |||
787 | FcPrivate FcLangSet * | 842 | FcPrivate FcLangSet * | |
788 | FcLangSetPromote (const FcChar8 *lang); | 843 | FcLangSetPromote (const FcChar8 *lang); | |
789 | 844 | |||
790 | FcPrivate FcLangSet * | 845 | FcPrivate FcLangSet * | |
791 | FcNameParseLangSet (const FcChar8 *string); | 846 | FcNameParseLangSet (const FcChar8 *string); | |
792 | 847 | |||
793 | FcPrivate FcBool | 848 | FcPrivate FcBool | |
794 | FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls); | 849 | FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls); | |
795 | 850 | |||
796 | FcPrivate FcChar8 * | 851 | FcPrivate FcChar8 * | |
797 | FcNameUnparseEscaped (FcPattern *pat, FcBool escape); | 852 | FcNameUnparseEscaped (FcPattern *pat, FcBool escape); | |
798 | 853 | |||
799 | /* fclist.c */ | 854 | /* fclist.c */ | |
@@ -820,49 +875,50 @@ FcListPatternMatchAny (const FcPattern * | @@ -820,49 +875,50 @@ FcListPatternMatchAny (const FcPattern * | |||
820 | #define FC_SLANT_OBJECT 7 | 875 | #define FC_SLANT_OBJECT 7 | |
821 | #define FC_WEIGHT_OBJECT 8 | 876 | #define FC_WEIGHT_OBJECT 8 | |
822 | #define FC_WIDTH_OBJECT 9 | 877 | #define FC_WIDTH_OBJECT 9 | |
823 | #define FC_SIZE_OBJECT 10 | 878 | #define FC_SIZE_OBJECT 10 | |
824 | #define FC_ASPECT_OBJECT 11 | 879 | #define FC_ASPECT_OBJECT 11 | |
825 | #define FC_PIXEL_SIZE_OBJECT 12 | 880 | #define FC_PIXEL_SIZE_OBJECT 12 | |
826 | #define FC_SPACING_OBJECT 13 | 881 | #define FC_SPACING_OBJECT 13 | |
827 | #define FC_FOUNDRY_OBJECT 14 | 882 | #define FC_FOUNDRY_OBJECT 14 | |
828 | #define FC_ANTIALIAS_OBJECT 15 | 883 | #define FC_ANTIALIAS_OBJECT 15 | |
829 | #define FC_HINT_STYLE_OBJECT 16 | 884 | #define FC_HINT_STYLE_OBJECT 16 | |
830 | #define FC_HINTING_OBJECT 17 | 885 | #define FC_HINTING_OBJECT 17 | |
831 | #define FC_VERTICAL_LAYOUT_OBJECT 18 | 886 | #define FC_VERTICAL_LAYOUT_OBJECT 18 | |
832 | #define FC_AUTOHINT_OBJECT 19 | 887 | #define FC_AUTOHINT_OBJECT 19 | |
833 | #define FC_GLOBAL_ADVANCE_OBJECT 20 | 888 | #define FC_GLOBAL_ADVANCE_OBJECT 20 /* deprecated */ | |
834 | #define FC_FILE_OBJECT 21 | 889 | #define FC_FILE_OBJECT 21 | |
835 | #define FC_INDEX_OBJECT 22 | 890 | #define FC_INDEX_OBJECT 22 | |
836 | #define FC_RASTERIZER_OBJECT 23 | 891 | #define FC_RASTERIZER_OBJECT 23 | |
837 | #define FC_OUTLINE_OBJECT 24 | 892 | #define FC_OUTLINE_OBJECT 24 | |
838 | #define FC_SCALABLE_OBJECT 25 | 893 | #define FC_SCALABLE_OBJECT 25 | |
839 | #define FC_DPI_OBJECT 26 | 894 | #define FC_DPI_OBJECT 26 | |
840 | #define FC_RGBA_OBJECT 27 | 895 | #define FC_RGBA_OBJECT 27 | |
841 | #define FC_SCALE_OBJECT 28 | 896 | #define FC_SCALE_OBJECT 28 | |
842 | #define FC_MINSPACE_OBJECT 29 | 897 | #define FC_MINSPACE_OBJECT 29 | |
843 | #define FC_CHAR_WIDTH_OBJECT 30 | 898 | #define FC_CHAR_WIDTH_OBJECT 30 | |
844 | #define FC_CHAR_HEIGHT_OBJECT 31 | 899 | #define FC_CHAR_HEIGHT_OBJECT 31 | |
845 | #define FC_MATRIX_OBJECT 32 | 900 | #define FC_MATRIX_OBJECT 32 | |
846 | #define FC_CHARSET_OBJECT 33 | 901 | #define FC_CHARSET_OBJECT 33 | |
847 | #define FC_LANG_OBJECT 34 | 902 | #define FC_LANG_OBJECT 34 | |
848 | #define FC_FONTVERSION_OBJECT 35 | 903 | #define FC_FONTVERSION_OBJECT 35 | |
849 | #define FC_CAPABILITY_OBJECT 36 | 904 | #define FC_CAPABILITY_OBJECT 36 | |
850 | #define FC_FONTFORMAT_OBJECT 37 | 905 | #define FC_FONTFORMAT_OBJECT 37 | |
851 | #define FC_EMBOLDEN_OBJECT 38 | 906 | #define FC_EMBOLDEN_OBJECT 38 | |
852 | #define FC_EMBEDDED_BITMAP_OBJECT 39 | 907 | #define FC_EMBEDDED_BITMAP_OBJECT 39 | |
853 | #define FC_DECORATIVE_OBJECT 40 | 908 | #define FC_DECORATIVE_OBJECT 40 | |
854 | #define FC_LCD_FILTER_OBJECT 41 | 909 | #define FC_LCD_FILTER_OBJECT 41 | |
855 | #define FC_MAX_BASE_OBJECT FC_LCD_FILTER_OBJECT | 910 | #define FC_NAMELANG_OBJECT 42 | |
911 | #define FC_MAX_BASE_OBJECT FC_NAMELANG_OBJECT | |||
856 | 912 | |||
857 | FcPrivate FcBool | 913 | FcPrivate FcBool | |
858 | FcNameBool (const FcChar8 *v, FcBool *result); | 914 | FcNameBool (const FcChar8 *v, FcBool *result); | |
859 | 915 | |||
860 | FcPrivate FcBool | 916 | FcPrivate FcBool | |
861 | FcObjectValidType (FcObject object, FcType type); | 917 | FcObjectValidType (FcObject object, FcType type); | |
862 | 918 | |||
863 | FcPrivate FcObject | 919 | FcPrivate FcObject | |
864 | FcObjectFromName (const char * name); | 920 | FcObjectFromName (const char * name); | |
865 | 921 | |||
866 | FcPrivate const char * | 922 | FcPrivate const char * | |
867 | FcObjectName (FcObject object); | 923 | FcObjectName (FcObject object); | |
868 | 924 | |||
@@ -872,51 +928,73 @@ FcObjectGetSet (void); | @@ -872,51 +928,73 @@ FcObjectGetSet (void); | |||
872 | FcPrivate FcBool | 928 | FcPrivate FcBool | |
873 | FcObjectInit (void); | 929 | FcObjectInit (void); | |
874 | 930 | |||
875 | FcPrivate void | 931 | FcPrivate void | |
876 | FcObjectFini (void); | 932 | FcObjectFini (void); | |
877 | 933 | |||
878 | #define FcObjectCompare(a, b) ((int) a - (int) b) | 934 | #define FcObjectCompare(a, b) ((int) a - (int) b) | |
879 | 935 | |||
880 | /* fcpat.c */ | 936 | /* fcpat.c */ | |
881 | 937 | |||
882 | FcPrivate FcValue | 938 | FcPrivate FcValue | |
883 | FcValueCanonicalize (const FcValue *v); | 939 | FcValueCanonicalize (const FcValue *v); | |
884 | 940 | |||
941 | FcPrivate FcValueListPtr | |||
942 | FcValueListCreate (void); | |||
943 | ||||
885 | FcPrivate void | 944 | FcPrivate void | |
886 | FcValueListDestroy (FcValueListPtr l); | 945 | FcValueListDestroy (FcValueListPtr l); | |
887 | 946 | |||
947 | FcPrivate FcValueListPtr | |||
948 | FcValueListPrepend (FcValueListPtr vallist, | |||
949 | FcValue value, | |||
950 | FcValueBinding binding); | |||
951 | ||||
952 | FcPrivate FcValueListPtr | |||
953 | FcValueListAppend (FcValueListPtr vallist, | |||
954 | FcValue value, | |||
955 | FcValueBinding binding); | |||
956 | ||||
957 | FcPrivate FcValueListPtr | |||
958 | FcValueListDuplicate(FcValueListPtr orig); | |||
959 | ||||
888 | FcPrivate FcPatternElt * | 960 | FcPrivate FcPatternElt * | |
889 | FcPatternObjectFindElt (const FcPattern *p, FcObject object); | 961 | FcPatternObjectFindElt (const FcPattern *p, FcObject object); | |
890 | 962 | |||
891 | FcPrivate FcPatternElt * | 963 | FcPrivate FcPatternElt * | |
892 | FcPatternObjectInsertElt (FcPattern *p, FcObject object); | 964 | FcPatternObjectInsertElt (FcPattern *p, FcObject object); | |
893 | 965 | |||
894 | FcPrivate FcBool | 966 | FcPrivate FcBool | |
967 | FcPatternObjectListAdd (FcPattern *p, | |||
968 | FcObject object, | |||
969 | FcValueListPtr list, | |||
970 | FcBool append); | |||
971 | ||||
972 | FcPrivate FcBool | |||
895 | FcPatternObjectAddWithBinding (FcPattern *p, | 973 | FcPatternObjectAddWithBinding (FcPattern *p, | |
896 | FcObject object, | 974 | FcObject object, | |
897 | FcValue value, | 975 | FcValue value, | |
898 | FcValueBinding binding, | 976 | FcValueBinding binding, | |
899 | FcBool append); | 977 | FcBool append); | |
900 | 978 | |||
901 | FcPrivate FcBool | 979 | FcPrivate FcBool | |
902 | FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append); | 980 | FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append); | |
903 | 981 | |||
904 | FcPrivate FcBool | 982 | FcPrivate FcBool | |
905 | FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append); | 983 | FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append); | |
906 | 984 | |||
907 | FcPrivate FcResult | 985 | FcPrivate FcResult | |
908 | FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v); | 986 | FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v); | |
909 | 987 | |||
910 | FcPrivate FcBool | 988 | FcPrivate FcBool | |
911 | FcPatternObjectDel (FcPattern *p, FcObject object); | 989 | FcPatternObjectDel (FcPattern *p, FcObject object); | |
912 | 990 | |||
913 | FcPrivate FcBool | 991 | FcPrivate FcBool | |
914 | FcPatternObjectRemove (FcPattern *p, FcObject object, int id); | 992 | FcPatternObjectRemove (FcPattern *p, FcObject object, int id); | |
915 | 993 | |||
916 | FcPrivate FcBool | 994 | FcPrivate FcBool | |
917 | FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i); | 995 | FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i); | |
918 | 996 | |||
919 | FcPrivate FcBool | 997 | FcPrivate FcBool | |
920 | FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d); | 998 | FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d); | |
921 | 999 | |||
922 | FcPrivate FcBool | 1000 | FcPrivate FcBool | |
@@ -945,60 +1023,77 @@ FcPatternObjectGetString (const FcPatter | @@ -945,60 +1023,77 @@ FcPatternObjectGetString (const FcPatter | |||
945 | 1023 | |||
946 | FcPrivate FcResult | 1024 | FcPrivate FcResult | |
947 | FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s); | 1025 | FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s); | |
948 | 1026 | |||
949 | FcPrivate FcResult | 1027 | FcPrivate FcResult | |
950 | FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c); | 1028 | FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c); | |
951 | 1029 | |||
952 | FcPrivate FcResult | 1030 | FcPrivate FcResult | |
953 | FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); | 1031 | FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); | |
954 | 1032 | |||
955 | FcPrivate FcResult | 1033 | FcPrivate FcResult | |
956 | FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls); | 1034 | FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls); | |
957 | 1035 | |||
958 | FcPrivate void | |||
959 | FcPatternFini (void); | |||
960 | ||||
961 | FcPrivate FcBool | 1036 | FcPrivate FcBool | |
962 | FcPatternAppend (FcPattern *p, FcPattern *s); | 1037 | FcPatternAppend (FcPattern *p, FcPattern *s); | |
963 | 1038 | |||
964 | FcPrivate const FcChar8 * | 1039 | FcPrivate const FcChar8 * | |
965 | FcStrStaticName (const FcChar8 *name); | 1040 | FcSharedStr (const FcChar8 *name); | |
1041 | ||||
1042 | FcPrivate FcBool | |||
1043 | FcSharedStrFree (const FcChar8 *name); | |||
966 | 1044 | |||
967 | FcPrivate FcChar32 | 1045 | FcPrivate FcChar32 | |
968 | FcStringHash (const FcChar8 *s); | 1046 | FcStringHash (const FcChar8 *s); | |
969 | 1047 | |||
970 | FcPrivate FcBool | 1048 | FcPrivate FcBool | |
971 | FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat); | 1049 | FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat); | |
972 | 1050 | |||
973 | FcPrivate FcPattern * | 1051 | FcPrivate FcPattern * | |
974 | FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat); | 1052 | FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat); | |
975 | 1053 | |||
976 | FcPrivate FcBool | 1054 | FcPrivate FcBool | |
977 | FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat); | 1055 | FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat); | |
978 | 1056 | |||
979 | FcPrivate FcValueList * | 1057 | FcPrivate FcValueList * | |
980 | FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat); | 1058 | FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat); | |
981 | 1059 | |||
982 | /* fcrender.c */ | 1060 | /* fcrender.c */ | |
983 | 1061 | |||
984 | /* fcmatrix.c */ | 1062 | /* fcmatrix.c */ | |
985 | 1063 | |||
986 | extern FcPrivate const FcMatrix FcIdentityMatrix; | 1064 | extern FcPrivate const FcMatrix FcIdentityMatrix; | |
987 | 1065 | |||
988 | FcPrivate void | 1066 | FcPrivate void | |
989 | FcMatrixFree (FcMatrix *mat); | 1067 | FcMatrixFree (FcMatrix *mat); | |
990 | 1068 | |||
1069 | /* fcstat.c */ | |||
1070 | ||||
1071 | FcPrivate int | |||
1072 | FcStat (const FcChar8 *file, struct stat *statb); | |||
1073 | ||||
1074 | FcPrivate int | |||
1075 | FcStatChecksum (const FcChar8 *file, struct stat *statb); | |||
1076 | ||||
1077 | FcPrivate FcBool | |||
1078 | FcIsFsMmapSafe (int fd); | |||
1079 | ||||
1080 | FcPrivate FcBool | |||
1081 | FcIsFsMtimeBroken (const FcChar8 *dir); | |||
1082 | ||||
991 | /* fcstr.c */ | 1083 | /* fcstr.c */ | |
1084 | FcPrivate FcBool | |||
1085 | FcStrSetAddLangs (FcStrSet *strs, const char *languages); | |||
1086 | ||||
992 | FcPrivate void | 1087 | FcPrivate void | |
993 | FcStrSetSort (FcStrSet * set); | 1088 | FcStrSetSort (FcStrSet * set); | |
994 | 1089 | |||
995 | FcPrivate void | 1090 | FcPrivate void | |
996 | FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size); | 1091 | FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size); | |
997 | 1092 | |||
998 | FcPrivate void | 1093 | FcPrivate void | |
999 | FcStrBufDestroy (FcStrBuf *buf); | 1094 | FcStrBufDestroy (FcStrBuf *buf); | |
1000 | 1095 | |||
1001 | FcPrivate FcChar8 * | 1096 | FcPrivate FcChar8 * | |
1002 | FcStrBufDone (FcStrBuf *buf); | 1097 | FcStrBufDone (FcStrBuf *buf); | |
1003 | 1098 | |||
1004 | FcPrivate FcChar8 * | 1099 | FcPrivate FcChar8 * | |
@@ -1006,26 +1101,32 @@ FcStrBufDoneStatic (FcStrBuf *buf); | @@ -1006,26 +1101,32 @@ FcStrBufDoneStatic (FcStrBuf *buf); | |||
1006 | 1101 | |||
1007 | FcPrivate FcBool | 1102 | FcPrivate FcBool | |
1008 | FcStrBufChar (FcStrBuf *buf, FcChar8 c); | 1103 | FcStrBufChar (FcStrBuf *buf, FcChar8 c); | |
1009 | 1104 | |||
1010 | FcPrivate FcBool | 1105 | FcPrivate FcBool | |
1011 | FcStrBufString (FcStrBuf *buf, const FcChar8 *s); | 1106 | FcStrBufString (FcStrBuf *buf, const FcChar8 *s); | |
1012 | 1107 | |||
1013 | FcPrivate FcBool | 1108 | FcPrivate FcBool | |
1014 | FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len); | 1109 | FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len); | |
1015 | 1110 | |||
1016 | FcPrivate int | 1111 | FcPrivate int | |
1017 | FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); | 1112 | FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); | |
1018 | 1113 | |||
1114 | FcPrivate FcBool | |||
1115 | FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex); | |||
1116 | ||||
1117 | FcPrivate FcBool | |||
1118 | FcStrRegexCmpIgnoreCase (const FcChar8 *s, const FcChar8 *regex); | |||
1119 | ||||
1019 | FcPrivate const FcChar8 * | 1120 | FcPrivate const FcChar8 * | |
1020 | FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); | 1121 | FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); | |
1021 | 1122 | |||
1022 | FcPrivate const FcChar8 * | 1123 | FcPrivate const FcChar8 * | |
1023 | FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); | 1124 | FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); | |
1024 | 1125 | |||
1025 | FcPrivate const FcChar8 * | 1126 | FcPrivate const FcChar8 * | |
1026 | FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2); | 1127 | FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2); | |
1027 | 1128 | |||
1028 | FcPrivate FcBool | 1129 | FcPrivate FcBool | |
1029 | FcStrUsesHome (const FcChar8 *s); | 1130 | FcStrUsesHome (const FcChar8 *s); | |
1030 | 1131 | |||
1031 | FcPrivate FcChar8 * | 1132 | FcPrivate FcChar8 * |
--- xsrc/external/mit/fontconfig/dist/src/ftglue.c 2010/11/21 06:50:47 1.3
+++ xsrc/external/mit/fontconfig/dist/src/ftglue.c 2013/06/03 06:04:33 1.4
@@ -8,27 +8,27 @@ | @@ -8,27 +8,27 @@ | |||
8 | * See ftglue.h for more information. | 8 | * See ftglue.h for more information. | |
9 | */ | 9 | */ | |
10 | 10 | |||
11 | #include "ftglue.h" | 11 | #include "ftglue.h" | |
12 | 12 | |||
13 | #if 0 | 13 | #if 0 | |
14 | #include <stdio.h> | 14 | #include <stdio.h> | |
15 | #define LOG(x) ftglue_log x | 15 | #define LOG(x) ftglue_log x | |
16 | 16 | |||
17 | static void | 17 | static void | |
18 | ftglue_log( const char* format, ... ) | 18 | ftglue_log( const char* format, ... ) | |
19 | { | 19 | { | |
20 | va_list ap; | 20 | va_list ap; | |
21 | 21 | |||
22 | va_start( ap, format ); | 22 | va_start( ap, format ); | |
23 | vfprintf( stderr, format, ap ); | 23 | vfprintf( stderr, format, ap ); | |
24 | va_end( ap ); | 24 | va_end( ap ); | |
25 | } | 25 | } | |
26 | 26 | |||
27 | #else | 27 | #else | |
28 | #define LOG(x) do {} while (0) | 28 | #define LOG(x) do {} while (0) | |
29 | #endif | 29 | #endif | |
30 | 30 | |||
31 | #undef read /* XXX: SSP/FORTIFY */ | 31 | #undef read /* XXX: SSP/FORTIFY */ | |
32 | 32 | |||
33 | /* only used internally */ | 33 | /* only used internally */ | |
34 | static FT_Pointer | 34 | static FT_Pointer | |
@@ -74,35 +74,36 @@ FTGLUE_APIDEF( FT_Long ) | @@ -74,35 +74,36 @@ FTGLUE_APIDEF( FT_Long ) | |||
74 | ftglue_stream_pos( FT_Stream stream ) | 74 | ftglue_stream_pos( FT_Stream stream ) | |
75 | { | 75 | { | |
76 | LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos )); | 76 | LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos )); | |
77 | return stream->pos; | 77 | return stream->pos; | |
78 | } | 78 | } | |
79 | 79 | |||
80 | 80 | |||
81 | FTGLUE_APIDEF( FT_Error ) | 81 | FTGLUE_APIDEF( FT_Error ) | |
82 | ftglue_stream_seek( FT_Stream stream, | 82 | ftglue_stream_seek( FT_Stream stream, | |
83 | FT_Long pos ) | 83 | FT_Long pos ) | |
84 | { | 84 | { | |
85 | FT_Error error = 0; | 85 | FT_Error error = 0; | |
86 | 86 | |||
87 | stream->pos = pos; | |||
88 | if ( stream->read ) | 87 | if ( stream->read ) | |
89 | { | 88 | { | |
90 | if ( stream->read( stream, pos, 0, 0 ) ) | 89 | if ( stream->read( stream, pos, 0, 0 ) ) | |
91 | error = FT_Err_Invalid_Stream_Operation; | 90 | error = FT_Err_Invalid_Stream_Operation; | |
92 | } | 91 | } | |
93 | else if ( pos > stream->size ) | 92 | else if ( pos > stream->size ) | |
94 | error = FT_Err_Invalid_Stream_Operation; | 93 | error = FT_Err_Invalid_Stream_Operation; | |
95 | 94 | |||
95 | if ( !error ) | |||
96 | stream->pos = pos; | |||
96 | LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error )); | 97 | LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error )); | |
97 | return error; | 98 | return error; | |
98 | } | 99 | } | |
99 | 100 | |||
100 | 101 | |||
101 | FTGLUE_APIDEF( FT_Error ) | 102 | FTGLUE_APIDEF( FT_Error ) | |
102 | ftglue_stream_frame_enter( FT_Stream stream, | 103 | ftglue_stream_frame_enter( FT_Stream stream, | |
103 | FT_ULong count ) | 104 | FT_ULong count ) | |
104 | { | 105 | { | |
105 | FT_Error error = FT_Err_Ok; | 106 | FT_Error error = FT_Err_Ok; | |
106 | FT_ULong read_bytes; | 107 | FT_ULong read_bytes; | |
107 | 108 | |||
108 | if ( stream->read ) | 109 | if ( stream->read ) | |
@@ -162,30 +163,30 @@ ftglue_stream_frame_exit( FT_Stream str | @@ -162,30 +163,30 @@ ftglue_stream_frame_exit( FT_Stream str | |||
162 | 163 | |||
163 | LOG(( "ftglue:stream:frame_exit()\n" )); | 164 | LOG(( "ftglue:stream:frame_exit()\n" )); | |
164 | } | 165 | } | |
165 | 166 | |||
166 | 167 | |||
167 | FTGLUE_APIDEF( FT_Error ) | 168 | FTGLUE_APIDEF( FT_Error ) | |
168 | ftglue_face_goto_table( FT_Face face, | 169 | ftglue_face_goto_table( FT_Face face, | |
169 | FT_ULong the_tag, | 170 | FT_ULong the_tag, | |
170 | FT_Stream stream ) | 171 | FT_Stream stream ) | |
171 | { | 172 | { | |
172 | FT_Error error; | 173 | FT_Error error; | |
173 | 174 | |||
174 | LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n", | 175 | LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n", | |
175 | face, | 176 | face, | |
176 | (int)((the_tag >> 24) & 0xFF), | 177 | (int)((the_tag >> 24) & 0xFF), | |
177 | (int)((the_tag >> 16) & 0xFF), | 178 | (int)((the_tag >> 16) & 0xFF), | |
178 | (int)((the_tag >> 8) & 0xFF), | 179 | (int)((the_tag >> 8) & 0xFF), | |
179 | (int)(the_tag & 0xFF), | 180 | (int)(the_tag & 0xFF), | |
180 | stream )); | 181 | stream )); | |
181 | 182 | |||
182 | if ( !FT_IS_SFNT(face) ) | 183 | if ( !FT_IS_SFNT(face) ) | |
183 | { | 184 | { | |
184 | LOG(( "not a SFNT face !!\n" )); | 185 | LOG(( "not a SFNT face !!\n" )); | |
185 | error = FT_Err_Invalid_Face_Handle; | 186 | error = FT_Err_Invalid_Face_Handle; | |
186 | } | 187 | } | |
187 | else | 188 | else | |
188 | { | 189 | { | |
189 | /* parse the directory table directly, without using | 190 | /* parse the directory table directly, without using | |
190 | * FreeType's built-in data structures | 191 | * FreeType's built-in data structures | |
191 | */ | 192 | */ | |
@@ -227,37 +228,37 @@ ftglue_face_goto_table( FT_Face face, | @@ -227,37 +228,37 @@ ftglue_face_goto_table( FT_Face face, | |||
227 | if ( FILE_Seek( offset+12 ) || | 228 | if ( FILE_Seek( offset+12 ) || | |
228 | ACCESS_Frame( count*16 ) ) | 229 | ACCESS_Frame( count*16 ) ) | |
229 | goto Exit; | 230 | goto Exit; | |
230 | 231 | |||
231 | for ( nn = 0; nn < count; nn++ ) | 232 | for ( nn = 0; nn < count; nn++ ) | |
232 | { | 233 | { | |
233 | FT_ULong tag = GET_ULong(); | 234 | FT_ULong tag = GET_ULong(); | |
234 | FT_ULong checksum = GET_ULong(); | 235 | FT_ULong checksum = GET_ULong(); | |
235 | FT_ULong start = GET_ULong(); | 236 | FT_ULong start = GET_ULong(); | |
236 | FT_ULong size = GET_ULong(); | 237 | FT_ULong size = GET_ULong(); | |
237 | 238 | |||
238 | FT_UNUSED(checksum); | 239 | FT_UNUSED(checksum); | |
239 | FT_UNUSED(size); | 240 | FT_UNUSED(size); | |
240 | 241 | |||
241 | if ( tag == the_tag ) | 242 | if ( tag == the_tag ) | |
242 | { | 243 | { | |
243 | LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size )); | 244 | LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size )); | |
244 | error = ftglue_stream_seek( stream, start ); | 245 | error = ftglue_stream_seek( stream, start ); | |
245 | goto FoundIt; | 246 | goto FoundIt; | |
246 | } | 247 | } | |
247 | } | 248 | } | |
248 | error = FT_Err_Table_Missing; | 249 | error = FT_Err_Table_Missing; | |
249 | 250 | |||
250 | FoundIt: | 251 | FoundIt: | |
251 | FORGET_Frame(); | 252 | FORGET_Frame(); | |
252 | } | 253 | } | |
253 | 254 | |||
254 | Exit: | 255 | Exit: | |
255 | LOG(( "TrueType error=%d\n", error )); | 256 | LOG(( "TrueType error=%d\n", error )); | |
256 | 257 | |||
257 | return error; | 258 | return error; | |
258 | } | 259 | } | |
259 | 260 | |||
260 | #undef QALLOC | 261 | #undef QALLOC | |
261 | #define __ftglue__ | 262 | #define __ftglue__ | |
262 | #include "fcaliastail.h" | 263 | #include "fcaliastail.h" | |
263 | #undef __ftglue__ | 264 | #undef __ftglue__ |