Overhaul the serialization system to create one mmapable file per directory

and distribute bytes for each directory from a single malloc for that
    directory. Store pointers as differences between the data pointed to
    and the pointer's address (s_off = s - v). Don't serialize data
    structures that never actually get serialized. Separate strings used
    for keys from strings used for values (in FcPatternElt and FcValue,
    respectively). Bump FC_CACHE_VERSION to 2.
This commit is contained in:
Patrick Lam 2005-08-24 06:21:30 +00:00
parent 212c9f437e
commit 4262e0b385
20 changed files with 1588 additions and 2259 deletions

View File

@ -93,7 +93,6 @@ usage (char *program)
exit (1);
}
#if 0
static int
nsubdirs (FcStrSet *set)
{
@ -192,6 +191,7 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
ret++;
continue;
}
#if 0 // put this back later after fixing DirCacheValid
if (!force && FcDirCacheValid (dir))
{
if (verbose)
@ -199,11 +199,13 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
set->nfont, nsubdirs(subdirs));
}
else
#endif
{
if (verbose)
printf ("caching, %d fonts, %d dirs\n",
set->nfont, nsubdirs (subdirs));
if (!FcDirSave (set, subdirs, dir))
if (!FcDirSave (set, dir))
{
fprintf (stderr, "Can't save cache in \"%s\"\n", dir);
ret++;
@ -223,7 +225,6 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
FcStrListDone (list);
return ret;
}
#endif
int
main (int argc, char **argv)
@ -280,10 +281,6 @@ main (int argc, char **argv)
return 1;
}
/* We don't yet have per-directory caches. */
ret = (FcCacheWrite (config) == FcFalse);
#if 0
if (argv[i])
{
dirs = FcStrSetCreate ();
@ -308,7 +305,6 @@ main (int argc, char **argv)
else
list = FcConfigGetConfigDirs (config);
ret = scanDirs (list, config, argv[0], force, verbose);
#endif
/*
* Now we need to sleep a second (or two, to be extra sure), to make
* sure that timestamps for changes after this run of fc-cache are later

View File

@ -48,7 +48,7 @@ FcMemFree (int kind, int size)
}
int
FcCacheNextOffset (int fd)
FcCacheBankToIndex (int bank)
{
return -1;
}
@ -404,7 +404,7 @@ main (int argc, char **argv)
if (j < 0)
j = i;
printf (" { (FcChar8 *) \"%s\",\n"
" { FC_REF_CONSTANT, %d, FcStorageDynamic, "
" { FC_REF_CONSTANT, %d, FC_BANK_DYNAMIC, "
"{ { (FcCharLeaf **) leaves_%s, "
"(FcChar16 *) numbers_%s } } } },\n",
langs[i],

View File

@ -59,22 +59,22 @@
__v__.u.d = va_arg (va, double); \
break; \
case FcTypeString: \
__v__.u.si = va_arg (va, FcObjectPtr); \
__v__.u.s = va_arg (va, const char *); \
break; \
case FcTypeBool: \
__v__.u.b = va_arg (va, FcBool); \
break; \
case FcTypeMatrix: \
__v__.u.mi = va_arg (va, FcMatrixPtr); \
__v__.u.m = va_arg (va, const FcMatrix *); \
break; \
case FcTypeCharSet: \
__v__.u.ci = va_arg (va, FcCharSetPtr); \
__v__.u.c = va_arg (va, const FcCharSet *); \
break; \
case FcTypeFTFace: \
__v__.u.f = va_arg (va, FT_Face); \
break; \
case FcTypeLangSet: \
__v__.u.li = va_arg (va, FcLangSetPtr); \
__v__.u.l = va_arg (va, const FcLangSet *); \
break; \
} \
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \

View File

@ -54,7 +54,7 @@ typedef int FcBool;
* it means multiple copies of the font information.
*/
#define FC_CACHE_VERSION "1"
#define FC_CACHE_VERSION "2"
#define FcTrue 1
#define FcFalse 0
@ -196,52 +196,28 @@ typedef enum _FcResult {
FcResultOutOfMemory
} FcResult;
typedef enum _FcStorage {
FcStorageStatic, FcStorageDynamic
} FcStorage;
typedef struct _FcPattern FcPattern;
typedef struct _FcLangSet FcLangSet;
typedef struct _FcMatrixPtr {
FcStorage storage;
union {
int stat;
FcMatrix *dyn;
} u;
} FcMatrixPtr;
typedef struct _FcCharSetPtr {
FcStorage storage;
union {
int stat;
FcCharSet *dyn;
} u;
} FcCharSetPtr;
typedef struct _FcLangSetPtr {
FcStorage storage;
union {
int stat;
FcLangSet *dyn;
} u;
} FcLangSetPtr;
typedef int FcObjectPtr;
#define FC_BANK_DYNAMIC 0
#define FC_BANK_FIRST 1
typedef struct _FcValue {
FcType type;
union {
FcObjectPtr si;
const FcChar8 *s;
int s_off;
int i;
FcBool b;
double d;
FcMatrixPtr mi;
FcCharSetPtr ci;
const FcMatrix *m;
const FcCharSet *c;
int c_off;
void *f;
const FcPattern *p;
FcLangSetPtr li;
const FcLangSet *l;
int l_off; // this is a difference of char *s
} u;
} FcValue;
@ -254,7 +230,7 @@ typedef struct _FcFontSet {
typedef struct _FcObjectSet {
int nobject;
int sobject;
FcObjectPtr *objects;
const char **objects;
} FcObjectSet;
typedef enum _FcMatchKind {
@ -471,7 +447,7 @@ FcDirScan (FcFontSet *set,
FcBool force);
FcBool
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
FcDirSave (FcFontSet *set, const FcChar8 *dir);
/* fcfreetype.c */
FcPattern *
@ -648,9 +624,6 @@ FcMatrixScale (FcMatrix *m, double sx, double sy);
void
FcMatrixShear (FcMatrix *m, double sh, double sv);
FcMatrix *
FcMatrixPtrU (FcMatrixPtr mi);
/* fcname.c */
FcBool

View File

@ -23,6 +23,7 @@
*/
#include <fcntl.h>
#include <dirent.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include "fcint.h"
@ -192,12 +193,6 @@ FcGlobalCacheDestroy (FcGlobalCache *cache)
free (cache);
}
/*
* Cache file syntax is quite simple:
*
* "file_name" id time "font_name" \n
*/
void
FcGlobalCacheLoad (FcGlobalCache *cache,
const FcChar8 *cache_file)
@ -388,89 +383,15 @@ bail0:
* Find the next presumably-mmapable offset after the current file
* pointer.
*/
int
FcCacheNextOffset(int fd)
static int
FcCacheNextOffset(off_t w)
{
off_t w;
w = lseek(fd, 0, SEEK_END);
if (w % PAGESIZE == 0)
return w;
else
return ((w / PAGESIZE)+1)*PAGESIZE;
}
/* will go away once we use config->cache */
#define CACHE_DEFAULT_TMPDIR "/tmp"
#define CACHE_DEFAULT_NAME "/fontconfig-mmap"
static char *
FcCacheFilename(void)
{
struct utsname b;
static char * name = 0;
if (name)
return name;
if (uname(&b) == -1)
name = CACHE_DEFAULT_NAME;
else
{
char * tmpname = getenv("TMPDIR");
char * logname = getenv("LOGNAME");
if (!tmpname)
tmpname = CACHE_DEFAULT_TMPDIR;
name = malloc(strlen(CACHE_DEFAULT_NAME) +
strlen(tmpname) +
(logname ? strlen(logname) : 0) + 5);
strcpy(name, tmpname);
strcat(name, CACHE_DEFAULT_NAME);
strcat(name, "-");
strcat(name, logname ? logname : "");
}
return name;
}
/*
* Wipe out static state.
*/
void
FcCacheClearStatic()
{
FcFontSetClearStatic();
FcPatternClearStatic();
FcValueListClearStatic();
FcObjectClearStatic();
FcMatrixClearStatic();
FcCharSetClearStatic();
FcLangSetClearStatic();
}
/*
* Trigger the counting phase: this tells us how much to allocate.
*/
FcBool
FcCachePrepareSerialize (FcConfig * config)
{
int i;
for (i = FcSetSystem; i <= FcSetApplication; i++)
if (config->fonts[i] && !FcFontSetPrepareSerialize(config->fonts[i]))
return FcFalse;
return FcTrue;
}
/* allocate and populate static structures */
FcBool
FcCacheSerialize (FcConfig * config)
{
int i;
for (i = FcSetSystem; i <= FcSetApplication; i++)
if (config->fonts[i] && !FcFontSetSerialize(config->fonts[i]))
return FcFalse;
return FcTrue;
}
/* get the current arch name */
/* caller is responsible for freeing returned pointer */
static char *
@ -531,7 +452,7 @@ FcCacheMoveDown (int fd, off_t start)
{
char * buf = malloc (BUF_SIZE);
char candidate_arch_machine_name[64], bytes_to_skip[7];
long bs; off_t pos;
long bs;
int c, bytes_skipped;
if (!buf)
@ -571,131 +492,294 @@ FcCacheMoveDown (int fd, off_t start)
return FcFalse;
}
/* read serialized state from the cache file */
FcBool
static int
FcCacheReadDirs (FcStrList *list, FcFontSet * set)
{
DIR *d;
struct dirent *e;
int ret = 0;
FcChar8 *dir;
FcChar8 *file, *base;
FcStrSet *subdirs;
FcStrList *sublist;
struct stat statb;
/*
* Now scan all of the directories into separate databases
* and write out the results
*/
while ((dir = FcStrListNext (list)))
{
/* freed below */
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file)
return FcFalse;
strcpy ((char *) file, (char *) dir);
strcat ((char *) file, "/");
base = file + strlen ((char *) file);
subdirs = FcStrSetCreate ();
if (!subdirs)
{
fprintf (stderr, "Can't create directory set\n");
ret++;
free (file);
continue;
}
if (access ((char *) dir, X_OK) < 0)
{
switch (errno) {
case ENOENT:
case ENOTDIR:
case EACCES:
break;
default:
fprintf (stderr, "\"%s\": ", dir);
perror ("");
ret++;
}
FcStrSetDestroy (subdirs);
free (file);
continue;
}
if (stat ((char *) dir, &statb) == -1)
{
fprintf (stderr, "\"%s\": ", dir);
perror ("");
FcStrSetDestroy (subdirs);
ret++;
free (file);
continue;
}
if (!S_ISDIR (statb.st_mode))
{
fprintf (stderr, "\"%s\": not a directory, skipping\n", dir);
FcStrSetDestroy (subdirs);
free (file);
continue;
}
d = opendir ((char *) dir);
if (!d)
{
FcStrSetDestroy (subdirs);
free (file);
continue;
}
while ((e = readdir (d)))
{
if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
{
strcpy ((char *) base, (char *) e->d_name);
if (FcFileIsDir (file) && !FcStrSetAdd (subdirs, file))
ret++;
}
}
closedir (d);
if (1 || FcDirCacheValid (dir))
{
FcDirCacheRead (set, dir);
}
else
{
ret++;
#if 0 // (implement per-dir loading)
if (verbose)
printf ("caching, %d fonts, %d dirs\n",
set->nfont, nsubdirs (subdirs));
if (!FcDirSave (set, dir))
{
fprintf (stderr, "Can't save cache in \"%s\"\n", dir);
ret++;
}
#endif
}
sublist = FcStrListCreate (subdirs);
FcStrSetDestroy (subdirs);
if (!sublist)
{
fprintf (stderr, "Can't create subdir list in \"%s\"\n", dir);
ret++;
free (file);
continue;
}
ret += FcCacheReadDirs (sublist, set);
free (file);
}
FcStrListDone (list);
return ret;
}
FcFontSet *
FcCacheRead (FcConfig *config)
{
int fd, i;
FcFontSet * s = FcFontSetCreate();
if (!s)
return 0;
if (force)
goto bail;
if (FcCacheReadDirs (FcConfigGetConfigDirs (config), s))
goto bail;
return s;
bail:
FcFontSetDestroy (s);
return 0;
}
/* read serialized state from the cache file */
FcBool
FcDirCacheRead (FcFontSet * set, const FcChar8 *dir)
{
FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
int fd;
FcCache metadata;
void * current_dir_block;
char * current_arch_machine_name;
char candidate_arch_machine_name[64], bytes_in_block[7];
off_t current_arch_start = 0;
if (force)
return FcFalse;
fd = open(FcCacheFilename(), O_RDONLY);
if (fd == -1)
return FcFalse;
goto bail;
if (!cache_file)
goto bail;
current_arch_machine_name = FcCacheGetCurrentArch();
fd = open(cache_file, O_RDONLY);
if (fd == -1)
goto bail0;
current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
if (current_arch_start < 0)
goto bail;
goto bail1;
lseek (fd, current_arch_start, SEEK_SET);
if (FcCacheReadString (fd, candidate_arch_machine_name,
sizeof (candidate_arch_machine_name)) == 0)
goto bail;
goto bail1;
if (FcCacheReadString (fd, bytes_in_block, 7) == 0)
goto bail;
goto bail1;
// sanity check for endianness issues
read(fd, &metadata, sizeof(FcCache));
if (metadata.magic != FC_CACHE_MAGIC)
goto bail;
goto bail1;
if (!FcObjectRead(fd, metadata)) goto bail1;
if (!FcStrSetRead(fd, metadata)) goto bail1;
if (!FcCharSetRead(fd, metadata)) goto bail1;
if (!FcMatrixRead(fd, metadata)) goto bail1;
if (!FcLangSetRead(fd, metadata)) goto bail1;
if (!FcValueListRead(fd, metadata)) goto bail1;
if (!FcPatternEltRead(fd, metadata)) goto bail1;
if (!FcPatternRead(fd, metadata)) goto bail1;
if (!FcFontSetRead(fd, config, metadata)) goto bail1;
if (metadata.count)
{
off_t pos = FcCacheNextOffset (lseek(fd, 0, SEEK_CUR));
current_dir_block = mmap (0, metadata.count,
PROT_READ, MAP_SHARED, fd, pos);
if (current_dir_block == MAP_FAILED)
perror("");
if (!FcFontSetUnserialize (metadata, set, current_dir_block))
goto bail1;
}
close(fd);
free (current_arch_machine_name);
free (cache_file);
return FcTrue;
bail1:
for (i = FcSetSystem; i <= FcSetApplication; i++)
config->fonts[i] = 0;
close(fd);
bail:
bail0:
free (current_arch_machine_name);
bail:
free (cache_file);
return FcFalse;
}
/* write serialized state to the cache file */
FcBool
FcCacheWrite (FcConfig * config)
FcDirCacheWrite (int bank, FcFontSet *set, const FcChar8 *dir)
{
int fd;
FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
int fd, bytes_to_write, metadata_bytes;
FcCache metadata;
off_t current_arch_start = 0, truncate_to;
char * current_arch_machine_name, bytes_written[7] = "dedbef";
void * current_dir_block, *final_dir_block;
if (!FcCachePrepareSerialize (config))
if (!cache_file)
goto bail;
FcFontSetNewBank();
bytes_to_write = FcFontSetNeededBytes (set);
metadata_bytes = FcCacheNextOffset (sizeof (FcCache));
if (!bytes_to_write)
{
unlink (cache_file);
free (cache_file);
return FcTrue;
}
current_dir_block = malloc (bytes_to_write);
memset (&metadata, 0, sizeof(FcCache));
metadata.count = bytes_to_write;
metadata.bank = bank;
if (!current_dir_block)
goto bail;
final_dir_block = FcFontSetDistributeBytes (&metadata, current_dir_block);
if (!FcFontSetSerialize (bank, set))
return FcFalse;
if (!FcCacheSerialize (config))
return FcFalse;
if (FcDebug () & FC_DBG_CACHE)
printf ("FcDirCacheWriteDir cache_file \"%s\"\n", cache_file);
fd = open(FcCacheFilename(), O_RDWR | O_CREAT, 0666);
fd = open(cache_file, O_RDWR | O_CREAT, 0666);
if (fd == -1)
return FcFalse;
current_arch_machine_name = FcCacheGetCurrentArch();
current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
if (current_arch_start < 0)
current_arch_start = FcCacheNextOffset (fd);
current_arch_start = FcCacheNextOffset (lseek(fd, 0, SEEK_END));
if (!FcCacheMoveDown(fd, current_arch_start))
goto bail;
goto bail1;
current_arch_start = lseek(fd, 0, SEEK_CUR);
if (ftruncate (fd, current_arch_start) == -1)
goto bail;
goto bail1;
/* reserve space for arch, count & metadata */
if (!FcCacheWriteString (fd, current_arch_machine_name))
goto bail;
if (!FcCacheWriteString (fd, bytes_written))
goto bail;
memset (&metadata, 0, sizeof(FcCache));
metadata.magic = FC_CACHE_MAGIC;
write(fd, &metadata, sizeof(FcCache));
if (!FcFontSetWrite(fd, config, &metadata)) goto bail;
if (!FcPatternWrite(fd, &metadata)) goto bail;
if (!FcPatternEltWrite(fd, &metadata)) goto bail;
if (!FcValueListWrite(fd, &metadata)) goto bail;
if (!FcLangSetWrite(fd, &metadata)) goto bail;
if (!FcCharSetWrite(fd, &metadata)) goto bail;
if (!FcMatrixWrite(fd, &metadata)) goto bail;
if (!FcStrSetWrite(fd, &metadata)) goto bail;
if (!FcObjectWrite(fd, &metadata)) goto bail;
goto bail1;
/* now write the address of the next offset */
truncate_to = FcCacheNextOffset(fd) - current_arch_start;
lseek(fd, current_arch_start + strlen(current_arch_machine_name)+1,
SEEK_SET);
truncate_to = FcCacheNextOffset(current_arch_start + bytes_to_write + metadata_bytes) -
current_arch_start;
strcpy (bytes_written, l64a(truncate_to));
if (!FcCacheWriteString (fd, bytes_written))
goto bail;
goto bail1;
/* now rewrite metadata & truncate file */
if (write(fd, &metadata, sizeof(FcCache)) != sizeof (FcCache))
goto bail;
metadata.magic = FC_CACHE_MAGIC;
write (fd, &metadata, sizeof(FcCache));
lseek (fd, FcCacheNextOffset (lseek(fd, 0, SEEK_END)), SEEK_SET);
write (fd, current_dir_block, bytes_to_write);
/* this actually serves to pad out the cache file */
if (ftruncate (fd, current_arch_start + truncate_to) == -1)
goto bail;
goto bail1;
close(fd);
return FcTrue;
bail:
bail1:
free (current_dir_block);
free (current_arch_machine_name);
bail:
unlink (cache_file);
free (cache_file);
return FcFalse;
}
@ -705,3 +789,56 @@ FcCacheForce (FcBool f)
{
force = f;
}
static int banks_ptr = 0, banks_alloc = 0;
static int * bankId = 0;
int
FcCacheBankCount (void)
{
return banks_ptr;
}
FcBool
FcCacheHaveBank (int bank)
{
int i;
if (bank < FC_BANK_FIRST)
return FcTrue;
for (i = 0; i < banks_ptr; i++)
if (bankId[i] == bank)
return FcTrue;
return FcFalse;
}
int
FcCacheBankToIndex (int bank)
{
static int lastBank = FC_BANK_DYNAMIC, lastIndex = -1;
int i;
int * b;
if (bank == lastBank)
return lastIndex;
for (i = 0; i < banks_ptr; i++)
if (bankId[i] == bank)
return i;
if (banks_ptr <= banks_alloc)
{
b = realloc (bankId, banks_alloc + 4);
if (!b)
return -1;
bankId = b;
banks_alloc += 4;
}
i = banks_ptr++;
bankId[i] = bank;
return i;
}

View File

@ -247,7 +247,7 @@ FcConfigDestroy (FcConfig *config)
FcBool
FcConfigBuildFonts (FcConfig *config)
{
FcFontSet *fonts;
FcFontSet *fonts, *cached_fonts;
FcGlobalCache *cache;
FcStrList *list;
FcChar8 *dir;
@ -269,19 +269,34 @@ FcConfigBuildFonts (FcConfig *config)
goto bail1;
#endif
list = FcConfigGetFontDirs (config);
if (!list)
goto bail1;
while ((dir = FcStrListNext (list)))
cached_fonts = FcCacheRead(config);
if (!cached_fonts)
{
if (FcDebug () & FC_DBG_FONTSET)
printf ("scan dir %s\n", dir);
FcDirScanConfig (fonts, config->fontDirs, cache,
config->blanks, dir, FcFalse, config);
list = FcConfigGetFontDirs (config);
if (!list)
goto bail1;
while ((dir = FcStrListNext (list)))
{
if (FcDebug () & FC_DBG_FONTSET)
printf ("scan dir %s\n", dir);
FcDirScanConfig (fonts, config->fontDirs, cache,
config->blanks, dir, FcFalse, config);
}
FcStrListDone (list);
}
else
{
int i;
for (i = 0; i < cached_fonts->nfont; i++)
{
if (FcConfigAcceptFont (config, cached_fonts->fonts[i]))
FcFontSetAdd (fonts, cached_fonts->fonts[i]);
}
FcFontSetDestroy (cached_fonts);
}
FcStrListDone (list);
if (FcDebug () & FC_DBG_FONTSET)
FcFontSetPrint (fonts);
@ -558,25 +573,24 @@ FcConfigPromote (FcValue v, FcValue u)
}
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
{
v.u.mi = FcIdentityMatrix;
v.u.m = &FcIdentityMatrix;
v.type = FcTypeMatrix;
}
else if (v.type == FcTypeString && u.type == FcTypeLangSet)
{
v.u.li = FcLangSetPtrCreateDynamic(FcLangSetPromote
(FcObjectPtrU(v.u.si)));
v.u.l = FcLangSetPromote (v.u.s);
v.type = FcTypeLangSet;
}
return v;
}
FcBool
FcConfigCompareValue (const FcValue left_o,
FcConfigCompareValue (const FcValue *left_o,
FcOp op,
const FcValue right_o)
const FcValue *right_o)
{
FcValue left = left_o;
FcValue right = right_o;
FcValue left = FcValueCanonicalize(left_o);
FcValue right = FcValueCanonicalize(right_o);
FcBool ret = FcFalse;
left = FcConfigPromote (left, right);
@ -632,20 +646,16 @@ FcConfigCompareValue (const FcValue left_o,
switch (op) {
case FcOpEqual:
case FcOpListing:
ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
FcObjectPtrU(right.u.si)) == 0;
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
break;
case FcOpContains:
ret = FcStrStrIgnoreCase (FcObjectPtrU(left.u.si),
FcObjectPtrU(right.u.si)) != 0;
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
break;
case FcOpNotEqual:
ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
FcObjectPtrU(right.u.si)) != 0;
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
break;
case FcOpNotContains:
ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
FcObjectPtrU(right.u.si)) == 0;
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
break;
default:
break;
@ -656,11 +666,11 @@ FcConfigCompareValue (const FcValue left_o,
case FcOpEqual:
case FcOpContains:
case FcOpListing:
ret = FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
ret = FcMatrixEqual (left.u.m, right.u.m);
break;
case FcOpNotEqual:
case FcOpNotContains:
ret = !FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
ret = !FcMatrixEqual (left.u.m, right.u.m);
break;
default:
break;
@ -671,17 +681,17 @@ FcConfigCompareValue (const FcValue left_o,
case FcOpContains:
case FcOpListing:
/* left contains right if right is a subset of left */
ret = FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
ret = FcCharSetIsSubset (right.u.c, left.u.c);
break;
case FcOpNotContains:
/* left contains right if right is a subset of left */
ret = !FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
ret = !FcCharSetIsSubset (right.u.c, left.u.c);
break;
case FcOpEqual:
ret = FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
ret = FcCharSetEqual (left.u.c, right.u.c);
break;
case FcOpNotEqual:
ret = !FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
ret = !FcCharSetEqual (left.u.c, right.u.c);
break;
default:
break;
@ -691,16 +701,16 @@ FcConfigCompareValue (const FcValue left_o,
switch (op) {
case FcOpContains:
case FcOpListing:
ret = FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
ret = FcLangSetContains (left.u.l, right.u.l);
break;
case FcOpNotContains:
ret = !FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
ret = !FcLangSetContains (left.u.l, right.u.l);
break;
case FcOpEqual:
ret = FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
ret = FcLangSetEqual (left.u.l, right.u.l);
break;
case FcOpNotEqual:
ret = !FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
ret = !FcLangSetEqual (left.u.l, right.u.l);
break;
default:
break;
@ -768,17 +778,17 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
case FcOpString:
v.type = FcTypeString;
v.u.si = FcObjectStaticName(e->u.sval);
v.u.s = FcObjectStaticName(e->u.sval);
v = FcValueSave (v);
break;
case FcOpMatrix:
v.type = FcTypeMatrix;
v.u.mi = FcMatrixPtrCreateDynamic(e->u.mval);
v.u.m = e->u.mval;
v = FcValueSave (v);
break;
case FcOpCharSet:
v.type = FcTypeCharSet;
v.u.ci = FcCharSetPtrCreateDynamic(e->u.cval);
v.u.c = e->u.cval;
v = FcValueSave (v);
break;
case FcOpBool:
@ -821,7 +831,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
vl = FcConfigEvaluate (p, e->u.tree.left);
vr = FcConfigEvaluate (p, e->u.tree.right);
v.type = FcTypeBool;
v.u.b = FcConfigCompareValue (vl, e->op, vr);
v.u.b = FcConfigCompareValue (&vl, e->op, &vr);
FcValueDestroy (vl);
FcValueDestroy (vr);
break;
@ -886,11 +896,9 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
switch (e->op) {
case FcOpPlus:
v.type = FcTypeString;
v.u.si = FcObjectStaticName
(FcStrPlus (FcObjectPtrU(vl.u.si),
FcObjectPtrU(vr.u.si)));
v.u.s = FcObjectStaticName (FcStrPlus (vl.u.s, vr.u.s));
if (!FcObjectPtrU(v.u.si))
if (!v.u.s)
v.type = FcTypeVoid;
break;
default:
@ -906,9 +914,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
if (m)
{
FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix));
FcMatrixMultiply (m, FcMatrixPtrU(vl.u.mi),
FcMatrixPtrU(vr.u.mi));
v.u.mi = FcMatrixPtrCreateDynamic(m);
FcMatrixMultiply (m, vl.u.m, vr.u.m);
v.u.m = m;
}
else
{
@ -1041,7 +1048,7 @@ FcConfigMatchValueList (FcPattern *p,
for (v = values; v; v = FcValueListPtrU(v->next))
{
/* Compare the pattern value to the match expression value */
if (FcConfigCompareValue (v->value, t->op, value))
if (FcConfigCompareValue (&v->value, t->op, &value))
{
if (!ret)
ret = v;
@ -1088,7 +1095,7 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
{
FcValueListPtr next = FcValueListPtrU(lp)->next;
if (lp.storage == FcStorageDynamic)
if (lp.bank == FC_BANK_DYNAMIC)
{
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
free (l);
@ -1866,7 +1873,7 @@ FcConfigGlobsMatch (const FcStrSet *globs,
int i;
for (i = 0; i < globs->num; i++)
if (FcConfigGlobMatch (FcStrSetGet(globs, i), string))
if (FcConfigGlobMatch (globs->strs[i], string))
return FcTrue;
return FcFalse;
}

View File

@ -23,34 +23,21 @@
*/
#include <stdlib.h>
#include <sys/mman.h>
#include "fcint.h"
/* #define CHECK */
/* #define CHATTY */
static FcCharSet * charsets = 0;
static FcChar16 * numbers = 0;
static int charset_ptr, charset_count;
static FcCharSet ** charsets = 0;
static FcChar16 ** numbers = 0;
static int charset_bank_count = 0, charset_ptr, charset_count;
static int charset_numbers_ptr, charset_numbers_count;
static FcCharLeaf * leaves = 0;
static FcCharLeaf ** leaves = 0;
static int charset_leaf_ptr, charset_leaf_count;
static int * leaf_idx = 0;
static int ** leaf_idx = 0;
static int charset_leaf_idx_ptr, charset_leaf_idx_count;
void
FcCharSetClearStatic()
{
charsets = 0;
numbers = 0;
charset_ptr = 0; charset_count = 0;
leaves = 0;
charset_leaf_ptr = 0; charset_leaf_count = 0;
leaf_idx = 0;
charset_leaf_idx_ptr = 0; charset_leaf_idx_count = 0;
}
FcCharSet *
FcCharSetCreate (void)
{
@ -62,7 +49,7 @@ FcCharSetCreate (void)
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
fcs->ref = 1;
fcs->num = 0;
fcs->storage = FcStorageDynamic;
fcs->bank = FC_BANK_DYNAMIC;
fcs->u.dyn.leaves = 0;
fcs->u.dyn.numbers = 0;
return fcs;
@ -77,18 +64,6 @@ FcCharSetNew (void)
return FcCharSetCreate ();
}
void
FcCharSetPtrDestroy (FcCharSetPtr fcs)
{
FcCharSetDestroy (FcCharSetPtrU(fcs));
if (fcs.storage == FcStorageDynamic &&
FcCharSetPtrU(fcs)->ref != FC_REF_CONSTANT)
{
free (fcs.u.dyn);
FcMemFree (FC_MEM_CHARSET, sizeof(FcCharSet));
}
}
void
FcCharSetDestroy (FcCharSet *fcs)
{
@ -97,7 +72,7 @@ FcCharSetDestroy (FcCharSet *fcs)
return;
if (--fcs->ref > 0)
return;
if (fcs->storage == FcStorageDynamic)
if (fcs->bank == FC_BANK_DYNAMIC)
{
for (i = 0; i < fcs->num; i++)
{
@ -173,7 +148,7 @@ FcCharSetPutLeaf (FcCharSet *fcs,
ucs4 >>= 8;
if (ucs4 >= 0x10000)
return FcFalse;
if (fcs->storage == FcStorageStatic)
if (fcs->bank != FC_BANK_DYNAMIC)
{
int i;
@ -190,7 +165,6 @@ FcCharSetPutLeaf (FcCharSet *fcs,
leaves[i] = FcCharSetGetLeaf(fcs, i);
memcpy (numbers, FcCharSetGetNumbers(fcs),
fcs->num * sizeof (FcChar16));
fcs->storage = FcStorageDynamic;
}
else
{
@ -264,14 +238,14 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf)
if (pos >= 0)
{
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
if (fcs->storage == FcStorageDynamic)
if (fcs->bank == FC_BANK_DYNAMIC)
{
free (fcs->u.dyn.leaves[pos]);
fcs->u.dyn.leaves[pos] = leaf;
}
else
{
leaves[leaf_idx[fcs->u.stat.leafidx_offset]+pos] = *leaf;
leaves[fcs->bank][leaf_idx[fcs->bank][fcs->u.stat.leafidx_offset]+pos] = *leaf;
}
return FcTrue;
}
@ -384,14 +358,6 @@ FcCharSetCopy (FcCharSet *src)
return src;
}
FcCharSetPtr
FcCharSetCopyPtr (FcCharSetPtr src)
{
if (FcCharSetPtrU(src)->ref != FC_REF_CONSTANT)
FcCharSetPtrU(src)->ref++;
return src;
}
FcBool
FcCharSetEqual (const FcCharSet *a, const FcCharSet *b)
{
@ -1081,8 +1047,8 @@ FcCharSetFreezeBase (FcCharSet *fcs)
ent->set.ref = FC_REF_CONSTANT;
ent->set.num = fcs->num;
ent->set.storage = fcs->storage;
if (fcs->storage == FcStorageDynamic)
ent->set.bank = fcs->bank;
if (fcs->bank == FC_BANK_DYNAMIC)
{
if (fcs->num)
{
@ -1154,7 +1120,7 @@ FcCharSetFreeze (FcCharSet *fcs)
}
n = FcCharSetFreezeBase (b);
bail1:
if (b->storage == FcStorageDynamic)
if (b->bank == FC_BANK_DYNAMIC)
{
if (b->u.dyn.leaves)
{
@ -1231,7 +1197,7 @@ FcNameParseCharSet (FcChar8 *string)
#endif
n = FcCharSetFreezeBase (c);
bail1:
if (c->storage == FcStorageDynamic)
if (c->bank == FC_BANK_DYNAMIC)
{
if (c->u.dyn.leaves)
{
@ -1323,205 +1289,160 @@ FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c)
return FcTrue;
}
FcCharSet *
FcCharSetPtrU (FcCharSetPtr ci)
void
FcCharSetNewBank(void)
{
switch (ci.storage)
{
case FcStorageDynamic:
return ci.u.dyn;
case FcStorageStatic:
return &charsets[ci.u.stat];
default:
return 0;
}
charset_count = 0;
charset_numbers_count = 0;
charset_leaf_count = 0;
charset_leaf_idx_count = 0;
}
FcCharSetPtr
FcCharSetPtrCreateDynamic(FcCharSet *c)
int
FcCharSetNeededBytes (const FcCharSet *c)
{
FcCharSetPtr new;
new.storage = FcStorageDynamic;
new.u.dyn = c;
return new;
}
FcBool
FcCharSetPrepareSerialize(FcCharSet *c)
{
/* note the redundancy */
/* yes, there's redundancy */
charset_count++;
charset_leaf_idx_count++;
charset_leaf_count += c->num;
charset_numbers_count += c->num;
return sizeof (FcCharSet) +
sizeof (int) + /* leaf_idx */
sizeof (FcCharLeaf) * c->num + /* leaf */
sizeof (FcChar16) * c->num; /* number */
}
static FcBool
FcCharSetEnsureBank (int bi)
{
if (!charsets || charset_bank_count <= bi)
{
int new_count = charset_bank_count + 2;
FcCharSet ** cs;
FcChar16 ** n;
FcCharLeaf ** lvs;
int ** lvi;
int i;
cs = realloc(charsets, sizeof(FcCharSet*) * new_count);
if (!cs) return 0;
n = realloc(numbers, sizeof(FcChar16*) * new_count);
if (!n) return 0;
lvs = realloc(leaves, sizeof(FcCharLeaf*) * new_count);
if (!lvs) return 0;
lvi = realloc(leaf_idx, sizeof(int*) * new_count);
if (!lvi) return 0;
charsets = cs; numbers = n; leaves = lvs; leaf_idx = lvi;
for (i = charset_bank_count; i < new_count; i++)
{
charsets[i] = 0;
numbers[i] = 0;
leaves[i] = 0;
leaf_idx[i] = 0;
}
charset_bank_count = new_count;
}
return FcTrue;
}
FcCharSetPtr
FcCharSetSerialize(FcCharSet *c)
void *
FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr)
{
int bi = FcCacheBankToIndex(metadata->bank);
if (!FcCharSetEnsureBank(bi))
return 0;
charsets[bi] = (FcCharSet *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcCharSet) * charset_count));
numbers[bi] = (FcChar16 *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof(FcChar16) * charset_numbers_count));
leaves[bi] = (FcCharLeaf *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof(FcCharLeaf) * charset_leaf_count));
leaf_idx[bi] = (int *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof(int) * charset_leaf_idx_count));
metadata->charset_count = charset_count;
metadata->charset_numbers_count = charset_numbers_count;
metadata->charset_leaf_count = charset_leaf_count;
metadata->charset_leaf_idx_count = charset_leaf_idx_count;
charset_ptr = 0; charset_leaf_ptr = 0;
charset_leaf_idx_ptr = 0; charset_numbers_ptr = 0;
return block_ptr;
}
FcCharSet *
FcCharSetSerialize(int bank, FcCharSet *c)
{
int i;
FcCharSetPtr newp;
FcCharSet new;
if (!charsets)
{
charsets = malloc(sizeof(FcCharSet) * charset_count);
if (!charsets) goto bail;
numbers = malloc(sizeof(FcChar16) * charset_numbers_count);
if (!numbers) goto bail1;
leaves = malloc(sizeof(FcCharLeaf) * charset_leaf_count);
if (!leaves) goto bail2;
leaf_idx = malloc(sizeof(int)*charset_leaf_idx_count);
if (!leaf_idx) goto bail3;
}
int bi = FcCacheBankToIndex(bank), cp = charset_ptr;
new.ref = FC_REF_CONSTANT;
new.storage = FcStorageStatic;
new.bank = bank;
new.u.stat.leafidx_offset = charset_leaf_idx_ptr;
new.u.stat.numbers_offset = charset_numbers_ptr;
new.num = c->num;
newp.storage = FcStorageStatic;
newp.u.stat = charset_ptr;
charsets[charset_ptr++] = new;
charsets[bi][charset_ptr++] = new;
leaf_idx[charset_leaf_idx_ptr++] = charset_leaf_ptr;
leaf_idx[bi][charset_leaf_idx_ptr++] = charset_leaf_ptr;
for (i = 0; i < c->num; i++)
{
memcpy (&leaves[charset_leaf_ptr++],
memcpy (&leaves[bi][charset_leaf_ptr++],
c->u.dyn.leaves[i], sizeof(FcCharLeaf));
numbers[charset_numbers_ptr++] = c->u.dyn.numbers[i];
numbers[bi][charset_numbers_ptr++] = c->u.dyn.numbers[i];
}
return newp;
bail3:
free (leaves);
bail2:
free (numbers);
bail1:
free (charsets);
bail:
return FcCharSetPtrCreateDynamic(0);
return &charsets[bi][cp];
}
FcBool
FcCharSetRead (int fd, FcCache metadata)
void *
FcCharSetUnserialize (FcCache metadata, void *block_ptr)
{
charsets = mmap(NULL,
metadata.charsets_length * sizeof (FcCharSet),
PROT_READ,
MAP_SHARED, fd, metadata.charsets_offset);
if (charsets == MAP_FAILED)
goto bail;
charset_count = charset_ptr = metadata.charsets_length;
int bi = FcCacheBankToIndex(metadata.bank);
if (!FcCharSetEnsureBank(bi))
return 0;
leaves = mmap(NULL,
metadata.charset_num_sum * sizeof (FcCharLeaf),
PROT_READ,
MAP_SHARED, fd, metadata.charset_leaf_offset);
if (leaves == MAP_FAILED)
goto bail1;
charset_leaf_count = charset_leaf_ptr = metadata.charset_num_sum;
charsets[bi] = (FcCharSet *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof (FcCharSet) * metadata.charset_count));
numbers[bi] = (FcChar16 *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof(FcChar16) * metadata.charset_numbers_count));
leaves[bi] = (FcCharLeaf *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof(FcCharLeaf) * metadata.charset_leaf_count));
leaf_idx[bi] = (int *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
(sizeof(int) * metadata.charset_leaf_idx_count));
leaf_idx = mmap(NULL,
metadata.charsets_length * sizeof (FcCharLeaf*),
PROT_READ,
MAP_SHARED, fd, metadata.charset_leafidx_offset);
if (leaf_idx == MAP_FAILED)
goto bail2;
charset_leaf_idx_count = charset_leaf_idx_ptr = metadata.charsets_length;
numbers = mmap(NULL,
metadata.charset_num_sum * sizeof (FcChar16),
PROT_READ,
MAP_SHARED, fd, metadata.charset_numbers_offset);
if (numbers == MAP_FAILED)
goto bail3;
charset_numbers_count = charset_numbers_ptr = metadata.charset_num_sum;
return FcTrue;
bail3:
munmap (leaf_idx, metadata.charsets_length * sizeof (FcCharLeaf*));
bail2:
munmap (leaves, metadata.charset_num_sum * sizeof (FcCharLeaf));
bail1:
munmap (charsets, metadata.charsets_length * sizeof (FcCharSet));
bail:
return FcFalse;
}
FcBool
FcCharSetWrite (int fd, FcCache *metadata)
{
metadata->charsets_length = charset_ptr;
metadata->charsets_offset = FcCacheNextOffset(fd);
if (charset_ptr > 0)
{
lseek (fd, metadata->charsets_offset, SEEK_SET);
if (write (fd, charsets, charset_ptr * sizeof(FcCharSet)) == -1)
return FcFalse;
}
metadata->charset_leaf_offset = FcCacheNextOffset(fd);
metadata->charset_num_sum = charset_leaf_ptr;
if (charset_leaf_ptr > 0)
{
lseek (fd, metadata->charset_leaf_offset, SEEK_SET);
if (write (fd, leaves, charset_leaf_ptr * sizeof(FcCharLeaf)) == -1)
return FcFalse;
}
metadata->charset_leafidx_offset = FcCacheNextOffset(fd);
if (charset_leaf_idx_ptr > 0)
{
lseek (fd, metadata->charset_leafidx_offset, SEEK_SET);
if (write (fd, leaf_idx, charset_leaf_idx_ptr * sizeof(FcCharLeaf*)) == -1)
return FcFalse;
}
metadata->charset_numbers_offset = FcCacheNextOffset(fd);
if (charset_leaf_ptr > 0)
{
lseek (fd, metadata->charset_numbers_offset, SEEK_SET);
if (write (fd, numbers, charset_leaf_ptr * sizeof(FcChar16)) == -1)
return FcFalse;
}
return FcTrue;
return block_ptr;
}
FcCharLeaf *
FcCharSetGetLeaf(const FcCharSet *c, int i)
{
switch (c->storage)
{
case FcStorageDynamic:
int bi;
if (c->bank == FC_BANK_DYNAMIC)
return c->u.dyn.leaves[i];
case FcStorageStatic:
return &leaves[leaf_idx[c->u.stat.leafidx_offset]+i];
default:
return 0;
}
bi = FcCacheBankToIndex(c->bank);
return &leaves[bi][leaf_idx[bi][c->u.stat.leafidx_offset]+i];
}
FcChar16 *
FcCharSetGetNumbers(const FcCharSet *c)
{
switch (c->storage)
{
case FcStorageDynamic:
int bi;
if (c->bank == FC_BANK_DYNAMIC)
return c->u.dyn.numbers;
case FcStorageStatic:
return &numbers[c->u.stat.numbers_offset];
default:
return 0;
}
bi = FcCacheBankToIndex(c->bank);
return &numbers[bi][c->u.stat.numbers_offset];
}

View File

@ -40,24 +40,20 @@ FcValuePrint (const FcValue v)
printf (" %g(f)", v.u.d);
break;
case FcTypeString:
printf (" \"%s\"", FcObjectPtrU(v.u.si));
printf (" \"%s\"", v.u.s);
break;
case FcTypeBool:
printf (" %s", v.u.b ? "FcTrue" : "FcFalse");
break;
case FcTypeMatrix:
{
FcMatrix *m = FcMatrixPtrU(v.u.mi);
printf (" (%f %f; %f %f)", m->xx, m->xy, m->yx, m->yy);
printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
break;
}
case FcTypeCharSet: /* XXX */
printf (" set");
break;
case FcTypeLangSet:
printf (" ");
FcLangSetPrint (FcLangSetPtrU(v.u.li));
FcLangSetPrint (v.u.l);
break;
case FcTypeFTFace:
printf (" face");
@ -70,7 +66,7 @@ FcValueListPrint (FcValueListPtr l)
{
for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
{
FcValuePrint (FcValueListPtrU(l)->value);
FcValuePrint (FcValueCanonicalize(&FcValueListPtrU(l)->value));
switch (FcValueListPtrU(l)->binding) {
case FcValueBindingWeak:
printf ("(w)");

View File

@ -274,10 +274,17 @@ FcDirScan (FcFontSet *set,
}
FcBool
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
FcDirSave (FcFontSet *set, const FcChar8 *dir)
{
#if 0
return FcDirCacheWriteDir (set, dirs, dir);
#endif
return FcTrue;
static int rand_state = 0;
int bank;
if (!rand_state)
rand_state = time(0L);
bank = rand_r(&rand_state);
while (FcCacheHaveBank(bank))
bank = rand_r(&rand_state);
return FcDirCacheWrite (bank, set, dir);
}

View File

@ -81,27 +81,58 @@ FcFontSetAdd (FcFontSet *s, FcPattern *font)
return FcTrue;
}
FcBool
FcFontSetPrepareSerialize (FcFontSet *s)
static int * fcfs_pat_count;
void
FcFontSetNewBank (void)
{
int i;
for (i = 0; i < s->nfont; i++)
if (!FcPatternPrepareSerialize(s->fonts[i]))
return FcFalse;
return FcTrue;
FcPatternNewBank();
FcObjectNewBank();
}
FcBool
FcFontSetSerialize (FcFontSet * s)
int
FcFontSetNeededBytes (FcFontSet *s)
{
int i;
FcPattern * p;
int i, c, cum = 0;
for (i = 0; i < s->nfont; i++)
{
p = FcPatternSerialize (s->fonts[i]);
c = FcPatternNeededBytes(s->fonts[i]);
if (c < 0)
return c;
cum += c;
}
if (cum > 0)
return cum + sizeof(int);
else
return 0;
}
void *
FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr)
{
fcfs_pat_count = (int *)block_ptr;
block_ptr = (int *)block_ptr + 1;
// we don't consume any bytes for the fontset itself,
// since we don't allocate it statically.
block_ptr = FcPatternDistributeBytes (metadata, block_ptr);
// for good measure, write out the object ids used for
// this bank to the file.
return FcObjectDistributeBytes (metadata, block_ptr);
}
FcBool
FcFontSetSerialize (int bank, FcFontSet * s)
{
int i;
FcPattern * p;
*fcfs_pat_count = s->nfont;
for (i = 0; i < s->nfont; i++)
{
p = FcPatternSerialize (bank, s->fonts[i]);
if (!p) return FcFalse;
FcPatternDestroy (s->fonts[i]);
@ -111,103 +142,34 @@ FcFontSetSerialize (FcFontSet * s)
return FcTrue;
}
void
FcFontSetClearStatic (void)
{
FcPatternClearStatic();
}
FcBool
FcFontSetRead(int fd, FcConfig * config, FcCache metadata)
FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr)
{
int i, mz, j;
FcPattern * buf;
int nfont;
int i, n;
lseek(fd, metadata.fontsets_offset, SEEK_SET);
for (i = FcSetSystem; i <= FcSetApplication; i++)
nfont = *(int *)block_ptr;
block_ptr = (int *)block_ptr + 1;
if (s->sfont < s->nfont + nfont)
{
if (config->fonts[i])
{
if (config->fonts[i]->nfont > 0 && config->fonts[i]->fonts)
free (config->fonts[i]->fonts);
free (config->fonts[i]);
}
int sfont = s->nfont + nfont;
FcPattern ** pp;
pp = realloc (s->fonts, sfont * sizeof (FcPattern));
if (!pp)
return FcFalse;
s->fonts = pp;
s->sfont = sfont;
}
n = s->nfont;
s->nfont += nfont;
for (i = FcSetSystem; i <= FcSetApplication; i++)
if (nfont > 0)
{
read(fd, &mz, sizeof(int));
if (mz != FC_CACHE_MAGIC)
continue;
config->fonts[i] = malloc(sizeof(FcFontSet));
if (!config->fonts[i])
return FcFalse;
FcMemAlloc(FC_MEM_FONTSET, sizeof(FcFontSet));
if (read(fd, config->fonts[i], sizeof(FcFontSet)) == -1)
goto bail;
if (config->fonts[i]->sfont > 0)
{
config->fonts[i]->fonts = malloc
(config->fonts[i]->sfont*sizeof(FcPattern *));
buf = malloc (config->fonts[i]->sfont * sizeof(FcPattern));
if (!config->fonts[i]->fonts || !buf)
goto bail;
for (j = 0; j < config->fonts[i]->nfont; j++)
{
config->fonts[i]->fonts[j] = buf+j;
if (read(fd, buf+j, sizeof(FcPattern)) == -1)
goto bail;
}
}
FcPattern * p = FcPatternUnserialize (metadata, block_ptr);
for (i = 0; i < nfont; i++)
s->fonts[n + i] = p+i;
}
return FcTrue;
bail:
for (i = FcSetSystem; i <= FcSetApplication; i++)
{
if (config->fonts[i])
{
if (config->fonts[i]->fonts)
free (config->fonts[i]->fonts);
free(config->fonts[i]);
}
config->fonts[i] = 0;
}
return FcFalse;
}
FcBool
FcFontSetWrite(int fd, FcConfig * config, FcCache * metadata)
{
int c, t, i, j;
int m = FC_CACHE_MAGIC, z = 0;
metadata->fontsets_offset = FcCacheNextOffset(fd);
lseek(fd, metadata->fontsets_offset, SEEK_SET);
for (i = FcSetSystem; i <= FcSetApplication; i++)
{
if (!config->fonts[i])
{
write(fd, &z, sizeof(int));
continue;
}
else
write(fd, &m, sizeof(int));
if ((c = write(fd, config->fonts[i], sizeof(FcFontSet))) == -1)
return FcFalse;
t = c;
if (config->fonts[i]->nfont > 0)
{
for (j = 0; j < config->fonts[i]->nfont; j++)
{
if ((c = write(fd, config->fonts[i]->fonts[j],
sizeof(FcPattern))) == -1)
return FcFalse;
}
}
}
return FcTrue;
}

View File

@ -61,9 +61,6 @@ FcInitLoadConfig (void)
if (!config)
return FcFalse;
if (!FcCacheRead(config))
FcCacheForce(FcTrue);
if (!FcConfigParseAndLoad (config, 0, FcTrue))
{
FcConfigDestroy (config);

View File

@ -109,16 +109,8 @@ typedef enum _FcValueBinding {
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
} FcValueBinding;
typedef struct _FcStrSetPtr {
FcStorage storage;
union {
int stat;
struct _FcStrSet *dyn;
} u;
} FcStrSetPtr;
typedef struct _FcValueListPtr {
FcStorage storage;
int bank;
union {
int stat;
struct _FcValueList *dyn;
@ -132,8 +124,10 @@ typedef struct _FcValueList {
FcValueBinding binding;
} FcValueList;
typedef int FcObjectPtr;
typedef struct _FcPatternEltPtr {
FcStorage storage;
int bank;
union {
int stat;
struct _FcPatternElt *dyn;
@ -150,6 +144,7 @@ struct _FcPattern {
int size;
FcPatternEltPtr elts;
int ref;
int bank;
};
typedef enum _FcOp {
@ -222,7 +217,7 @@ typedef struct _FcCharLeaf {
struct _FcCharSet {
int ref; /* reference count */
int num; /* size of leaves and numbers arrays */
FcStorage storage;
int bank;
union {
struct {
FcCharLeaf **leaves;
@ -239,11 +234,7 @@ struct _FcStrSet {
int ref; /* reference count */
int num;
int size;
FcStorage storage;
union {
FcChar8 **strs;
int stridx_offset;
} u;
FcChar8 **strs;
};
struct _FcStrList {
@ -261,21 +252,17 @@ typedef struct _FcStrBuf {
typedef struct _FcCache {
int magic;
off_t fontsets_offset;
off_t pattern_offset; int pattern_length;
off_t patternelt_offset; int patternelt_length;
off_t valuelist_offset; int valuelist_length;
off_t object_offset; int object_length;
off_t objectcontent_offset; int objectcontent_length;
off_t langsets_offset; int langsets_length;
off_t charsets_offset; int charsets_length;
off_t charset_leaf_offset; int charset_num_sum;
off_t charset_leafidx_offset;
off_t charset_numbers_offset;
off_t matrices_offset; int matrices_length;
off_t strsets_offset; int strsets_length;
off_t strsets_idx_offset; int strsets_idx_length;
off_t strset_buf_offset; int strset_buf_length;
int count;
int bank;
int pattern_count;
int patternelt_count;
int valuelist_count;
int str_count;
int langset_count;
int charset_count;
int charset_numbers_count;
int charset_leaf_count;
int charset_leaf_idx_count;
} FcCache;
/*
@ -321,6 +308,11 @@ typedef struct _FcCaseFold {
#define FC_MAX_FILE_LEN 4096
#define FC_STORAGE_STATIC 0x80
#define fc_value_string(v) (((v)->type & FC_STORAGE_STATIC) ? ((FcChar8 *) v) + (v)->u.s_off : (v) -> u.s)
#define fc_value_charset(v) (((v)->type & FC_STORAGE_STATIC) ? (const FcCharSet *)(((char *) v) + (v)->u.c_off) : (v) -> u.c)
#define fc_value_langset(v) (((v)->type & FC_STORAGE_STATIC) ? (const FcLangSet *)(((char *) v) + (v)->u.l_off) : (v) -> u.l)
/*
* The per-user ~/.fonts.cache-<version> file is loaded into
* this data structure. Each directory gets a substructure
@ -449,26 +441,29 @@ typedef struct _FcCharMap FcCharMap;
/* fccache.c */
int
FcCacheNextOffset(int fd);
void
FcCacheForce(FcBool force);
void
FcCacheClearStatic(void);
FcBool
FcCachePrepareSerialize(FcConfig * config);
FcCacheSerialize (int bank, FcConfig * config);
FcBool
FcCacheSerialize (FcConfig * config);
FcBool
FcFontSet *
FcCacheRead (FcConfig *config);
FcBool
FcCacheWrite (FcConfig * config);
FcDirCacheRead (FcFontSet * set, const FcChar8 *dir);
FcBool
FcDirCacheWrite (int bank, FcFontSet *set, const FcChar8 *dir);
int
FcCacheBankCount (void);
FcBool
FcCacheHaveBank (int bank);
int
FcCacheBankToIndex (int bank);
/* fccfg.c */
@ -508,9 +503,9 @@ FcConfigSetFonts (FcConfig *config,
FcSetName set);
FcBool
FcConfigCompareValue (const FcValue m,
FcConfigCompareValue (const FcValue *m,
FcOp op,
const FcValue v);
const FcValue *v);
FcBool
FcConfigGlobAdd (FcConfig *config,
@ -534,9 +529,6 @@ FcConfigAcceptFont (FcConfig *config,
FcCharSet *
FcCharSetFreeze (FcCharSet *cs);
FcCharSetPtr
FcCharSetCopyPtr (FcCharSetPtr src);
void
FcCharSetThawAll (void);
@ -550,19 +542,20 @@ FcCharLeaf *
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
void
FcCharSetPtrDestroy (FcCharSetPtr fcs);
FcCharSetNewBank (void);
void
FcCharSetClearStatic(void);
int
FcCharSetNeededBytes (const FcCharSet *c);
FcBool
FcCharSetPrepareSerialize(FcCharSet *c);
void *
FcCharSetDistributeBytes (FcCache * metadata,
void * block_ptr);
FcCharSetPtr
FcCharSetSerialize(FcCharSet *c);
FcCharSet *
FcCharSetSerialize(int bank, FcCharSet *c);
FcCharSetPtr
FcCharSetPtrCreateDynamic(FcCharSet *c);
void *
FcCharSetUnserialize (FcCache metadata, void *block_ptr);
FcCharLeaf *
FcCharSetGetLeaf(const FcCharSet *c, int i);
@ -570,12 +563,6 @@ FcCharSetGetLeaf(const FcCharSet *c, int i);
FcChar16 *
FcCharSetGetNumbers(const FcCharSet *c);
FcBool
FcCharSetRead (int fd, FcCache metadata);
FcBool
FcCharSetWrite (int fd, FcCache *metadata);
/* fcdbg.c */
void
FcValueListPrint (const FcValueListPtr l);
@ -601,9 +588,6 @@ FcSubstPrint (const FcSubst *subst);
int
FcDebug (void);
FcCharSet *
FcCharSetPtrU (FcCharSetPtr mi);
/* fcdir.c */
FcBool
@ -650,19 +634,19 @@ FcFreeTypeGetPrivateMap (FT_Encoding encoding);
/* fcfs.c */
void
FcFontSetClearStatic (void);
FcFontSetNewBank (void);
int
FcFontSetNeededBytes (FcFontSet *s);
void *
FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr);
FcBool
FcFontSetPrepareSerialize (FcFontSet * s);
FcFontSetSerialize (int bank, FcFontSet * s);
FcBool
FcFontSetSerialize (FcFontSet * s);
FcBool
FcFontSetRead(int fd, FcConfig * config, FcCache metadata);
FcBool
FcFontSetWrite(int fd, FcConfig * config, FcCache * metadata);
FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr);
/* fcgram.y */
int
@ -745,28 +729,20 @@ FcBool
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
void
FcLangSetClearStatic (void);
FcLangSetNewBank (void);
FcBool
FcLangSetPrepareSerialize (FcLangSet *l);
int
FcLangSetNeededBytes (const FcLangSet *l);
FcLangSetPtr
FcLangSetSerialize (FcLangSet *l);
void *
FcLangSetDistributeBytes (FcCache * metadata,
void * block_ptr);
FcLangSet *
FcLangSetPtrU (FcLangSetPtr li);
FcLangSetSerialize (int bank, FcLangSet *l);
FcLangSetPtr
FcLangSetPtrCreateDynamic (FcLangSet *l);
void
FcLangSetPtrDestroy (FcLangSetPtr li);
FcBool
FcLangSetRead (int fd, FcCache metadata);
FcBool
FcLangSetWrite (int fd, FcCache *metadata);
void *
FcLangSetUnserialize (FcCache metadata, void *block_ptr);
/* fclist.c */
@ -781,7 +757,30 @@ FcListPatternMatchAny (const FcPattern *p,
FcBool
FcNameBool (const FcChar8 *v, FcBool *result);
void
FcObjectNewBank(void);
void *
FcObjectDistributeBytes (FcCache * metadata,
void * block_ptr);
FcObjectPtr
FcObjectToPtr (const char * si);
int
FcObjectNeededBytes (FcObjectPtr p);
void
FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr);
FcObjectPtr
FcObjectSerialize (FcObjectPtr s);
/* fcpat.c */
FcValue
FcValueCanonicalize (const FcValue *v);
void
FcValueListDestroy (FcValueListPtr l);
@ -807,18 +806,9 @@ FcPatternFini (void);
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s);
void
FcObjectClearStatic(void);
FcObjectPtr
const char *
FcObjectStaticName (const char *name);
FcBool
FcObjectRead (int fd, FcCache metadata);
FcBool
FcObjectWrite (int fd, FcCache * metadata);
const char *
FcObjectPtrU (FcObjectPtr p);
@ -826,16 +816,13 @@ int
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
void
FcObjectPtrDestroy (FcObjectPtr p);
FcPatternNewBank (void);
FcBool
FcPatternPrepareSerialize (FcPattern *p);
int
FcPatternNeededBytes (FcPattern *p);
void
FcValueListClearStatic (void);
void
FcPatternClearStatic (void);
void *
FcPatternDistributeBytes (FcCache * metadata, void * block_ptr);
FcValueList *
FcValueListPtrU(FcValueListPtr p);
@ -846,85 +833,25 @@ FcPatternEltU (FcPatternEltPtr pei);
FcValueListPtr
FcValueListPtrCreateDynamic(FcValueList * p);
FcBool
FcValueListPrepareSerialize (FcValueList *p);
FcValueListPtr
FcValueListSerialize(FcValueList *pi);
FcPattern *
FcPatternSerialize (int bank, FcPattern * p);
FcPattern *
FcPatternSerialize (FcPattern * p);
FcBool
FcPatternRead (int fd, FcCache metadata);
FcBool
FcPatternWrite (int fd, FcCache *metadata);
FcBool
FcPatternEltRead (int fd, FcCache metadata);
FcBool
FcPatternEltWrite (int fd, FcCache *metadata);
FcBool
FcValueListRead (int fd, FcCache metadata);
FcBool
FcValueListWrite (int fd, FcCache *metadata);
FcPatternUnserialize (FcCache metadata, void *block_ptr);
/* fcrender.c */
/* fcmatrix.c */
extern const FcMatrixPtr FcIdentityMatrix;
extern const FcMatrix FcIdentityMatrix;
void
FcMatrixFree (FcMatrix *mat);
void
FcMatrixPtrDestroy (FcMatrixPtr mi);
FcBool
FcMatrixPrepareSerialize(FcMatrix *m);
FcMatrixPtr
FcMatrixSerialize(FcMatrix *m);
FcMatrix *
FcMatrixPtrU (FcMatrixPtr mi);
FcMatrixPtr
FcMatrixPtrCreateDynamic (FcMatrix *m);
void
FcMatrixClearStatic (void);
FcBool
FcMatrixWrite (int fd, FcCache *metadata);
FcBool
FcMatrixRead (int fd, FcCache metadata);
/* fcstr.c */
FcStrSet *
FcStrSetPtrU (const FcStrSetPtr set);
FcStrSetPtr
FcStrSetPtrCreateDynamic (const FcStrSet * set);
void
FcStrSetClearStatic (void);
FcBool
FcStrSetPrepareSerialize (const FcStrSet *set);
void
FcStrSetSort (FcStrSet * set);
FcChar8 *
FcStrSetGet (const FcStrSet *set, int i);
FcChar8 *
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
@ -949,15 +876,6 @@ FcStrBufString (FcStrBuf *buf, const FcChar8 *s);
FcBool
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
FcStrSetPtr
FcStrSetSerialize (FcStrSet *set);
FcBool
FcStrSetRead (int fd, FcCache metadata);
FcBool
FcStrSetWrite (int fd, FcCache *metadata);
int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);

View File

@ -22,8 +22,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <fcntl.h>
#include <sys/mman.h>
#include "fcint.h"
typedef struct {
@ -40,7 +38,7 @@ typedef struct {
struct _FcLangSet {
FcChar32 map[NUM_LANG_SET_MAP];
FcStrSetPtr extra;
FcStrSet *extra;
};
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
@ -217,22 +215,15 @@ FcLangSetCreate (void)
return 0;
FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet));
memset (ls->map, '\0', sizeof (ls->map));
ls->extra = FcStrSetPtrCreateDynamic(0);
ls->extra = 0;
return ls;
}
void
FcLangSetPtrDestroy (FcLangSetPtr li)
{
if (li.storage == FcStorageDynamic)
FcLangSetDestroy(FcLangSetPtrU(li));
}
void
FcLangSetDestroy (FcLangSet *ls)
{
if (FcStrSetPtrU(ls->extra))
FcStrSetDestroy (FcStrSetPtrU(ls->extra));
if (ls->extra)
FcStrSetDestroy (ls->extra);
FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet));
free (ls);
}
@ -246,21 +237,21 @@ FcLangSetCopy (const FcLangSet *ls)
if (!new)
goto bail0;
memcpy (new->map, ls->map, sizeof (new->map));
if (FcStrSetPtrU(ls->extra))
if (ls->extra)
{
FcStrList *list;
FcChar8 *extra;
new->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
if (!FcStrSetPtrU(new->extra))
new->extra = FcStrSetCreate ();
if (!new->extra)
goto bail1;
list = FcStrListCreate (FcStrSetPtrU(ls->extra));
list = FcStrListCreate (ls->extra);
if (!list)
goto bail1;
while ((extra = FcStrListNext (list)))
if (!FcStrSetAdd (FcStrSetPtrU(new->extra), extra))
if (!FcStrSetAdd (new->extra, extra))
{
FcStrListDone (list);
goto bail1;
@ -341,13 +332,13 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
FcLangSetBitSet (ls, id);
return FcTrue;
}
if (!FcStrSetPtrU(ls->extra))
if (!ls->extra)
{
ls->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
if (!FcStrSetPtrU(ls->extra))
ls->extra = FcStrSetCreate ();
if (!ls->extra)
return FcFalse;
}
return FcStrSetAdd (FcStrSetPtrU(ls->extra), lang);
return FcStrSetAdd (ls->extra, lang);
}
FcLangResult
@ -379,9 +370,9 @@ FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
if (FcLangSetBitGet (ls, i) && r < best)
best = r;
}
if (FcStrSetPtrU(ls->extra))
if (ls->extra)
{
FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
FcStrList *list = FcStrListCreate (ls->extra);
FcChar8 *extra;
FcLangResult r;
@ -437,15 +428,15 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb)
best = FcLangDifferentCountry;
break;
}
if (FcStrSetPtrU(lsa->extra))
if (lsa->extra)
{
r = FcLangSetCompareStrSet (lsb, FcStrSetPtrU(lsa->extra));
r = FcLangSetCompareStrSet (lsb, lsa->extra);
if (r < best)
best = r;
}
if (best > FcLangEqual && FcStrSetPtrU(lsb->extra))
if (best > FcLangEqual && lsb->extra)
{
r = FcLangSetCompareStrSet (lsa, FcStrSetPtrU(lsb->extra));
r = FcLangSetCompareStrSet (lsa, lsb->extra);
if (r < best)
best = r;
}
@ -464,7 +455,7 @@ FcLangSetPromote (const FcChar8 *lang)
int id;
memset (ls.map, '\0', sizeof (ls.map));
ls.extra = FcStrSetPtrCreateDynamic(0);
ls.extra = 0;
id = FcLangSetIndex (lang);
if (id > 0)
{
@ -472,11 +463,10 @@ FcLangSetPromote (const FcChar8 *lang)
}
else
{
ls.extra = FcStrSetPtrCreateDynamic(&strs);
ls.extra = &strs;
strs.num = 1;
strs.size = 1;
strs.storage = FcStorageDynamic;
strs.u.strs = &str;
strs.strs = &str;
strs.ref = 1;
str = (FcChar8 *) lang;
}
@ -491,8 +481,8 @@ FcLangSetHash (const FcLangSet *ls)
for (i = 0; i < NUM_LANG_SET_MAP; i++)
h ^= ls->map[i];
if (FcStrSetPtrU(ls->extra))
h ^= FcStrSetPtrU(ls->extra)->num;
if (ls->extra)
h ^= ls->extra->num;
return h;
}
@ -553,9 +543,9 @@ FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
}
}
}
if (FcStrSetPtrU(ls->extra))
if (ls->extra)
{
FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
FcStrList *list = FcStrListCreate (ls->extra);
FcChar8 *extra;
if (!list)
@ -583,10 +573,10 @@ FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb)
if (lsa->map[i] != lsb->map[i])
return FcFalse;
}
if (!FcStrSetPtrU(lsa->extra) && !FcStrSetPtrU(lsb->extra))
if (!lsa->extra && !lsb->extra)
return FcTrue;
if (FcStrSetPtrU(lsa->extra) && FcStrSetPtrU(lsb->extra))
return FcStrSetEqual (FcStrSetPtrU(lsa->extra), FcStrSetPtrU(lsb->extra));
if (lsa->extra && lsb->extra)
return FcStrSetEqual (lsa->extra, lsb->extra);
return FcFalse;
}
@ -620,9 +610,9 @@ FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
FcLangContains (fcLangCharSets[i].lang, lang))
return FcTrue;
}
if (FcStrSetPtrU(ls->extra))
if (ls->extra)
{
FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
FcStrList *list = FcStrListCreate (ls->extra);
FcChar8 *extra;
if (list)
@ -676,9 +666,9 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
}
}
}
if (FcStrSetPtrU(lsb->extra))
if (lsb->extra)
{
FcStrList *list = FcStrListCreate (FcStrSetPtrU(lsb->extra));
FcStrList *list = FcStrListCreate (lsb->extra);
FcChar8 *extra;
if (list)
@ -700,105 +690,82 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
return FcTrue;
}
static FcLangSet * langsets = 0;
static int langset_ptr = 0, langset_count = 0;
FcLangSet *
FcLangSetPtrU (FcLangSetPtr li)
{
switch (li.storage)
{
case FcStorageDynamic:
return li.u.dyn;
case FcStorageStatic:
return &langsets[li.u.stat];
default:
return 0;
}
}
FcLangSetPtr
FcLangSetPtrCreateDynamic (FcLangSet *li)
{
FcLangSetPtr new;
new.storage = FcStorageDynamic;
new.u.dyn = li;
return new;
}
static FcLangSet ** langsets = 0;
static int langset_bank_count = 0, langset_ptr = 0, langset_count = 0;
void
FcLangSetClearStatic (void)
FcLangSetNewBank (void)
{
FcStrSetClearStatic();
langset_ptr = 0;
langset_count = 0;
}
/* should only write one copy of any particular FcLangSet */
FcBool
FcLangSetPrepareSerialize (FcLangSet *l)
/* ideally, should only write one copy of any particular FcLangSet */
int
FcLangSetNeededBytes (const FcLangSet *l)
{
langset_count++;
if (l && FcStrSetPtrU(l->extra))
return FcStrSetPrepareSerialize (FcStrSetPtrU(l->extra));
return sizeof (FcLangSet);
}
static FcBool
FcLangSetEnsureBank (int bi)
{
if (!langsets || bi >= langset_bank_count)
{
int new_count = langset_bank_count + 2;
int i;
FcLangSet** tt;
tt = realloc(langsets, new_count * sizeof(FcLangSet *));
if (!tt)
return FcFalse;
langsets = tt;
for (i = langset_bank_count; i < new_count; i++)
langsets[i] = 0;
langset_bank_count = new_count;
}
return FcTrue;
}
FcLangSetPtr
FcLangSetSerialize(FcLangSet *l)
void *
FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr)
{
FcLangSetPtr new;
int p = langset_ptr;
int bi = FcCacheBankToIndex(metadata->bank);
if (!FcLangSetEnsureBank(bi))
return 0;
if (!l) return FcLangSetPtrCreateDynamic(0);
langsets[bi] = block_ptr;
block_ptr = (void *)((char *)block_ptr +
langset_count * sizeof(FcLangSet));
langset_ptr = 0;
metadata->langset_count = langset_count;
return block_ptr;
}
if (!langsets)
{
FcLangSet* t;
t = (FcLangSet *)malloc(langset_count * sizeof(FcLangSet));
if (!t)
return FcLangSetPtrCreateDynamic(0);
langsets = t;
langset_ptr = 0;
}
FcLangSet *
FcLangSetSerialize(int bank, FcLangSet *l)
{
int p = langset_ptr, bi = FcCacheBankToIndex(bank);
langsets[langset_ptr] = *l;
if (FcStrSetPtrU(l->extra))
langsets[langset_ptr].extra =
FcStrSetSerialize(FcStrSetPtrU(l->extra));
else
langsets[langset_ptr].extra = FcStrSetPtrCreateDynamic(0);
if (!l) return 0;
langsets[bi][langset_ptr] = *l;
langsets[bi][langset_ptr].extra = 0;
langset_ptr++;
new.storage = FcStorageStatic;
new.u.stat = p;
return new;
return &langsets[bi][p];
}
FcBool
FcLangSetWrite (int fd, FcCache *metadata)
void *
FcLangSetUnserialize (FcCache metadata, void *block_ptr)
{
metadata->langsets_length = langset_ptr;
metadata->langsets_offset = FcCacheNextOffset(fd);
int bi = FcCacheBankToIndex(metadata.bank);
if (!FcLangSetEnsureBank(bi))
return 0;
if (langset_ptr > 0)
{
lseek (fd, metadata->langsets_offset, SEEK_SET);
return write(fd, langsets,
metadata->langsets_length * sizeof(FcLangSet)) != -1;
}
return FcTrue;
}
FcBool
FcLangSetRead (int fd, FcCache metadata)
{
langsets = mmap(NULL,
metadata.langsets_length * sizeof (FcLangSet),
PROT_READ,
MAP_SHARED, fd, metadata.langsets_offset);
if (langsets == MAP_FAILED)
return FcFalse;
langset_count = langset_ptr = metadata.langsets_length;
return FcTrue;
FcMemAlloc (FC_MEM_LANGSET, metadata.langset_count * sizeof(FcLangSet));
langsets[bi] = (FcLangSet *)block_ptr;
block_ptr = (void *)((char *)block_ptr +
metadata.langset_count * sizeof(FcLangSet));
return block_ptr;
}

View File

@ -23,9 +23,6 @@
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include "fcint.h"
FcObjectSet *
@ -47,18 +44,17 @@ FcBool
FcObjectSetAdd (FcObjectSet *os, const char *object)
{
int s;
FcObjectPtr *objects;
FcObjectPtr obj;
const char **objects;
int high, low, mid, c;
if (os->nobject == os->sobject)
{
s = os->sobject + 4;
if (os->objects)
objects = (FcObjectPtr *) realloc ((void *) os->objects,
s * sizeof (FcObjectPtr));
objects = (const char **) realloc ((void *) os->objects,
s * sizeof (const char *));
else
objects = (FcObjectPtr *) malloc (s * sizeof (FcObjectPtr));
objects = (const char **) malloc (s * sizeof (const char *));
if (!objects)
return FcFalse;
if (os->sobject)
@ -71,11 +67,11 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
low = 0;
mid = 0;
c = 1;
obj = FcObjectStaticName (object);
object = FcObjectStaticName (object);
while (low <= high)
{
mid = (low + high) >> 1;
c = FcObjectPtrCompare(os->objects[mid], obj);
c = os->objects[mid] - object;
if (c == 0)
return FcTrue;
if (c < 0)
@ -86,8 +82,8 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
if (c < 0)
mid++;
memmove (os->objects + mid + 1, os->objects + mid,
(os->nobject - mid) * sizeof (FcObjectPtr));
os->objects[mid] = obj;
(os->nobject - mid) * sizeof (const char *));
os->objects[mid] = object;
os->nobject++;
return FcTrue;
}
@ -145,9 +141,9 @@ FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
* (OpListing is OpContains except for strings
* where it requires an exact match)
*/
if (FcConfigCompareValue (FcValueListPtrU(fnt)->value,
if (FcConfigCompareValue (&FcValueListPtrU(fnt)->value,
FcOpListing,
FcValueListPtrU(pat)->value))
&FcValueListPtrU(pat)->value))
break;
}
if (!FcValueListPtrU(fnt))
@ -167,8 +163,8 @@ FcListValueListEqual (FcValueListPtr v1orig,
{
for (v2 = v2orig; FcValueListPtrU(v2);
v2 = FcValueListPtrU(v2)->next)
if (FcValueEqual (FcValueListPtrU(v1)->value,
FcValueListPtrU(v2)->value))
if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
break;
if (!FcValueListPtrU(v2))
return FcFalse;
@ -178,8 +174,8 @@ FcListValueListEqual (FcValueListPtr v1orig,
{
for (v1 = v1orig; FcValueListPtrU(v1);
v1 = FcValueListPtrU(v1)->next)
if (FcValueEqual (FcValueListPtrU(v1)->value,
FcValueListPtrU(v2)->value))
if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
break;
if (!FcValueListPtrU(v1))
return FcFalse;
@ -197,8 +193,8 @@ FcListPatternEqual (FcPattern *p1,
for (i = 0; i < os->nobject; i++)
{
e1 = FcPatternFindElt (p1, FcObjectPtrU(os->objects[i]));
e2 = FcPatternFindElt (p2, FcObjectPtrU(os->objects[i]));
e1 = FcPatternFindElt (p1, os->objects[i]);
e2 = FcPatternFindElt (p2, os->objects[i]);
if (!e1 && !e2)
continue;
if (!e1 || !e2)
@ -245,8 +241,9 @@ FcListMatrixHash (const FcMatrix *m)
}
static FcChar32
FcListValueHash (FcValue v)
FcListValueHash (FcValue *value)
{
FcValue v = FcValueCanonicalize(value);
switch (v.type) {
case FcTypeVoid:
return 0;
@ -255,17 +252,17 @@ FcListValueHash (FcValue v)
case FcTypeDouble:
return (FcChar32) (int) v.u.d;
case FcTypeString:
return FcStrHashIgnoreCase (FcObjectPtrU(v.u.si));
return FcStrHashIgnoreCase (v.u.s);
case FcTypeBool:
return (FcChar32) v.u.b;
case FcTypeMatrix:
return FcListMatrixHash (FcMatrixPtrU(v.u.mi));
return FcListMatrixHash (v.u.m);
case FcTypeCharSet:
return FcCharSetCount (FcCharSetPtrU(v.u.ci));
return FcCharSetCount (v.u.c);
case FcTypeFTFace:
return (long) v.u.f;
case FcTypeLangSet:
return FcLangSetHash (FcLangSetPtrU(v.u.li));
return FcLangSetHash (v.u.l);
}
return 0;
}
@ -277,7 +274,7 @@ FcListValueListHash (FcValueListPtr list)
while (FcValueListPtrU(list))
{
h = h ^ FcListValueHash (FcValueListPtrU(list)->value);
h = h ^ FcListValueHash (&FcValueListPtrU(list)->value);
list = FcValueListPtrU(list)->next;
}
return h;
@ -293,7 +290,7 @@ FcListPatternHash (FcPattern *font,
for (n = 0; n < os->nobject; n++)
{
e = FcPatternFindElt (font, FcObjectPtrU(os->objects[n]));
e = FcPatternFindElt (font, os->objects[n]);
if (e)
h = h ^ FcListValueListHash (e->values);
}
@ -371,15 +368,15 @@ FcListAppend (FcListHashTable *table,
for (o = 0; o < os->nobject; o++)
{
e = FcPatternFindElt (font, FcObjectPtrU(os->objects[o]));
e = FcPatternFindElt (font, os->objects[o]);
if (e)
{
for (v = e->values; FcValueListPtrU(v);
v = FcValueListPtrU(v)->next)
{
if (!FcPatternAdd (bucket->pattern,
FcObjectPtrU(os->objects[o]),
FcValueListPtrU(v)->value, FcTrue))
os->objects[o],
FcValueCanonicalize(&FcValueListPtrU(v)->value), FcTrue))
goto bail2;
}
}

View File

@ -28,26 +28,26 @@
#include <stdio.h>
static double
FcCompareNumber (char *object, FcValue value1, FcValue value2)
FcCompareNumber (char *object, FcValue *value1, FcValue *value2)
{
double v1, v2, v;
switch (value1.type) {
switch (value1->type) {
case FcTypeInteger:
v1 = (double) value1.u.i;
v1 = (double) value1->u.i;
break;
case FcTypeDouble:
v1 = value1.u.d;
v1 = value1->u.d;
break;
default:
return -1.0;
}
switch (value2.type) {
switch (value2->type) {
case FcTypeInteger:
v2 = (double) value2.u.i;
v2 = (double) value2->u.i;
break;
case FcTypeDouble:
v2 = value2.u.d;
v2 = value2->u.d;
break;
default:
return -1.0;
@ -59,38 +59,38 @@ FcCompareNumber (char *object, FcValue value1, FcValue value2)
}
static double
FcCompareString (char *object, FcValue value1, FcValue value2)
FcCompareString (char *object, FcValue *v1, FcValue *v2)
{
FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
if (value2.type != FcTypeString || value1.type != FcTypeString)
return -1.0;
return (double) FcStrCmpIgnoreCase
(FcObjectPtrU(value1.u.si), FcObjectPtrU(value2.u.si)) != 0;
return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
}
static double
FcCompareFamily (char *object, FcValue value1, FcValue value2)
FcCompareFamily (char *object, FcValue *v1, FcValue *v2)
{
FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
if (value2.type != FcTypeString || value1.type != FcTypeString)
return -1.0;
return (double) FcStrCmpIgnoreBlanksAndCase
(FcObjectPtrU(value1.u.si), FcObjectPtrU(value2.u.si)) != 0;
return (double) FcStrCmpIgnoreBlanksAndCase (value1.u.s, value2.u.s) != 0;
}
static double
FcCompareLang (char *object, FcValue value1, FcValue value2)
FcCompareLang (char *object, FcValue *v1, FcValue *v2)
{
FcLangResult result;
FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
switch (value1.type) {
case FcTypeLangSet:
switch (value2.type) {
case FcTypeLangSet:
result = FcLangSetCompare (FcLangSetPtrU(value1.u.li),
FcLangSetPtrU(value2.u.li));
result = FcLangSetCompare (value1.u.l, value2.u.l);
break;
case FcTypeString:
result = FcLangSetHasLang (FcLangSetPtrU(value1.u.li),
FcObjectPtrU(value2.u.si));
result = FcLangSetHasLang (value1.u.l,
value2.u.s);
break;
default:
return -1.0;
@ -99,12 +99,11 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
case FcTypeString:
switch (value2.type) {
case FcTypeLangSet:
result = FcLangSetHasLang (FcLangSetPtrU(value2.u.li),
FcObjectPtrU(value1.u.si));
result = FcLangSetHasLang (value2.u.l, value1.u.s);
break;
case FcTypeString:
result = FcLangCompare (FcObjectPtrU(value1.u.si),
FcObjectPtrU(value2.u.si));
result = FcLangCompare (value1.u.s,
value2.u.s);
break;
default:
return -1.0;
@ -125,43 +124,44 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
}
static double
FcCompareBool (char *object, FcValue value1, FcValue value2)
FcCompareBool (char *object, FcValue *value1, FcValue *value2)
{
if (value2.type != FcTypeBool || value1.type != FcTypeBool)
if (value2->type != FcTypeBool || value1->type != FcTypeBool)
return -1.0;
return (double) value2.u.b != value1.u.b;
return (double) value2->u.b != value1->u.b;
}
static double
FcCompareCharSet (char *object, FcValue value1, FcValue value2)
FcCompareCharSet (char *object, FcValue *v1, FcValue *v2)
{
FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
if (value2.type != FcTypeCharSet || value1.type != FcTypeCharSet)
return -1.0;
return (double) FcCharSetSubtractCount (FcCharSetPtrU(value1.u.ci),
FcCharSetPtrU(value2.u.ci));
return (double) FcCharSetSubtractCount (value1.u.c, value2.u.c);
}
static double
FcCompareSize (char *object, FcValue value1, FcValue value2)
FcCompareSize (char *object, FcValue *value1, FcValue *value2)
{
double v1, v2, v;
switch (value1.type) {
switch (value1->type) {
case FcTypeInteger:
v1 = value1.u.i;
v1 = value1->u.i;
break;
case FcTypeDouble:
v1 = value1.u.d;
v1 = value1->u.d;
break;
default:
return -1;
}
switch (value2.type) {
switch (value2->type) {
case FcTypeInteger:
v2 = value2.u.i;
v2 = value2->u.i;
break;
case FcTypeDouble:
v2 = value2.u.d;
v2 = value2->u.d;
break;
default:
return -1;
@ -176,7 +176,7 @@ FcCompareSize (char *object, FcValue value1, FcValue value2)
typedef struct _FcMatcher {
char *object;
double (*compare) (char *object, FcValue value1, FcValue value2);
double (*compare) (char *object, FcValue *value1, FcValue *value2);
int strong, weak;
} FcMatcher;
@ -315,7 +315,7 @@ FcCompareValueList (const char *object,
(FcChar8 *) object) != 0)
{
if (bestValue)
*bestValue = FcValueListPtrU(v2orig)->value;
*bestValue = FcValueCanonicalize(&FcValueListPtrU(v2orig)->value);
return FcTrue;
}
#if 0
@ -343,8 +343,8 @@ FcCompareValueList (const char *object,
v2 = FcValueListPtrU(v2)->next)
{
v = (*_FcMatchers[i].compare) (_FcMatchers[i].object,
FcValueListPtrU(v1)->value,
FcValueListPtrU(v2)->value);
&FcValueListPtrU(v1)->value,
&FcValueListPtrU(v2)->value);
if (v < 0)
{
*result = FcResultTypeMismatch;
@ -356,7 +356,7 @@ FcCompareValueList (const char *object,
if (v < best)
{
if (bestValue)
*bestValue = FcValueListPtrU(v2)->value;
*bestValue = FcValueCanonicalize(&FcValueListPtrU(v2)->value);
best = v;
}
if (FcValueListPtrU(v1)->binding == FcValueBindingStrong)
@ -478,7 +478,7 @@ FcFontRenderPrepare (FcConfig *config,
}
}
else
v = FcValueListPtrU(fe->values)->value;
v = FcValueCanonicalize(&FcValueListPtrU(fe->values)->value);
FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
}
for (i = 0; i < pat->num; i++)
@ -487,7 +487,7 @@ FcFontRenderPrepare (FcConfig *config,
fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
if (!fe)
FcPatternAdd (new, FcObjectPtrU(pe->object),
FcValueListPtrU(pe->values)->value, FcTrue);
FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue);
}
FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
return new;
@ -780,8 +780,8 @@ FcFontSetSort (FcConfig *config,
FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch &&
FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch)
{
double compare = FcCompareLang (FC_LANG, patternLang,
nodeLang);
double compare = FcCompareLang (FC_LANG, &patternLang,
&nodeLang);
if (compare >= 0 && compare < 2)
{
if (FcDebug () & FC_DBG_MATCHV)

View File

@ -25,14 +25,9 @@
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/mman.h>
#include "fcint.h"
FcMatrix _id = { 1, 0, 0, 1 };
const FcMatrixPtr FcIdentityMatrix = {
.storage = FcStorageDynamic,
.u.dyn = &_id
};
const FcMatrix FcIdentityMatrix = { 1, 0, 0, 1 };
FcMatrix *
FcMatrixCopy (const FcMatrix *mat)
@ -48,17 +43,10 @@ FcMatrixCopy (const FcMatrix *mat)
return r;
}
void
FcMatrixPtrDestroy (FcMatrixPtr mi)
{
if (mi.storage == FcStorageDynamic)
FcMatrixFree (mi.u.dyn);
}
void
FcMatrixFree (FcMatrix *mat)
{
if (mat != FcMatrixPtrU(FcIdentityMatrix))
if (mat != &FcIdentityMatrix)
{
FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix));
free (mat);
@ -127,87 +115,3 @@ FcMatrixShear (FcMatrix *m, double sh, double sv)
r.yy = 1;
FcMatrixMultiply (m, &r, m);
}
static FcMatrix * matrices = 0;
static int matrix_ptr = 0, matrix_count = 0;
void
FcMatrixClearStatic (void)
{
matrices = 0;
matrix_ptr = 0;
matrix_count = 0;
}
FcMatrix *
FcMatrixPtrU (FcMatrixPtr mi)
{
switch (mi.storage)
{
case FcStorageDynamic:
return mi.u.dyn;
case FcStorageStatic:
return &matrices[mi.u.stat];
default:
return 0;
}
}
FcMatrixPtr
FcMatrixPtrCreateDynamic (FcMatrix *mi)
{
FcMatrixPtr new;
new.storage = FcStorageDynamic;
new.u.dyn = mi;
return new;
}
FcBool
FcMatrixPrepareSerialize(FcMatrix *m)
{
matrix_count++;
return FcTrue;
}
FcMatrixPtr
FcMatrixSerialize(FcMatrix *m)
{
FcMatrixPtr new;
if (matrix_count == matrix_ptr)
return FcMatrixPtrCreateDynamic(0);
new.storage = FcStorageStatic;
new.u.stat = matrix_ptr++;
return new;
}
FcBool
FcMatrixRead (int fd, FcCache metadata)
{
matrices = mmap(NULL,
metadata.matrices_length * sizeof (FcMatrix),
PROT_READ,
MAP_SHARED, fd, metadata.matrices_offset);
if (matrices == MAP_FAILED)
return FcFalse;
matrix_count = matrix_ptr = metadata.matrices_length;
return FcTrue;
}
FcBool
FcMatrixWrite (int fd, FcCache *metadata)
{
metadata->matrices_length = matrix_ptr;
metadata->matrices_offset = FcCacheNextOffset(fd);
if (matrix_ptr > 0)
{
lseek(fd, metadata->matrices_offset, SEEK_SET);
return write(fd, matrices,
metadata->matrices_length * sizeof(FcMatrix)) != -1;
}
return FcTrue;
}

View File

@ -145,6 +145,74 @@ FcNameGetObjectType (const char *object)
return 0;
}
static int objectptr_count = 1;
static int objectptr_alloc = 0;
static int * objectptr_indices = 0;
void
FcObjectNewBank(void)
{
objectptr_count = 1;
objectptr_alloc = 0;
objectptr_indices = 0;
}
// XXX todo: introduce a hashtable for faster lookup
FcObjectPtr
FcObjectToPtr (const char * object)
{
int i;
const FcObjectTypeList *l;
const FcObjectType *t;
for (l = _FcObjectTypes; l; l = l->next)
{
for (i = 0; i < l->ntypes; i++)
{
t = &l->types[i];
if (!strcmp (object, t->object))
return i;
}
}
abort();
return 0;
}
const char *
FcObjectPtrU (FcObjectPtr si)
{
return _FcObjectTypes->types[si].object;
}
int
FcObjectNeededBytes (FcObjectPtr si)
{
return 0;
}
void *
FcObjectDistributeBytes (FcCache * metadata, void * block_ptr)
{
return block_ptr;
}
FcObjectPtr
FcObjectSerialize (FcObjectPtr si)
{
return si;
}
void
FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr)
{
}
int
FcObjectPtrCompare (const FcObjectPtr a, const FcObjectPtr b)
{
return a - b;
}
static const FcConstant _FcBaseConstants[] = {
{ (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, },
{ (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, },
@ -321,7 +389,7 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
v.u.i = atoi ((char *) string);
break;
case FcTypeString:
v.u.si = FcObjectStaticName(string);
v.u.s = FcObjectStaticName(string);
break;
case FcTypeBool:
if (!FcNameBool (string, &v.u.b))
@ -331,14 +399,14 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
v.u.d = strtod ((char *) string, 0);
break;
case FcTypeMatrix:
v.u.mi = FcMatrixPtrCreateDynamic(m);
v.u.m = m;
sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
break;
case FcTypeCharSet:
v.u.ci = FcCharSetPtrCreateDynamic(FcNameParseCharSet (string));
v.u.c = FcNameParseCharSet (string);
break;
case FcTypeLangSet:
v.u.li = FcLangSetPtrCreateDynamic(FcNameParseLangSet (string));
v.u.l = FcNameParseLangSet (string);
break;
default:
break;
@ -436,10 +504,10 @@ FcNameParse (const FcChar8 *name)
{
switch (v.type) {
case FcTypeCharSet:
FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
FcCharSetDestroy ((FcCharSet *) v.u.c);
break;
case FcTypeLangSet:
FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
FcLangSetDestroy ((FcLangSet *) v.u.l);
break;
default:
break;
@ -448,10 +516,10 @@ FcNameParse (const FcChar8 *name)
}
switch (v.type) {
case FcTypeCharSet:
FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
FcCharSetDestroy ((FcCharSet *) v.u.c);
break;
case FcTypeLangSet:
FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
FcLangSetDestroy ((FcLangSet *) v.u.l);
break;
default:
break;
@ -503,10 +571,12 @@ FcNameUnparseString (FcStrBuf *buf,
static FcBool
FcNameUnparseValue (FcStrBuf *buf,
FcValue v,
int bank,
FcValue *v0,
FcChar8 *escape)
{
FcChar8 temp[1024];
FcValue v = FcValueCanonicalize(v0);
switch (v.type) {
case FcTypeVoid:
@ -518,20 +588,17 @@ FcNameUnparseValue (FcStrBuf *buf,
sprintf ((char *) temp, "%g", v.u.d);
return FcNameUnparseString (buf, temp, 0);
case FcTypeString:
return FcNameUnparseString (buf, FcObjectPtrU(v.u.si), escape);
return FcNameUnparseString (buf, v.u.s, escape);
case FcTypeBool:
return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
case FcTypeMatrix:
{
FcMatrix * m = FcMatrixPtrU(v.u.mi);
sprintf ((char *) temp, "%g %g %g %g",
m->xx, m->xy, m->yx, m->yy);
v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
return FcNameUnparseString (buf, temp, 0);
}
case FcTypeCharSet:
return FcNameUnparseCharSet (buf, FcCharSetPtrU(v.u.ci));
return FcNameUnparseCharSet (buf, v.u.c);
case FcTypeLangSet:
return FcNameUnparseLangSet (buf, FcLangSetPtrU(v.u.li));
return FcNameUnparseLangSet (buf, v.u.l);
case FcTypeFTFace:
return FcTrue;
}
@ -545,7 +612,7 @@ FcNameUnparseValueList (FcStrBuf *buf,
{
while (FcValueListPtrU(v))
{
if (!FcNameUnparseValue (buf, FcValueListPtrU(v)->value, escape))
if (!FcNameUnparseValue (buf, v.bank, &FcValueListPtrU(v)->value, escape))
return FcFalse;
if (FcValueListPtrU(v = FcValueListPtrU(v)->next))
if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,6 @@
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/mman.h>
#include "fcint.h"
FcChar8 *
@ -849,67 +848,10 @@ FcStrSetCreate (void)
set->ref = 1;
set->num = 0;
set->size = 0;
set->storage = FcStorageDynamic;
set->u.strs = 0;
set->strs = 0;
return set;
}
static FcChar8 * strset_buf = 0;
static int strset_buf_ptr = 0, strset_buf_count = 0;
static int * strset_idx = 0;
static int strset_idx_ptr = 0, strset_idx_count = 0;
static FcStrSet * strsets = 0;
static int strset_ptr = 0, strset_count = 0;
void FcStrSetClearStatic()
{
strset_buf = 0; strset_buf_ptr = 0; strset_buf_count = 0;
strset_idx = 0; strset_idx_ptr = 0; strset_idx_count = 0;
strsets = 0; strset_ptr = 0; strset_count = 0;
}
FcChar8 *
FcStrSetGet (const FcStrSet *set, int i)
{
int index;
switch (set->storage)
{
case FcStorageStatic:
index = strset_idx[set->u.stridx_offset];
if (index == -1)
return 0;
return &strset_buf[index];
case FcStorageDynamic:
return set->u.strs[i];
default:
return 0;
}
}
FcStrSet *
FcStrSetPtrU (const FcStrSetPtr set)
{
switch (set.storage)
{
case FcStorageStatic:
return &strsets[set.u.stat];
case FcStorageDynamic:
return (FcStrSet *)set.u.dyn;
default:
return 0;
}
}
FcStrSetPtr
FcStrSetPtrCreateDynamic (const FcStrSet * set)
{
FcStrSetPtr new;
new.storage = FcStorageDynamic;
new.u.dyn = (FcStrSet *)set;
return new;
}
static FcBool
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
{
@ -918,7 +860,7 @@ _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
FcStrFree (s);
return FcTrue;
}
if (set->num == set->size || set->storage == FcStorageStatic)
if (set->num == set->size)
{
FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
@ -926,24 +868,14 @@ _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
return FcFalse;
FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
set->size = set->size + 1;
if (set->storage == FcStorageDynamic)
{
if (set->num)
memcpy (strs, set->u.strs, set->num * sizeof (FcChar8 *));
if (set->u.strs)
free (set->u.strs);
}
else
{
if (set->num)
memcpy (strs, strset_idx+set->u.stridx_offset,
set->num * sizeof (FcChar8 *));
set->storage = FcStorageDynamic;
}
set->u.strs = strs;
if (set->num)
memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
if (set->strs)
free (set->strs);
set->strs = strs;
}
set->u.strs[set->num++] = s;
set->u.strs[set->num] = 0;
set->strs[set->num++] = s;
set->strs[set->num] = 0;
return FcTrue;
}
@ -953,7 +885,7 @@ FcStrSetMember (FcStrSet *set, const FcChar8 *s)
int i;
for (i = 0; i < set->num; i++)
if (!FcStrCmp (FcStrSetGet(set, i), s))
if (!FcStrCmp (set->strs[i], s))
return FcTrue;
return FcFalse;
}
@ -965,7 +897,7 @@ FcStrSetEqual (FcStrSet *sa, FcStrSet *sb)
if (sa->num != sb->num)
return FcFalse;
for (i = 0; i < sa->num; i++)
if (!FcStrSetMember (sb, FcStrSetGet(sa, i)))
if (!FcStrSetMember (sb, sa->strs[i]))
return FcFalse;
return FcTrue;
}
@ -1004,15 +936,14 @@ FcStrSetDel (FcStrSet *set, const FcChar8 *s)
int i;
for (i = 0; i < set->num; i++)
if (!FcStrCmp (FcStrSetGet(set, i), s))
if (!FcStrCmp (set->strs[i], s))
{
if (set->storage == FcStorageDynamic)
FcStrFree (set->u.strs[i]);
FcStrFree (set->strs[i]);
/*
* copy remaining string pointers and trailing
* NULL
*/
memmove (FcStrSetGet(set, i), FcStrSetGet(set, i+1),
memmove (&set->strs[i], &set->strs[i+1],
(set->num - i) * sizeof (FcChar8 *));
set->num--;
return FcTrue;
@ -1027,194 +958,16 @@ FcStrSetDestroy (FcStrSet *set)
{
int i;
if (set->storage == FcStorageDynamic)
{
for (i = 0; i < set->num; i++)
FcStrFree (set->u.strs[i]);
FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
if (set->u.strs)
free (set->u.strs);
FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
}
for (i = 0; i < set->num; i++)
FcStrFree (set->strs[i]);
FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
if (set->strs)
free (set->strs);
FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
free (set);
}
}
static int _FcStrSetSort_helper (const void * a, const void * b)
{
return FcStrCmp (&strset_buf[(int)a],
&strset_buf[(int)b]);
}
void
FcStrSetSort (FcStrSet * set)
{
switch (set->storage)
{
case FcStorageDynamic:
qsort (set->u.strs, set->num, sizeof (FcChar8 *),
(int (*)(const void *, const void *)) FcStrCmp);
break;
case FcStorageStatic:
qsort (strset_idx+set->u.stridx_offset, set->num, sizeof (int),
_FcStrSetSort_helper);
break;
default:
break;
}
}
FcBool
FcStrSetPrepareSerialize (const FcStrSet *set)
{
int i;
if (!set)
return FcTrue;
strset_count ++;
strset_idx_count += set->num;
for (i = 0; i < set->num; i++)
{
if (FcStrSetGet(set, i))
strset_buf_count += strlen(FcStrSetGet(set, i));
}
return FcTrue;
}
FcStrSetPtr
FcStrSetSerialize (FcStrSet *set)
{
FcStrSet * new;
FcStrSetPtr newp;
int i;
if (!strsets)
{
strsets = malloc (strset_count * sizeof(FcStrSet));
if (!strsets) goto bail1;
strset_idx = malloc (strset_idx_count * sizeof(int));
if (!strset_idx) goto bail2;
strset_buf = malloc (strset_buf_count * sizeof (FcChar8));
if (!strset_buf) goto bail3;
}
if (!set)
return FcStrSetPtrCreateDynamic(0);
newp.storage = FcStorageStatic;
newp.u.stat = strset_ptr;
new = &strsets[strset_ptr++];
new->ref = set->ref;
new->num = set->num;
new->size = set->num;
new->storage = FcStorageStatic;
new->u.stridx_offset = strset_idx_ptr;
for (i = 0; i < set->num; i++)
{
FcChar8 * s = FcStrSetGet(set, i);
if (s)
{
memcpy(strset_buf+strset_buf_ptr, s,
strlen((char *)s));
strset_idx[strset_idx_ptr++] = strset_buf_ptr;
strset_buf_ptr += strlen((char *)s)+1;
}
else
strset_idx[strset_idx_ptr++] = -1;
}
if (strset_ptr > strset_count || strset_idx_ptr > strset_idx_count)
return FcStrSetPtrCreateDynamic(0);
// problem with multiple ptrs to the same StrSet.
// should hash StrSets or something.
// FcStrSetDestroy (set);
return newp;
bail3:
free (strset_idx);
bail2:
free (strsets);
bail1:
return FcStrSetPtrCreateDynamic(0);
}
FcBool
FcStrSetRead (int fd, FcCache metadata)
{
strsets = mmap(NULL,
metadata.strsets_length * sizeof (FcStrSet),
PROT_READ,
MAP_SHARED, fd, metadata.strsets_offset);
if (strsets == MAP_FAILED)
goto bail;
strset_count = strset_ptr = metadata.strsets_length;
strset_idx = mmap(NULL,
metadata.strsets_idx_length * sizeof (int),
PROT_READ,
MAP_SHARED, fd, metadata.strsets_idx_offset);
if (strset_idx == MAP_FAILED)
goto bail1;
strset_idx_count = strset_idx_ptr = metadata.strsets_length;
strset_buf = mmap(NULL,
metadata.strset_buf_length * sizeof (char),
PROT_READ,
MAP_SHARED, fd, metadata.strset_buf_offset);
if (strset_buf == MAP_FAILED)
goto bail2;
strset_buf_count = strset_buf_ptr = metadata.strset_buf_length;
return FcTrue;
bail2:
munmap (strset_idx, metadata.strsets_idx_length * sizeof (int));
bail1:
munmap (strsets, metadata.strsets_length * sizeof (FcStrSet));
bail:
return FcFalse;
}
FcBool
FcStrSetWrite (int fd, FcCache *metadata)
{
metadata->strsets_length = strset_ptr;
metadata->strsets_offset = FcCacheNextOffset(fd);
if (strset_ptr > 0)
{
lseek (fd, metadata->strsets_offset, SEEK_SET);
if (write (fd, strsets, strset_ptr * sizeof(FcStrSet)) == -1)
return FcFalse;
}
metadata->strsets_idx_length = strset_idx_ptr;
metadata->strsets_idx_offset = FcCacheNextOffset(fd);
if (strset_idx_ptr > 0)
{
lseek (fd, metadata->strsets_idx_offset, SEEK_SET);
if (write (fd, strset_idx, strset_idx_ptr * sizeof (int)) == -1)
return FcFalse;
}
metadata->strset_buf_offset = FcCacheNextOffset(fd);
metadata->strset_buf_length = strset_buf_ptr;
if (strset_buf_ptr > 0)
{
lseek (fd, metadata->strset_buf_offset, SEEK_SET);
if (write (fd, strset_buf,
metadata->strset_buf_length * sizeof (char)) == -1)
return FcFalse;
}
return FcTrue;
}
FcStrList *
FcStrListCreate (FcStrSet *set)
{
@ -1235,7 +988,7 @@ FcStrListNext (FcStrList *list)
{
if (list->n >= list->set->num)
return 0;
return FcStrSetGet(list->set, list->n++);
return list->set->strs[list->n++];
}
void

View File

@ -1878,8 +1878,8 @@ FcPopValue (FcConfigParse *parse)
switch (vstack->tag) {
case FcVStackString:
value.u.si = FcObjectStaticName(FcStrCopy (vstack->u.string));
if (FcObjectPtrU(value.u.si))
value.u.s = FcStrCopy (vstack->u.string);
if (value.u.s)
value.type = FcTypeString;
break;
case FcVStackConstant:
@ -1895,8 +1895,8 @@ FcPopValue (FcConfigParse *parse)
value.type = FcTypeInteger;
break;
case FcVStackMatrix:
value.u.mi = FcMatrixPtrCreateDynamic(FcMatrixCopy (vstack->u.matrix));
if (FcMatrixPtrU(value.u.mi))
value.u.m = FcMatrixCopy (vstack->u.matrix);
if (value.u.m)
value.type = FcTypeMatrix;
break;
case FcVStackBool:
@ -2281,9 +2281,10 @@ FcConfigParseAndLoadDir (FcConfig *config,
if (ret)
{
int i;
FcStrSetSort (files);
qsort (files->strs, files->num, sizeof (FcChar8 *),
(int (*)(const void *, const void *)) FcStrCmp);
for (i = 0; ret && i < files->num; i++)
ret = FcConfigParseAndLoad (config, FcStrSetGet(files, i), complain);
ret = FcConfigParseAndLoad (config, files->strs[i], complain);
}
bail3:
FcStrSetDestroy (files);