+2005-10-31 Patrick Lam <plam@mit.edu>
+ * fc-cat/fc-cat.c:
+ * src/fccache.c:
+ * src/fcfreetype.c:
+ * src/fcint.h:
+ * src/fclist.c:
+ * src/fcpat.c:
+
+ Reinstate basename patch, but keep a hash table linking FcPatterns
+ to their fully-qualified font names for clients' benefit. Clients
+ only pay for the font names once they request the FC_FILE property
+ from an FcPattern, but the font name is malloc'd at that point (i.e.
+ not mmapped: that's impossible, since it may vary between machines.)
+ Clients do have to pay for a copy of the path name per cache file.
+
+ Note that FcPatternGetString now does some rewriting if you ask
+ for an FC_FILE, appending the pathname as appropriate.
+
+2005-10-31 Patrick Lam <plam@mit.edu>
+ * src/fcfreetype.c (FcFreeTypeQuery):
+
+ Revert basename patch, which breaks fontconfig clients on my system.
+
2005-10-25 Jinghua Luo <sunmoon1997@gmail.com>
reviewed by: plam
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
/* read serialized state from the cache file */
static FcBool
-FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char *cache_file)
+FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file)
{
int fd;
char * current_arch_machine_name;
while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
FcStrSetAdd (dirs, (FcChar8 *)subdirName);
- if (!FcDirCacheConsume (fd, set))
+ if (!FcDirCacheConsume (fd, dir, set))
goto bail1;
close(fd);
i = 1;
#endif
- if (FcCacheFileRead (fs, dirs, argv[i]))
+ if (FcCacheFileRead (fs, dirs, dirname (argv[i]), argv[i]))
FcCachePrintSet (fs, dirs, argv[i]);
FcStrSetDestroy (dirs);
FcDirCacheProduce (FcFontSet *set, FcCache * metadata);
static FcBool
-FcDirCacheConsume (int fd, FcFontSet *set);
+FcDirCacheConsume (int fd, const char * dir, FcFontSet *set);
FcBool
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir);
static FcBool
FcCacheHaveBank (int bank);
+static void
+FcCacheAddBankDir (int bank, const char * dir);
+
#define FC_DBG_CACHE_REF 1024
static char *
if (strncmp (d->name, dir, strlen(dir)) == 0)
{
lseek (cache->fd, d->offset, SEEK_SET);
- if (!FcDirCacheConsume (cache->fd, set))
+ if (!FcDirCacheConsume (cache->fd, dir, set))
return FcFalse;
if (strcmp (d->name, dir) == 0)
ret = FcTrue;
while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
FcStrSetAdd (dirs, (FcChar8 *)subdirName);
- if (!FcDirCacheConsume (fd, set))
+ if (!FcDirCacheConsume (fd, (const char *)dir, set))
goto bail1;
close(fd);
}
static FcBool
-FcDirCacheConsume (int fd, FcFontSet *set)
+FcDirCacheConsume (int fd, const char * dir, FcFontSet *set)
{
FcCache metadata;
void * current_dir_block;
if (!FcFontSetUnserialize (metadata, set, current_dir_block))
return FcFalse;
+ FcCacheAddBankDir (metadata.bank, dir);
+
return FcTrue;
}
static int banks_ptr = 0, banks_alloc = 0;
static int * bankId = 0, * bankIdx = 0;
+static const char ** bankDirs = 0;
static FcBool
FcCacheHaveBank (int bank)
if (banks_ptr >= banks_alloc)
{
int * b, * bidx;
+ const char ** bds;
+
b = realloc (bankId, (banks_alloc + 4) * sizeof(int));
if (!b)
return -1;
return -1;
bankIdx = bidx;
+ bds = realloc (bankDirs, (banks_alloc + 4) * sizeof (char *));
+ if (!bds)
+ return -1;
+ bankDirs = bds;
+
banks_alloc += 4;
}
bankIdx[i] = i;
return i;
}
+
+static void
+FcCacheAddBankDir (int bank, const char * dir)
+{
+ int bi = FcCacheBankToIndex (bank);
+
+ if (bi < 0)
+ return;
+
+ bankDirs[bi] = (const char *)FcStrCopy ((FcChar8 *)dir);
+}
+
+const char *
+FcCacheFindBankDir (int bank)
+{
+ int bi = FcCacheBankToIndex (bank);
+ return bankDirs[bi];
+}
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <libgen.h>
#include "fcint.h"
#include <ft2build.h>
#include FT_FREETYPE_H
printf ("Saving unique fullname %s\n", full);
}
- if (!FcPatternAddString (pat, FC_FILE, file))
+ if (!FcPatternAddString (pat, FC_FILE, (FcChar8 *)basename((char *)file)))
goto bail1;
+ FcPatternAddFullFname (pat, (const char *)file);
+
if (!FcPatternAddInteger (pat, FC_INDEX, id))
goto bail1;
int
FcCacheBankToIndex (int bank);
+
+const char *
+FcCacheFindBankDir (int bank);
/* fccfg.c */
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s);
+void
+FcPatternAddFullFname (const FcPattern *p, const char *fname);
+
+const char *
+FcPatternFindFullFname (const FcPattern *p);
+
const FcChar8 *
FcStrStaticName (const FcChar8 *name);
else
defidx = 0;
+ /* Also, copy over the full path info. */
+ if (!strcmp (os->objects[o], FC_FILE))
+ {
+ FcChar8 * s;
+ FcPatternGetString (font, FC_FILE, 0, &s);
+ FcPatternAddFullFname (bucket->pattern, FcPatternFindFullFname(font));
+ }
+
e = FcPatternFindElt (font, os->objects[o]);
if (e)
{
{
int i;
+ if (FcPatternFindFullFname (p))
+ FcPatternAddFullFname (p, 0);
+
if (p->ref == FC_REF_CONSTANT || --p->ref > 0)
return;
return r;
if (v.type != FcTypeString)
return FcResultTypeMismatch;
+
+ if (FcObjectToPtr(object) == FcObjectToPtr(FC_FILE))
+ {
+ const char *fn, *fpath;
+ FcChar8 *fname;
+ int size;
+
+ fn = FcPatternFindFullFname(p);
+ if (fn)
+ {
+ *s = (FcChar8 *) fn;
+ return FcResultMatch;
+ }
+
+ if (!p->bank)
+ {
+ *s = (FcChar8 *) v.u.s;
+ return FcResultMatch;
+ }
+
+ fpath = FcCacheFindBankDir (p->bank);
+ size = strlen((char*)fpath) + 1 + strlen ((char *)v.u.s) + 1;
+ fname = malloc (size);
+ if (!fname)
+ return FcResultOutOfMemory;
+
+ FcMemAlloc (FC_MEM_STRING, size);
+ strcpy ((char *)fname, (char *)fpath);
+ strcat ((char *)fname, "/");
+ strcat ((char *)fname, (char *)v.u.s);
+
+ FcPatternAddFullFname (p, (const char *)fname);
+ *s = (FcChar8 *)fname;
+ return FcResultMatch;
+ }
+
*s = (FcChar8 *) v.u.s;
return FcResultMatch;
}
return block_ptr;
}
+/* we don't store these in the FcPattern itself because
+ * we don't want to serialize the directory names */
+
+/* I suppose this should be cleaned, too... */
+typedef struct _FcPatternDirMapping {
+ const FcPattern *p;
+ const char *fname;
+} FcPatternDirMapping;
+
+#define PATTERNDIR_HASH_SIZE 31
+static struct patternDirBucket {
+ struct patternDirBucket *next;
+ FcPatternDirMapping m;
+} FcPatternDirBuckets[PATTERNDIR_HASH_SIZE];
+
+void
+FcPatternAddFullFname (const FcPattern *p, const char *fname)
+{
+ struct patternDirBucket *pb;
+
+ /* N.B. FcPatternHash fails, since it's contents-based, not
+ * address-based, and we're in the process of mutating the FcPattern. */
+ for (pb = &FcPatternDirBuckets
+ [((int)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE];
+ pb->m.p != p && pb->next;
+ pb = pb->next)
+ ;
+
+ if (pb->m.p == p)
+ {
+ pb->m.fname = fname;
+ return;
+ }
+
+ pb->next = malloc (sizeof (struct patternDirBucket));
+ if (!pb->next)
+ return;
+ FcMemAlloc (FC_MEM_CACHE, sizeof (struct patternDirBucket));
+
+ pb->next->next = 0;
+ pb->next->m.p = p;
+ pb->next->m.fname = fname;
+}
+
+const char *
+FcPatternFindFullFname (const FcPattern *p)
+{
+ struct patternDirBucket *pb;
+
+ for (pb = &FcPatternDirBuckets
+ [((int)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE];
+ pb; pb = pb->next)
+ if (pb->m.p == p)
+ return pb->m.fname;
+
+ return 0;
+}
+