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.
This commit is contained in:
Patrick Lam 2005-11-01 05:26:27 +00:00
parent be99726f67
commit e77c17184a
7 changed files with 181 additions and 8 deletions

View File

@ -1,3 +1,26 @@
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

View File

@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
@ -165,7 +166,7 @@ usage (char *program)
/* 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;
@ -193,7 +194,7 @@ FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char *cache_file)
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);
@ -326,7 +327,7 @@ main (int argc, char **argv)
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);

View File

@ -44,7 +44,7 @@ static void *
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);
@ -58,6 +58,9 @@ FcCacheMachineSignature (void);
static FcBool
FcCacheHaveBank (int bank);
static void
FcCacheAddBankDir (int bank, const char * dir);
#define FC_DBG_CACHE_REF 1024
static char *
@ -254,7 +257,7 @@ FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, con
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;
@ -734,7 +737,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir)
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);
@ -749,7 +752,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir)
}
static FcBool
FcDirCacheConsume (int fd, FcFontSet *set)
FcDirCacheConsume (int fd, const char * dir, FcFontSet *set)
{
FcCache metadata;
void * current_dir_block;
@ -771,6 +774,8 @@ FcDirCacheConsume (int fd, FcFontSet *set)
if (!FcFontSetUnserialize (metadata, set, current_dir_block))
return FcFalse;
FcCacheAddBankDir (metadata.bank, dir);
return FcTrue;
}
@ -964,6 +969,7 @@ FcCacheMachineSignature ()
static int banks_ptr = 0, banks_alloc = 0;
static int * bankId = 0, * bankIdx = 0;
static const char ** bankDirs = 0;
static FcBool
FcCacheHaveBank (int bank)
@ -999,6 +1005,8 @@ FcCacheBankToIndex (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;
@ -1009,6 +1017,11 @@ FcCacheBankToIndex (int bank)
return -1;
bankIdx = bidx;
bds = realloc (bankDirs, (banks_alloc + 4) * sizeof (char *));
if (!bds)
return -1;
bankDirs = bds;
banks_alloc += 4;
}
@ -1017,3 +1030,22 @@ FcCacheBankToIndex (int bank)
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];
}

View File

@ -47,6 +47,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include "fcint.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@ -1287,9 +1288,11 @@ FcFreeTypeQuery (const FcChar8 *file,
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;

View File

@ -450,6 +450,9 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir);
int
FcCacheBankToIndex (int bank);
const char *
FcCacheFindBankDir (int bank);
/* fccfg.c */
@ -802,6 +805,12 @@ FcPatternFini (void);
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);

View File

@ -422,6 +422,14 @@ FcListAppend (FcListHashTable *table,
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)
{

View File

@ -295,6 +295,9 @@ FcPatternDestroy (FcPattern *p)
{
int i;
if (FcPatternFindFullFname (p))
FcPatternAddFullFname (p, 0);
if (p->ref == FC_REF_CONSTANT || --p->ref > 0)
return;
@ -1115,6 +1118,42 @@ FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s
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;
}
@ -1874,3 +1913,61 @@ FcStrUnserialize (FcCache metadata, void *block_ptr)
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;
}