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:
parent
212c9f437e
commit
4262e0b385
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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)) \
|
||||
|
|
|
@ -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
|
||||
|
|
419
src/fccache.c
419
src/fccache.c
|
@ -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;
|
||||
}
|
||||
|
|
109
src/fccfg.c
109
src/fccfg.c
|
@ -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;
|
||||
}
|
||||
|
|
331
src/fccharset.c
331
src/fccharset.c
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
12
src/fcdbg.c
12
src/fcdbg.c
|
@ -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)");
|
||||
|
|
17
src/fcdir.c
17
src/fcdir.c
|
@ -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);
|
||||
}
|
||||
|
|
168
src/fcfs.c
168
src/fcfs.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -61,9 +61,6 @@ FcInitLoadConfig (void)
|
|||
if (!config)
|
||||
return FcFalse;
|
||||
|
||||
if (!FcCacheRead(config))
|
||||
FcCacheForce(FcTrue);
|
||||
|
||||
if (!FcConfigParseAndLoad (config, 0, FcTrue))
|
||||
{
|
||||
FcConfigDestroy (config);
|
||||
|
|
284
src/fcint.h
284
src/fcint.h
|
@ -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);
|
||||
|
||||
|
|
215
src/fclang.c
215
src/fclang.c
|
@ -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;
|
||||
}
|
||||
|
|
57
src/fclist.c
57
src/fclist.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
100
src/fcmatrix.c
100
src/fcmatrix.c
|
@ -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;
|
||||
}
|
||||
|
|
101
src/fcname.c
101
src/fcname.c
|
@ -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))
|
||||
|
|
1566
src/fcpat.c
1566
src/fcpat.c
File diff suppressed because it is too large
Load Diff
289
src/fcstr.c
289
src/fcstr.c
|
@ -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
|
||||
|
|
13
src/fcxml.c
13
src/fcxml.c
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue