Mon Jun 3 06:04:33 2013 UTC ()
merge fontconfig 2.10.2


(mrg)
diff -r1.1.1.1 -r0 xsrc/external/mit/fontconfig/dist/acinclude.m4
diff -r1.1.1.2 -r0 xsrc/external/mit/fontconfig/dist/configure.in
diff -r1.1.1.1 -r0 xsrc/external/mit/fontconfig/dist/conf.d/20-fix-globaladvance.conf
diff -r1.1.1.1 -r0 xsrc/external/mit/fontconfig/dist/doc/FcLangSetGetLangs.3
diff -r1.1.1.1 -r0 xsrc/external/mit/fontconfig/dist/doc/fontconfig-devel/fclangsetgetlangs.html
diff -r1.1.1.2 -r0 xsrc/external/mit/fontconfig/dist/fc-arch/Makefile.am
diff -r1.1.1.2 -r0 xsrc/external/mit/fontconfig/dist/fc-arch/Makefile.in
diff -r1.1.1.2 -r0 xsrc/external/mit/fontconfig/dist/fc-arch/fc-arch.c
diff -r1.1.1.2 -r0 xsrc/external/mit/fontconfig/dist/fc-arch/fcarch.tmpl.h
diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/fc-cache/fc-cache.c
diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/src/fccache.c
diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/src/fcmatch.c
diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/src/fcname.c
diff -r1.3 -r1.4 xsrc/external/mit/fontconfig/dist/src/fcint.h
diff -r1.3 -r1.4 xsrc/external/mit/fontconfig/dist/src/ftglue.c

File Deleted: xsrc/external/mit/fontconfig/dist/Attic/acinclude.m4

File Deleted: xsrc/external/mit/fontconfig/dist/Attic/configure.in

File Deleted: xsrc/external/mit/fontconfig/dist/conf.d/Attic/20-fix-globaladvance.conf

File Deleted: xsrc/external/mit/fontconfig/dist/doc/FcLangSetGetLangs.3

File Deleted: xsrc/external/mit/fontconfig/dist/doc/fontconfig-devel/fclangsetgetlangs.html

File Deleted: xsrc/external/mit/fontconfig/dist/fc-arch/Attic/Makefile.am

File Deleted: xsrc/external/mit/fontconfig/dist/fc-arch/Attic/Makefile.in

File Deleted: xsrc/external/mit/fontconfig/dist/fc-arch/Attic/fc-arch.c

File Deleted: xsrc/external/mit/fontconfig/dist/fc-arch/Attic/fcarch.tmpl.h

cvs diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/fc-cache/fc-cache.c (expand / switch to unified diff)

