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:
parent
be99726f67
commit
e77c17184a
23
ChangeLog
23
ChangeLog
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -451,6 +451,9 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir);
|
|||
int
|
||||
FcCacheBankToIndex (int bank);
|
||||
|
||||
const char *
|
||||
FcCacheFindBankDir (int bank);
|
||||
|
||||
/* fccfg.c */
|
||||
|
||||
FcBool
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
97
src/fcpat.c
97
src/fcpat.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue