#ifdef out old cache stuff, replace with first version of new mmapping
cache. Add *Read and *Write procedures which mmap in and write out the fontconfig data structures to disk. Currently, create cache in /tmp, with different sections for each architecture (as returned by uname's .machine field. Run the fc-cache binary to create a new cache file; fontconfig then uses this cache file on subsequent runs, saving lots of memory. Also fixes a few bugs and leaks.
This commit is contained in:
parent
e1b9d091c6
commit
212c9f437e
|
@ -93,6 +93,7 @@ usage (char *program)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int
|
static int
|
||||||
nsubdirs (FcStrSet *set)
|
nsubdirs (FcStrSet *set)
|
||||||
{
|
{
|
||||||
|
@ -222,6 +223,7 @@ scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool
|
||||||
FcStrListDone (list);
|
FcStrListDone (list);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
|
@ -268,12 +270,20 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
if (systemOnly)
|
if (systemOnly)
|
||||||
FcConfigEnableHome (FcFalse);
|
FcConfigEnableHome (FcFalse);
|
||||||
config = FcInitLoadConfig ();
|
FcCacheForce (FcTrue);
|
||||||
|
/* need to use FcInitLoadConfig when we use dirs */
|
||||||
|
FcInit ();
|
||||||
|
config = FcConfigGetCurrent ();
|
||||||
if (!config)
|
if (!config)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
|
fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We don't yet have per-directory caches. */
|
||||||
|
ret = (FcCacheWrite (config) == FcFalse);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (argv[i])
|
if (argv[i])
|
||||||
{
|
{
|
||||||
dirs = FcStrSetCreate ();
|
dirs = FcStrSetCreate ();
|
||||||
|
@ -298,6 +308,7 @@ main (int argc, char **argv)
|
||||||
else
|
else
|
||||||
list = FcConfigGetConfigDirs (config);
|
list = FcConfigGetConfigDirs (config);
|
||||||
ret = scanDirs (list, config, argv[0], force, verbose);
|
ret = scanDirs (list, config, argv[0], force, verbose);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Now we need to sleep a second (or two, to be extra sure), to make
|
* 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
|
* sure that timestamps for changes after this run of fc-cache are later
|
||||||
|
|
|
@ -47,6 +47,12 @@ FcMemFree (int kind, int size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
FcCacheNextOffset (int fd)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
FcChar8 *
|
FcChar8 *
|
||||||
FcConfigHome (void)
|
FcConfigHome (void)
|
||||||
{
|
{
|
||||||
|
|
1079
src/fccache.c
1079
src/fccache.c
File diff suppressed because it is too large
Load Diff
14
src/fccfg.c
14
src/fccfg.c
|
@ -252,16 +252,22 @@ FcConfigBuildFonts (FcConfig *config)
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
FcChar8 *dir;
|
FcChar8 *dir;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (config->cache)
|
||||||
|
FcGlobalCacheLoad (cache, config->cache);
|
||||||
|
#endif
|
||||||
|
if (config->fonts[FcSetSystem])
|
||||||
|
return FcTrue;
|
||||||
|
|
||||||
fonts = FcFontSetCreate ();
|
fonts = FcFontSetCreate ();
|
||||||
if (!fonts)
|
if (!fonts)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
cache = FcGlobalCacheCreate ();
|
cache = FcGlobalCacheCreate ();
|
||||||
if (!cache)
|
if (!cache)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
#endif
|
||||||
if (config->cache)
|
|
||||||
FcGlobalCacheLoad (cache, config->cache);
|
|
||||||
|
|
||||||
list = FcConfigGetFontDirs (config);
|
list = FcConfigGetFontDirs (config);
|
||||||
if (!list)
|
if (!list)
|
||||||
|
@ -280,9 +286,11 @@ FcConfigBuildFonts (FcConfig *config)
|
||||||
if (FcDebug () & FC_DBG_FONTSET)
|
if (FcDebug () & FC_DBG_FONTSET)
|
||||||
FcFontSetPrint (fonts);
|
FcFontSetPrint (fonts);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (config->cache)
|
if (config->cache)
|
||||||
FcGlobalCacheSave (cache, config->cache);
|
FcGlobalCacheSave (cache, config->cache);
|
||||||
FcGlobalCacheDestroy (cache);
|
FcGlobalCacheDestroy (cache);
|
||||||
|
#endif
|
||||||
|
|
||||||
FcConfigSetFonts (config, fonts, FcSetSystem);
|
FcConfigSetFonts (config, fonts, FcSetSystem);
|
||||||
|
|
||||||
|
|
103
src/fccharset.c
103
src/fccharset.c
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
|
|
||||||
/* #define CHECK */
|
/* #define CHECK */
|
||||||
|
@ -383,6 +384,14 @@ FcCharSetCopy (FcCharSet *src)
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcCharSetPtr
|
||||||
|
FcCharSetCopyPtr (FcCharSetPtr src)
|
||||||
|
{
|
||||||
|
if (FcCharSetPtrU(src)->ref != FC_REF_CONSTANT)
|
||||||
|
FcCharSetPtrU(src)->ref++;
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcCharSetEqual (const FcCharSet *a, const FcCharSet *b)
|
FcCharSetEqual (const FcCharSet *a, const FcCharSet *b)
|
||||||
{
|
{
|
||||||
|
@ -1369,10 +1378,11 @@ FcCharSetSerialize(FcCharSet *c)
|
||||||
if (!leaf_idx) goto bail3;
|
if (!leaf_idx) goto bail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
new.ref = c->ref;
|
new.ref = FC_REF_CONSTANT;
|
||||||
new.storage = FcStorageStatic;
|
new.storage = FcStorageStatic;
|
||||||
new.u.stat.leafidx_offset = charset_leaf_ptr;
|
new.u.stat.leafidx_offset = charset_leaf_idx_ptr;
|
||||||
new.u.stat.numbers_offset = charset_numbers_ptr;
|
new.u.stat.numbers_offset = charset_numbers_ptr;
|
||||||
|
new.num = c->num;
|
||||||
|
|
||||||
newp.storage = FcStorageStatic;
|
newp.storage = FcStorageStatic;
|
||||||
newp.u.stat = charset_ptr;
|
newp.u.stat = charset_ptr;
|
||||||
|
@ -1398,6 +1408,95 @@ FcCharSetSerialize(FcCharSet *c)
|
||||||
return FcCharSetPtrCreateDynamic(0);
|
return FcCharSetPtrCreateDynamic(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcCharSetRead (int fd, FcCache metadata)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
FcCharLeaf *
|
FcCharLeaf *
|
||||||
FcCharSetGetLeaf(const FcCharSet *c, int i)
|
FcCharSetGetLeaf(const FcCharSet *c, int i)
|
||||||
{
|
{
|
||||||
|
|
17
src/fcdir.c
17
src/fcdir.c
|
@ -45,13 +45,15 @@ FcFileScanConfig (FcFontSet *set,
|
||||||
FcConfig *config)
|
FcConfig *config)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
#if 0
|
||||||
FcChar8 *name;
|
FcChar8 *name;
|
||||||
|
FcGlobalCacheFile *cache_file;
|
||||||
|
FcGlobalCacheDir *cache_dir;
|
||||||
|
#endif
|
||||||
FcPattern *font;
|
FcPattern *font;
|
||||||
FcBool ret = FcTrue;
|
FcBool ret = FcTrue;
|
||||||
FcBool isDir;
|
FcBool isDir;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
FcGlobalCacheFile *cache_file;
|
|
||||||
FcGlobalCacheDir *cache_dir;
|
|
||||||
FcBool need_scan;
|
FcBool need_scan;
|
||||||
|
|
||||||
if (config && !FcConfigAcceptFilename (config, file))
|
if (config && !FcConfigAcceptFilename (config, file))
|
||||||
|
@ -64,6 +66,7 @@ FcFileScanConfig (FcFontSet *set,
|
||||||
{
|
{
|
||||||
need_scan = FcTrue;
|
need_scan = FcTrue;
|
||||||
font = 0;
|
font = 0;
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Check the cache
|
* Check the cache
|
||||||
*/
|
*/
|
||||||
|
@ -104,6 +107,7 @@ FcFileScanConfig (FcFontSet *set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Nothing in the cache, scan the file
|
* Nothing in the cache, scan the file
|
||||||
*/
|
*/
|
||||||
|
@ -123,6 +127,7 @@ FcFileScanConfig (FcFontSet *set,
|
||||||
isDir = FcTrue;
|
isDir = FcTrue;
|
||||||
ret = FcStrSetAdd (dirs, file);
|
ret = FcStrSetAdd (dirs, file);
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Update the cache
|
* Update the cache
|
||||||
*/
|
*/
|
||||||
|
@ -137,6 +142,7 @@ FcFileScanConfig (FcFontSet *set,
|
||||||
FcStrFree (unparse);
|
FcStrFree (unparse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Add the font
|
* Add the font
|
||||||
|
@ -193,6 +199,7 @@ FcDirScanConfig (FcFontSet *set,
|
||||||
|
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Check fonts.cache-<version> file
|
* Check fonts.cache-<version> file
|
||||||
*/
|
*/
|
||||||
|
@ -208,6 +215,7 @@ FcDirScanConfig (FcFontSet *set,
|
||||||
*/
|
*/
|
||||||
if (cache && FcGlobalCacheScanDir (set, dirs, cache, dir, config))
|
if (cache && FcGlobalCacheScanDir (set, dirs, cache, dir, config))
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* freed below */
|
/* freed below */
|
||||||
|
@ -246,8 +254,10 @@ FcDirScanConfig (FcFontSet *set,
|
||||||
* Now that the directory has been scanned,
|
* Now that the directory has been scanned,
|
||||||
* add the cache entry
|
* add the cache entry
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
if (ret && cache)
|
if (ret && cache)
|
||||||
FcGlobalCacheUpdate (cache, dir, 0, 0);
|
FcGlobalCacheUpdate (cache, dir, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -266,5 +276,8 @@ FcDirScan (FcFontSet *set,
|
||||||
FcBool
|
FcBool
|
||||||
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
|
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
return FcDirCacheWriteDir (set, dirs, dir);
|
return FcDirCacheWriteDir (set, dirs, dir);
|
||||||
|
#endif
|
||||||
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
95
src/fcfs.c
95
src/fcfs.c
|
@ -116,3 +116,98 @@ FcFontSetClearStatic (void)
|
||||||
{
|
{
|
||||||
FcPatternClearStatic();
|
FcPatternClearStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcFontSetRead(int fd, FcConfig * config, FcCache metadata)
|
||||||
|
{
|
||||||
|
int i, mz, j;
|
||||||
|
FcPattern * buf;
|
||||||
|
|
||||||
|
lseek(fd, metadata.fontsets_offset, SEEK_SET);
|
||||||
|
for (i = FcSetSystem; i <= FcSetApplication; i++)
|
||||||
|
{
|
||||||
|
if (config->fonts[i])
|
||||||
|
{
|
||||||
|
if (config->fonts[i]->nfont > 0 && config->fonts[i]->fonts)
|
||||||
|
free (config->fonts[i]->fonts);
|
||||||
|
free (config->fonts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = FcSetSystem; i <= FcSetApplication; i++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,6 +61,9 @@ FcInitLoadConfig (void)
|
||||||
if (!config)
|
if (!config)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
|
if (!FcCacheRead(config))
|
||||||
|
FcCacheForce(FcTrue);
|
||||||
|
|
||||||
if (!FcConfigParseAndLoad (config, 0, FcTrue))
|
if (!FcConfigParseAndLoad (config, 0, FcTrue))
|
||||||
{
|
{
|
||||||
FcConfigDestroy (config);
|
FcConfigDestroy (config);
|
||||||
|
|
146
src/fcint.h
146
src/fcint.h
|
@ -259,6 +259,25 @@ typedef struct _FcStrBuf {
|
||||||
int size;
|
int size;
|
||||||
} FcStrBuf;
|
} 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;
|
||||||
|
} FcCache;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To map adobe glyph names to unicode values, a precomputed hash
|
* To map adobe glyph names to unicode values, a precomputed hash
|
||||||
* table is used
|
* table is used
|
||||||
|
@ -312,6 +331,7 @@ typedef struct _FcCaseFold {
|
||||||
* cache which is then rewritten to the users home directory
|
* cache which is then rewritten to the users home directory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FC_CACHE_MAGIC 0x12345678
|
||||||
#define FC_GLOBAL_CACHE_DIR_HASH_SIZE 37
|
#define FC_GLOBAL_CACHE_DIR_HASH_SIZE 37
|
||||||
#define FC_GLOBAL_CACHE_FILE_HASH_SIZE 67
|
#define FC_GLOBAL_CACHE_FILE_HASH_SIZE 67
|
||||||
|
|
||||||
|
@ -429,65 +449,26 @@ typedef struct _FcCharMap FcCharMap;
|
||||||
|
|
||||||
/* fccache.c */
|
/* fccache.c */
|
||||||
|
|
||||||
FcGlobalCache *
|
int
|
||||||
FcGlobalCacheCreate (void);
|
FcCacheNextOffset(int fd);
|
||||||
|
|
||||||
void
|
void
|
||||||
FcGlobalCacheDestroy (FcGlobalCache *cache);
|
FcCacheForce(FcBool force);
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcGlobalCacheCheckTime (const FcChar8*file, FcGlobalCacheInfo *info);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FcGlobalCacheReferenced (FcGlobalCache *cache,
|
FcCacheClearStatic(void);
|
||||||
FcGlobalCacheInfo *info);
|
|
||||||
|
|
||||||
void
|
|
||||||
FcGlobalCacheReferenceSubdir (FcGlobalCache *cache,
|
|
||||||
const FcChar8 *dir);
|
|
||||||
|
|
||||||
FcGlobalCacheDir *
|
|
||||||
FcGlobalCacheDirGet (FcGlobalCache *cache,
|
|
||||||
const FcChar8 *dir,
|
|
||||||
int len,
|
|
||||||
FcBool create_missing);
|
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcGlobalCacheScanDir (FcFontSet *set,
|
FcCachePrepareSerialize(FcConfig * config);
|
||||||
FcStrSet *dirs,
|
|
||||||
FcGlobalCache *cache,
|
|
||||||
const FcChar8 *dir,
|
|
||||||
FcConfig *config);
|
|
||||||
|
|
||||||
FcGlobalCacheFile *
|
|
||||||
FcGlobalCacheFileGet (FcGlobalCache *cache,
|
|
||||||
const FcChar8 *file,
|
|
||||||
int id,
|
|
||||||
int *count);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
FcGlobalCacheLoad (FcGlobalCache *cache,
|
|
||||||
const FcChar8 *cache_file);
|
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcGlobalCacheUpdate (FcGlobalCache *cache,
|
FcCacheSerialize (FcConfig * config);
|
||||||
const FcChar8 *file,
|
|
||||||
int id,
|
|
||||||
const FcChar8 *name);
|
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcGlobalCacheSave (FcGlobalCache *cache,
|
FcCacheRead (FcConfig *config);
|
||||||
const FcChar8 *cache_file);
|
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheReadDir (FcFontSet *set,
|
FcCacheWrite (FcConfig * config);
|
||||||
FcStrSet *dirs,
|
|
||||||
const FcChar8 *dir,
|
|
||||||
FcConfig *config);
|
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcDirCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
|
|
||||||
|
|
||||||
/* fccfg.c */
|
/* fccfg.c */
|
||||||
|
|
||||||
|
@ -553,6 +534,9 @@ FcConfigAcceptFont (FcConfig *config,
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcCharSetFreeze (FcCharSet *cs);
|
FcCharSetFreeze (FcCharSet *cs);
|
||||||
|
|
||||||
|
FcCharSetPtr
|
||||||
|
FcCharSetCopyPtr (FcCharSetPtr src);
|
||||||
|
|
||||||
void
|
void
|
||||||
FcCharSetThawAll (void);
|
FcCharSetThawAll (void);
|
||||||
|
|
||||||
|
@ -586,6 +570,12 @@ FcCharSetGetLeaf(const FcCharSet *c, int i);
|
||||||
FcChar16 *
|
FcChar16 *
|
||||||
FcCharSetGetNumbers(const FcCharSet *c);
|
FcCharSetGetNumbers(const FcCharSet *c);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcCharSetRead (int fd, FcCache metadata);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcCharSetWrite (int fd, FcCache *metadata);
|
||||||
|
|
||||||
/* fcdbg.c */
|
/* fcdbg.c */
|
||||||
void
|
void
|
||||||
FcValueListPrint (const FcValueListPtr l);
|
FcValueListPrint (const FcValueListPtr l);
|
||||||
|
@ -668,6 +658,12 @@ FcFontSetPrepareSerialize (FcFontSet * s);
|
||||||
FcBool
|
FcBool
|
||||||
FcFontSetSerialize (FcFontSet * s);
|
FcFontSetSerialize (FcFontSet * s);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcFontSetRead(int fd, FcConfig * config, FcCache metadata);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcFontSetWrite(int fd, FcConfig * config, FcCache * metadata);
|
||||||
|
|
||||||
/* fcgram.y */
|
/* fcgram.y */
|
||||||
int
|
int
|
||||||
FcConfigparse (void);
|
FcConfigparse (void);
|
||||||
|
@ -766,6 +762,12 @@ FcLangSetPtrCreateDynamic (FcLangSet *l);
|
||||||
void
|
void
|
||||||
FcLangSetPtrDestroy (FcLangSetPtr li);
|
FcLangSetPtrDestroy (FcLangSetPtr li);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcLangSetRead (int fd, FcCache metadata);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcLangSetWrite (int fd, FcCache *metadata);
|
||||||
|
|
||||||
/* fclist.c */
|
/* fclist.c */
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -774,18 +776,6 @@ FcListPatternMatchAny (const FcPattern *p,
|
||||||
|
|
||||||
/* fcmatch.c */
|
/* fcmatch.c */
|
||||||
|
|
||||||
/* fcmmap.c */
|
|
||||||
|
|
||||||
void
|
|
||||||
FcCacheClearStatic(void);
|
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcCachePrepareSerialize(FcConfig * config);
|
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcCacheSerialize (FcConfig * config);
|
|
||||||
|
|
||||||
|
|
||||||
/* fcname.c */
|
/* fcname.c */
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -824,7 +814,10 @@ FcObjectPtr
|
||||||
FcObjectStaticName (const char *name);
|
FcObjectStaticName (const char *name);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcObjectPrepareSerialize (FcObjectPtr si);
|
FcObjectRead (int fd, FcCache metadata);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcObjectWrite (int fd, FcCache * metadata);
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
FcObjectPtrU (FcObjectPtr p);
|
FcObjectPtrU (FcObjectPtr p);
|
||||||
|
@ -832,9 +825,6 @@ FcObjectPtrU (FcObjectPtr p);
|
||||||
int
|
int
|
||||||
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
|
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
|
||||||
|
|
||||||
FcObjectPtr
|
|
||||||
FcObjectPtrCreateDynamic (const char * s);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FcObjectPtrDestroy (FcObjectPtr p);
|
FcObjectPtrDestroy (FcObjectPtr p);
|
||||||
|
|
||||||
|
@ -865,6 +855,24 @@ FcValueListSerialize(FcValueList *pi);
|
||||||
FcPattern *
|
FcPattern *
|
||||||
FcPatternSerialize (FcPattern * p);
|
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);
|
||||||
|
|
||||||
/* fcrender.c */
|
/* fcrender.c */
|
||||||
|
|
||||||
/* fcmatrix.c */
|
/* fcmatrix.c */
|
||||||
|
@ -892,6 +900,12 @@ FcMatrixPtrCreateDynamic (FcMatrix *m);
|
||||||
void
|
void
|
||||||
FcMatrixClearStatic (void);
|
FcMatrixClearStatic (void);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcMatrixWrite (int fd, FcCache *metadata);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcMatrixRead (int fd, FcCache metadata);
|
||||||
|
|
||||||
/* fcstr.c */
|
/* fcstr.c */
|
||||||
FcStrSet *
|
FcStrSet *
|
||||||
FcStrSetPtrU (const FcStrSetPtr set);
|
FcStrSetPtrU (const FcStrSetPtr set);
|
||||||
|
@ -938,6 +952,12 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
|
||||||
FcStrSetPtr
|
FcStrSetPtr
|
||||||
FcStrSetSerialize (FcStrSet *set);
|
FcStrSetSerialize (FcStrSet *set);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcStrSetRead (int fd, FcCache metadata);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcStrSetWrite (int fd, FcCache *metadata);
|
||||||
|
|
||||||
int
|
int
|
||||||
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
|
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
|
||||||
|
|
||||||
|
|
28
src/fclang.c
28
src/fclang.c
|
@ -774,3 +774,31 @@ FcLangSetSerialize(FcLangSet *l)
|
||||||
new.u.stat = p;
|
new.u.stat = p;
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcLangSetWrite (int fd, FcCache *metadata)
|
||||||
|
{
|
||||||
|
metadata->langsets_length = langset_ptr;
|
||||||
|
metadata->langsets_offset = FcCacheNextOffset(fd);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
|
|
||||||
FcMatrix _id = { 1, 0, 0, 1 };
|
FcMatrix _id = { 1, 0, 0, 1 };
|
||||||
|
@ -182,3 +183,31 @@ FcMatrixSerialize(FcMatrix *m)
|
||||||
return new;
|
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;
|
||||||
|
}
|
||||||
|
|
235
src/fcpat.c
235
src/fcpat.c
|
@ -94,8 +94,7 @@ FcValueSave (FcValue v)
|
||||||
v.type = FcTypeVoid;
|
v.type = FcTypeVoid;
|
||||||
break;
|
break;
|
||||||
case FcTypeCharSet:
|
case FcTypeCharSet:
|
||||||
v.u.ci = FcCharSetPtrCreateDynamic
|
v.u.ci = FcCharSetCopyPtr (v.u.ci);
|
||||||
(FcCharSetCopy (FcCharSetPtrU(v.u.ci)));
|
|
||||||
if (!FcCharSetPtrU(v.u.ci))
|
if (!FcCharSetPtrU(v.u.ci))
|
||||||
v.type = FcTypeVoid;
|
v.type = FcTypeVoid;
|
||||||
break;
|
break;
|
||||||
|
@ -1270,7 +1269,6 @@ FcPatternEltU (FcPatternEltPtr pei)
|
||||||
switch (pei.storage)
|
switch (pei.storage)
|
||||||
{
|
{
|
||||||
case FcStorageStatic:
|
case FcStorageStatic:
|
||||||
if (pei.u.stat == 0) return 0;
|
|
||||||
return &fcpatternelts[pei.u.stat];
|
return &fcpatternelts[pei.u.stat];
|
||||||
case FcStorageDynamic:
|
case FcStorageDynamic:
|
||||||
return pei.u.dyn;
|
return pei.u.dyn;
|
||||||
|
@ -1324,6 +1322,8 @@ FcValueListClearStatic (void)
|
||||||
fcvaluelist_count = 0;
|
fcvaluelist_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FcBool
|
||||||
|
FcObjectPrepareSerialize (FcObjectPtr si);
|
||||||
static FcObjectPtr
|
static FcObjectPtr
|
||||||
FcObjectSerialize (FcObjectPtr si);
|
FcObjectSerialize (FcObjectPtr si);
|
||||||
|
|
||||||
|
@ -1408,11 +1408,12 @@ FcPatternSerialize (FcPattern *old)
|
||||||
fcpatternelt_ptr = 0;
|
fcpatternelt_ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = FcPatternCreate();
|
p = &fcpatterns[fcpattern_ptr++];
|
||||||
elts = fcpatternelt_ptr;
|
elts = fcpatternelt_ptr;
|
||||||
nep = &fcpatternelts[elts];
|
nep = &fcpatternelts[elts];
|
||||||
if (!nep)
|
if (!nep)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
fcpatternelt_ptr += old->num;
|
fcpatternelt_ptr += old->num;
|
||||||
|
|
||||||
for (e = FcPatternEltU(old->elts), i=0; i < old->num; i++, e++)
|
for (e = FcPatternEltU(old->elts), i=0; i < old->num; i++, e++)
|
||||||
|
@ -1438,12 +1439,13 @@ FcPatternSerialize (FcPattern *old)
|
||||||
}
|
}
|
||||||
|
|
||||||
nep[i].values = nv_head;
|
nep[i].values = nv_head;
|
||||||
nep[i].object = FcObjectSerialize
|
nep[i].object = FcObjectSerialize (e->object);
|
||||||
(FcObjectStaticName(FcObjectPtrU(e->object)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->elts = old->elts;
|
||||||
p->elts = FcPatternEltPtrCreateStatic(elts);
|
p->elts = FcPatternEltPtrCreateStatic(elts);
|
||||||
p->size = old->num;
|
p->size = old->num;
|
||||||
|
p->num = old->num;
|
||||||
p->ref = FC_REF_CONSTANT;
|
p->ref = FC_REF_CONSTANT;
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
|
@ -1455,6 +1457,68 @@ FcPatternSerialize (FcPattern *old)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternRead (int fd, FcCache metadata)
|
||||||
|
{
|
||||||
|
fcpatterns = mmap(NULL,
|
||||||
|
metadata.pattern_length * sizeof (FcPattern),
|
||||||
|
PROT_READ,
|
||||||
|
MAP_SHARED, fd, metadata.pattern_offset);
|
||||||
|
if (fcpatterns == MAP_FAILED)
|
||||||
|
return FcFalse;
|
||||||
|
fcpattern_count = fcpattern_ptr = metadata.pattern_length;
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternWrite (int fd, FcCache *metadata)
|
||||||
|
{
|
||||||
|
int c = fcpattern_ptr;
|
||||||
|
off_t w = FcCacheNextOffset(fd);
|
||||||
|
|
||||||
|
metadata->pattern_offset = w;
|
||||||
|
metadata->pattern_length = c;
|
||||||
|
|
||||||
|
if (c > 0)
|
||||||
|
{
|
||||||
|
lseek(fd, w, SEEK_SET);
|
||||||
|
return write(fd, fcpatterns, c*sizeof(FcPattern)) != -1;
|
||||||
|
}
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternEltRead (int fd, FcCache metadata)
|
||||||
|
{
|
||||||
|
fcpatternelts = mmap(NULL,
|
||||||
|
metadata.patternelt_length * sizeof (FcPatternElt),
|
||||||
|
PROT_READ,
|
||||||
|
MAP_SHARED, fd, metadata.patternelt_offset);
|
||||||
|
if (fcpatternelts == MAP_FAILED)
|
||||||
|
return FcFalse;
|
||||||
|
fcpatternelt_count = fcpatternelt_ptr = metadata.patternelt_length;
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternEltWrite (int fd, FcCache *metadata)
|
||||||
|
{
|
||||||
|
int c = fcpatternelt_ptr;
|
||||||
|
off_t w = FcCacheNextOffset(fd);
|
||||||
|
|
||||||
|
metadata->patternelt_offset = w;
|
||||||
|
metadata->patternelt_length = c;
|
||||||
|
|
||||||
|
if (c > 0)
|
||||||
|
{
|
||||||
|
lseek(fd, w, SEEK_SET);
|
||||||
|
return write(fd, fcpatternelts, c*sizeof(FcPatternElt)) != -1;
|
||||||
|
}
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
FcValueListPtr
|
FcValueListPtr
|
||||||
FcValueListSerialize(FcValueList *pi)
|
FcValueListSerialize(FcValueList *pi)
|
||||||
{
|
{
|
||||||
|
@ -1480,13 +1544,18 @@ FcValueListSerialize(FcValueList *pi)
|
||||||
switch (v->type)
|
switch (v->type)
|
||||||
{
|
{
|
||||||
case FcTypeString:
|
case FcTypeString:
|
||||||
if (FcObjectPtrU(v->u.si))
|
/* this departs from the usual convention of dereferencing
|
||||||
|
* foo before serialization; FcObjectSerialize does the
|
||||||
|
* translation itself. */
|
||||||
|
/* also, v->u.si is 0 iff the string is null. */
|
||||||
|
/* also, have to update the old pi */
|
||||||
|
if (v->u.si)
|
||||||
{
|
{
|
||||||
FcObjectPtr si =
|
FcObjectPtr si = FcObjectSerialize(v->u.si);
|
||||||
FcObjectSerialize(FcObjectStaticName(FcObjectPtrU(v->u.si)));
|
if (!FcObjectPtrU(si))
|
||||||
if (!FcObjectPtrU(v->u.si))
|
|
||||||
return FcValueListPtrCreateDynamic(pi);
|
return FcValueListPtrCreateDynamic(pi);
|
||||||
v->u.si = si;
|
v->u.si = si;
|
||||||
|
pi->value.u.si = si;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FcTypeMatrix:
|
case FcTypeMatrix:
|
||||||
|
@ -1503,7 +1572,7 @@ FcValueListSerialize(FcValueList *pi)
|
||||||
if (FcCharSetPtrU(v->u.ci))
|
if (FcCharSetPtrU(v->u.ci))
|
||||||
{
|
{
|
||||||
FcCharSetPtr ci = FcCharSetSerialize(FcCharSetPtrU(v->u.ci));
|
FcCharSetPtr ci = FcCharSetSerialize(FcCharSetPtrU(v->u.ci));
|
||||||
if (!FcCharSetPtrU(v->u.ci))
|
if (!FcCharSetPtrU(ci))
|
||||||
return FcValueListPtrCreateDynamic(pi);
|
return FcValueListPtrCreateDynamic(pi);
|
||||||
v->u.ci = ci;
|
v->u.ci = ci;
|
||||||
}
|
}
|
||||||
|
@ -1512,7 +1581,7 @@ FcValueListSerialize(FcValueList *pi)
|
||||||
if (FcLangSetPtrU(v->u.li))
|
if (FcLangSetPtrU(v->u.li))
|
||||||
{
|
{
|
||||||
FcLangSetPtr li = FcLangSetSerialize(FcLangSetPtrU(v->u.li));
|
FcLangSetPtr li = FcLangSetSerialize(FcLangSetPtrU(v->u.li));
|
||||||
if (!FcLangSetPtrU(v->u.li))
|
if (!FcLangSetPtrU(li))
|
||||||
return FcValueListPtrCreateDynamic(pi);
|
return FcValueListPtrCreateDynamic(pi);
|
||||||
v->u.li = li;
|
v->u.li = li;
|
||||||
}
|
}
|
||||||
|
@ -1523,13 +1592,41 @@ FcValueListSerialize(FcValueList *pi)
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcValueListRead (int fd, FcCache metadata)
|
||||||
|
{
|
||||||
|
fcvaluelists = mmap(NULL,
|
||||||
|
metadata.valuelist_length * sizeof (FcValueList),
|
||||||
|
PROT_READ,
|
||||||
|
MAP_SHARED, fd, metadata.valuelist_offset);
|
||||||
|
if (fcvaluelists == MAP_FAILED)
|
||||||
|
return FcFalse;
|
||||||
|
fcvaluelist_count = fcvaluelist_ptr = metadata.valuelist_length;
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcValueListWrite (int fd, FcCache *metadata)
|
||||||
|
{
|
||||||
|
metadata->valuelist_offset = FcCacheNextOffset(fd);
|
||||||
|
metadata->valuelist_length = fcvaluelist_ptr;
|
||||||
|
|
||||||
|
if (fcvaluelist_ptr > 0)
|
||||||
|
{
|
||||||
|
lseek(fd, metadata->valuelist_offset, SEEK_SET);
|
||||||
|
return write(fd, fcvaluelists,
|
||||||
|
fcvaluelist_ptr * sizeof(FcValueList)) != -1;
|
||||||
|
}
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
FcValueList *
|
FcValueList *
|
||||||
FcValueListPtrU (FcValueListPtr pi)
|
FcValueListPtrU (FcValueListPtr pi)
|
||||||
{
|
{
|
||||||
switch (pi.storage)
|
switch (pi.storage)
|
||||||
{
|
{
|
||||||
case FcStorageStatic:
|
case FcStorageStatic:
|
||||||
if (pi.u.stat == 0) return 0;
|
|
||||||
return &fcvaluelists[pi.u.stat];
|
return &fcvaluelists[pi.u.stat];
|
||||||
case FcStorageDynamic:
|
case FcStorageDynamic:
|
||||||
return pi.u.dyn;
|
return pi.u.dyn;
|
||||||
|
@ -1642,7 +1739,7 @@ FcObjectStaticName (const char *name)
|
||||||
objectptr_alloc = s;
|
objectptr_alloc = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeof (struct objectBucket) + strlen (name) + 1;
|
size = sizeof (struct objectBucket) + sizeof (char *);
|
||||||
b = malloc (size);
|
b = malloc (size);
|
||||||
if (!b)
|
if (!b)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1687,6 +1784,9 @@ FcObjectPtrDestroy (FcObjectPtr p)
|
||||||
const char *
|
const char *
|
||||||
FcObjectPtrU (FcObjectPtr si)
|
FcObjectPtrU (FcObjectPtr si)
|
||||||
{
|
{
|
||||||
|
if (si == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (objectptr_indices[si] > 0)
|
if (objectptr_indices[si] > 0)
|
||||||
return &objectcontent_static_buf[objectptr_indices[si]];
|
return &objectcontent_static_buf[objectptr_indices[si]];
|
||||||
else
|
else
|
||||||
|
@ -1750,7 +1850,7 @@ FcObjectRebuildStaticNameHashtable (void)
|
||||||
/* Hmm. This will have a terrible effect on the memory size,
|
/* Hmm. This will have a terrible effect on the memory size,
|
||||||
* because the mmapped strings now get reallocated on the heap.
|
* because the mmapped strings now get reallocated on the heap.
|
||||||
* Is it all worth it? (Of course, the Serialization codepath is
|
* Is it all worth it? (Of course, the Serialization codepath is
|
||||||
* not problematic.) */
|
* not problematic, because the program quits just afterwards.) */
|
||||||
static FcBool
|
static FcBool
|
||||||
FcObjectPtrConvertToStatic(FcBool renumber)
|
FcObjectPtrConvertToStatic(FcBool renumber)
|
||||||
{
|
{
|
||||||
|
@ -1784,6 +1884,8 @@ FcObjectPtrConvertToStatic(FcBool renumber)
|
||||||
new_indices = malloc (active_count * sizeof(int));
|
new_indices = malloc (active_count * sizeof(int));
|
||||||
if (!new_indices)
|
if (!new_indices)
|
||||||
goto bail2;
|
goto bail2;
|
||||||
|
new_indices[0] = 0;
|
||||||
|
new_static_buf[0] = 0;
|
||||||
|
|
||||||
FcMemAlloc (FC_MEM_STATICSTR, new_static_bytes);
|
FcMemAlloc (FC_MEM_STATICSTR, new_static_bytes);
|
||||||
FcMemFree (FC_MEM_STATICSTR, objectptr_count * sizeof (int));
|
FcMemFree (FC_MEM_STATICSTR, objectptr_count * sizeof (int));
|
||||||
|
@ -1817,8 +1919,8 @@ FcObjectPtrConvertToStatic(FcBool renumber)
|
||||||
int n = FcObjectStaticName(fixed_length_buf+i*(longest_string+1));
|
int n = FcObjectStaticName(fixed_length_buf+i*(longest_string+1));
|
||||||
if (renumber)
|
if (renumber)
|
||||||
{
|
{
|
||||||
object_old_id_to_new[n] = i;
|
object_old_id_to_new[n] = i+1;
|
||||||
new_indices[i] = p-new_static_buf;
|
new_indices[i+1] = p-new_static_buf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
new_indices[n] = p-new_static_buf;
|
new_indices[n] = p-new_static_buf;
|
||||||
|
@ -1907,21 +2009,11 @@ FcObjectClearStatic(void)
|
||||||
object_old_id_to_new = 0;
|
object_old_id_to_new = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcObjectPtr
|
|
||||||
FcObjectSerialize (FcObjectPtr si)
|
|
||||||
{
|
|
||||||
if (objectptr_first_serialization)
|
|
||||||
if (!FcObjectPtrConvertToStatic(FcTrue))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return object_old_id_to_new[si];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In the pre-serialization phase, mark the used strings with
|
/* In the pre-serialization phase, mark the used strings with
|
||||||
* -1 in the mapping array. */
|
* -1 in the mapping array. */
|
||||||
/* The first call to the serialization phase assigns actual
|
/* The first call to the serialization phase assigns actual
|
||||||
* static indices to the strings (sweep). */
|
* static indices to the strings (sweep). */
|
||||||
FcBool
|
static FcBool
|
||||||
FcObjectPrepareSerialize (FcObjectPtr si)
|
FcObjectPrepareSerialize (FcObjectPtr si)
|
||||||
{
|
{
|
||||||
if (object_old_id_to_new == 0)
|
if (object_old_id_to_new == 0)
|
||||||
|
@ -1942,6 +2034,93 @@ FcObjectPrepareSerialize (FcObjectPtr si)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FcObjectPtr
|
||||||
|
FcObjectSerialize (FcObjectPtr si)
|
||||||
|
{
|
||||||
|
if (objectptr_first_serialization)
|
||||||
|
if (!FcObjectPtrConvertToStatic(FcTrue))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return object_old_id_to_new[si];
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcObjectRead (int fd, FcCache metadata)
|
||||||
|
{
|
||||||
|
/* do we have to merge strings?
|
||||||
|
* it's possible to merge dynamic strings, as long as we only store
|
||||||
|
* static strings to disk and as long as all static strings have lower
|
||||||
|
* ids than any dynamic strings. */
|
||||||
|
|
||||||
|
objectcontent_dynamic_count = 1;
|
||||||
|
objectcontent_dynamic_alloc = 0;
|
||||||
|
objectcontent_dynamic = 0;
|
||||||
|
objectcontent_dynamic_refcount = 0;
|
||||||
|
|
||||||
|
/* well, we do need to allocate dynamic strings all the time,
|
||||||
|
* so this would just have to be converted. It takes 1.4k on
|
||||||
|
* my system. - PL */
|
||||||
|
/* objectptr_indices = mmap(NULL, */
|
||||||
|
/* metadata.object_length * sizeof (int), */
|
||||||
|
/* PROT_READ, */
|
||||||
|
/* MAP_SHARED, fd, metadata.object_offset); */
|
||||||
|
/* if (objectptr_indices == MAP_FAILED) */
|
||||||
|
/* goto bail; */
|
||||||
|
|
||||||
|
objectptr_count = metadata.object_length;
|
||||||
|
objectptr_alloc = metadata.object_length;
|
||||||
|
objectptr_indices = malloc (metadata.object_length * sizeof (int));
|
||||||
|
if (!objectptr_indices)
|
||||||
|
goto bail;
|
||||||
|
FcMemAlloc (FC_MEM_STATICSTR, metadata.object_length * sizeof (int));
|
||||||
|
lseek (fd, metadata.object_offset, SEEK_SET);
|
||||||
|
read (fd, objectptr_indices, metadata.object_length * sizeof (int));
|
||||||
|
|
||||||
|
objectcontent_static_buf =
|
||||||
|
mmap(NULL,
|
||||||
|
metadata.objectcontent_length * sizeof (char),
|
||||||
|
PROT_READ,
|
||||||
|
MAP_SHARED, fd, metadata.objectcontent_offset);
|
||||||
|
if (objectptr_indices == MAP_FAILED)
|
||||||
|
goto bail1;
|
||||||
|
objectcontent_static_bytes = metadata.objectcontent_length;
|
||||||
|
|
||||||
|
FcObjectRebuildStaticNameHashtable ();
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
|
||||||
|
bail1:
|
||||||
|
/*munmap(objectptr_indices, metadata.object_length * sizeof(int));*/
|
||||||
|
free (objectptr_indices);
|
||||||
|
bail:
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcObjectWrite (int fd, FcCache * metadata)
|
||||||
|
{
|
||||||
|
/* there should be no dynamic strings:
|
||||||
|
* serialize ought to have zapped 'em. */
|
||||||
|
if (objectcontent_dynamic_alloc)
|
||||||
|
return FcFalse;
|
||||||
|
|
||||||
|
metadata->object_length = objectptr_count;
|
||||||
|
metadata->object_offset = FcCacheNextOffset(fd);
|
||||||
|
lseek(fd, metadata->object_offset, SEEK_SET);
|
||||||
|
if (write (fd, objectptr_indices,
|
||||||
|
metadata->object_length * sizeof (int)) == -1)
|
||||||
|
return FcFalse;
|
||||||
|
|
||||||
|
metadata->objectcontent_length = objectcontent_static_bytes;
|
||||||
|
metadata->objectcontent_offset = FcCacheNextOffset(fd);
|
||||||
|
lseek(fd, metadata->objectcontent_offset, SEEK_SET);
|
||||||
|
if (write (fd, objectcontent_static_buf,
|
||||||
|
metadata->objectcontent_length * sizeof (char)) == -1)
|
||||||
|
return FcFalse;
|
||||||
|
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FcObjectStaticNameFini (void)
|
FcObjectStaticNameFini (void)
|
||||||
{
|
{
|
||||||
|
|
76
src/fcstr.c
76
src/fcstr.c
|
@ -25,6 +25,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
|
|
||||||
FcChar8 *
|
FcChar8 *
|
||||||
|
@ -1129,8 +1130,8 @@ FcStrSetSerialize (FcStrSet *set)
|
||||||
if (strset_ptr > strset_count || strset_idx_ptr > strset_idx_count)
|
if (strset_ptr > strset_count || strset_idx_ptr > strset_idx_count)
|
||||||
return FcStrSetPtrCreateDynamic(0);
|
return FcStrSetPtrCreateDynamic(0);
|
||||||
|
|
||||||
// problem with multiple ptrs to the same LangSet.
|
// problem with multiple ptrs to the same StrSet.
|
||||||
// should hash LangSets or something.
|
// should hash StrSets or something.
|
||||||
// FcStrSetDestroy (set);
|
// FcStrSetDestroy (set);
|
||||||
|
|
||||||
return newp;
|
return newp;
|
||||||
|
@ -1143,6 +1144,77 @@ FcStrSetSerialize (FcStrSet *set)
|
||||||
return FcStrSetPtrCreateDynamic(0);
|
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 *
|
FcStrList *
|
||||||
FcStrListCreate (FcStrSet *set)
|
FcStrListCreate (FcStrSet *set)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue