[Fontconfig] fontconfig: Branch 'fc-2_4-keithp'

Keith Packard keithp at kemper.freedesktop.org
Wed Aug 30 13:51:27 PDT 2006


 fc-cat/fc-cat.c |  136 +++++++++++++++++++++++++++++---------------------------
 src/fccache.c   |    6 --
 src/fccharset.c |    3 -
 src/fcdbg.c     |   20 +++++++-
 src/fcint.h     |   15 ++++--
 src/fcpat.c     |    7 ++
 6 files changed, 111 insertions(+), 76 deletions(-)

New commits:
diff-tree c02886485b293179e8492cad9a34eb431dd4bfc9 (from e3096d90fd3e0ba8b62d2c6df4cfb24f08a0766c)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Wed Aug 30 13:51:03 2006 -0700

    FcCharSetSerialize was using wrong offset for leaves. Make fc-cat work.
    
    FcCharSetSerialize was computing the offset to the unserialized leaf,
    which left it pointing at random data when the cache was reloaded.
    
    fc-cat has been updated to work with the new cache structure.
    
    Various debug messages extended to help diagnose serialization errors.

diff --git a/fc-cat/fc-cat.c b/fc-cat/fc-cat.c
index 36f8bd9..b988a29 100644
--- a/fc-cat/fc-cat.c
+++ b/fc-cat/fc-cat.c
@@ -53,6 +53,7 @@
 #include <getopt.h>
 const struct option longopts[] = {
     {"version", 0, 0, 'V'},
+    {"verbose", 0, 0, 'v'},
     {"help", 0, 0, '?'},
     {NULL,0,0,0},
 };
@@ -167,39 +168,22 @@ usage (char *program)
     exit (1);
 }
 