--- 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
120static FcStrSet *processed_dirs; 118static FcStrSet *processed_dirs;
121 119
122static int 120static int
123scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose) 121scanDirs (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
253static FcBool 252static FcBool
254cleanCacheDirectory (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 
343static FcBool 
344cleanCacheDirectories (FcConfig *config, FcBool verbose) 253cleanCacheDirectories (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
364int 273int
365main (int argc, char **argv) 274main (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}

cvs diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/src/fccache.c (expand / switch to unified diff)

--- 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
44struct MD5Context { 46struct 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
50static void MD5Init(struct MD5Context *ctx); 52static void MD5Init(struct MD5Context *ctx);
51static void MD5Update(struct MD5Context *ctx, const unsigned char *buf, unsigned len); 53static void MD5Update(struct MD5Context *ctx, const unsigned char *buf, unsigned len);
52static void MD5Final(unsigned char digest[16], struct MD5Context *ctx); 54static void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
53static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]); 55static 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 59static FcBool
58 60FcCacheIsMmapSafe (int fd)
59#include <windows.h> 
60 
61#ifdef __GNUC__ 
62typedef long long INT64; 
63#define EPOCH_OFFSET 11644473600ll 
64#else 
65#define EPOCH_OFFSET 11644473600i64 
66typedef __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 
88int 
89FcStat (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
136static const char bin2hex[] = { '0', '1', '2', '3', 84static 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
141static FcChar8 * 89static FcChar8 *
142FcDirCacheBasename (const FcChar8 * dir, FcChar8 cache_base[CACHEBASE_LEN]) 90FcDirCacheBasename (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 */
223static FcBool 171static FcBool
224FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,  172FcDirCacheProcess (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
278typedef struct _FcCacheSkip FcCacheSkip; 226typedef 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
297static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL]; 245static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL];
298static int fcCacheMaxLevel; 246static int fcCacheMaxLevel;
299 247
300#if HAVE_RANDOM 248
301# define FcRandom() random() 249static int32_t
 250FcRandom(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 */
317static int 310static int
318random_level (void) 311random_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
397static FcCacheSkip * 390static FcCacheSkip *
398FcCacheFindByAddr (void *object) 391FcCacheFindByAddr (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
511static FcBool 504static FcBool
512FcCacheTimeValid (FcCache *cache, struct stat *dir_stat) 505FcCacheTimeValid (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 */
531static FcCache * 524static FcCache *
532FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) 525FcDirCacheMapFd (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 */
672static FcBool 668static FcBool
673FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) 669FcDirCacheValidateHelper (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
691static FcBool 687static FcBool
692FcDirCacheValidConfig (const FcChar8 *dir, FcConfig *config) 688FcDirCacheValidConfig (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
699FcBool 695FcBool
700FcDirCacheValid (const FcChar8 *dir) 696FcDirCacheValid (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 */
714FcCache * 710FcCache *
715FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs) 711FcDirCacheBuild (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
803bail2: 797bail2:
804 free (cache); 798 free (cache);
805bail1: 799bail1:
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
815static FcBool 809static FcBool
816FcMakeDirectory (const FcChar8 *dir) 810FcMakeDirectory (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
 964FcBool
 965FcDirCacheClean (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
973const FcChar8 * 1062const FcChar8 *
974FcCacheDir args1(const FcCache *c) 1063FcCacheDir args1(const FcCache *c)
975{ 1064{
976 return FcCacheDir (c); 1065 return FcCacheDir (c);
977} 1066}
978 1067
979FcFontSet * 1068FcFontSet *
980FcCacheCopySet args1(const FcCache *c) 1069FcCacheCopySet 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 */
1122static void MD5Final(unsigned char digest[16], struct MD5Context *ctx) 1211static 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
 1353FcBool
 1354FcDirCacheCreateTagFile (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
 1415void
 1416FcCacheCreateTagFile (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__

cvs diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/src/fcmatch.c (expand / switch to unified diff)

--- 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
31static double 32static double
32FcCompareNumber (FcValue *value1, FcValue *value2) 33FcCompareNumber (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
62static double 63static double
63FcCompareString (FcValue *v1, FcValue *v2) 64FcCompareString (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
68static double 69static double
69FcCompareFamily (FcValue *v1, FcValue *v2) 70FcCompareFamily (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
83static double 84static double
84FcCompareLang (FcValue *v1, FcValue *v2) 85FcCompareLang (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
 178static double
 179FcCompareFilename (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
177typedef struct _FcMatcher { 194typedef 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 */
188static const FcMatcher _FcMatchers [] = { 205static 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
224static const FcMatcher* 243static const FcMatcher*
225FcObjectToMatcher (FcObject object) 244FcObjectToMatcher (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
269static FcBool 301static FcBool
270FcCompareValueList (FcObject object, 302FcCompareValueList (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
351static FcBool 390static FcBool
352FcCompare (FcPattern *pat, 391FcCompare (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
388FcPattern * 428FcPattern *
389FcFontRenderPrepare (FcConfig *config, 429FcFontRenderPrepare (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
509FcPattern * 641FcPattern *
510FcFontSetMatch (FcConfig *config, 642FcFontSetMatch (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
531FcPattern * 669FcPattern *
532FcFontMatch (FcConfig *config, 670FcFontMatch (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
808bail2: 967bail2:
809 FcFontSetDestroy (ret); 968 FcFontSetDestroy (ret);
810bail1: 969bail1:
811 free (nodes); 970 free (nodes);
812bail0: 971bail0:
813 return 0; 972 return 0;
814} 973}
815 974
816FcFontSet * 975FcFontSet *
817FcFontSort (FcConfig *config, 976FcFontSort (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}

cvs diff -r1.2 -r1.3 xsrc/external/mit/fontconfig/dist/src/fcname.c (expand / switch to unified diff)

--- 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
37static const FcObjectType _FcBaseObjectTypes[] = { 37static 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
83typedef struct _FcObjectTypeList FcObjectTypeList; 84typedef struct _FcObjectTypeList FcObjectTypeList;
84 85
85struct _FcObjectTypeList { 86struct _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
91static const FcObjectTypeList _FcBaseObjectTypesList = { 92static 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
286const FcObjectType * 287const FcObjectType *
287FcNameGetObjectType (const char *object) 288FcNameGetObjectType (const char *object)
288{ 289{
289 return FcObjectFindByName (object, FcFalse); 290 return FcObjectFindByName (object, FcFalse);
290} 291}
291 292
292FcBool 293FcBool
293FcObjectValidType (FcObject object, FcType type) 294FcObjectValidType (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
320FcObject 319FcObject
321FcObjectFromName (const char * name) 320FcObjectFromName (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
493FcBool 492FcBool
494FcNameUnregisterConstants (const FcConstant *consts, int nconsts) 493FcNameUnregisterConstants (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
513const FcConstant * 512const FcConstant *
514FcNameGetConstant (FcChar8 *string) 513FcNameGetConstant (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
528FcBool 527FcBool
529FcNameConstant (FcChar8 *string, int *result) 528FcNameConstant (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
541FcBool 540FcBool
542FcNameBool (const FcChar8 *v, FcBool *result) 541FcNameBool (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
576static FcValue 575static FcValue
577FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m) 576FcNameConvert (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
619static const FcChar8 * 619static const FcChar8 *
620FcNameFindNext (const FcChar8 *cur, const char *delim, FcChar8 *save, FcChar8 *last) 620FcNameFindNext (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
644FcPattern * 644FcPattern *
645FcNameParse (const FcChar8 *name) 645FcNameParse (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
760bail2: 741bail2:
761 FcPatternDestroy (pat); 742 FcPatternDestroy (pat);
762bail1: 743bail1:
763 free (save); 744 free (save);
764bail0: 745bail0:
765 return 0; 746 return 0;
766} 747}
767static FcBool 748static FcBool
768FcNameUnparseString (FcStrBuf *buf,  749FcNameUnparseString (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
786FcBool 767FcBool
787FcNameUnparseValue (FcStrBuf *buf, 768FcNameUnparseValue (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
821FcBool 802FcBool
@@ -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);
897bail0: 877bail0:
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__

cvs diff -r1.3 -r1.4 xsrc/external/mit/fontconfig/dist/src/fcint.h (expand / switch to unified diff)

--- 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>
 79typedef UINT (WINAPI *pfnGetSystemWindowsDirectory)(LPSTR, UINT);
 80typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
 81extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory;
 82extern 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
140typedef enum _FcValueBinding { 158typedef 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
190typedef struct _FcValueList *FcValueListPtr; 208typedef struct _FcValueList *FcValueListPtr;
191 209
192typedef struct _FcValueList { 210typedef 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
200typedef int FcObject; 218typedef int FcObject;
201 219
202typedef struct _FcPatternElt *FcPatternEltPtr; 220typedef 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 */
209typedef struct _FcPatternElt { 227typedef 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
216struct _FcPattern { 234struct _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
233typedef enum _FcOp { 251typedef 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
 266typedef 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
248typedef struct _FcExpr { 274typedef 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
265typedef struct _FcExprPage FcExprPage; 292typedef struct _FcExprPage FcExprPage;
266 293
267struct _FcExprPage { 294struct _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
274typedef enum _FcQual { 301typedef 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
280typedef struct _FcTest { 307typedef 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
343struct _FcCache { 370struct _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
383typedef struct _FcCharSetFreezer FcCharSetFreezer; 410typedef struct _FcCharSetFreezer FcCharSetFreezer;
384 411
385typedef struct _FcSerialize { 412typedef 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
397typedef struct _FcGlyphName { 424typedef 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
516extern FcPrivate FcConfig *_fcConfig; 543extern FcPrivate FcConfig *_fcConfig;
517 544
518typedef struct _FcFileTime { 545typedef struct _FcFileTime {
519 time_t time; 546 time_t time;
520 FcBool set; 547 FcBool set;
521} FcFileTime; 548} FcFileTime;
522 549
523typedef struct _FcCharMap FcCharMap; 550typedef struct _FcCharMap FcCharMap;
524 551
 552typedef struct _FcRange FcRange;
 553
 554struct _FcRange {
 555 FcChar32 begin;
 556 FcChar32 end;
 557};
 558
 559typedef struct _FcStatFS FcStatFS;
 560
 561struct _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
529FcPrivate FcCache * 570FcPrivate FcCache *
530FcDirCacheScan (const FcChar8 *dir, FcConfig *config); 571FcDirCacheScan (const FcChar8 *dir, FcConfig *config);
531 572
532FcPrivate FcCache * 573FcPrivate FcCache *
533FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs); 574FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs);
534 575
535FcPrivate FcBool 576FcPrivate FcBool
536FcDirCacheWrite (FcCache *cache, FcConfig *config); 577FcDirCacheWrite (FcCache *cache, FcConfig *config);
537  578
 579FcPrivate FcBool
 580FcDirCacheCreateTagFile (const FcChar8 *cache_dir);
 581
538FcPrivate void 582FcPrivate void
539FcCacheObjectReference (void *object); 583FcCacheObjectReference (void *object);
540 584
541FcPrivate void 585FcPrivate void
542FcCacheObjectDereference (void *object); 586FcCacheObjectDereference (void *object);
543 587
544FcPrivate void 588FcPrivate void
545FcCacheFini (void); 589FcCacheFini (void);
546  590
547FcPrivate void 591FcPrivate void
548FcDirCacheReference (FcCache *cache, int nref); 592FcDirCacheReference (FcCache *cache, int nref);
549 593
550#ifdef _WIN32 
551FcPrivate int 
552FcStat (const char *file, struct stat *statb); 
553#else 
554#define FcStat stat 
555#endif 
556 
557/* fccfg.c */ 594/* fccfg.c */
558 595
 596FcPrivate FcChar8 *
 597FcConfigXdgCacheHome (void);
 598
 599FcPrivate FcChar8 *
 600FcConfigXdgConfigHome (void);
 601
 602FcPrivate FcChar8 *
 603FcConfigXdgDataHome (void);
 604
559FcPrivate FcExpr * 605FcPrivate FcExpr *
560FcConfigAllocExpr (FcConfig *config); 606FcConfigAllocExpr (FcConfig *config);
561 607
562FcPrivate FcBool 608FcPrivate FcBool
563FcConfigAddConfigDir (FcConfig *config, 609FcConfigAddConfigDir (FcConfig *config,
564 const FcChar8 *d); 610 const FcChar8 *d);
565 611
566FcPrivate FcBool 612FcPrivate FcBool
567FcConfigAddFontDir (FcConfig *config, 613FcConfigAddFontDir (FcConfig *config,
568 const FcChar8 *d); 614 const FcChar8 *d);
569 615
570FcPrivate FcBool 616FcPrivate FcBool
571FcConfigAddDir (FcConfig *config, 617FcConfigAddDir (FcConfig *config,
@@ -611,33 +657,33 @@ FcConfigAcceptFilename (FcConfig *config @@ -611,33 +657,33 @@ FcConfigAcceptFilename (FcConfig *config
611FcPrivate FcBool 657FcPrivate FcBool
612FcConfigPatternsAdd (FcConfig *config, 658FcConfigPatternsAdd (FcConfig *config,
613 FcPattern *pattern, 659 FcPattern *pattern,
614 FcBool accept); 660 FcBool accept);
615 661
616FcPrivate FcBool 662FcPrivate FcBool
617FcConfigAcceptFont (FcConfig *config, 663FcConfigAcceptFont (FcConfig *config,
618 const FcPattern *font); 664 const FcPattern *font);
619 665
620FcPrivate FcFileTime 666FcPrivate FcFileTime
621FcConfigModifiedTime (FcConfig *config); 667FcConfigModifiedTime (FcConfig *config);
622 668
623FcPrivate FcBool 669FcPrivate FcBool
624FcConfigAddCache (FcConfig *config, FcCache *cache,  670FcConfigAddCache (FcConfig *config, FcCache *cache,
625 FcSetName set, FcStrSet *dirSet); 671 FcSetName set, FcStrSet *dirSet);
626 672
627/* fcserialize.c */ 673/* fcserialize.c */
628FcPrivate intptr_t 674FcPrivate intptr_t
629FcAlignSize (intptr_t size); 675FcAlignSize (intptr_t size);
630  676
631FcPrivate FcSerialize * 677FcPrivate FcSerialize *
632FcSerializeCreate (void); 678FcSerializeCreate (void);
633 679
634FcPrivate void 680FcPrivate void
635FcSerializeDestroy (FcSerialize *serialize); 681FcSerializeDestroy (FcSerialize *serialize);
636 682
637FcPrivate FcBool 683FcPrivate FcBool
638FcSerializeAlloc (FcSerialize *serialize, const void *object, int size); 684FcSerializeAlloc (FcSerialize *serialize, const void *object, int size);
639 685
640FcPrivate intptr_t 686FcPrivate intptr_t
641FcSerializeReserve (FcSerialize *serialize, int size); 687FcSerializeReserve (FcSerialize *serialize, int size);
642 688
643FcPrivate intptr_t 689FcPrivate intptr_t
@@ -685,49 +731,55 @@ FcPrivate FcCharLeaf * @@ -685,49 +731,55 @@ FcPrivate FcCharLeaf *
685FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4); 731FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
686 732
687FcPrivate FcBool 733FcPrivate FcBool
688FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs); 734FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs);
689 735
690FcPrivate FcCharSet * 736FcPrivate FcCharSet *
691FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs); 737FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs);
692 738
693FcPrivate FcChar16 * 739FcPrivate FcChar16 *
694FcCharSetGetNumbers(const FcCharSet *c); 740FcCharSetGetNumbers(const FcCharSet *c);
695 741
696/* fcdbg.c */ 742/* fcdbg.c */
697FcPrivate void 743FcPrivate void
698FcValueListPrint (const FcValueListPtr l); 744FcValuePrintWithPosition (const FcValue v, FcBool show_pos_mark);
 745
 746FcPrivate void
 747FcValueListPrintWithPosition (FcValueListPtr l, const FcValueListPtr pos);
 748
 749FcPrivate void
 750FcValueListPrint (FcValueListPtr l);
699 751
700FcPrivate void 752FcPrivate void
701FcLangSetPrint (const FcLangSet *ls); 753FcLangSetPrint (const FcLangSet *ls);
702 754
703FcPrivate void 755FcPrivate void
704FcOpPrint (FcOp op); 756FcOpPrint (FcOp op);
705 757
706FcPrivate void 758FcPrivate void
707FcTestPrint (const FcTest *test); 759FcTestPrint (const FcTest *test);
708 760
709FcPrivate void 761FcPrivate void
710FcExprPrint (const FcExpr *expr); 762FcExprPrint (const FcExpr *expr);
711 763
712FcPrivate void 764FcPrivate void
713FcEditPrint (const FcEdit *edit); 765FcEditPrint (const FcEdit *edit);
714 766
715FcPrivate void 767FcPrivate void
716FcSubstPrint (const FcSubst *subst); 768FcSubstPrint (const FcSubst *subst);
717 769
718FcPrivate void 770FcPrivate void
719FcCharSetPrint (const FcCharSet *c); 771FcCharSetPrint (const FcCharSet *c);
720  772
721extern FcPrivate int FcDebugVal; 773extern FcPrivate int FcDebugVal;
722 774
723#define FcDebug() (FcDebugVal) 775#define FcDebug() (FcDebugVal)
724 776
725FcPrivate void 777FcPrivate void
726FcInitDebug (void); 778FcInitDebug (void);
727 779
728/* fcdefault.c */ 780/* fcdefault.c */
729FcPrivate FcChar8 * 781FcPrivate FcChar8 *
730FcGetDefaultLang (void); 782FcGetDefaultLang (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
770FcPrivate void 822FcPrivate void
771FcMemReport (void); 823FcMemReport (void);
772 824
773FcPrivate void 825FcPrivate void
774FcMemAlloc (int kind, int size); 826FcMemAlloc (int kind, int size);
775 827
776FcPrivate void 828FcPrivate void
777FcMemFree (int kind, int size); 829FcMemFree (int kind, int size);
778 830
779/* fclang.c */ 831/* fclang.c */
780FcPrivate FcLangSet * 832FcPrivate FcLangSet *
781FcFreeTypeLangSet (const FcCharSet *charset,  833FcFreeTypeLangSet (const FcCharSet *charset,
782 const FcChar8 *exclusiveLang); 834 const FcChar8 *exclusiveLang);
783 835
 836FcPrivate FcChar8 *
 837FcLangNormalize (const FcChar8 *lang);
 838
784FcPrivate FcLangResult 839FcPrivate FcLangResult
785FcLangCompare (const FcChar8 *s1, const FcChar8 *s2); 840FcLangCompare (const FcChar8 *s1, const FcChar8 *s2);
786  841
787FcPrivate FcLangSet * 842FcPrivate FcLangSet *
788FcLangSetPromote (const FcChar8 *lang); 843FcLangSetPromote (const FcChar8 *lang);
789 844
790FcPrivate FcLangSet * 845FcPrivate FcLangSet *
791FcNameParseLangSet (const FcChar8 *string); 846FcNameParseLangSet (const FcChar8 *string);
792 847
793FcPrivate FcBool 848FcPrivate FcBool
794FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls); 849FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
795 850
796FcPrivate FcChar8 * 851FcPrivate FcChar8 *
797FcNameUnparseEscaped (FcPattern *pat, FcBool escape); 852FcNameUnparseEscaped (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
857FcPrivate FcBool 913FcPrivate FcBool
858FcNameBool (const FcChar8 *v, FcBool *result); 914FcNameBool (const FcChar8 *v, FcBool *result);
859 915
860FcPrivate FcBool 916FcPrivate FcBool
861FcObjectValidType (FcObject object, FcType type); 917FcObjectValidType (FcObject object, FcType type);
862 918
863FcPrivate FcObject 919FcPrivate FcObject
864FcObjectFromName (const char * name); 920FcObjectFromName (const char * name);
865 921
866FcPrivate const char * 922FcPrivate const char *
867FcObjectName (FcObject object); 923FcObjectName (FcObject object);
868 924
@@ -872,51 +928,73 @@ FcObjectGetSet (void); @@ -872,51 +928,73 @@ FcObjectGetSet (void);
872FcPrivate FcBool 928FcPrivate FcBool
873FcObjectInit (void); 929FcObjectInit (void);
874 930
875FcPrivate void 931FcPrivate void
876FcObjectFini (void); 932FcObjectFini (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
882FcPrivate FcValue 938FcPrivate FcValue
883FcValueCanonicalize (const FcValue *v); 939FcValueCanonicalize (const FcValue *v);
884 940
 941FcPrivate FcValueListPtr
 942FcValueListCreate (void);
 943
885FcPrivate void 944FcPrivate void
886FcValueListDestroy (FcValueListPtr l); 945FcValueListDestroy (FcValueListPtr l);
887 946
 947FcPrivate FcValueListPtr
 948FcValueListPrepend (FcValueListPtr vallist,
 949 FcValue value,
 950 FcValueBinding binding);
 951
 952FcPrivate FcValueListPtr
 953FcValueListAppend (FcValueListPtr vallist,
 954 FcValue value,
 955 FcValueBinding binding);
 956
 957FcPrivate FcValueListPtr
 958FcValueListDuplicate(FcValueListPtr orig);
 959
888FcPrivate FcPatternElt * 960FcPrivate FcPatternElt *
889FcPatternObjectFindElt (const FcPattern *p, FcObject object); 961FcPatternObjectFindElt (const FcPattern *p, FcObject object);
890 962
891FcPrivate FcPatternElt * 963FcPrivate FcPatternElt *
892FcPatternObjectInsertElt (FcPattern *p, FcObject object); 964FcPatternObjectInsertElt (FcPattern *p, FcObject object);
893 965
894FcPrivate FcBool 966FcPrivate FcBool
 967FcPatternObjectListAdd (FcPattern *p,
 968 FcObject object,
 969 FcValueListPtr list,
 970 FcBool append);
 971
 972FcPrivate FcBool
895FcPatternObjectAddWithBinding (FcPattern *p, 973FcPatternObjectAddWithBinding (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
901FcPrivate FcBool 979FcPrivate FcBool
902FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append); 980FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append);
903  981
904FcPrivate FcBool 982FcPrivate FcBool
905FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append); 983FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append);
906  984
907FcPrivate FcResult 985FcPrivate FcResult
908FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v); 986FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v);
909  987
910FcPrivate FcBool 988FcPrivate FcBool
911FcPatternObjectDel (FcPattern *p, FcObject object); 989FcPatternObjectDel (FcPattern *p, FcObject object);
912 990
913FcPrivate FcBool 991FcPrivate FcBool
914FcPatternObjectRemove (FcPattern *p, FcObject object, int id); 992FcPatternObjectRemove (FcPattern *p, FcObject object, int id);
915 993
916FcPrivate FcBool 994FcPrivate FcBool
917FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i); 995FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i);
918 996
919FcPrivate FcBool 997FcPrivate FcBool
920FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d); 998FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d);
921 999
922FcPrivate FcBool 1000FcPrivate FcBool
@@ -945,60 +1023,77 @@ FcPatternObjectGetString (const FcPatter @@ -945,60 +1023,77 @@ FcPatternObjectGetString (const FcPatter
945 1023
946FcPrivate FcResult 1024FcPrivate FcResult
947FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s); 1025FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s);
948 1026
949FcPrivate FcResult 1027FcPrivate FcResult
950FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c); 1028FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c);
951 1029
952FcPrivate FcResult 1030FcPrivate FcResult
953FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); 1031FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b);
954 1032
955FcPrivate FcResult 1033FcPrivate FcResult
956FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls); 1034FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls);
957 1035
958FcPrivate void 
959FcPatternFini (void); 
960 
961FcPrivate FcBool 1036FcPrivate FcBool
962FcPatternAppend (FcPattern *p, FcPattern *s); 1037FcPatternAppend (FcPattern *p, FcPattern *s);
963 1038
964FcPrivate const FcChar8 * 1039FcPrivate const FcChar8 *
965FcStrStaticName (const FcChar8 *name); 1040FcSharedStr (const FcChar8 *name);
 1041
 1042FcPrivate FcBool
 1043FcSharedStrFree (const FcChar8 *name);
966 1044
967FcPrivate FcChar32 1045FcPrivate FcChar32
968FcStringHash (const FcChar8 *s); 1046FcStringHash (const FcChar8 *s);
969 1047
970FcPrivate FcBool 1048FcPrivate FcBool
971FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat); 1049FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat);
972 1050
973FcPrivate FcPattern * 1051FcPrivate FcPattern *
974FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat); 1052FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat);
975 1053
976FcPrivate FcBool 1054FcPrivate FcBool
977FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat); 1055FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat);
978 1056
979FcPrivate FcValueList * 1057FcPrivate FcValueList *
980FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat); 1058FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat);
981 1059
982/* fcrender.c */ 1060/* fcrender.c */
983 1061
984/* fcmatrix.c */ 1062/* fcmatrix.c */
985 1063
986extern FcPrivate const FcMatrix FcIdentityMatrix; 1064extern FcPrivate const FcMatrix FcIdentityMatrix;
987 1065
988FcPrivate void 1066FcPrivate void
989FcMatrixFree (FcMatrix *mat); 1067FcMatrixFree (FcMatrix *mat);
990 1068
 1069/* fcstat.c */
 1070
 1071FcPrivate int
 1072FcStat (const FcChar8 *file, struct stat *statb);
 1073
 1074FcPrivate int
 1075FcStatChecksum (const FcChar8 *file, struct stat *statb);
 1076
 1077FcPrivate FcBool
 1078FcIsFsMmapSafe (int fd);
 1079
 1080FcPrivate FcBool
 1081FcIsFsMtimeBroken (const FcChar8 *dir);
 1082
991/* fcstr.c */ 1083/* fcstr.c */
 1084FcPrivate FcBool
 1085FcStrSetAddLangs (FcStrSet *strs, const char *languages);
 1086
992FcPrivate void 1087FcPrivate void
993FcStrSetSort (FcStrSet * set); 1088FcStrSetSort (FcStrSet * set);
994 1089
995FcPrivate void 1090FcPrivate void
996FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size); 1091FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size);
997 1092
998FcPrivate void 1093FcPrivate void
999FcStrBufDestroy (FcStrBuf *buf); 1094FcStrBufDestroy (FcStrBuf *buf);
1000 1095
1001FcPrivate FcChar8 * 1096FcPrivate FcChar8 *
1002FcStrBufDone (FcStrBuf *buf); 1097FcStrBufDone (FcStrBuf *buf);
1003 1098
1004FcPrivate FcChar8 * 1099FcPrivate FcChar8 *
@@ -1006,26 +1101,32 @@ FcStrBufDoneStatic (FcStrBuf *buf); @@ -1006,26 +1101,32 @@ FcStrBufDoneStatic (FcStrBuf *buf);
1006 1101
1007FcPrivate FcBool 1102FcPrivate FcBool
1008FcStrBufChar (FcStrBuf *buf, FcChar8 c); 1103FcStrBufChar (FcStrBuf *buf, FcChar8 c);
1009 1104
1010FcPrivate FcBool 1105FcPrivate FcBool
1011FcStrBufString (FcStrBuf *buf, const FcChar8 *s); 1106FcStrBufString (FcStrBuf *buf, const FcChar8 *s);
1012 1107
1013FcPrivate FcBool 1108FcPrivate FcBool
1014FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len); 1109FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
1015 1110
1016FcPrivate int 1111FcPrivate int
1017FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); 1112FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
1018 1113
 1114FcPrivate FcBool
 1115FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex);
 1116
 1117FcPrivate FcBool
 1118FcStrRegexCmpIgnoreCase (const FcChar8 *s, const FcChar8 *regex);
 1119
1019FcPrivate const FcChar8 * 1120FcPrivate const FcChar8 *
1020FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); 1121FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
1021 1122
1022FcPrivate const FcChar8 * 1123FcPrivate const FcChar8 *
1023FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2); 1124FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
1024 1125
1025FcPrivate const FcChar8 * 1126FcPrivate const FcChar8 *
1026FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2); 1127FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2);
1027 1128
1028FcPrivate FcBool 1129FcPrivate FcBool
1029FcStrUsesHome (const FcChar8 *s); 1130FcStrUsesHome (const FcChar8 *s);
1030 1131
1031FcPrivate FcChar8 * 1132FcPrivate FcChar8 *

cvs diff -r1.3 -r1.4 xsrc/external/mit/fontconfig/dist/src/ftglue.c (expand / switch to unified diff)

--- 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
17static void 17static void
18ftglue_log( const char* format, ... ) 18ftglue_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 */
34static FT_Pointer 34static FT_Pointer
@@ -74,35 +74,36 @@ FTGLUE_APIDEF( FT_Long ) @@ -74,35 +74,36 @@ FTGLUE_APIDEF( FT_Long )
74ftglue_stream_pos( FT_Stream stream ) 74ftglue_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
81FTGLUE_APIDEF( FT_Error ) 81FTGLUE_APIDEF( FT_Error )
82ftglue_stream_seek( FT_Stream stream, 82ftglue_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
101FTGLUE_APIDEF( FT_Error ) 102FTGLUE_APIDEF( FT_Error )
102ftglue_stream_frame_enter( FT_Stream stream, 103ftglue_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
167FTGLUE_APIDEF( FT_Error ) 168FTGLUE_APIDEF( FT_Error )
168ftglue_face_goto_table( FT_Face face, 169ftglue_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
254Exit: 255Exit:
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__