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>
|
2005-10-25 Jinghua Luo <sunmoon1997@gmail.com>
|
||||||
reviewed by: plam
|
reviewed by: plam
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -165,7 +166,7 @@ usage (char *program)
|
||||||
|
|
||||||
/* read serialized state from the cache file */
|
/* read serialized state from the cache file */
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char *cache_file)
|
FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char * current_arch_machine_name;
|
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)
|
while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
|
||||||
FcStrSetAdd (dirs, (FcChar8 *)subdirName);
|
FcStrSetAdd (dirs, (FcChar8 *)subdirName);
|
||||||
|
|
||||||
if (!FcDirCacheConsume (fd, set))
|
if (!FcDirCacheConsume (fd, dir, set))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -326,7 +327,7 @@ main (int argc, char **argv)
|
||||||
i = 1;
|
i = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (FcCacheFileRead (fs, dirs, argv[i]))
|
if (FcCacheFileRead (fs, dirs, dirname (argv[i]), argv[i]))
|
||||||
FcCachePrintSet (fs, dirs, argv[i]);
|
FcCachePrintSet (fs, dirs, argv[i]);
|
||||||
|
|
||||||
FcStrSetDestroy (dirs);
|
FcStrSetDestroy (dirs);
|
||||||
|
|
|
@ -44,7 +44,7 @@ static void *
|
||||||
FcDirCacheProduce (FcFontSet *set, FcCache * metadata);
|
FcDirCacheProduce (FcFontSet *set, FcCache * metadata);
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcDirCacheConsume (int fd, FcFontSet *set);
|
FcDirCacheConsume (int fd, const char * dir, FcFontSet *set);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir);
|
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir);
|
||||||
|
@ -58,6 +58,9 @@ FcCacheMachineSignature (void);
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCacheHaveBank (int bank);
|
FcCacheHaveBank (int bank);
|
||||||
|
|
||||||
|
static void
|
||||||
|
FcCacheAddBankDir (int bank, const char * dir);
|
||||||
|
|
||||||
#define FC_DBG_CACHE_REF 1024
|
#define FC_DBG_CACHE_REF 1024
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -254,7 +257,7 @@ FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, con
|
||||||
if (strncmp (d->name, dir, strlen(dir)) == 0)
|
if (strncmp (d->name, dir, strlen(dir)) == 0)
|
||||||
{
|
{
|
||||||
lseek (cache->fd, d->offset, SEEK_SET);
|
lseek (cache->fd, d->offset, SEEK_SET);
|
||||||
if (!FcDirCacheConsume (cache->fd, set))
|
if (!FcDirCacheConsume (cache->fd, dir, set))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (strcmp (d->name, dir) == 0)
|
if (strcmp (d->name, dir) == 0)
|
||||||
ret = FcTrue;
|
ret = FcTrue;
|
||||||
|
@ -734,7 +737,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir)
|
||||||
while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
|
while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
|
||||||
FcStrSetAdd (dirs, (FcChar8 *)subdirName);
|
FcStrSetAdd (dirs, (FcChar8 *)subdirName);
|
||||||
|
|
||||||
if (!FcDirCacheConsume (fd, set))
|
if (!FcDirCacheConsume (fd, (const char *)dir, set))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -749,7 +752,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcDirCacheConsume (int fd, FcFontSet *set)
|
FcDirCacheConsume (int fd, const char * dir, FcFontSet *set)
|
||||||
{
|
{
|
||||||
FcCache metadata;
|
FcCache metadata;
|
||||||
void * current_dir_block;
|
void * current_dir_block;
|
||||||
|
@ -771,6 +774,8 @@ FcDirCacheConsume (int fd, FcFontSet *set)
|
||||||
if (!FcFontSetUnserialize (metadata, set, current_dir_block))
|
if (!FcFontSetUnserialize (metadata, set, current_dir_block))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
|
FcCacheAddBankDir (metadata.bank, dir);
|
||||||
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,6 +969,7 @@ FcCacheMachineSignature ()
|
||||||
|
|
||||||
static int banks_ptr = 0, banks_alloc = 0;
|
static int banks_ptr = 0, banks_alloc = 0;
|
||||||
static int * bankId = 0, * bankIdx = 0;
|
static int * bankId = 0, * bankIdx = 0;
|
||||||
|
static const char ** bankDirs = 0;
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCacheHaveBank (int bank)
|
FcCacheHaveBank (int bank)
|
||||||
|
@ -999,6 +1005,8 @@ FcCacheBankToIndex (int bank)
|
||||||
if (banks_ptr >= banks_alloc)
|
if (banks_ptr >= banks_alloc)
|
||||||
{
|
{
|
||||||
int * b, * bidx;
|
int * b, * bidx;
|
||||||
|
const char ** bds;
|
||||||
|
|
||||||
b = realloc (bankId, (banks_alloc + 4) * sizeof(int));
|
b = realloc (bankId, (banks_alloc + 4) * sizeof(int));
|
||||||
if (!b)
|
if (!b)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1009,6 +1017,11 @@ FcCacheBankToIndex (int bank)
|
||||||
return -1;
|
return -1;
|
||||||
bankIdx = bidx;
|
bankIdx = bidx;
|
||||||
|
|
||||||
|
bds = realloc (bankDirs, (banks_alloc + 4) * sizeof (char *));
|
||||||
|
if (!bds)
|
||||||
|
return -1;
|
||||||
|
bankDirs = bds;
|
||||||
|
|
||||||
banks_alloc += 4;
|
banks_alloc += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1017,3 +1030,22 @@ FcCacheBankToIndex (int bank)
|
||||||
bankIdx[i] = i;
|
bankIdx[i] = i;
|
||||||
return 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 <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
@ -1287,9 +1288,11 @@ FcFreeTypeQuery (const FcChar8 *file,
|
||||||
printf ("Saving unique fullname %s\n", full);
|
printf ("Saving unique fullname %s\n", full);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FcPatternAddString (pat, FC_FILE, file))
|
if (!FcPatternAddString (pat, FC_FILE, (FcChar8 *)basename((char *)file)))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
|
FcPatternAddFullFname (pat, (const char *)file);
|
||||||
|
|
||||||
if (!FcPatternAddInteger (pat, FC_INDEX, id))
|
if (!FcPatternAddInteger (pat, FC_INDEX, id))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
|
|
|
@ -451,6 +451,9 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir);
|
||||||
int
|
int
|
||||||
FcCacheBankToIndex (int bank);
|
FcCacheBankToIndex (int bank);
|
||||||
|
|
||||||
|
const char *
|
||||||
|
FcCacheFindBankDir (int bank);
|
||||||
|
|
||||||
/* fccfg.c */
|
/* fccfg.c */
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -802,6 +805,12 @@ FcPatternFini (void);
|
||||||
FcBool
|
FcBool
|
||||||
FcPatternAppend (FcPattern *p, FcPattern *s);
|
FcPatternAppend (FcPattern *p, FcPattern *s);
|
||||||
|
|
||||||
|
void
|
||||||
|
FcPatternAddFullFname (const FcPattern *p, const char *fname);
|
||||||
|
|
||||||
|
const char *
|
||||||
|
FcPatternFindFullFname (const FcPattern *p);
|
||||||
|
|
||||||
const FcChar8 *
|
const FcChar8 *
|
||||||
FcStrStaticName (const FcChar8 *name);
|
FcStrStaticName (const FcChar8 *name);
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,14 @@ FcListAppend (FcListHashTable *table,
|
||||||
else
|
else
|
||||||
defidx = 0;
|
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]);
|
e = FcPatternFindElt (font, os->objects[o]);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
|
|
97
src/fcpat.c
97
src/fcpat.c
|
@ -295,6 +295,9 @@ FcPatternDestroy (FcPattern *p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (FcPatternFindFullFname (p))
|
||||||
|
FcPatternAddFullFname (p, 0);
|
||||||
|
|
||||||
if (p->ref == FC_REF_CONSTANT || --p->ref > 0)
|
if (p->ref == FC_REF_CONSTANT || --p->ref > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1115,6 +1118,42 @@ FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s
|
||||||
return r;
|
return r;
|
||||||
if (v.type != FcTypeString)
|
if (v.type != FcTypeString)
|
||||||
return FcResultTypeMismatch;
|
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;
|
*s = (FcChar8 *) v.u.s;
|
||||||
return FcResultMatch;
|
return FcResultMatch;
|
||||||
}
|
}
|
||||||
|
@ -1874,3 +1913,61 @@ FcStrUnserialize (FcCache metadata, void *block_ptr)
|
||||||
return 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