-/* read serialized state from the cache file */
-static char *
-FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char *cache_file)
+static int
+FcCacheFileOpen (char *cache_file, off_t *size)
 {
-    FILE *file;
     int fd;
-    char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
-    static char name_buf[8192];
-    FcChar8 * ls;
-    char * buf;
-    int i;
-
-    if (!cache_file)
-        goto bail;
-
-    file = fopen(cache_file, "rb");
-    if (file == NULL)
-        goto bail;
+    struct stat file_stat;
 
-    if (!FcDirCacheConsume (file, set, dirs, NULL, name_buf))
-	goto bail1;
-    
-    fclose (file);
-    
-    printf ("fc-cat: printing directory cache for cache which would be named %s\n", 
-	    name_buf);
-
-    return name_buf;
-
- bail1:
-    fclose (file);
- bail:
-    return 0;
+    fd = open(cache_file, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+
+    if (fstat (fd, &file_stat) < 0) {
+	close (fd); 
+	return -1;
+    }
+    *size = file_stat.st_size;
+    return fd;
 }
 
 /*
@@ -210,11 +194,10 @@ static const FcChar8 *
 FcFileBaseName (const char *cache, const FcChar8 *file)
 {
     const FcChar8   *cache_slash;
+    int		    cache_len = strlen (cache);
 
-    cache_slash = FcStrLastSlash ((const FcChar8 *)cache);
-    if (cache_slash && !strncmp ((const char *) cache, (const char *) file,
-				 (cache_slash + 1) - (const FcChar8 *)cache))
-	return file + ((cache_slash + 1) - (const FcChar8 *)cache);
+    if (!strncmp (cache, file, cache_len) && file[cache_len] == '/')
+	return file + cache_len + 1;
     return file;
 }
 
@@ -252,14 +235,15 @@ FcCachePrintSet (FcFontSet *set, FcStrSe
     
     for (n = 0; n < set->nfont; n++)
     {
-	font = set->fonts[n];
+	FcPattern   **fonts = FcFontSetFonts (set);
+	FcPattern   *encoded_font = fonts[n];
+	FcPattern   *font = FcEncodedOffsetToPtr (set, encoded_font, FcPattern);
+
 	if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
 	    goto bail3;
 	base = FcFileBaseName (base_name, file);
 	if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
 	    goto bail3;
-	if (FcDebug () & FC_DBG_CACHEV)
-	    printf (" write file \"%s\"\n", base);
 	if (!FcCacheWriteStringOld (stdout, base))
 	    goto bail3;
 	if (PUTC (' ', stdout) == EOF)
@@ -293,17 +277,19 @@ int
 main (int argc, char **argv)
 {
     int		i;
+    int		ret = 0;
+    FcFontSet	*fs;
+    FcStrSet    *dirs;
+    FcCache	*cache;
+    FcConfig	*config;
+    int		verbose = 0;
 #if HAVE_GETOPT_LONG || HAVE_GETOPT
     int		c;
-    FcFontSet	*fs = FcFontSetCreate();
-    FcStrSet    *dirs = FcStrSetCreate();
-    char	*name_buf;
-    FcConfig	*config;
 
 #if HAVE_GETOPT_LONG
-    while ((c = getopt_long (argc, argv, "fsVv?", longopts, NULL)) != -1)
+    while ((c = getopt_long (argc, argv, "Vv?", longopts, NULL)) != -1)
 #else
-    while ((c = getopt (argc, argv, "fsVv?")) != -1)
+    while ((c = getopt (argc, argv, "Vv?")) != -1)
 #endif
     {
 	switch (c) {
@@ -311,6 +297,9 @@ main (int argc, char **argv)
 	    fprintf (stderr, "fontconfig version %d.%d.%d\n", 
 		     FC_MAJOR, FC_MINOR, FC_REVISION);
 	    exit (0);
+	case 'v':
+	    verbose++;
+	    break;
 	default:
 	    usage (argv[0]);
 	}
@@ -331,29 +320,48 @@ main (int argc, char **argv)
     if (i >= argc)
         usage (argv[0]);
 
-    if (FcFileIsDir ((const FcChar8 *)argv[i]))
-    {
-        char * dummy_name = (char *)FcStrPlus ((FcChar8 *)argv[i], 
-                                               (FcChar8 *)"/dummy");
-        if (!FcDirScanConfig (fs, dirs, 0, 
-                              (const FcChar8 *)argv[i], FcFalse, config))
-            fprintf (stderr, "couldn't load font dir %s\n", argv[i]);
-        else
-        {
-            /* sorry, we can't tell you where the cache file is. */
-            FcCachePrintSet (fs, dirs, dummy_name);
-            FcStrFree ((FcChar8 *)dummy_name);
-        }
-    }
-    else if ((name_buf = FcCacheFileRead (fs, dirs, argv[i])) != 0)
-	FcCachePrintSet (fs, dirs, name_buf);
-    else
+    for (; i < argc; i++)
     {
-	printf ("nothing to do\n");
-    }
+	int	fd;
+	int	j;
+	off_t	size;
+	intptr_t	*cache_dirs;
+	
+	if (FcFileIsDir ((const FcChar8 *)argv[i]))
+	    fd = FcDirCacheOpen (config, (const FcChar8 *) argv[i], &size);
+	else
+	    fd = FcCacheFileOpen (argv[i], &size);
+	if (fd < 0)
+	{
+	    perror (argv[i]);
+	    ret++;
+	    continue;
+	}
+	
+	cache = FcDirCacheMap (fd, size);
+	close (fd);
+	if (!cache)
+	{
+	    fprintf (stderr, "%s: cannot map cache\n", argv[i]);
+	    ret++;
+	    continue;
+	}
+	dirs = FcStrSetCreate ();
+	fs = FcCacheSet (cache);
+	cache_dirs = FcCacheDirs (cache);
+	for (j = 0; j < cache->dirs_count; j++) 
+	    FcStrSetAdd (dirs, FcOffsetToPtr (cache_dirs,
+					      cache_dirs[j],
+					      FcChar8));
+
+	if (verbose)
+	    printf ("Name: %s\nDirectory: %s\n", argv[i], FcCacheDir(cache));
+        FcCachePrintSet (fs, dirs, FcCacheDir (cache));
 
-    FcStrSetDestroy (dirs);
-    FcFontSetDestroy (fs);
+	FcStrSetDestroy (dirs);
+
+	FcDirCacheUnmap (cache);
+    }
 
     return 0;
 }
diff --git a/src/fccache.c b/src/fccache.c
index c1c58fb..9f35f29 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -255,8 +255,7 @@ FcDirCacheOpen (FcConfig *config, const 
     return fd;
 }
 
-#if 0
-static void
+void
 FcDirCacheUnmap (FcCache *cache)
 {
     if (cache->magic == FC_CACHE_MAGIC_COPY)
@@ -270,10 +269,9 @@ FcDirCacheUnmap (FcCache *cache)
     UnmapViewOfFile (cache);
 #endif
 }
