Rewrite global cache handling code in fontconfig to eliminate per-file
syscalls
This commit is contained in:
parent
23cd70c4ef
commit
327a7fd491
|
@ -191,7 +191,7 @@ typedef enum { FcEndianBig, FcEndianLittle } FcEndian;
|
||||||
|
|
||||||
typedef struct _FcConfig FcConfig;
|
typedef struct _FcConfig FcConfig;
|
||||||
|
|
||||||
typedef struct _FcFileCache FcFileCache;
|
typedef struct _FcGlobalCache FcFileCache;
|
||||||
|
|
||||||
typedef struct _FcBlanks FcBlanks;
|
typedef struct _FcBlanks FcBlanks;
|
||||||
|
|
||||||
|
@ -365,9 +365,6 @@ FcDirScan (FcFontSet *set,
|
||||||
FcBool
|
FcBool
|
||||||
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
|
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcDirCacheValid (const FcChar8 *dir);
|
|
||||||
|
|
||||||
/* fcfreetype.c */
|
/* fcfreetype.c */
|
||||||
FcPattern *
|
FcPattern *
|
||||||
FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
|
FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
|
||||||
|
|
1014
src/fccache.c
1014
src/fccache.c
File diff suppressed because it is too large
Load Diff
23
src/fccfg.c
23
src/fccfg.c
|
@ -171,20 +171,20 @@ FcConfigDestroy (FcConfig *config)
|
||||||
FcBool
|
FcBool
|
||||||
FcConfigBuildFonts (FcConfig *config)
|
FcConfigBuildFonts (FcConfig *config)
|
||||||
{
|
{
|
||||||
FcFontSet *fonts;
|
FcFontSet *fonts;
|
||||||
FcFileCache *cache;
|
FcGlobalCache *cache;
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
FcChar8 *dir;
|
FcChar8 *dir;
|
||||||
|
|
||||||
fonts = FcFontSetCreate ();
|
fonts = FcFontSetCreate ();
|
||||||
if (!fonts)
|
if (!fonts)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
|
|
||||||
cache = FcFileCacheCreate ();
|
cache = FcGlobalCacheCreate ();
|
||||||
if (!cache)
|
if (!cache)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
FcFileCacheLoad (cache, config->cache);
|
FcGlobalCacheLoad (cache, config->cache);
|
||||||
|
|
||||||
list = FcConfigGetFontDirs (config);
|
list = FcConfigGetFontDirs (config);
|
||||||
if (!list)
|
if (!list)
|
||||||
|
@ -202,8 +202,8 @@ FcConfigBuildFonts (FcConfig *config)
|
||||||
if (FcDebug () & FC_DBG_FONTSET)
|
if (FcDebug () & FC_DBG_FONTSET)
|
||||||
FcFontSetPrint (fonts);
|
FcFontSetPrint (fonts);
|
||||||
|
|
||||||
FcFileCacheSave (cache, config->cache);
|
FcGlobalCacheSave (cache, config->cache);
|
||||||
FcFileCacheDestroy (cache);
|
FcGlobalCacheDestroy (cache);
|
||||||
|
|
||||||
FcConfigSetFonts (config, fonts, FcSetSystem);
|
FcConfigSetFonts (config, fonts, FcSetSystem);
|
||||||
|
|
||||||
|
@ -456,8 +456,6 @@ typedef struct _FcSubState {
|
||||||
FcValueList *value;
|
FcValueList *value;
|
||||||
} FcSubState;
|
} FcSubState;
|
||||||
|
|
||||||
static const FcMatrix FcIdentityMatrix = { 1, 0, 0, 1 };
|
|
||||||
|
|
||||||
static FcValue
|
static FcValue
|
||||||
FcConfigPromote (FcValue v, FcValue u)
|
FcConfigPromote (FcValue v, FcValue u)
|
||||||
{
|
{
|
||||||
|
@ -468,9 +466,8 @@ FcConfigPromote (FcValue v, FcValue u)
|
||||||
}
|
}
|
||||||
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
|
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
|
||||||
{
|
{
|
||||||
v.u.m = FcMatrixCopy (&FcIdentityMatrix);
|
v.u.m = &FcIdentityMatrix;
|
||||||
if (v.u.m)
|
v.type = FcTypeMatrix;
|
||||||
v.type = FcTypeMatrix;
|
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
183
src/fcdir.c
183
src/fcdir.c
|
@ -38,44 +38,71 @@ FcFileIsDir (const FcChar8 *file)
|
||||||
FcBool
|
FcBool
|
||||||
FcFileScan (FcFontSet *set,
|
FcFileScan (FcFontSet *set,
|
||||||
FcStrSet *dirs,
|
FcStrSet *dirs,
|
||||||
FcFileCache *cache,
|
FcGlobalCache *cache,
|
||||||
FcBlanks *blanks,
|
FcBlanks *blanks,
|
||||||
const FcChar8 *file,
|
const FcChar8 *file,
|
||||||
FcBool force)
|
FcBool force)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
FcChar8 *name;
|
FcChar8 *name;
|
||||||
FcPattern *font;
|
FcPattern *font;
|
||||||
FcBool ret = FcTrue;
|
FcBool ret = FcTrue;
|
||||||
FcBool isDir;
|
FcBool isDir;
|
||||||
int count;
|
int count = 0;
|
||||||
|
FcGlobalCacheFile *cache_file;
|
||||||
|
FcGlobalCacheDir *cache_dir;
|
||||||
|
FcBool need_scan;
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
cache = 0;
|
||||||
id = 0;
|
id = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!force && cache)
|
need_scan = FcTrue;
|
||||||
name = FcFileCacheFind (cache, file, id, &count);
|
font = 0;
|
||||||
else
|
/*
|
||||||
name = 0;
|
* Check the cache
|
||||||
if (name)
|
*/
|
||||||
|
if (cache)
|
||||||
{
|
{
|
||||||
/* "." means the file doesn't contain a font */
|
if ((cache_file = FcGlobalCacheFileGet (cache, file, id, &count)))
|
||||||
if (FcStrCmp (name, FC_FONT_FILE_INVALID) == 0)
|
|
||||||
font = 0;
|
|
||||||
else if (FcStrCmp (name, FC_FONT_FILE_DIR) == 0)
|
|
||||||
{
|
{
|
||||||
ret = FcStrSetAdd (dirs, file);
|
/*
|
||||||
font = 0;
|
* Found a cache entry for the file
|
||||||
|
*/
|
||||||
|
if (FcGlobalCacheCheckTime (&cache_file->info))
|
||||||
|
{
|
||||||
|
name = cache_file->name;
|
||||||
|
need_scan = FcFalse;
|
||||||
|
FcGlobalCacheReferenced (cache, &cache_file->info);
|
||||||
|
/* "." means the file doesn't contain a font */
|
||||||
|
if (FcStrCmp (name, FC_FONT_FILE_INVALID) != 0)
|
||||||
|
{
|
||||||
|
font = FcNameParse (name);
|
||||||
|
if (font)
|
||||||
|
if (!FcPatternAddString (font, FC_FILE, file))
|
||||||
|
ret = FcFalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if ((cache_dir = FcGlobalCacheDirGet (cache, file,
|
||||||
|
strlen ((const char *) file),
|
||||||
|
FcFalse)))
|
||||||
{
|
{
|
||||||
font = FcNameParse (name);
|
if (FcGlobalCacheCheckTime (&cache_dir->info))
|
||||||
if (font)
|
{
|
||||||
if (!FcPatternAddString (font, FC_FILE, file))
|
font = 0;
|
||||||
|
need_scan = FcFalse;
|
||||||
|
FcGlobalCacheReferenced (cache, &cache_dir->info);
|
||||||
|
if (!FcStrSetAdd (dirs, file))
|
||||||
ret = FcFalse;
|
ret = FcFalse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
/*
|
||||||
|
* Nothing in the cache, scan the file
|
||||||
|
*/
|
||||||
|
if (need_scan)
|
||||||
{
|
{
|
||||||
if (FcDebug () & FC_DBG_SCAN)
|
if (FcDebug () & FC_DBG_SCAN)
|
||||||
{
|
{
|
||||||
|
@ -91,35 +118,24 @@ FcFileScan (FcFontSet *set,
|
||||||
isDir = FcTrue;
|
isDir = FcTrue;
|
||||||
ret = FcStrSetAdd (dirs, file);
|
ret = FcStrSetAdd (dirs, file);
|
||||||
}
|
}
|
||||||
if (!force && cache)
|
/*
|
||||||
|
* Update the cache
|
||||||
|
*/
|
||||||
|
if (cache && font)
|
||||||
{
|
{
|
||||||
if (font)
|
FcChar8 *unparse;
|
||||||
{
|
|
||||||
FcChar8 *unparse;
|
|
||||||
|
|
||||||
unparse = FcNameUnparse (font);
|
unparse = FcNameUnparse (font);
|
||||||
if (unparse)
|
if (unparse)
|
||||||
{
|
|
||||||
(void) FcFileCacheUpdate (cache, file, id, unparse);
|
|
||||||
free (unparse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (isDir)
|
(void) FcGlobalCacheUpdate (cache, file, id, unparse);
|
||||||
{
|
free (unparse);
|
||||||
FcFileCacheUpdate (cache, file, id, (FcChar8 *)
|
|
||||||
FC_FONT_FILE_DIR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* negative cache files not containing fonts */
|
|
||||||
FcFileCacheUpdate (cache, file, id, (FcChar8 *)
|
|
||||||
FC_FONT_FILE_INVALID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Add the font
|
||||||
|
*/
|
||||||
if (font)
|
if (font)
|
||||||
{
|
{
|
||||||
if (!FcFontSetAdd (set, font))
|
if (!FcFontSetAdd (set, font))
|
||||||
|
@ -134,40 +150,37 @@ FcFileScan (FcFontSet *set,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
|
||||||
FcDirCacheValid (const FcChar8 *dir)
|
|
||||||
{
|
|
||||||
FcChar8 *path;
|
|
||||||
FcBool ret;
|
|
||||||
|
|
||||||
path = (FcChar8 *) malloc (strlen ((const char *) dir) + 1 +
|
|
||||||
strlen ((const char *) FC_DIR_CACHE_FILE) + 1);
|
|
||||||
if (!path)
|
|
||||||
return FcFalse;
|
|
||||||
strcpy ((char *) path, (const char *) dir);
|
|
||||||
strcat ((char *) path, (const char *) "/");
|
|
||||||
strcat ((char *) path, (const char *) FC_DIR_CACHE_FILE);
|
|
||||||
ret = FcFileCacheValid (path);
|
|
||||||
free (path);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FC_MAX_FILE_LEN 4096
|
#define FC_MAX_FILE_LEN 4096
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirScan (FcFontSet *set,
|
FcDirScan (FcFontSet *set,
|
||||||
FcStrSet *dirs,
|
FcStrSet *dirs,
|
||||||
FcFileCache *cache,
|
FcGlobalCache *cache,
|
||||||
FcBlanks *blanks,
|
FcBlanks *blanks,
|
||||||
const FcChar8 *dir,
|
const FcChar8 *dir,
|
||||||
FcBool force)
|
FcBool force)
|
||||||
{
|
{
|
||||||
DIR *d;
|
DIR *d;
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
FcChar8 *file;
|
FcChar8 *file;
|
||||||
FcChar8 *base;
|
FcChar8 *base;
|
||||||
FcBool ret = FcTrue;
|
FcBool ret = FcTrue;
|
||||||
|
|
||||||
|
if (!force)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Check fonts.cache file
|
||||||
|
*/
|
||||||
|
if (FcDirCacheReadDir (set, dirs, dir))
|
||||||
|
return FcTrue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check ~/.fonts.cache file
|
||||||
|
*/
|
||||||
|
if (cache && FcGlobalCacheScanDir (set, dirs, cache, dir))
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
|
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
|
||||||
if (!file)
|
if (!file)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
@ -175,18 +188,9 @@ FcDirScan (FcFontSet *set,
|
||||||
strcpy ((char *) file, (char *) dir);
|
strcpy ((char *) file, (char *) dir);
|
||||||
strcat ((char *) file, "/");
|
strcat ((char *) file, "/");
|
||||||
base = file + strlen ((char *) file);
|
base = file + strlen ((char *) file);
|
||||||
if (!force)
|
|
||||||
{
|
|
||||||
strcpy ((char *) base, FC_DIR_CACHE_FILE);
|
|
||||||
|
|
||||||
if (FcFileCacheReadDir (set, dirs, file))
|
|
||||||
{
|
|
||||||
free (file);
|
|
||||||
return FcTrue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d = opendir ((char *) dir);
|
d = opendir ((char *) dir);
|
||||||
|
|
||||||
if (!d)
|
if (!d)
|
||||||
{
|
{
|
||||||
free (file);
|
free (file);
|
||||||
|
@ -205,25 +209,14 @@ FcDirScan (FcFontSet *set,
|
||||||
}
|
}
|
||||||
free (file);
|
free (file);
|
||||||
closedir (d);
|
closedir (d);
|
||||||
|
if (ret && cache)
|
||||||
|
FcGlobalCacheUpdate (cache, dir, 0, 0);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
|
FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
|
||||||
{
|
{
|
||||||
FcChar8 *file;
|
return FcDirCacheWriteDir (set, dirs, dir);
|
||||||
FcChar8 *base;
|
|
||||||
FcBool ret;
|
|
||||||
|
|
||||||
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + 256 + 1);
|
|
||||||
if (!file)
|
|
||||||
return FcFalse;
|
|
||||||
|
|
||||||
strcpy ((char *) file, (char *) dir);
|
|
||||||
strcat ((char *) file, "/");
|
|
||||||
base = file + strlen ((char *) file);
|
|
||||||
strcpy ((char *) base, FC_DIR_CACHE_FILE);
|
|
||||||
ret = FcFileCacheWriteDir (set, dirs, file);
|
|
||||||
free (file);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
124
src/fcint.h
124
src/fcint.h
|
@ -195,24 +195,53 @@ typedef struct _FcStrBuf {
|
||||||
int size;
|
int size;
|
||||||
} FcStrBuf;
|
} FcStrBuf;
|
||||||
|
|
||||||
typedef struct _FcFileCacheEnt {
|
/*
|
||||||
struct _FcFileCacheEnt *next;
|
* The per-user ~/.fonts.cache file is loaded into
|
||||||
unsigned int hash;
|
* this data structure. Each directory gets a substructure
|
||||||
FcChar8 *file;
|
* which is validated by comparing the directory timestamp with
|
||||||
int id;
|
* that saved in the cache. When valid, the entire directory cache
|
||||||
time_t time;
|
* can be immediately loaded without reading the directory. Otherwise,
|
||||||
FcChar8 *name;
|
* the files are checked individually; updated files are loaded into the
|
||||||
FcBool referenced;
|
* cache which is then rewritten to the users home directory
|
||||||
} FcFileCacheEnt;
|
*/
|
||||||
|
|
||||||
#define FC_FILE_CACHE_HASH_SIZE 509
|
#define FC_GLOBAL_CACHE_DIR_HASH_SIZE 37
|
||||||
|
#define FC_GLOBAL_CACHE_FILE_HASH_SIZE 67
|
||||||
|
|
||||||
struct _FcFileCache {
|
typedef struct _FcGlobalCacheInfo {
|
||||||
FcFileCacheEnt *ents[FC_FILE_CACHE_HASH_SIZE];
|
unsigned int hash;
|
||||||
FcBool updated;
|
FcChar8 *file;
|
||||||
int entries;
|
time_t time;
|
||||||
int referenced;
|
FcBool referenced;
|
||||||
};
|
} FcGlobalCacheInfo;
|
||||||
|
|
||||||
|
typedef struct _FcGlobalCacheFile {
|
||||||
|
struct _FcGlobalCacheFile *next;
|
||||||
|
FcGlobalCacheInfo info;
|
||||||
|
int id;
|
||||||
|
FcChar8 *name;
|
||||||
|
} FcGlobalCacheFile;
|
||||||
|
|
||||||
|
typedef struct _FcGlobalCacheSubdir {
|
||||||
|
struct _FcGlobalCacheSubdir *next;
|
||||||
|
FcChar8 *file;
|
||||||
|
} FcGlobalCacheSubdir;
|
||||||
|
|
||||||
|
typedef struct _FcGlobalCacheDir {
|
||||||
|
struct _FcGlobalCacheDir *next;
|
||||||
|
FcGlobalCacheInfo info;
|
||||||
|
int len;
|
||||||
|
FcGlobalCacheFile *ents[FC_GLOBAL_CACHE_FILE_HASH_SIZE];
|
||||||
|
FcGlobalCacheSubdir *subdirs;
|
||||||
|
} FcGlobalCacheDir;
|
||||||
|
|
||||||
|
typedef struct _FcGlobalCache {
|
||||||
|
FcGlobalCacheDir *ents[FC_GLOBAL_CACHE_DIR_HASH_SIZE];
|
||||||
|
FcBool updated;
|
||||||
|
FcBool broken;
|
||||||
|
int entries;
|
||||||
|
int referenced;
|
||||||
|
} FcGlobalCache;
|
||||||
|
|
||||||
struct _FcAtomic {
|
struct _FcAtomic {
|
||||||
FcChar8 *file; /* original file name */
|
FcChar8 *file; /* original file name */
|
||||||
|
@ -284,40 +313,60 @@ typedef struct _FcCharMap FcCharMap;
|
||||||
|
|
||||||
/* fccache.c */
|
/* fccache.c */
|
||||||
|
|
||||||
FcFileCache *
|
FcGlobalCache *
|
||||||
FcFileCacheCreate (void);
|
FcGlobalCacheCreate (void);
|
||||||
|
|
||||||
FcChar8 *
|
|
||||||
FcFileCacheFind (FcFileCache *cache,
|
|
||||||
const FcChar8 *file,
|
|
||||||
int id,
|
|
||||||
int *count);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FcFileCacheDestroy (FcFileCache *cache);
|
FcGlobalCacheDestroy (FcGlobalCache *cache);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcFileCacheValid (const FcChar8 *cache_file);
|
FcGlobalCacheCheckTime (FcGlobalCacheInfo *info);
|
||||||
|
|
||||||
void
|
void
|
||||||
FcFileCacheLoad (FcFileCache *cache,
|
FcGlobalCacheReferenced (FcGlobalCache *cache,
|
||||||
const FcChar8 *cache_file);
|
FcGlobalCacheInfo *info);
|
||||||
|
|
||||||
|
FcGlobalCacheDir *
|
||||||
|
FcGlobalCacheDirGet (FcGlobalCache *cache,
|
||||||
|
const FcChar8 *dir,
|
||||||
|
int len,
|
||||||
|
FcBool create_missing);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcFileCacheUpdate (FcFileCache *cache,
|
FcGlobalCacheScanDir (FcFontSet *set,
|
||||||
const FcChar8 *file,
|
FcStrSet *dirs,
|
||||||
int id,
|
FcGlobalCache *cache,
|
||||||
const FcChar8 *name);
|
const FcChar8 *dir);
|
||||||
|
|
||||||
|
FcGlobalCacheFile *
|
||||||
|
FcGlobalCacheFileGet (FcGlobalCache *cache,
|
||||||
|
const FcChar8 *file,
|
||||||
|
int id,
|
||||||
|
int *count);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FcGlobalCacheLoad (FcGlobalCache *cache,
|
||||||
|
const FcChar8 *cache_file);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcFileCacheSave (FcFileCache *cache,
|
FcGlobalCacheUpdate (FcGlobalCache *cache,
|
||||||
const FcChar8 *cache_file);
|
const FcChar8 *file,
|
||||||
|
int id,
|
||||||
|
const FcChar8 *name);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcFileCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *cache_file);
|
FcGlobalCacheSave (FcGlobalCache *cache,
|
||||||
|
const FcChar8 *cache_file);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcFileCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *cache_file);
|
FcDirCacheValid (const FcChar8 *cache_file);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcDirCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcDirCacheWriteDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
|
||||||
|
|
||||||
/* fccfg.c */
|
/* fccfg.c */
|
||||||
|
|
||||||
|
@ -523,6 +572,9 @@ FcPatternAddWithBinding (FcPattern *p,
|
||||||
/* fcrender.c */
|
/* fcrender.c */
|
||||||
|
|
||||||
/* fcmatrix.c */
|
/* fcmatrix.c */
|
||||||
|
|
||||||
|
extern const FcMatrix FcIdentityMatrix;
|
||||||
|
|
||||||
void
|
void
|
||||||
FcMatrixFree (FcMatrix *mat);
|
FcMatrixFree (FcMatrix *mat);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
|
|
||||||
|
const FcMatrix FcIdentityMatrix = { 1, 0, 0, 1 };
|
||||||
|
|
||||||
FcMatrix *
|
FcMatrix *
|
||||||
FcMatrixCopy (const FcMatrix *mat)
|
FcMatrixCopy (const FcMatrix *mat)
|
||||||
{
|
{
|
||||||
|
@ -44,8 +46,11 @@ FcMatrixCopy (const FcMatrix *mat)
|
||||||
void
|
void
|
||||||
FcMatrixFree (FcMatrix *mat)
|
FcMatrixFree (FcMatrix *mat)
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix));
|
if (mat != &FcIdentityMatrix)
|
||||||
free (mat);
|
{
|
||||||
|
FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix));
|
||||||
|
free (mat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
|
Loading…
Reference in New Issue