-#endif
 
 /* read serialized state from the cache file */
-static FcCache *
+FcCache *
 FcDirCacheMap (int fd, off_t size)
 {
     FcCache	*cache;
diff --git a/src/fccharset.c b/src/fccharset.c
index d55c611..96dcbe7 100644
--- a/src/fccharset.c
+++ b/src/fccharset.c
@@ -1320,7 +1320,8 @@ FcCharSetSerialize(FcSerialize *serializ
 	if (!leaf_serialized)
 	    return NULL;
 	*leaf_serialized = *leaf;
-	leaves_serialized[i] = FcPtrToOffset (leaves_serialized, leaf);
+	leaves_serialized[i] = FcPtrToOffset (leaves_serialized, 
+					      leaf_serialized);
 	numbers_serialized[i] = numbers[i];
     }
     
diff --git a/src/fcdbg.c b/src/fcdbg.c
index 16b6bfd..c82dd3a 100644
--- a/src/fcdbg.c
+++ b/src/fcdbg.c
@@ -100,12 +100,26 @@ void
 FcCharSetPrint (const FcCharSet *c)
 {
     int	i, j;
-
+    intptr_t	*leaves = FcCharSetLeaves (c);
+    FcChar16	*numbers = FcCharSetNumbers (c);
+    
+    printf ("CharSet  0x%x\n", (intptr_t) c);
+    printf ("Leaves:  +%d = 0x%x\n", c->leaves_offset, (intptr_t) leaves);
+    printf ("Numbers: +%d = 0x%x\n", c->numbers_offset, (intptr_t) numbers);
+    
+    for (i = 0; i < c->num; i++)
+    {
+	printf ("Page %d: %04x +%d = 0x%x\n", 
+		i, numbers[i], leaves[i], 
+		(intptr_t) FcOffsetToPtr (leaves, leaves[i], FcCharLeaf));
+    }
+		
     for (i = 0; i < c->num; i++)
     {
-	FcCharLeaf	*leaf = FcCharSetLeaf(c, i);
+	intptr_t	leaf_offset = leaves[i];
+	FcCharLeaf	*leaf = FcOffsetToPtr (leaves, leaf_offset, FcCharLeaf);
 	
-	printf ("%04x:", FcCharSetNumbers(c)[i]);
+	printf ("%04x:", numbers[i]);
 	for (j = 0; j < 256/32; j++)
 	    printf (" %08x", leaf->map[j]);
 	printf ("\n");
diff --git a/src/fcint.h b/src/fcint.h
index 2f656cb..adb3b16 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -199,11 +199,12 @@ struct _FcPattern {
 #define FcPatternElts(p)	FcOffsetMember(p,elts_offset,FcPatternElt)
 
 #define FcFontSetFonts(fs)	FcPointerMember(fs,fonts,FcPattern *)
-/*
+
 #define FcFontSetFont(fs,i)	(FcIsEncodedOffset((fs)->fonts) ? \
-				 FcOffsetToPtr(FcFontSetFonts(fs), \
-					       FcFontSetFonts(fs)[i]) : \
-				 fs->fonts[i])*/
+				 FcEncodedOffsetToPtr(FcFontSetFonts(fs), \
+						      FcFontSetFonts(fs)[i], \
+						      FcPattern) : \
+				 fs->fonts[i])
 						
 typedef enum _FcOp {
     FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet, 
@@ -490,6 +491,12 @@ FcBool
 FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs,
 		   const FcChar8 *dir, char *dirname);
     
+FcCache *
+FcDirCacheMap (int fd, off_t size);
+
+void
+FcDirCacheUnmap (FcCache *cache);
+
 FcBool
 FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
  
diff --git a/src/fcpat.c b/src/fcpat.c
index 7432745..3eb8a73 100644
--- a/src/fcpat.c
+++ b/src/fcpat.c
@@ -1096,6 +1096,13 @@ FcPatternSerialize (FcSerialize *seriali
 							  values_serialized,
 							  FcValueList);
     }
+    if (FcDebug() & FC_DBG_CACHEV) {
+	printf ("Raw pattern:\n");
+	FcPatternPrint (pat);
+	printf ("Serialized pattern:\n");
+	FcPatternPrint (pat_serialized);
+	printf ("\n");
+    }
     return pat_serialized;
 }
 


More information about the Fontconfig mailing list