Rework cache files to use offsets for all data structures.
Replace all of the bank/id pairs with simple offsets, recode several data structures to always use offsets inside the library to avoid conditional paths. Exposed data structures use pointers to hold offsets, setting the low bit to distinguish between offset and pointer. Use offset-based data structures for lang charset encodings; eliminates separate data structure format for that file. Much testing will be needed; offsets are likely not detected everywhere in the library yet.
This commit is contained in:
parent
2a9179d889
commit
7ce1967331
|
@ -31,4 +31,5 @@
|
||||||
@@@ name endian char char* int Pattern EltPtr Elt * Elt ObjPtr VLPtr Value Binding VL * CharSet Leaf** Char16 * Char16 Leaf Char32 Cache PageSize
|
@@@ name endian char char* int Pattern EltPtr Elt * Elt ObjPtr VLPtr Value Binding VL * CharSet Leaf** Char16 * Char16 Leaf Char32 Cache PageSize
|
||||||
x86 78563412_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_0000000c_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
|
x86 78563412_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_0000000c_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
|
||||||
x86-64 78563412_00000001_00000008_00000004_00000020_00000010_00000008_00000018_00000004_00000010_00000010_00000004_00000008_00000020_00000008_00000008_00000002_00000020_00000004_00000040_00001000
|
x86-64 78563412_00000001_00000008_00000004_00000020_00000010_00000008_00000018_00000004_00000010_00000010_00000004_00000008_00000020_00000008_00000008_00000002_00000020_00000004_00000040_00001000
|
||||||
ppc 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
|
ppc-4k 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00001000
|
||||||
|
ppc-64k 12345678_00000001_00000004_00000004_00000018_00000008_00000004_0000000c_00000004_00000008_00000010_00000004_00000004_00000014_00000004_00000004_00000002_00000020_00000004_00000038_00010000
|
||||||
|
|
|
@ -37,10 +37,6 @@
|
||||||
* functions are also needed in slightly modified form
|
* functions are also needed in slightly modified form
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const FcChar16 langBankNumbers[1]; /* place holders so that externs resolve */
|
|
||||||
const FcCharLeaf langBankLeaves[1];
|
|
||||||
const int langBankLeafIdx[1];
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FcMemAlloc (int kind, int size)
|
FcMemAlloc (int kind, int size)
|
||||||
{
|
{
|
||||||
|
@ -51,18 +47,6 @@ FcMemFree (int kind, int size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int* _fcBankId = 0;
|
|
||||||
int* _fcBankIdx = 0;
|
|
||||||
FcValueList ** _fcValueLists = 0;
|
|
||||||
FcPatternElt ** _fcPatternElts = 0;
|
|
||||||
int FcDebugVal = 0;
|
|
||||||
|
|
||||||
int
|
|
||||||
FcCacheBankToIndexMTF (int bank)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcChar8 *
|
FcChar8 *
|
||||||
FcConfigHome (void)
|
FcConfigHome (void)
|
||||||
{
|
{
|
||||||
|
@ -239,19 +223,18 @@ main (int argc, char **argv)
|
||||||
static char *files[MAX_LANG];
|
static char *files[MAX_LANG];
|
||||||
static FcCharSet *sets[MAX_LANG];
|
static FcCharSet *sets[MAX_LANG];
|
||||||
static int duplicate[MAX_LANG];
|
static int duplicate[MAX_LANG];
|
||||||
static int offsets[MAX_LANG];
|
|
||||||
static int country[MAX_LANG];
|
static int country[MAX_LANG];
|
||||||
static char *names[MAX_LANG];
|
static char *names[MAX_LANG];
|
||||||
static char *langs[MAX_LANG];
|
static char *langs[MAX_LANG];
|
||||||
|
static int off[MAX_LANG];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int offset = 0;
|
|
||||||
int ncountry = 0;
|
int ncountry = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
int nsets = 0;
|
||||||
int argi;
|
int argi;
|
||||||
FcCharLeaf **leaves;
|
FcCharLeaf **leaves;
|
||||||
int total_leaves = 0;
|
int total_leaves = 0;
|
||||||
int offset_count = 0;
|
int l, sl, tl, tn;
|
||||||
int l, sl, tl;
|
|
||||||
static char line[1024];
|
static char line[1024];
|
||||||
static FcChar32 map[MAX_LANG_SET_MAP];
|
static FcChar32 map[MAX_LANG_SET_MAP];
|
||||||
int num_lang_set_map;
|
int num_lang_set_map;
|
||||||
|
@ -290,6 +273,7 @@ main (int argc, char **argv)
|
||||||
i++;
|
i++;
|
||||||
fclose (f);
|
fclose (f);
|
||||||
}
|
}
|
||||||
|
nsets = i;
|
||||||
sets[i] = 0;
|
sets[i] = 0;
|
||||||
leaves = malloc (total_leaves * sizeof (FcCharLeaf *));
|
leaves = malloc (total_leaves * sizeof (FcCharLeaf *));
|
||||||
tl = 0;
|
tl = 0;
|
||||||
|
@ -301,10 +285,10 @@ main (int argc, char **argv)
|
||||||
for (sl = 0; sl < sets[i]->num; sl++)
|
for (sl = 0; sl < sets[i]->num; sl++)
|
||||||
{
|
{
|
||||||
for (l = 0; l < tl; l++)
|
for (l = 0; l < tl; l++)
|
||||||
if (leaves[l] == FcCharSetGetLeaf(sets[i], sl))
|
if (leaves[l] == FcCharSetLeaf(sets[i], sl))
|
||||||
break;
|
break;
|
||||||
if (l == tl)
|
if (l == tl)
|
||||||
leaves[tl++] = FcCharSetGetLeaf(sets[i], sl);
|
leaves[tl++] = FcCharSetLeaf(sets[i], sl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,22 +305,6 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
printf ("/* total size: %d unique leaves: %d */\n\n",
|
printf ("/* total size: %d unique leaves: %d */\n\n",
|
||||||
total_leaves, tl);
|
total_leaves, tl);
|
||||||
/*
|
|
||||||
* Dump leaves
|
|
||||||
*/
|
|
||||||
printf ("const FcCharLeaf langBankLeaves[%d] = {\n", tl);
|
|
||||||
for (l = 0; l < tl; l++)
|
|
||||||
{
|
|
||||||
printf (" { { /* %d */", l);
|
|
||||||
for (i = 0; i < 256/32; i++)
|
|
||||||
{
|
|
||||||
if (i % 4 == 0)
|
|
||||||
printf ("\n ");
|
|
||||||
printf (" 0x%08x,", leaves[l]->map[i]);
|
|
||||||
}
|
|
||||||
printf ("\n } },\n");
|
|
||||||
}
|
|
||||||
printf ("};\n\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find duplicate charsets
|
* Find duplicate charsets
|
||||||
|
@ -355,97 +323,37 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
tn = 0;
|
||||||
* Find ranges for each letter for faster searching
|
for (i = 0; sets[i]; i++) {
|
||||||
*/
|
|
||||||
setRangeChar = 'a';
|
|
||||||
for (i = 0; sets[i]; i++)
|
|
||||||
{
|
|
||||||
char c = names[i][0];
|
|
||||||
|
|
||||||
while (setRangeChar <= c && c <= 'z')
|
|
||||||
setRangeStart[setRangeChar++ - 'a'] = i;
|
|
||||||
}
|
|
||||||
for (setRangeChar = 'a'; setRangeChar < 'z'; setRangeChar++)
|
|
||||||
setRangeEnd[setRangeChar - 'a'] = setRangeStart[setRangeChar+1-'a'] - 1;
|
|
||||||
setRangeEnd[setRangeChar - 'a'] = i - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dump arrays
|
|
||||||
*/
|
|
||||||
for (i = 0; sets[i]; i++)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (duplicate[i] >= 0)
|
if (duplicate[i] >= 0)
|
||||||
continue;
|
continue;
|
||||||
|
off[i] = tn;
|
||||||
for (n = 0; n < sets[i]->num; n++)
|
tn += sets[i]->num;
|
||||||
{
|
|
||||||
for (l = 0; l < tl; l++)
|
|
||||||
if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
|
|
||||||
break;
|
|
||||||
if (l == tl)
|
|
||||||
fatal (names[i], 0, "can't find leaf");
|
|
||||||
offset_count++;
|
|
||||||
}
|
|
||||||
offsets[i] = offset;
|
|
||||||
offset += sets[i]->num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("const int langBankLeafIdx[%d] = {\n",
|
printf ("#define LEAF0 (%d * sizeof (FcLangCharSet))\n", nsets);
|
||||||
offset_count);
|
printf ("#define OFF0 (LEAF0 + %d * sizeof (FcCharLeaf))\n", tl);
|
||||||
for (i = 0; sets[i]; i++)
|
printf ("#define NUM0 (OFF0 + %d * sizeof (intptr_t))\n", tn);
|
||||||
{
|
printf ("#define SET(n) (n * sizeof (FcLangCharSet) + offsetof (FcLangCharSet, charset))\n");
|
||||||
int n;
|
printf ("#define OFF(s,o) (OFF0 + o * sizeof (intptr_t) - SET(s))\n");
|
||||||
|
printf ("#define NUM(s,n) (NUM0 + n * sizeof (FcChar16) - SET(s))\n");
|
||||||
if (duplicate[i] >= 0)
|
printf ("#define LEAF(o,l) (LEAF0 + l * sizeof (FcCharLeaf) - (OFF0 + o * sizeof (intptr_t)))\n");
|
||||||
continue;
|
printf ("#define fcLangCharSets (fcLangData.langCharSets)\n");
|
||||||
for (n = 0; n < sets[i]->num; n++)
|
|
||||||
{
|
|
||||||
if (n % 8 == 0)
|
|
||||||
printf (" ");
|
|
||||||
for (l = 0; l < tl; l++)
|
|
||||||
if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
|
|
||||||
break;
|
|
||||||
if (l == tl)
|
|
||||||
fatal (names[i], 0, "can't find leaf");
|
|
||||||
printf (" %3d,", l);
|
|
||||||
if (n % 8 == 7)
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
|
||||||
if (n % 8 != 0)
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
printf ("};\n\n");
|
|
||||||
|
|
||||||
printf ("const FcChar16 langBankNumbers[%d] = {\n",
|
printf ("static const struct {\n"
|
||||||
offset_count);
|
" FcLangCharSet langCharSets[%d];\n"
|
||||||
|
" FcCharLeaf leaves[%d];\n"
|
||||||
for (i = 0; sets[i]; i++)
|
" intptr_t leaf_offsets[%d];\n"
|
||||||
{
|
" FcChar16 numbers[%d];\n"
|
||||||
int n;
|
"} fcLangData = {\n",
|
||||||
|
nsets, tl, tn, tn);
|
||||||
if (duplicate[i] >= 0)
|
|
||||||
continue;
|
|
||||||
for (n = 0; n < sets[i]->num; n++)
|
|
||||||
{
|
|
||||||
if (n % 8 == 0)
|
|
||||||
printf (" ");
|
|
||||||
printf (" 0x%04x,", FcCharSetGetNumbers(sets[i])[n]);
|
|
||||||
if (n % 8 == 7)
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
if (n % 8 != 0)
|
|
||||||
printf ("\n");
|
|
||||||
}
|
|
||||||
printf ("};\n\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump sets
|
* Dump sets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf ("const FcLangCharSet fcLangCharSets[] = {\n");
|
printf ("{\n");
|
||||||
for (i = 0; sets[i]; i++)
|
for (i = 0; sets[i]; i++)
|
||||||
{
|
{
|
||||||
int j = duplicate[i];
|
int j = duplicate[i];
|
||||||
|
@ -453,13 +361,83 @@ main (int argc, char **argv)
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
j = i;
|
j = i;
|
||||||
|
|
||||||
printf (" { (FcChar8 *) \"%s\",\n"
|
printf (" { (FcChar8 *) \"%s\", "
|
||||||
" { FC_REF_CONSTANT, %d, FC_BANK_LANGS, "
|
" { FC_REF_CONSTANT, %d, OFF(%d,%d), NUM(%d,%d) } }, /* %d */\n",
|
||||||
"{ { %d, %d } } } }, /* %d */\n",
|
|
||||||
langs[i],
|
langs[i],
|
||||||
sets[j]->num, offsets[j], offsets[j], j);
|
sets[j]->num, i, off[j], i, off[j], i);
|
||||||
}
|
}
|
||||||
|
printf ("},\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump leaves
|
||||||
|
*/
|
||||||
|
printf ("{\n");
|
||||||
|
for (l = 0; l < tl; l++)
|
||||||
|
{
|
||||||
|
printf (" { { /* %d */", l);
|
||||||
|
for (i = 0; i < 256/32; i++)
|
||||||
|
{
|
||||||
|
if (i % 4 == 0)
|
||||||
|
printf ("\n ");
|
||||||
|
printf (" 0x%08x,", leaves[l]->map[i]);
|
||||||
|
}
|
||||||
|
printf ("\n } },\n");
|
||||||
|
}
|
||||||
|
printf ("},\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dump leaves
|
||||||
|
*/
|
||||||
|
printf ("{\n");
|
||||||
|
for (i = 0; sets[i]; i++)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (duplicate[i] >= 0)
|
||||||
|
continue;
|
||||||
|
printf (" /* %s */\n", names[i]);
|
||||||
|
for (n = 0; n < sets[i]->num; n++)
|
||||||
|
{
|
||||||
|
if (n % 4 == 0)
|
||||||
|
printf (" ");
|
||||||
|
for (l = 0; l < tl; l++)
|
||||||
|
if (leaves[l] == FcCharSetLeaf(sets[i], n))
|
||||||
|
break;
|
||||||
|
if (l == tl)
|
||||||
|
fatal (names[i], 0, "can't find leaf");
|
||||||
|
printf (" LEAF(%3d,%3d),", off[i], l);
|
||||||
|
if (n % 4 == 3)
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
if (n % 4 != 0)
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
printf ("},\n");
|
||||||
|
|
||||||
|
|
||||||
|
printf ("{\n");
|
||||||
|
for (i = 0; sets[i]; i++)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (duplicate[i] >= 0)
|
||||||
|
continue;
|
||||||
|
printf (" /* %s */\n", names[i]);
|
||||||
|
for (n = 0; n < sets[i]->num; n++)
|
||||||
|
{
|
||||||
|
if (n % 8 == 0)
|
||||||
|
printf (" ");
|
||||||
|
printf (" 0x%04x,", FcCharSetNumbers (sets[i])[n]);
|
||||||
|
if (n % 8 == 7)
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
if (n % 8 != 0)
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
printf ("}\n");
|
||||||
|
|
||||||
printf ("};\n\n");
|
printf ("};\n\n");
|
||||||
|
|
||||||
printf ("#define NUM_LANG_CHAR_SET %d\n", i);
|
printf ("#define NUM_LANG_CHAR_SET %d\n", i);
|
||||||
num_lang_set_map = (i + 31) / 32;
|
num_lang_set_map = (i + 31) / 32;
|
||||||
printf ("#define NUM_LANG_SET_MAP %d\n", num_lang_set_map);
|
printf ("#define NUM_LANG_SET_MAP %d\n", num_lang_set_map);
|
||||||
|
@ -506,6 +484,23 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find ranges for each letter for faster searching
|
||||||
|
*/
|
||||||
|
setRangeChar = 'a';
|
||||||
|
memset(setRangeStart, '\0', sizeof (setRangeStart));
|
||||||
|
memset(setRangeEnd, '\0', sizeof (setRangeEnd));
|
||||||
|
for (i = 0; sets[i]; i++)
|
||||||
|
{
|
||||||
|
char c = names[i][0];
|
||||||
|
|
||||||
|
while (setRangeChar <= c && c <= 'z')
|
||||||
|
setRangeStart[setRangeChar++ - 'a'] = i;
|
||||||
|
}
|
||||||
|
for (setRangeChar = 'a'; setRangeChar < 'z'; setRangeChar++)
|
||||||
|
setRangeEnd[setRangeChar - 'a'] = setRangeStart[setRangeChar+1-'a'] - 1;
|
||||||
|
setRangeEnd[setRangeChar - 'a'] = i - 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump sets start/finish for the fastpath
|
* Dump sets start/finish for the fastpath
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -212,17 +212,14 @@ typedef struct _FcValue {
|
||||||
FcType type;
|
FcType type;
|
||||||
union {
|
union {
|
||||||
const FcChar8 *s;
|
const FcChar8 *s;
|
||||||
int s_off;
|
|
||||||
int i;
|
int i;
|
||||||
FcBool b;
|
FcBool b;
|
||||||
double d;
|
double d;
|
||||||
const FcMatrix *m;
|
const FcMatrix *m;
|
||||||
const FcCharSet *c;
|
const FcCharSet *c;
|
||||||
int c_off;
|
|
||||||
void *f;
|
void *f;
|
||||||
const FcPattern *p;
|
const FcPattern *p;
|
||||||
const FcLangSet *l;
|
const FcLangSet *l;
|
||||||
int l_off; /* this is a difference of char *s */
|
|
||||||
} u;
|
} u;
|
||||||
} FcValue;
|
} FcValue;
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ libfontconfig_la_SOURCES = \
|
||||||
fcmatrix.c \
|
fcmatrix.c \
|
||||||
fcname.c \
|
fcname.c \
|
||||||
fcpat.c \
|
fcpat.c \
|
||||||
|
fcserialize.c \
|
||||||
fcstr.c \
|
fcstr.c \
|
||||||
fcxml.c \
|
fcxml.c \
|
||||||
ftglue.h \
|
ftglue.h \
|
||||||
|
|
575
src/fccache.c
575
src/fccache.c
|
@ -1,6 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* $RCSId: xc/lib/fontconfig/src/fccache.c,v 1.12 2002/08/22 07:36:44 keithp Exp $
|
|
||||||
*
|
|
||||||
* Copyright © 2000 Keith Packard
|
* Copyright © 2000 Keith Packard
|
||||||
* Copyright © 2005 Patrick Lam
|
* Copyright © 2005 Patrick Lam
|
||||||
*
|
*
|
||||||
|
@ -37,29 +35,12 @@
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ENDIAN_TEST 0x12345678
|
|
||||||
#define MACHINE_SIGNATURE_SIZE (9 + 5*20 + 1)
|
|
||||||
/* for when we don't have sysconf: */
|
|
||||||
#define FC_HARDCODED_PAGESIZE 8192
|
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static FILE *
|
static int
|
||||||
FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path);
|
FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size);
|
||||||
|
|
||||||
static void *
|
|
||||||
FcDirCacheProduce (FcFontSet *set, FcCache * metadata);
|
|
||||||
|
|
||||||
static off_t
|
|
||||||
FcCacheNextOffset(off_t w);
|
|
||||||
|
|
||||||
static FcBool
|
|
||||||
FcCacheHaveBank (int bank);
|
|
||||||
|
|
||||||
static void
|
|
||||||
FcCacheAddBankDir (int bank, const char * dir);
|
|
||||||
|
|
||||||
struct MD5Context {
|
struct MD5Context {
|
||||||
FcChar32 buf[4];
|
FcChar32 buf[4];
|
||||||
|
@ -74,67 +55,17 @@ static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
|
||||||
|
|
||||||
#define FC_DBG_CACHE_REF 1024
|
#define FC_DBG_CACHE_REF 1024
|
||||||
|
|
||||||
static char *
|
|
||||||
FcCacheReadString (FILE *file, char *dest, int len)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
char *d = dest;
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while ((c = getc (file)) != EOF && len > 0) {
|
|
||||||
*d++ = c;
|
|
||||||
if (c == '\0')
|
|
||||||
return dest;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FcBool
|
|
||||||
FcCacheWriteString (int fd, const char *chars)
|
|
||||||
{
|
|
||||||
if (write (fd, chars, strlen(chars)+1) != strlen(chars)+1)
|
|
||||||
return FcFalse;
|
|
||||||
return FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the next presumably-mmapable offset after the supplied file
|
|
||||||
* position.
|
|
||||||
*/
|
|
||||||
static off_t
|
|
||||||
FcCacheNextOffset(off_t w)
|
|
||||||
{
|
|
||||||
static long pagesize = -1;
|
|
||||||
|
|
||||||
if (w == -1)
|
|
||||||
return w;
|
|
||||||
|
|
||||||
if (pagesize == -1)
|
|
||||||
#if defined (HAVE_SYSCONF)
|
|
||||||
pagesize = sysconf(_SC_PAGESIZE);
|
|
||||||
#else
|
|
||||||
pagesize = FC_HARDCODED_PAGESIZE;
|
|
||||||
#endif
|
|
||||||
if (w % pagesize == 0)
|
|
||||||
return w;
|
|
||||||
else
|
|
||||||
return ((w / pagesize)+1)*pagesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Does not check that the cache has the appropriate arch section. */
|
/* Does not check that the cache has the appropriate arch section. */
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
|
FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
|
||||||
{
|
{
|
||||||
FILE *file;
|
int fd;
|
||||||
|
|
||||||
file = FcDirCacheOpen (config, dir, NULL);
|
fd = FcDirCacheOpen (config, dir, NULL);
|
||||||
|
|
||||||
if (file == NULL)
|
if (fd < 0)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
fclose (file);
|
close (fd);
|
||||||
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
@ -282,218 +213,281 @@ FcCacheRead (FcConfig *config)
|
||||||
* This searches the list of cache dirs for the relevant cache file,
|
* This searches the list of cache dirs for the relevant cache file,
|
||||||
* returning the first one found.
|
* returning the first one found.
|
||||||
*/
|
*/
|
||||||
static FILE *
|
static int
|
||||||
FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path)
|
FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size)
|
||||||
{
|
{
|
||||||
FILE *file = NULL;
|
int fd = -1;
|
||||||
FcChar8 *cache_hashed = NULL;
|
|
||||||
FcChar8 cache_base[CACHEBASE_LEN];
|
FcChar8 cache_base[CACHEBASE_LEN];
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
FcChar8 *cache_dir;
|
FcChar8 *cache_dir;
|
||||||
struct stat file_stat, dir_stat;
|
struct stat file_stat, dir_stat;
|
||||||
|
|
||||||
if (stat ((char *) dir, &dir_stat) < 0)
|
if (stat ((char *) dir, &dir_stat) < 0)
|
||||||
return NULL;
|
return -1;
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
FcDirCacheBasename (dir, cache_base);
|
||||||
|
|
||||||
list = FcStrListCreate (config->cacheDirs);
|
list = FcStrListCreate (config->cacheDirs);
|
||||||
if (!list)
|
if (!list)
|
||||||
return NULL;
|
return -1;
|
||||||
|
|
||||||
while ((cache_dir = FcStrListNext (list)))
|
while ((cache_dir = FcStrListNext (list)))
|
||||||
{
|
{
|
||||||
cache_hashed = FcStrPlus (cache_dir, cache_base);
|
FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base);
|
||||||
if (!cache_hashed)
|
if (!cache_hashed)
|
||||||
break;
|
break;
|
||||||
file = fopen((char *) cache_hashed, "rb");
|
fd = open((char *) cache_hashed, O_RDONLY | O_BINARY);
|
||||||
if (file != NULL) {
|
FcStrFree (cache_hashed);
|
||||||
if (fstat (fileno (file), &file_stat) >= 0 &&
|
if (fd >= 0) {
|
||||||
|
if (fstat (fd, &file_stat) >= 0 &&
|
||||||
dir_stat.st_mtime <= file_stat.st_mtime)
|
dir_stat.st_mtime <= file_stat.st_mtime)
|
||||||
{
|
{
|
||||||
|
if (size)
|
||||||
|
*size = file_stat.st_size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fclose (file);
|
close (fd);
|
||||||
file = NULL;
|
fd = -1;
|
||||||
}
|
}
|
||||||
FcStrFree (cache_hashed);
|
|
||||||
cache_hashed = NULL;
|
|
||||||
}
|
}
|
||||||
FcStrListDone (list);
|
FcStrListDone (list);
|
||||||
|
|
||||||
if (file == NULL)
|
return fd;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (cache_path)
|
|
||||||
*cache_path = cache_hashed;
|
|
||||||
else
|
|
||||||
FcStrFree (cache_hashed);
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void
|
||||||
|
FcDirCacheUnmap (FcCache *cache)
|
||||||
|
{
|
||||||
|
if (cache->magic == FC_CACHE_MAGIC_COPY)
|
||||||
|
{
|
||||||
|
free (cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
||||||
|
munmap (cache, cache->size);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
UnmapViewOfFile (cache);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* read serialized state from the cache file */
|
/* read serialized state from the cache file */
|
||||||
FcBool
|
static FcCache *
|
||||||
FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs,
|
FcDirCacheMap (int fd, off_t size)
|
||||||
const FcChar8 *dir, char *dirname)
|
|
||||||
{
|
{
|
||||||
FcCache metadata;
|
FcCache *cache;
|
||||||
void *current_dir_block;
|
FcBool allocated = FcFalse;
|
||||||
char subdir_name[FC_MAX_FILE_LEN + 1 + 12 + 1];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (fread(&metadata, sizeof(FcCache), 1, file) != 1)
|
if (size < sizeof (FcCache))
|
||||||
goto bail;
|
return NULL;
|
||||||
if (metadata.magic != FC_CACHE_MAGIC)
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
/* skip directory name; it's just for fc-cat */
|
|
||||||
if (!FcCacheReadString (file, subdir_name, sizeof (subdir_name)))
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
if (dirname)
|
|
||||||
strcpy (dirname, subdir_name);
|
|
||||||
|
|
||||||
for (i = 0; i < metadata.subdirs; i++) {
|
|
||||||
if (!FcCacheReadString (file, subdir_name, sizeof (subdir_name)))
|
|
||||||
goto bail;
|
|
||||||
FcStrSetAdd (dirs, (FcChar8 *)subdir_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metadata.count)
|
|
||||||
{
|
|
||||||
int fd = fileno (file);
|
|
||||||
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
||||||
current_dir_block = mmap (0, metadata.count,
|
cache = mmap (0, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
PROT_READ, MAP_SHARED, fd, metadata.pos);
|
|
||||||
if (current_dir_block == MAP_FAILED)
|
|
||||||
goto bail;
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
{
|
{
|
||||||
HANDLE hFileMap;
|
HANDLE hFileMap;
|
||||||
|
|
||||||
hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL, PAGE_READONLY, 0, 0, NULL);
|
cache = NULL;
|
||||||
if (hFileMap == NULL)
|
hFileMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), NULL,
|
||||||
goto bail;
|
PAGE_READONLY, 0, 0, NULL);
|
||||||
|
if (hFileMap != NULL)
|
||||||
current_dir_block = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, metadata.pos, metadata.count);
|
|
||||||
if (current_dir_block == NULL)
|
|
||||||
{
|
{
|
||||||
|
cache = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, size);
|
||||||
CloseHandle (hFileMap);
|
CloseHandle (hFileMap);
|
||||||
goto bail;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (lseek (fd, metatdata.pos, SEEK_SET) == -1)
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
current_dir_block = malloc (metadata.count);
|
|
||||||
if (!current_dir_block)
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
/* could also use CreateMappedViewOfFile under MinGW... */
|
|
||||||
if (read (fd, current_dir_block, metadata.count) != metadata.count)
|
|
||||||
{
|
|
||||||
free (current_dir_block);
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
FcCacheAddBankDir (metadata.bank, (char *) dir);
|
if (!cache)
|
||||||
if (!FcFontSetUnserialize (&metadata, set, current_dir_block))
|
{
|
||||||
goto bail;
|
cache = malloc (size);
|
||||||
|
if (!cache)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (read (fd, cache, size) != size)
|
||||||
|
{
|
||||||
|
free (cache);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
allocated = FcTrue;
|
||||||
|
}
|
||||||
|
if (cache->magic != FC_CACHE_MAGIC ||
|
||||||
|
cache->size != size)
|
||||||
|
{
|
||||||
|
if (allocated)
|
||||||
|
free (cache);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(HAVE_MMAP) || defined(__CYGWIN__)
|
||||||
|
munmap (cache, size);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
UnmapViewOfFile (cache);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FcTrue;
|
/* Mark allocated caches so they're freed rather than unmapped */
|
||||||
|
if (allocated)
|
||||||
|
cache->magic = FC_CACHE_MAGIC_COPY;
|
||||||
|
|
||||||
bail:
|
return cache;
|
||||||
return FcFalse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs,
|
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs,
|
||||||
const FcChar8 *dir, FcConfig *config)
|
const FcChar8 *dir, FcConfig *config)
|
||||||
{
|
{
|
||||||
FILE *file;
|
int fd;
|
||||||
|
FcCache *cache;
|
||||||
|
off_t size;
|
||||||
|
int i;
|
||||||
|
FcFontSet *cache_set;
|
||||||
|
intptr_t *cache_dirs;
|
||||||
|
FcPattern **cache_fonts;
|
||||||
|
|
||||||
file = FcDirCacheOpen (config, dir, NULL);
|
fd = FcDirCacheOpen (config, dir, &size);
|
||||||
if (file == NULL)
|
if (fd < 0)
|
||||||
goto bail;
|
return FcFalse;
|
||||||
|
|
||||||
if (!FcDirCacheConsume (file, set, dirs, dir, NULL))
|
cache = FcDirCacheMap (fd, size);
|
||||||
goto bail1;
|
|
||||||
|
if (!cache)
|
||||||
|
{
|
||||||
|
if (FcDebug() & FC_DBG_CACHE)
|
||||||
|
printf ("FcDirCacheRead failed to map cache for %s\n", dir);
|
||||||
|
close (fd);
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_set = FcCacheSet (cache);
|
||||||
|
cache_fonts = FcFontSetFonts(cache_set);
|
||||||
|
if (FcDebug() & FC_DBG_CACHE)
|
||||||
|
printf ("FcDirCacheRead mapped cache for %s (%d fonts %d subdirs)\n",
|
||||||
|
dir, cache_set->nfont, cache->dirs_count);
|
||||||
|
for (i = 0; i < cache_set->nfont; i++)
|
||||||
|
{
|
||||||
|
FcPattern *font = FcEncodedOffsetToPtr (cache_set,
|
||||||
|
cache_fonts[i],
|
||||||
|
FcPattern);
|
||||||
|
if (FcDebug() & FC_DBG_CACHEV) {
|
||||||
|
printf ("Mapped font %d\n", i);
|
||||||
|
FcPatternPrint (font);
|
||||||
|
}
|
||||||
|
FcFontSetAdd (set, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_dirs = FcCacheDirs (cache);
|
||||||
|
for (i = 0; i < cache->dirs_count; i++)
|
||||||
|
FcStrSetAdd (dirs, FcOffsetToPtr (cache_dirs,
|
||||||
|
cache_dirs[i],
|
||||||
|
FcChar8));
|
||||||
|
|
||||||
if (config)
|
if (config)
|
||||||
FcConfigAddFontDir (config, (FcChar8 *)dir);
|
FcConfigAddFontDir (config, (FcChar8 *)dir);
|
||||||
|
|
||||||
fclose (file);
|
close (fd);
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
|
||||||
bail1:
|
|
||||||
fclose (file);
|
|
||||||
bail:
|
|
||||||
return FcFalse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache file is:
|
||||||
|
*
|
||||||
|
* FcCache
|
||||||
|
* dir name
|
||||||
|
* subdirs
|
||||||
|
* FcFontSet
|
||||||
|
*/
|
||||||
|
|
||||||
static void *
|
static FcCache *
|
||||||
FcDirCacheProduce (FcFontSet *set, FcCache *metadata)
|
FcDirCacheProduce (FcFontSet *set, const FcChar8 *dir, FcStrSet *dirs)
|
||||||
{
|
{
|
||||||
void * current_dir_block, * final_dir_block;
|
FcSerialize *serialize = FcSerializeCreate ();
|
||||||
static unsigned int rand_state = 0;
|
FcCache *cache;
|
||||||
int bank, needed_bytes_no_align;
|
int i;
|
||||||
|
intptr_t cache_offset;
|
||||||
|
intptr_t dirs_offset;
|
||||||
|
FcChar8 *dir_serialize;
|
||||||
|
intptr_t *dirs_serialize;
|
||||||
|
FcFontSet *set_serialize;
|
||||||
|
|
||||||
#if defined (HAVE_RAND_R)
|
if (!serialize)
|
||||||
if (!rand_state)
|
return NULL;
|
||||||
rand_state = time(0L);
|
/*
|
||||||
bank = rand_r(&rand_state);
|
* Space for cache structure
|
||||||
|
*/
|
||||||
|
cache_offset = FcSerializeReserve (serialize, sizeof (FcCache));
|
||||||
|
/*
|
||||||
|
* Directory name
|
||||||
|
*/
|
||||||
|
if (!FcStrSerializeAlloc (serialize, dir))
|
||||||
|
goto bail1;
|
||||||
|
/*
|
||||||
|
* Subdirs
|
||||||
|
*/
|
||||||
|
dirs_offset = FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *));
|
||||||
|
for (i = 0; i < dirs->num; i++)
|
||||||
|
if (!FcStrSerializeAlloc (serialize, dirs->strs[i]))
|
||||||
|
goto bail1;
|
||||||
|
|
||||||
while (FcCacheHaveBank(bank))
|
/*
|
||||||
bank = rand_r(&rand_state);
|
* Patterns
|
||||||
#else
|
*/
|
||||||
if (!rand_state)
|
if (!FcFontSetSerializeAlloc (serialize, set))
|
||||||
{
|
goto bail1;
|
||||||
rand_state = 1;
|
|
||||||
srand (time (0L));
|
|
||||||
}
|
|
||||||
bank = rand();
|
|
||||||
|
|
||||||
while (FcCacheHaveBank(bank))
|
/* Serialize layout complete. Now allocate space and fill it */
|
||||||
bank = rand();
|
cache = malloc (serialize->size);
|
||||||
#endif
|
if (!cache)
|
||||||
|
goto bail1;
|
||||||
memset (metadata, 0, sizeof(FcCache));
|
|
||||||
FcFontSetNewBank();
|
|
||||||
needed_bytes_no_align = FcFontSetNeededBytes (set);
|
|
||||||
metadata->count = needed_bytes_no_align +
|
|
||||||
FcFontSetNeededBytesAlign ();
|
|
||||||
metadata->magic = FC_CACHE_MAGIC;
|
|
||||||
metadata->bank = bank;
|
|
||||||
|
|
||||||
if (!needed_bytes_no_align) /* not a failure, no fonts to write */
|
|
||||||
{
|
|
||||||
/* no, you don't really need to write any bytes at all. */
|
|
||||||
metadata->count = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_dir_block = malloc (metadata->count);
|
|
||||||
if (!current_dir_block)
|
|
||||||
goto bail;
|
|
||||||
/* shut up valgrind */
|
/* shut up valgrind */
|
||||||
memset (current_dir_block, 0, metadata->count);
|
memset (cache, 0, serialize->size);
|
||||||
final_dir_block = FcFontSetDistributeBytes (metadata, current_dir_block);
|
|
||||||
|
|
||||||
if ((void *)((char *)current_dir_block+metadata->count) < final_dir_block)
|
serialize->linear = cache;
|
||||||
goto bail;
|
|
||||||
|
|
||||||
if (!FcFontSetSerialize (bank, set))
|
cache->magic = FC_CACHE_MAGIC;
|
||||||
goto bail;
|
cache->size = serialize->size;
|
||||||
|
|
||||||
return current_dir_block;
|
/*
|
||||||
|
* Serialize directory name
|
||||||
|
*/
|
||||||
|
dir_serialize = FcStrSerialize (serialize, dir);
|
||||||
|
if (!dir_serialize)
|
||||||
|
goto bail2;
|
||||||
|
cache->dir = FcPtrToOffset (cache, dir_serialize);
|
||||||
|
|
||||||
bail:
|
/*
|
||||||
free (current_dir_block);
|
* Serialize sub dirs
|
||||||
return 0;
|
*/
|
||||||
|
dirs_serialize = FcSerializePtr (serialize, dirs);
|
||||||
|
if (!dirs_serialize)
|
||||||
|
goto bail2;
|
||||||
|
cache->dirs = FcPtrToOffset (cache, dirs_serialize);
|
||||||
|
cache->dirs_count = dirs->num;
|
||||||
|
for (i = 0; i < dirs->num; i++)
|
||||||
|
{
|
||||||
|
FcChar8 *d_serialize = FcStrSerialize (serialize, dirs->strs[i]);
|
||||||
|
if (!d_serialize)
|
||||||
|
goto bail2;
|
||||||
|
dirs_serialize[i] = FcPtrToOffset (dirs_serialize, d_serialize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serialize font set
|
||||||
|
*/
|
||||||
|
set_serialize = FcFontSetSerialize (serialize, set);
|
||||||
|
if (!set_serialize)
|
||||||
|
goto bail2;
|
||||||
|
cache->set = FcPtrToOffset (cache, set_serialize);
|
||||||
|
|
||||||
|
FcSerializeDestroy (serialize);
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
|
||||||
|
bail2:
|
||||||
|
free (cache);
|
||||||
|
bail1:
|
||||||
|
FcSerializeDestroy (serialize);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
|
@ -524,14 +518,12 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c
|
||||||
{
|
{
|
||||||
FcChar8 cache_base[CACHEBASE_LEN];
|
FcChar8 cache_base[CACHEBASE_LEN];
|
||||||
FcChar8 *cache_hashed;
|
FcChar8 *cache_hashed;
|
||||||
int fd, i;
|
int fd;
|
||||||
FcAtomic *atomic;
|
FcAtomic *atomic;
|
||||||
FcCache metadata;
|
FcCache *cache;
|
||||||
void *current_dir_block = 0;
|
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
FcChar8 *cache_dir = NULL;
|
FcChar8 *cache_dir = NULL;
|
||||||
FcChar8 *test_dir;
|
FcChar8 *test_dir;
|
||||||
off_t header_len;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write it to the first directory in the list which is writable
|
* Write it to the first directory in the list which is writable
|
||||||
|
@ -563,14 +555,15 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c
|
||||||
FcStrListDone (list);
|
FcStrListDone (list);
|
||||||
if (!cache_dir)
|
if (!cache_dir)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
FcDirCacheBasename (dir, cache_base);
|
||||||
cache_hashed = FcStrPlus (cache_dir, cache_base);
|
cache_hashed = FcStrPlus (cache_dir, cache_base);
|
||||||
if (!cache_hashed)
|
if (!cache_hashed)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
current_dir_block = FcDirCacheProduce (set, &metadata);
|
cache = FcDirCacheProduce (set, dir, dirs);
|
||||||
|
|
||||||
if (metadata.count && !current_dir_block)
|
if (!cache)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
if (FcDebug () & FC_DBG_CACHE)
|
if (FcDebug () & FC_DBG_CACHE)
|
||||||
|
@ -579,54 +572,24 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c
|
||||||
|
|
||||||
atomic = FcAtomicCreate ((FcChar8 *)cache_hashed);
|
atomic = FcAtomicCreate ((FcChar8 *)cache_hashed);
|
||||||
if (!atomic)
|
if (!atomic)
|
||||||
goto bail1;
|
goto bail2;
|
||||||
|
|
||||||
if (!FcAtomicLock (atomic))
|
if (!FcAtomicLock (atomic))
|
||||||
goto bail2;
|
goto bail3;
|
||||||
|
|
||||||
fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666);
|
fd = open((char *)FcAtomicNewFile (atomic), O_RDWR | O_CREAT | O_BINARY, 0666);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
goto bail3;
|
goto bail4;
|
||||||
|
|
||||||
/*
|
if (write (fd, cache, cache->size) != cache->size)
|
||||||
* Compute file header length -- the FcCache followed by the subdir names
|
|
||||||
*/
|
|
||||||
header_len = sizeof (FcCache);
|
|
||||||
header_len += strlen ((char *) dir) + 1;
|
|
||||||
for (i = 0; i < dirs->size; i++)
|
|
||||||
header_len += strlen ((char *)dirs->strs[i]) + 1;
|
|
||||||
|
|
||||||
metadata.pos = FcCacheNextOffset (lseek (fd, 0, SEEK_CUR) + header_len);
|
|
||||||
metadata.subdirs = dirs->size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write out the header
|
|
||||||
*/
|
|
||||||
if (write (fd, &metadata, sizeof(FcCache)) != sizeof(FcCache))
|
|
||||||
{
|
{
|
||||||
perror("write metadata");
|
perror ("write cache");
|
||||||
goto bail5;
|
goto bail5;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcCacheWriteString (fd, (char *) dir);
|
|
||||||
|
|
||||||
for (i = 0; i < dirs->size; i++)
|
|
||||||
FcCacheWriteString (fd, (char *)dirs->strs[i]);
|
|
||||||
|
|
||||||
if (metadata.count)
|
|
||||||
{
|
|
||||||
if (lseek (fd, metadata.pos, SEEK_SET) != metadata.pos)
|
|
||||||
perror("lseek");
|
|
||||||
else if (write (fd, current_dir_block, metadata.count) !=
|
|
||||||
metadata.count)
|
|
||||||
perror("write current_dir_block");
|
|
||||||
free (current_dir_block);
|
|
||||||
current_dir_block = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
if (!FcAtomicReplaceOrig(atomic))
|
if (!FcAtomicReplaceOrig(atomic))
|
||||||
goto bail3;
|
goto bail4;
|
||||||
FcStrFree ((FcChar8 *)cache_hashed);
|
FcStrFree ((FcChar8 *)cache_hashed);
|
||||||
FcAtomicUnlock (atomic);
|
FcAtomicUnlock (atomic);
|
||||||
FcAtomicDestroy (atomic);
|
FcAtomicDestroy (atomic);
|
||||||
|
@ -634,99 +597,17 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c
|
||||||
|
|
||||||
bail5:
|
bail5:
|
||||||
close (fd);
|
close (fd);
|
||||||
bail3:
|
bail4:
|
||||||
FcAtomicUnlock (atomic);
|
FcAtomicUnlock (atomic);
|
||||||
bail2:
|
bail3:
|
||||||
FcAtomicDestroy (atomic);
|
FcAtomicDestroy (atomic);
|
||||||
|
bail2:
|
||||||
|
free (cache);
|
||||||
bail1:
|
bail1:
|
||||||
FcStrFree ((FcChar8 *)cache_hashed);
|
FcStrFree ((FcChar8 *)cache_hashed);
|
||||||
if (current_dir_block)
|
|
||||||
free (current_dir_block);
|
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int banks_ptr = 0, banks_alloc = 0;
|
|
||||||
int * _fcBankId = 0, * _fcBankIdx = 0;
|
|
||||||
static const char ** bankDirs = 0;
|
|
||||||
|
|
||||||
static FcBool
|
|
||||||
FcCacheHaveBank (int bank)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (bank < FC_BANK_FIRST)
|
|
||||||
return FcTrue;
|
|
||||||
|
|
||||||
for (i = 0; i < banks_ptr; i++)
|
|
||||||
if (_fcBankId[i] == bank)
|
|
||||||
return FcTrue;
|
|
||||||
|
|
||||||
return FcFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcCacheBankToIndexMTF (int bank)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < banks_ptr; i++)
|
|
||||||
if (_fcBankId[_fcBankIdx[i]] == bank)
|
|
||||||
{
|
|
||||||
int t = _fcBankIdx[i];
|
|
||||||
|
|
||||||
for (j = i; j > 0; j--)
|
|
||||||
_fcBankIdx[j] = _fcBankIdx[j-1];
|
|
||||||
_fcBankIdx[0] = t;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (banks_ptr >= banks_alloc)
|
|
||||||
{
|
|
||||||
int * b, * bidx;
|
|
||||||
const char ** bds;
|
|
||||||
|
|
||||||
b = realloc (_fcBankId, (banks_alloc + 4) * sizeof(int));
|
|
||||||
if (!b)
|
|
||||||
return -1;
|
|
||||||
_fcBankId = b;
|
|
||||||
|
|
||||||
bidx = realloc (_fcBankIdx, (banks_alloc + 4) * sizeof(int));
|
|
||||||
if (!bidx)
|
|
||||||
return -1;
|
|
||||||
_fcBankIdx = bidx;
|
|
||||||
|
|
||||||
bds = realloc (bankDirs, (banks_alloc + 4) * sizeof (char *));
|
|
||||||
if (!bds)
|
|
||||||
return -1;
|
|
||||||
bankDirs = bds;
|
|
||||||
|
|
||||||
banks_alloc += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = banks_ptr++;
|
|
||||||
_fcBankId[i] = bank;
|
|
||||||
_fcBankIdx[i] = i;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
FcCacheAddBankDir (int bank, const char * dir)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndexMTF (bank);
|
|
||||||
|
|
||||||
if (bi < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bankDirs[bi] = (const char *)FcStrCopy ((FcChar8 *)dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
FcCacheFindBankDir (int bank)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndex (bank);
|
|
||||||
return bankDirs[bi];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code implements the MD5 message-digest algorithm.
|
* This code implements the MD5 message-digest algorithm.
|
||||||
* The algorithm is due to Ron Rivest. This code was
|
* The algorithm is due to Ron Rivest. This code was
|
||||||
|
|
102
src/fccfg.c
102
src/fccfg.c
|
@ -310,11 +310,12 @@ FcConfigBuildFonts (FcConfig *config)
|
||||||
for (i = 0; i < cached_fonts->nfont; i++)
|
for (i = 0; i < cached_fonts->nfont; i++)
|
||||||
{
|
{
|
||||||
FcChar8 *cfn;
|
FcChar8 *cfn;
|
||||||
FcPatternGetString (cached_fonts->fonts[i], FC_FILE, 0, &cfn);
|
FcPattern *font = cached_fonts->fonts[i];
|
||||||
|
FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &cfn);
|
||||||
|
|
||||||
if (FcConfigAcceptFont (config, cached_fonts->fonts[i]) &&
|
if (FcConfigAcceptFont (config, font) &&
|
||||||
(cfn && FcConfigAcceptFilename (config, cfn)))
|
(cfn && FcConfigAcceptFilename (config, cfn)))
|
||||||
FcFontSetAdd (fonts, cached_fonts->fonts[i]);
|
FcFontSetAdd (fonts, font);
|
||||||
|
|
||||||
cached_fonts->fonts[i] = 0; /* prevent free in FcFontSetDestroy */
|
cached_fonts->fonts[i] = 0; /* prevent free in FcFontSetDestroy */
|
||||||
}
|
}
|
||||||
|
@ -841,7 +842,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
|
||||||
v.u.b = e->u.bval;
|
v.u.b = e->u.bval;
|
||||||
break;
|
break;
|
||||||
case FcOpField:
|
case FcOpField:
|
||||||
r = FcPatternGet (p, e->u.field, 0, &v);
|
r = FcPatternObjectGet (p, e->u.object, 0, &v);
|
||||||
if (r != FcResultMatch)
|
if (r != FcResultMatch)
|
||||||
v.type = FcTypeVoid;
|
v.type = FcTypeVoid;
|
||||||
v = FcValueSave (v);
|
v = FcValueSave (v);
|
||||||
|
@ -1093,7 +1094,7 @@ FcConfigMatchValueList (FcPattern *p,
|
||||||
e = 0;
|
e = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (v = values; v; v = FcValueListPtrU(v->next))
|
for (v = values; v; v = FcValueListNext(v))
|
||||||
{
|
{
|
||||||
/* Compare the pattern value to the match expression value */
|
/* Compare the pattern value to the match expression value */
|
||||||
if (FcConfigCompareValue (&v->value, t->op, &value))
|
if (FcConfigCompareValue (&v->value, t->op, &value))
|
||||||
|
@ -1129,17 +1130,17 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
|
||||||
if (e->op == FcOpComma)
|
if (e->op == FcOpComma)
|
||||||
{
|
{
|
||||||
l->value = FcConfigEvaluate (p, e->u.tree.left);
|
l->value = FcConfigEvaluate (p, e->u.tree.left);
|
||||||
l->next = FcValueListPtrCreateDynamic(FcConfigValues (p, e->u.tree.right, binding));
|
l->next = FcConfigValues (p, e->u.tree.right, binding);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
l->value = FcConfigEvaluate (p, e);
|
l->value = FcConfigEvaluate (p, e);
|
||||||
l->next = FcValueListPtrCreateDynamic(0);
|
l->next = NULL;
|
||||||
}
|
}
|
||||||
l->binding = binding;
|
l->binding = binding;
|
||||||
if (l->value.type == FcTypeVoid)
|
if (l->value.type == FcTypeVoid)
|
||||||
{
|
{
|
||||||
FcValueList *next = FcValueListPtrU(l->next);
|
FcValueList *next = FcValueListNext(l);
|
||||||
|
|
||||||
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
|
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
|
||||||
free (l);
|
free (l);
|
||||||
|
@ -1162,27 +1163,26 @@ FcConfigAdd (FcValueListPtr *head,
|
||||||
sameBinding = position->binding;
|
sameBinding = position->binding;
|
||||||
else
|
else
|
||||||
sameBinding = FcValueBindingWeak;
|
sameBinding = FcValueBindingWeak;
|
||||||
for (v = FcValueListPtrCreateDynamic(new); FcValueListPtrU(v);
|
for (v = new; v != NULL; v = FcValueListNext(v))
|
||||||
v = FcValueListPtrU(v)->next)
|
if (v->binding == FcValueBindingSame)
|
||||||
if (FcValueListPtrU(v)->binding == FcValueBindingSame)
|
v->binding = sameBinding;
|
||||||
FcValueListPtrU(v)->binding = sameBinding;
|
|
||||||
if (append)
|
if (append)
|
||||||
{
|
{
|
||||||
if (position)
|
if (position)
|
||||||
prev = &position->next;
|
prev = &position->next;
|
||||||
else
|
else
|
||||||
for (prev = head; FcValueListPtrU(*prev);
|
for (prev = head; *prev != NULL;
|
||||||
prev = &(FcValueListPtrU(*prev)->next))
|
prev = &(*prev)->next)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (position)
|
if (position)
|
||||||
{
|
{
|
||||||
for (prev = head; FcValueListPtrU(*prev);
|
for (prev = head; *prev != NULL;
|
||||||
prev = &(FcValueListPtrU(*prev)->next))
|
prev = &(*prev)->next)
|
||||||
{
|
{
|
||||||
if (FcValueListPtrU(*prev) == position)
|
if (*prev == position)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1191,7 +1191,7 @@ FcConfigAdd (FcValueListPtr *head,
|
||||||
|
|
||||||
if (FcDebug () & FC_DBG_EDIT)
|
if (FcDebug () & FC_DBG_EDIT)
|
||||||
{
|
{
|
||||||
if (!FcValueListPtrU(*prev))
|
if (*prev == NULL)
|
||||||
printf ("position not on list\n");
|
printf ("position not on list\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1205,12 +1205,12 @@ FcConfigAdd (FcValueListPtr *head,
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
last = FcValueListPtrCreateDynamic(new);
|
last = new;
|
||||||
while (FcValueListPtrU(FcValueListPtrU(last)->next))
|
while (last->next != NULL)
|
||||||
last = FcValueListPtrU(last)->next;
|
last = last->next;
|
||||||
|
|
||||||
FcValueListPtrU(last)->next = *prev;
|
last->next = *prev;
|
||||||
*prev = FcValueListPtrCreateDynamic(new);
|
*prev = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FcDebug () & FC_DBG_EDIT)
|
if (FcDebug () & FC_DBG_EDIT)
|
||||||
|
@ -1229,14 +1229,13 @@ FcConfigDel (FcValueListPtr *head,
|
||||||
{
|
{
|
||||||
FcValueListPtr *prev;
|
FcValueListPtr *prev;
|
||||||
|
|
||||||
for (prev = head; FcValueListPtrU(*prev);
|
for (prev = head; *prev != NULL; prev = &(*prev)->next)
|
||||||
prev = &(FcValueListPtrU(*prev)->next))
|
|
||||||
{
|
{
|
||||||
if (FcValueListPtrU(*prev) == position)
|
if (*prev == position)
|
||||||
{
|
{
|
||||||
*prev = position->next;
|
*prev = position->next;
|
||||||
position->next = FcValueListPtrCreateDynamic(0);
|
position->next = NULL;
|
||||||
FcValueListDestroy (FcValueListPtrCreateDynamic(position));
|
FcValueListDestroy (position);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1244,13 +1243,13 @@ FcConfigDel (FcValueListPtr *head,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FcConfigPatternAdd (FcPattern *p,
|
FcConfigPatternAdd (FcPattern *p,
|
||||||
const char *object,
|
FcObject object,
|
||||||
FcValueList *list,
|
FcValueList *list,
|
||||||
FcBool append)
|
FcBool append)
|
||||||
{
|
{
|
||||||
if (list)
|
if (list)
|
||||||
{
|
{
|
||||||
FcPatternElt *e = FcPatternInsertElt (p, object);
|
FcPatternElt *e = FcPatternObjectInsertElt (p, object);
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
return;
|
return;
|
||||||
|
@ -1263,24 +1262,24 @@ FcConfigPatternAdd (FcPattern *p,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
FcConfigPatternDel (FcPattern *p,
|
FcConfigPatternDel (FcPattern *p,
|
||||||
const char *object)
|
FcObject object)
|
||||||
{
|
{
|
||||||
FcPatternElt *e = FcPatternFindElt (p, object);
|
FcPatternElt *e = FcPatternObjectFindElt (p, object);
|
||||||
if (!e)
|
if (!e)
|
||||||
return;
|
return;
|
||||||
while (FcValueListPtrU(e->values))
|
while (e->values != NULL)
|
||||||
FcConfigDel (&e->values, FcValueListPtrU(e->values));
|
FcConfigDel (&e->values, e->values);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FcConfigPatternCanon (FcPattern *p,
|
FcConfigPatternCanon (FcPattern *p,
|
||||||
const char *object)
|
FcObject object)
|
||||||
{
|
{
|
||||||
FcPatternElt *e = FcPatternFindElt (p, object);
|
FcPatternElt *e = FcPatternObjectFindElt (p, object);
|
||||||
if (!e)
|
if (!e)
|
||||||
return;
|
return;
|
||||||
if (!FcValueListPtrU(e->values))
|
if (e->values == NULL)
|
||||||
FcPatternDel (p, object);
|
FcPatternObjectDel (p, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -1337,7 +1336,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
else
|
else
|
||||||
m = p;
|
m = p;
|
||||||
if (m)
|
if (m)
|
||||||
st[i].elt = FcPatternFindElt (m, t->field);
|
st[i].elt = FcPatternObjectFindElt (m, t->object);
|
||||||
else
|
else
|
||||||
st[i].elt = 0;
|
st[i].elt = 0;
|
||||||
/*
|
/*
|
||||||
|
@ -1358,12 +1357,12 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
* Check to see if there is a match, mark the location
|
* Check to see if there is a match, mark the location
|
||||||
* to apply match-relative edits
|
* to apply match-relative edits
|
||||||
*/
|
*/
|
||||||
st[i].value = FcConfigMatchValueList (m, t, FcValueListPtrU(st[i].elt->values));
|
st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
|
||||||
if (!st[i].value)
|
if (!st[i].value)
|
||||||
break;
|
break;
|
||||||
if (t->qual == FcQualFirst && st[i].value != FcValueListPtrU(st[i].elt->values))
|
if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
|
||||||
break;
|
break;
|
||||||
if (t->qual == FcQualNotFirst && st[i].value == FcValueListPtrU(st[i].elt->values))
|
if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (t)
|
if (t)
|
||||||
|
@ -1391,8 +1390,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
for (t = s->test, i = 0; t; t = t->next, i++)
|
for (t = s->test, i = 0; t; t = t->next, i++)
|
||||||
{
|
{
|
||||||
if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
|
if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
|
||||||
!FcStrCmpIgnoreCase ((FcChar8 *) t->field,
|
t->object == e->object)
|
||||||
(FcChar8 *) e->field))
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* KLUDGE - the pattern may have been reallocated or
|
* KLUDGE - the pattern may have been reallocated or
|
||||||
|
@ -1401,7 +1399,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
* the element again
|
* the element again
|
||||||
*/
|
*/
|
||||||
if (e != s->edit && st[i].elt)
|
if (e != s->edit && st[i].elt)
|
||||||
st[i].elt = FcPatternFindElt (p, t->field);
|
st[i].elt = FcPatternObjectFindElt (p, t->object);
|
||||||
if (!st[i].elt)
|
if (!st[i].elt)
|
||||||
t = 0;
|
t = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1416,7 +1414,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
FcValueList *thisValue = st[i].value;
|
FcValueList *thisValue = st[i].value;
|
||||||
FcValueList *nextValue = thisValue ? FcValueListPtrU(thisValue->next) : 0;
|
FcValueList *nextValue = thisValue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append the new list of values after the current value
|
* Append the new list of values after the current value
|
||||||
|
@ -1444,8 +1442,8 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
* Delete all of the values and insert
|
* Delete all of the values and insert
|
||||||
* the new set
|
* the new set
|
||||||
*/
|
*/
|
||||||
FcConfigPatternDel (p, e->field);
|
FcConfigPatternDel (p, e->object);
|
||||||
FcConfigPatternAdd (p, e->field, l, FcTrue);
|
FcConfigPatternAdd (p, e->object, l, FcTrue);
|
||||||
/*
|
/*
|
||||||
* Adjust any pointers into the value list as they no
|
* Adjust any pointers into the value list as they no
|
||||||
* longer point to anything valid
|
* longer point to anything valid
|
||||||
|
@ -1468,7 +1466,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
}
|
}
|
||||||
/* fall through ... */
|
/* fall through ... */
|
||||||
case FcOpPrependFirst:
|
case FcOpPrependFirst:
|
||||||
FcConfigPatternAdd (p, e->field, l, FcFalse);
|
FcConfigPatternAdd (p, e->object, l, FcFalse);
|
||||||
break;
|
break;
|
||||||
case FcOpAppend:
|
case FcOpAppend:
|
||||||
if (t)
|
if (t)
|
||||||
|
@ -1478,10 +1476,10 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
}
|
}
|
||||||
/* fall through ... */
|
/* fall through ... */
|
||||||
case FcOpAppendLast:
|
case FcOpAppendLast:
|
||||||
FcConfigPatternAdd (p, e->field, l, FcTrue);
|
FcConfigPatternAdd (p, e->object, l, FcTrue);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FcValueListDestroy (FcValueListPtrCreateDynamic(l));
|
FcValueListDestroy (l);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1490,7 +1488,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
||||||
* any properties without data
|
* any properties without data
|
||||||
*/
|
*/
|
||||||
for (e = s->edit; e; e = e->next)
|
for (e = s->edit; e; e = e->next)
|
||||||
FcConfigPatternCanon (p, e->field);
|
FcConfigPatternCanon (p, e->object);
|
||||||
|
|
||||||
if (FcDebug () & FC_DBG_EDIT)
|
if (FcDebug () & FC_DBG_EDIT)
|
||||||
{
|
{
|
||||||
|
|
429
src/fccharset.c
429
src/fccharset.c
|
@ -29,33 +29,6 @@
|
||||||
|
|
||||||
/* #define CHATTY */
|
/* #define CHATTY */
|
||||||
|
|
||||||
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 int charset_leaf_ptr, charset_leaf_count;
|
|
||||||
static int ** leaf_idx = 0;
|
|
||||||
static int charset_leaf_idx_ptr, charset_leaf_idx_count;
|
|
||||||
|
|
||||||
extern const FcChar16 langBankNumbers[];
|
|
||||||
extern const FcCharLeaf langBankLeaves[];
|
|
||||||
extern const int langBankLeafIdx[];
|
|
||||||
|
|
||||||
static FcBool
|
|
||||||
FcCharSetEnsureBank (int bi);
|
|
||||||
|
|
||||||
void
|
|
||||||
FcLangCharSetPopulate (void)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndexMTF (FC_BANK_LANGS);
|
|
||||||
FcCharSetEnsureBank (bi);
|
|
||||||
charsets[bi] = 0;
|
|
||||||
numbers[bi] = (FcChar16 *)langBankNumbers;
|
|
||||||
leaves[bi] = (FcCharLeaf *)langBankLeaves;
|
|
||||||
leaf_idx[bi] = (int *)langBankLeafIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcCharSetCreate (void)
|
FcCharSetCreate (void)
|
||||||
{
|
{
|
||||||
|
@ -67,9 +40,8 @@ FcCharSetCreate (void)
|
||||||
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
|
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||||
fcs->ref = 1;
|
fcs->ref = 1;
|
||||||
fcs->num = 0;
|
fcs->num = 0;
|
||||||
fcs->bank = FC_BANK_DYNAMIC;
|
fcs->leaves_offset = FcPtrToOffset (fcs, NULL);
|
||||||
fcs->u.dyn.leaves = 0;
|
fcs->numbers_offset = FcPtrToOffset (fcs, NULL);
|
||||||
fcs->u.dyn.numbers = 0;
|
|
||||||
return fcs;
|
return fcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,27 +58,25 @@ void
|
||||||
FcCharSetDestroy (FcCharSet *fcs)
|
FcCharSetDestroy (FcCharSet *fcs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (fcs->ref == FC_REF_CONSTANT)
|
if (fcs->ref == FC_REF_CONSTANT)
|
||||||
return;
|
return;
|
||||||
if (--fcs->ref > 0)
|
if (--fcs->ref > 0)
|
||||||
return;
|
return;
|
||||||
if (fcs->bank == FC_BANK_DYNAMIC)
|
|
||||||
{
|
|
||||||
for (i = 0; i < fcs->num; i++)
|
for (i = 0; i < fcs->num; i++)
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
|
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
|
||||||
free (fcs->u.dyn.leaves[i]);
|
free (FcCharSetLeaf (fcs, i));
|
||||||
}
|
}
|
||||||
if (fcs->u.dyn.leaves)
|
if (FcCharSetLeaves (fcs))
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
|
||||||
free (fcs->u.dyn.leaves);
|
free (FcCharSetLeaves (fcs));
|
||||||
}
|
}
|
||||||
if (fcs->u.dyn.numbers)
|
if (FcCharSetNumbers (fcs))
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
||||||
free (fcs->u.dyn.numbers);
|
free (FcCharSetNumbers (fcs));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||||
free (fcs);
|
free (fcs);
|
||||||
|
@ -121,7 +91,7 @@ FcCharSetDestroy (FcCharSet *fcs)
|
||||||
static int
|
static int
|
||||||
FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
|
FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
|
||||||
{
|
{
|
||||||
FcChar16 *numbers = FcCharSetGetNumbers(fcs);
|
FcChar16 *numbers = FcCharSetNumbers(fcs);
|
||||||
FcChar16 page;
|
FcChar16 page;
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = fcs->num - 1;
|
int high = fcs->num - 1;
|
||||||
|
@ -150,7 +120,7 @@ FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4)
|
||||||
{
|
{
|
||||||
int pos = FcCharSetFindLeafPos (fcs, ucs4);
|
int pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
return FcCharSetGetLeaf(fcs, pos);
|
return FcCharSetLeaf(fcs, pos);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,68 +130,55 @@ FcCharSetPutLeaf (FcCharSet *fcs,
|
||||||
FcCharLeaf *leaf,
|
FcCharLeaf *leaf,
|
||||||
int pos)
|
int pos)
|
||||||
{
|
{
|
||||||
FcCharLeaf **leaves;
|
intptr_t *leaves = FcCharSetLeaves (fcs);
|
||||||
FcChar16 *numbers;
|
FcChar16 *numbers = FcCharSetNumbers (fcs);
|
||||||
|
|
||||||
ucs4 >>= 8;
|
ucs4 >>= 8;
|
||||||
if (ucs4 >= 0x10000)
|
if (ucs4 >= 0x10000)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (fcs->bank != FC_BANK_DYNAMIC)
|
if (!leaves)
|
||||||
|
leaves = malloc (sizeof (*leaves));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intptr_t *new_leaves = realloc (leaves, (fcs->num + 1) *
|
||||||
|
sizeof (*leaves));
|
||||||
|
intptr_t distance = (intptr_t) new_leaves - (intptr_t) leaves;
|
||||||
|
|
||||||
|
if (new_leaves && distance)
|
||||||
{
|
{
|
||||||
/* convert to dynamic */
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
leaves = malloc ((fcs->num + 1) * sizeof (FcCharLeaf *));
|
|
||||||
if (!leaves)
|
|
||||||
return FcFalse;
|
|
||||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
|
||||||
numbers = malloc ((fcs->num + 1) * sizeof (FcChar16));
|
|
||||||
if (!numbers)
|
|
||||||
{
|
|
||||||
free (leaves);
|
|
||||||
return FcFalse;
|
|
||||||
}
|
|
||||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
|
|
||||||
|
|
||||||
for (i = 0; i < fcs->num; i++)
|
for (i = 0; i < fcs->num; i++)
|
||||||
leaves[i] = FcCharSetGetLeaf(fcs, i);
|
new_leaves[i] -= distance;
|
||||||
memcpy (numbers, FcCharSetGetNumbers(fcs),
|
}
|
||||||
fcs->num * sizeof (FcChar16));
|
leaves = new_leaves;
|
||||||
|
|
||||||
fcs->bank = FC_BANK_DYNAMIC;
|
|
||||||
fcs->u.dyn.leaves = leaves;
|
|
||||||
fcs->u.dyn.numbers = numbers;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!fcs->u.dyn.leaves)
|
|
||||||
leaves = malloc (sizeof (FcCharLeaf *));
|
|
||||||
else
|
|
||||||
leaves = realloc (fcs->u.dyn.leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
|
||||||
if (!leaves)
|
if (!leaves)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
if (fcs->num)
|
if (fcs->num)
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t));
|
||||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t));
|
||||||
fcs->u.dyn.leaves = leaves;
|
fcs->leaves_offset = FcPtrToOffset (fcs, leaves);
|
||||||
if (!fcs->u.dyn.numbers)
|
|
||||||
|
if (!numbers)
|
||||||
numbers = malloc (sizeof (FcChar16));
|
numbers = malloc (sizeof (FcChar16));
|
||||||
else
|
else
|
||||||
numbers = realloc (fcs->u.dyn.numbers, (fcs->num + 1) * sizeof (FcChar16));
|
numbers = realloc (numbers, (fcs->num + 1) * sizeof (FcChar16));
|
||||||
if (!numbers)
|
if (!numbers)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
if (fcs->num)
|
if (fcs->num)
|
||||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
||||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
|
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
|
||||||
fcs->u.dyn.numbers = numbers;
|
fcs->numbers_offset = FcPtrToOffset (fcs, numbers);
|
||||||
}
|
|
||||||
|
|
||||||
memmove (fcs->u.dyn.leaves + pos + 1, fcs->u.dyn.leaves + pos,
|
memmove (leaves + pos + 1, leaves + pos,
|
||||||
(fcs->num - pos) * sizeof (FcCharLeaf *));
|
(fcs->num - pos) * sizeof (*leaves));
|
||||||
memmove (fcs->u.dyn.numbers + pos + 1, fcs->u.dyn.numbers + pos,
|
memmove (numbers + pos + 1, numbers + pos,
|
||||||
(fcs->num - pos) * sizeof (FcChar16));
|
(fcs->num - pos) * sizeof (*numbers));
|
||||||
fcs->u.dyn.numbers[pos] = (FcChar16) ucs4;
|
numbers[pos] = (FcChar16) ucs4;
|
||||||
fcs->u.dyn.leaves[pos] = leaf;
|
leaves[pos] = FcPtrToOffset (leaves, leaf);
|
||||||
fcs->num++;
|
fcs->num++;
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +196,7 @@ FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4)
|
||||||
|
|
||||||
pos = FcCharSetFindLeafPos (fcs, ucs4);
|
pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
return FcCharSetGetLeaf(fcs, pos);
|
return FcCharSetLeaf(fcs, pos);
|
||||||
|
|
||||||
leaf = calloc (1, sizeof (FcCharLeaf));
|
leaf = calloc (1, sizeof (FcCharLeaf));
|
||||||
if (!leaf)
|
if (!leaf)
|
||||||
|
@ -264,16 +221,9 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf)
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
|
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
|
||||||
if (fcs->bank == FC_BANK_DYNAMIC)
|
free (FcCharSetLeaf (fcs, pos));
|
||||||
{
|
FcCharSetLeaves(fcs)[pos] = FcPtrToOffset (FcCharSetLeaves(fcs),
|
||||||
free (fcs->u.dyn.leaves[pos]);
|
leaf);
|
||||||
fcs->u.dyn.leaves[pos] = leaf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndex(fcs->bank);
|
|
||||||
leaves[bi][leaf_idx[fcs->bank][fcs->u.stat.leafidx_offset]+pos] = *leaf;
|
|
||||||
}
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
pos = -pos - 1;
|
pos = -pos - 1;
|
||||||
|
@ -324,9 +274,9 @@ FcCharSetIterSet (const FcCharSet *fcs, FcCharSetIter *iter)
|
||||||
iter->leaf = 0;
|
iter->leaf = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
|
iter->ucs4 = (FcChar32) FcCharSetNumbers(fcs)[pos] << 8;
|
||||||
}
|
}
|
||||||
iter->leaf = FcCharSetGetLeaf(fcs, pos);
|
iter->leaf = FcCharSetLeaf(fcs, pos);
|
||||||
iter->pos = pos;
|
iter->pos = pos;
|
||||||
#ifdef CHATTY
|
#ifdef CHATTY
|
||||||
printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf);
|
printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf);
|
||||||
|
@ -344,8 +294,8 @@ FcCharSetIterNext (const FcCharSet *fcs, FcCharSetIter *iter)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
|
iter->ucs4 = (FcChar32) FcCharSetNumbers(fcs)[pos] << 8;
|
||||||
iter->leaf = FcCharSetGetLeaf(fcs, pos);
|
iter->leaf = FcCharSetLeaf(fcs, pos);
|
||||||
iter->pos = pos;
|
iter->pos = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -662,15 +612,15 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
||||||
ai = 0;
|
ai = 0;
|
||||||
while (ai < a->num && bi < b->num)
|
while (ai < a->num && bi < b->num)
|
||||||
{
|
{
|
||||||
an = FcCharSetGetNumbers(a)[ai];
|
an = FcCharSetNumbers(a)[ai];
|
||||||
bn = FcCharSetGetNumbers(b)[bi];
|
bn = FcCharSetNumbers(b)[bi];
|
||||||
/*
|
/*
|
||||||
* Check matching pages
|
* Check matching pages
|
||||||
*/
|
*/
|
||||||
if (an == bn)
|
if (an == bn)
|
||||||
{
|
{
|
||||||
FcChar32 *am = FcCharSetGetLeaf(a, ai)->map;
|
FcChar32 *am = FcCharSetLeaf(a, ai)->map;
|
||||||
FcChar32 *bm = FcCharSetGetLeaf(b, bi)->map;
|
FcChar32 *bm = FcCharSetLeaf(b, bi)->map;
|
||||||
|
|
||||||
if (am != bm)
|
if (am != bm)
|
||||||
{
|
{
|
||||||
|
@ -701,7 +651,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
||||||
while (low <= high)
|
while (low <= high)
|
||||||
{
|
{
|
||||||
int mid = (low + high) >> 1;
|
int mid = (low + high) >> 1;
|
||||||
bn = FcCharSetGetNumbers(b)[mid];
|
bn = FcCharSetNumbers(b)[mid];
|
||||||
if (bn == an)
|
if (bn == an)
|
||||||
{
|
{
|
||||||
high = mid;
|
high = mid;
|
||||||
|
@ -713,7 +663,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
||||||
high = mid - 1;
|
high = mid - 1;
|
||||||
}
|
}
|
||||||
bi = high;
|
bi = high;
|
||||||
while (bi < b->num && FcCharSetGetNumbers(b)[bi] < an)
|
while (bi < b->num && FcCharSetNumbers(b)[bi] < an)
|
||||||
bi++;
|
bi++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1021,10 +971,10 @@ FcCharSetHash (FcCharSet *fcs)
|
||||||
|
|
||||||
/* hash in leaves */
|
/* hash in leaves */
|
||||||
for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++)
|
for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++)
|
||||||
hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map);
|
hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetLeaf(fcs, i)->map);
|
||||||
/* hash in numbers */
|
/* hash in numbers */
|
||||||
for (i = 0; i < fcs->num; i++)
|
for (i = 0; i < fcs->num; i++)
|
||||||
hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetGetNumbers(fcs);
|
hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetNumbers(fcs);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,6 +991,7 @@ FcCharSetFreezeBase (FcCharSet *fcs)
|
||||||
FcCharSetEnt **bucket = &FcCharSetHashTable[hash % FC_CHAR_SET_HASH_SIZE];
|
FcCharSetEnt **bucket = &FcCharSetHashTable[hash % FC_CHAR_SET_HASH_SIZE];
|
||||||
FcCharSetEnt *ent;
|
FcCharSetEnt *ent;
|
||||||
int size;
|
int size;
|
||||||
|
int i;
|
||||||
|
|
||||||
FcCharSetTotal++;
|
FcCharSetTotal++;
|
||||||
FcCharSetTotalEnts += fcs->num;
|
FcCharSetTotalEnts += fcs->num;
|
||||||
|
@ -1048,15 +999,15 @@ FcCharSetFreezeBase (FcCharSet *fcs)
|
||||||
{
|
{
|
||||||
if (ent->hash == hash &&
|
if (ent->hash == hash &&
|
||||||
ent->set.num == fcs->num &&
|
ent->set.num == fcs->num &&
|
||||||
!memcmp (FcCharSetGetNumbers(&ent->set),
|
!memcmp (FcCharSetNumbers(&ent->set),
|
||||||
FcCharSetGetNumbers(fcs),
|
FcCharSetNumbers(fcs),
|
||||||
fcs->num * sizeof (FcChar16)))
|
fcs->num * sizeof (FcChar16)))
|
||||||
{
|
{
|
||||||
FcBool ok = FcTrue;
|
FcBool ok = FcTrue;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < fcs->num; i++)
|
for (i = 0; i < fcs->num; i++)
|
||||||
if (FcCharSetGetLeaf(&ent->set, i) != FcCharSetGetLeaf(fcs, i))
|
if (FcCharSetLeaf(&ent->set, i) != FcCharSetLeaf(fcs, i))
|
||||||
ok = FcFalse;
|
ok = FcFalse;
|
||||||
if (ok)
|
if (ok)
|
||||||
return &ent->set;
|
return &ent->set;
|
||||||
|
@ -1075,26 +1026,26 @@ FcCharSetFreezeBase (FcCharSet *fcs)
|
||||||
|
|
||||||
ent->set.ref = FC_REF_CONSTANT;
|
ent->set.ref = FC_REF_CONSTANT;
|
||||||
ent->set.num = fcs->num;
|
ent->set.num = fcs->num;
|
||||||
ent->set.bank = fcs->bank;
|
|
||||||
if (fcs->bank == FC_BANK_DYNAMIC)
|
|
||||||
{
|
|
||||||
if (fcs->num)
|
if (fcs->num)
|
||||||
{
|
{
|
||||||
ent->set.u.dyn.leaves = (FcCharLeaf **) (ent + 1);
|
intptr_t *ent_leaves;
|
||||||
ent->set.u.dyn.numbers = (FcChar16 *) (ent->set.u.dyn.leaves + fcs->num);
|
|
||||||
memcpy (ent->set.u.dyn.leaves, fcs->u.dyn.leaves, fcs->num * sizeof (FcCharLeaf *));
|
ent->set.leaves_offset = sizeof (ent->set);
|
||||||
memcpy (ent->set.u.dyn.numbers, fcs->u.dyn.numbers, fcs->num * sizeof (FcChar16));
|
ent->set.numbers_offset = (ent->set.leaves_offset +
|
||||||
|
fcs->num * sizeof (intptr_t));
|
||||||
|
|
||||||
|
ent_leaves = FcCharSetLeaves (&ent->set);
|
||||||
|
for (i = 0; i < fcs->num; i++)
|
||||||
|
ent_leaves[i] = FcPtrToOffset (ent_leaves,
|
||||||
|
FcCharSetLeaf (fcs, i));
|
||||||
|
memcpy (FcCharSetNumbers (&ent->set),
|
||||||
|
FcCharSetNumbers (fcs),
|
||||||
|
fcs->num * sizeof (FcChar16));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ent->set.u.dyn.leaves = 0;
|
ent->set.leaves_offset = 0;
|
||||||
ent->set.u.dyn.numbers = 0;
|
ent->set.numbers_offset = 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ent->set.u.stat.leafidx_offset = fcs->u.stat.leafidx_offset;
|
|
||||||
ent->set.u.stat.numbers_offset = fcs->u.stat.numbers_offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ent->hash = hash;
|
ent->hash = hash;
|
||||||
|
@ -1140,26 +1091,23 @@ FcCharSetFreeze (FcCharSet *fcs)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
for (i = 0; i < fcs->num; i++)
|
for (i = 0; i < fcs->num; i++)
|
||||||
{
|
{
|
||||||
l = FcCharSetFreezeLeaf (FcCharSetGetLeaf(fcs, i));
|
l = FcCharSetFreezeLeaf (FcCharSetLeaf(fcs, i));
|
||||||
if (!l)
|
if (!l)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
if (!FcCharSetInsertLeaf (b, FcCharSetGetNumbers(fcs)[i] << 8, l))
|
if (!FcCharSetInsertLeaf (b, FcCharSetNumbers(fcs)[i] << 8, l))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
}
|
}
|
||||||
n = FcCharSetFreezeBase (b);
|
n = FcCharSetFreezeBase (b);
|
||||||
bail1:
|
bail1:
|
||||||
if (b->bank == FC_BANK_DYNAMIC)
|
if (FcCharSetLeaves (b))
|
||||||
{
|
|
||||||
if (b->u.dyn.leaves)
|
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
|
FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
|
||||||
free (b->u.dyn.leaves);
|
free (FcCharSetLeaves (b));
|
||||||
}
|
}
|
||||||
if (b->u.dyn.numbers)
|
if (FcCharSetNumbers (b))
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
|
FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
|
||||||
free (b->u.dyn.numbers);
|
free (FcCharSetNumbers (b));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||||
free (b);
|
free (b);
|
||||||
|
@ -1225,20 +1173,17 @@ FcNameParseCharSet (FcChar8 *string)
|
||||||
#endif
|
#endif
|
||||||
n = FcCharSetFreezeBase (c);
|
n = FcCharSetFreezeBase (c);
|
||||||
bail1:
|
bail1:
|
||||||
if (c->bank == FC_BANK_DYNAMIC)
|
if (FcCharSetLeaves (c))
|
||||||
{
|
|
||||||
if (c->u.dyn.leaves)
|
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
|
FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
|
||||||
free (c->u.dyn.leaves);
|
free (FcCharSetLeaves (c));
|
||||||
}
|
}
|
||||||
if (c->u.dyn.numbers)
|
if (FcCharSetNumbers (c))
|
||||||
{
|
{
|
||||||
FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
|
FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
|
||||||
free (c->u.dyn.numbers);
|
free (FcCharSetNumbers (c));
|
||||||
}
|
}
|
||||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||||
}
|
|
||||||
free (c);
|
free (c);
|
||||||
bail0:
|
bail0:
|
||||||
return n;
|
return n;
|
||||||
|
@ -1317,175 +1262,67 @@ FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c)
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
FcBool
|
||||||
FcCharSetNewBank(void)
|
FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs)
|
||||||
{
|
{
|
||||||
charset_count = 0;
|
intptr_t *leaves = FcCharSetLeaves (cs);
|
||||||
charset_numbers_count = 0;
|
FcChar16 *numbers = FcCharSetNumbers (cs);
|
||||||
charset_leaf_count = 0;
|
|
||||||
charset_leaf_idx_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcCharSetNeededBytes (const FcCharSet *c)
|
|
||||||
{
|
|
||||||
/* yes, there's redundancy */
|
|
||||||
charset_count++;
|
|
||||||
charset_leaf_idx_count += c->num;
|
|
||||||
charset_leaf_count += c->num;
|
|
||||||
charset_numbers_count += c->num;
|
|
||||||
return sizeof (FcCharSet) +
|
|
||||||
sizeof (int) * c->num + /* leaf_idx */
|
|
||||||
sizeof (FcCharLeaf) * c->num + /* leaf */
|
|
||||||
sizeof (FcChar16) * c->num; /* number */
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcCharSetNeededBytesAlign (void)
|
|
||||||
{
|
|
||||||
return fc_alignof (FcCharSet) + fc_alignof (int) +
|
|
||||||
fc_alignof (FcCharLeaf) + fc_alignof (FcChar16);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
int i;
|
||||||
|
|
||||||
cs = realloc(charsets, sizeof(FcCharSet*) * new_count);
|
if (!FcSerializeAlloc (serialize, cs, sizeof (FcCharSet)))
|
||||||
if (!cs) return 0;
|
return FcFalse;
|
||||||
n = realloc(numbers, sizeof(FcChar16*) * new_count);
|
if (!FcSerializeAlloc (serialize, leaves, cs->num * sizeof (intptr_t)))
|
||||||
if (!n) return 0;
|
return FcFalse;
|
||||||
lvs = realloc(leaves, sizeof(FcCharLeaf*) * new_count);
|
if (!FcSerializeAlloc (serialize, numbers, cs->num * sizeof (FcChar16)))
|
||||||
if (!lvs) return 0;
|
return FcFalse;
|
||||||
lvi = realloc(leaf_idx, sizeof(int*) * new_count);
|
for (i = 0; i < cs->num; i++)
|
||||||
if (!lvi) return 0;
|
if (!FcSerializeAlloc (serialize, FcCharSetLeaf(cs, i),
|
||||||
|
sizeof (FcCharLeaf)))
|
||||||
charsets = cs; numbers = n; leaves = lvs; leaf_idx = lvi;
|
return FcFalse;
|
||||||
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;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndex(metadata->bank);
|
|
||||||
if (!FcCharSetEnsureBank(bi))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
block_ptr = ALIGN (block_ptr, FcCharSet);
|
|
||||||
charsets[bi] = (FcCharSet *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof (FcCharSet) * charset_count));
|
|
||||||
block_ptr = ALIGN (block_ptr, FcChar16);
|
|
||||||
numbers[bi] = (FcChar16 *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof(FcChar16) * charset_numbers_count));
|
|
||||||
block_ptr = ALIGN (block_ptr, FcCharLeaf);
|
|
||||||
leaves[bi] = (FcCharLeaf *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof(FcCharLeaf) * charset_leaf_count));
|
|
||||||
block_ptr = ALIGN (block_ptr, int);
|
|
||||||
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 *
|
FcCharSet *
|
||||||
FcCharSetSerialize(int bank, FcCharSet *c)
|
FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
|
||||||
{
|
{
|
||||||
|
FcCharSet *cs_serialized = FcSerializePtr (serialize, cs);
|
||||||
|
intptr_t *leaves, *leaves_serialized;
|
||||||
|
FcChar16 *numbers, *numbers_serialized;
|
||||||
|
FcCharLeaf *leaf, *leaf_serialized;
|
||||||
int i;
|
int i;
|
||||||
FcCharSet new;
|
|
||||||
int bi = FcCacheBankToIndex(bank), cp = charset_ptr;
|
|
||||||
|
|
||||||
new.ref = FC_REF_CONSTANT;
|
if (!cs_serialized)
|
||||||
new.bank = bank;
|
return NULL;
|
||||||
new.u.stat.leafidx_offset = charset_leaf_idx_ptr;
|
|
||||||
new.u.stat.numbers_offset = charset_numbers_ptr;
|
|
||||||
new.num = c->num;
|
|
||||||
|
|
||||||
charsets[bi][charset_ptr++] = new;
|
cs_serialized->ref = FC_REF_CONSTANT;
|
||||||
|
cs_serialized->num = cs->num;
|
||||||
|
|
||||||
for (i = 0; i < c->num; i++)
|
leaves = FcCharSetLeaves (cs);
|
||||||
|
leaves_serialized = FcSerializePtr (serialize, leaves);
|
||||||
|
if (!leaves_serialized)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cs_serialized->leaves_offset = FcPtrToOffset (cs_serialized,
|
||||||
|
leaves_serialized);
|
||||||
|
|
||||||
|
numbers = FcCharSetNumbers (cs);
|
||||||
|
numbers_serialized = FcSerializePtr (serialize, numbers);
|
||||||
|
if (!numbers)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cs_serialized->numbers_offset = FcPtrToOffset (cs_serialized,
|
||||||
|
numbers_serialized);
|
||||||
|
|
||||||
|
for (i = 0; i < cs->num; i++)
|
||||||
{
|
{
|
||||||
leaf_idx[bi][charset_leaf_idx_ptr++] = charset_leaf_ptr;
|
leaf = FcCharSetLeaf (cs, i);
|
||||||
memcpy (&leaves[bi][charset_leaf_ptr++],
|
leaf_serialized = FcSerializePtr (serialize, leaf);
|
||||||
c->u.dyn.leaves[i], sizeof(FcCharLeaf));
|
if (!leaf_serialized)
|
||||||
numbers[bi][charset_numbers_ptr++] = c->u.dyn.numbers[i];
|
return NULL;
|
||||||
|
*leaf_serialized = *leaf;
|
||||||
|
leaves_serialized[i] = FcPtrToOffset (leaves_serialized, leaf);
|
||||||
|
numbers_serialized[i] = numbers[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return &charsets[bi][cp];
|
return cs_serialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
FcCharSetUnserialize (FcCache *metadata, void *block_ptr)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndex(metadata->bank);
|
|
||||||
if (!FcCharSetEnsureBank(bi))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
block_ptr = ALIGN (block_ptr, FcCharSet);
|
|
||||||
charsets[bi] = (FcCharSet *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof (FcCharSet) * metadata->charset_count));
|
|
||||||
block_ptr = ALIGN (block_ptr, FcChar16);
|
|
||||||
numbers[bi] = (FcChar16 *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof(FcChar16) * metadata->charset_numbers_count));
|
|
||||||
block_ptr = ALIGN (block_ptr, FcCharLeaf);
|
|
||||||
leaves[bi] = (FcCharLeaf *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof(FcCharLeaf) * metadata->charset_leaf_count));
|
|
||||||
block_ptr = ALIGN (block_ptr, int);
|
|
||||||
leaf_idx[bi] = (int *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
(sizeof(int) * metadata->charset_leaf_idx_count));
|
|
||||||
|
|
||||||
return block_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcCharLeaf *
|
|
||||||
FcCharSetGetLeaf(const FcCharSet *c, int i)
|
|
||||||
{
|
|
||||||
int bi;
|
|
||||||
if (c->bank == FC_BANK_DYNAMIC)
|
|
||||||
return c->u.dyn.leaves[i];
|
|
||||||
bi = FcCacheBankToIndex(c->bank);
|
|
||||||
|
|
||||||
return &leaves[bi][leaf_idx[bi][c->u.stat.leafidx_offset+i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
FcChar16 *
|
|
||||||
FcCharSetGetNumbers(const FcCharSet *c)
|
|
||||||
{
|
|
||||||
int bi;
|
|
||||||
if (c->bank == FC_BANK_DYNAMIC)
|
|
||||||
return c->u.dyn.numbers;
|
|
||||||
bi = FcCacheBankToIndex(c->bank);
|
|
||||||
|
|
||||||
return &numbers[bi][c->u.stat.numbers_offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
43
src/fcdbg.c
43
src/fcdbg.c
|
@ -49,7 +49,8 @@ FcValuePrint (const FcValue v)
|
||||||
printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
||||||
break;
|
break;
|
||||||
case FcTypeCharSet: /* XXX */
|
case FcTypeCharSet: /* XXX */
|
||||||
printf (" set");
|
printf (" ");
|
||||||
|
FcCharSetPrint (v.u.c);
|
||||||
break;
|
break;
|
||||||
case FcTypeLangSet:
|
case FcTypeLangSet:
|
||||||
printf (" ");
|
printf (" ");
|
||||||
|
@ -64,10 +65,10 @@ FcValuePrint (const FcValue v)
|
||||||
void
|
void
|
||||||
FcValueListPrint (FcValueListPtr l)
|
FcValueListPrint (FcValueListPtr l)
|
||||||
{
|
{
|
||||||
for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
|
for (; l != NULL; l = FcValueListNext(l))
|
||||||
{
|
{
|
||||||
FcValuePrint (FcValueCanonicalize(&FcValueListPtrU(l)->value));
|
FcValuePrint (FcValueCanonicalize(&l->value));
|
||||||
switch (FcValueListPtrU(l)->binding) {
|
switch (l->binding) {
|
||||||
case FcValueBindingWeak:
|
case FcValueBindingWeak:
|
||||||
printf ("(w)");
|
printf ("(w)");
|
||||||
break;
|
break;
|
||||||
|
@ -95,6 +96,22 @@ FcLangSetPrint (const FcLangSet *ls)
|
||||||
FcStrBufDestroy (&buf);
|
FcStrBufDestroy (&buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FcCharSetPrint (const FcCharSet *c)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < c->num; i++)
|
||||||
|
{
|
||||||
|
FcCharLeaf *leaf = FcCharSetLeaf(c, i);
|
||||||
|
|
||||||
|
printf ("%04x:", FcCharSetNumbers(c)[i]);
|
||||||
|
for (j = 0; j < 256/32; j++)
|
||||||
|
printf (" %08x", leaf->map[j]);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FcPatternPrint (const FcPattern *p)
|
FcPatternPrint (const FcPattern *p)
|
||||||
{
|
{
|
||||||
|
@ -109,15 +126,15 @@ FcPatternPrint (const FcPattern *p)
|
||||||
printf ("Pattern has %d elts (size %d)\n", p->num, p->size);
|
printf ("Pattern has %d elts (size %d)\n", p->num, p->size);
|
||||||
for (i = 0; i < p->num; i++)
|
for (i = 0; i < p->num; i++)
|
||||||
{
|
{
|
||||||
e = FcPatternEltU(p->elts) + i;
|
e = &FcPatternElts(p)[i];
|
||||||
printf ("\t%s:", FcObjectPtrU(e->object));
|
printf ("\t%s:", FcObjectName(e->object));
|
||||||
/* so that fc-match properly displays file: foo... */
|
/* so that fc-match properly displays file: foo... */
|
||||||
if (e->object == FcObjectToPtr(FC_FILE))
|
if (e->object == FC_FILE_OBJECT)
|
||||||
{
|
{
|
||||||
FcChar8 * s;
|
FcChar8 * s;
|
||||||
FcPatternGetString (p, FC_FILE, 0, &s);
|
FcPatternObjectGetString (p, FC_FILE_OBJECT, 0, &s);
|
||||||
printf (" \"%s\"", s);
|
printf (" \"%s\"", s);
|
||||||
switch (FcValueListPtrU(e->values)->binding) {
|
switch (FcPatternEltValues(e)->binding) {
|
||||||
case FcValueBindingWeak:
|
case FcValueBindingWeak:
|
||||||
printf ("(w)");
|
printf ("(w)");
|
||||||
break;
|
break;
|
||||||
|
@ -130,7 +147,7 @@ FcPatternPrint (const FcPattern *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FcValueListPrint (e->values);
|
FcValueListPrint (FcPatternEltValues(e));
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
@ -197,7 +214,7 @@ FcExprPrint (const FcExpr *expr)
|
||||||
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
|
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
|
||||||
case FcOpCharSet: printf ("charset\n"); break;
|
case FcOpCharSet: printf ("charset\n"); break;
|
||||||
case FcOpNil: printf ("nil\n"); break;
|
case FcOpNil: printf ("nil\n"); break;
|
||||||
case FcOpField: printf ("%s", expr->u.field); break;
|
case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break;
|
||||||
case FcOpConst: printf ("%s", expr->u.constant); break;
|
case FcOpConst: printf ("%s", expr->u.constant); break;
|
||||||
case FcOpQuest:
|
case FcOpQuest:
|
||||||
FcExprPrint (expr->u.tree.left);
|
FcExprPrint (expr->u.tree.left);
|
||||||
|
@ -307,7 +324,7 @@ FcTestPrint (const FcTest *test)
|
||||||
printf ("not_first ");
|
printf ("not_first ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf ("%s ", test->field);
|
printf ("%s ", FcObjectName (test->object));
|
||||||
FcOpPrint (test->op);
|
FcOpPrint (test->op);
|
||||||
printf (" ");
|
printf (" ");
|
||||||
FcExprPrint (test->expr);
|
FcExprPrint (test->expr);
|
||||||
|
@ -317,7 +334,7 @@ FcTestPrint (const FcTest *test)
|
||||||
void
|
void
|
||||||
FcEditPrint (const FcEdit *edit)
|
FcEditPrint (const FcEdit *edit)
|
||||||
{
|
{
|
||||||
printf ("Edit %s ", edit->field);
|
printf ("Edit %s ", FcObjectName (edit->object));
|
||||||
FcOpPrint (edit->op);
|
FcOpPrint (edit->op);
|
||||||
printf (" ");
|
printf (" ");
|
||||||
FcExprPrint (edit->expr);
|
FcExprPrint (edit->expr);
|
||||||
|
|
|
@ -26,14 +26,14 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *field;
|
FcObject field;
|
||||||
FcBool value;
|
FcBool value;
|
||||||
} FcBoolDefaults[] = {
|
} FcBoolDefaults[] = {
|
||||||
{ FC_HINTING, FcTrue }, /* !FT_LOAD_NO_HINTING */
|
{ FC_HINTING_OBJECT, FcTrue }, /* !FT_LOAD_NO_HINTING */
|
||||||
{ FC_VERTICAL_LAYOUT, FcFalse }, /* FC_LOAD_VERTICAL_LAYOUT */
|
{ FC_VERTICAL_LAYOUT_OBJECT, FcFalse }, /* FC_LOAD_VERTICAL_LAYOUT */
|
||||||
{ FC_AUTOHINT, FcFalse }, /* FC_LOAD_FORCE_AUTOHINT */
|
{ FC_AUTOHINT_OBJECT, FcFalse }, /* FC_LOAD_FORCE_AUTOHINT */
|
||||||
{ FC_GLOBAL_ADVANCE, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
|
{ FC_GLOBAL_ADVANCE_OBJECT, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
|
||||||
{ FC_EMBEDDED_BITMAP, FcTrue }, /* !FC_LOAD_NO_BITMAP */
|
{ FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
|
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
|
||||||
|
@ -105,63 +105,63 @@ FcDefaultSubstitute (FcPattern *pattern)
|
||||||
FcValue v;
|
FcValue v;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (FcPatternGet (pattern, FC_STYLE, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
if (FcPatternGet (pattern, FC_WEIGHT, 0, &v) == FcResultNoMatch )
|
if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch )
|
||||||
{
|
{
|
||||||
FcPatternAddInteger (pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM);
|
FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_MEDIUM);
|
||||||
}
|
}
|
||||||
if (FcPatternGet (pattern, FC_SLANT, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
|
FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FcPatternGet (pattern, FC_WIDTH, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
FcPatternAddInteger (pattern, FC_WIDTH, FC_WIDTH_NORMAL);
|
FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL);
|
||||||
|
|
||||||
for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++)
|
for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++)
|
||||||
if (FcPatternGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
|
||||||
FcPatternAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
|
FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
|
||||||
|
|
||||||
if (FcPatternGet (pattern, FC_PIXEL_SIZE, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
double dpi, size, scale;
|
double dpi, size, scale;
|
||||||
|
|
||||||
if (FcPatternGetDouble (pattern, FC_SIZE, 0, &size) != FcResultMatch)
|
if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
|
||||||
{
|
{
|
||||||
size = 12.0;
|
size = 12.0;
|
||||||
(void) FcPatternDel (pattern, FC_SIZE);
|
(void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
|
||||||
FcPatternAddDouble (pattern, FC_SIZE, size);
|
FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
|
||||||
}
|
}
|
||||||
if (FcPatternGetDouble (pattern, FC_SCALE, 0, &scale) != FcResultMatch)
|
if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
|
||||||
{
|
{
|
||||||
scale = 1.0;
|
scale = 1.0;
|
||||||
(void) FcPatternDel (pattern, FC_SCALE);
|
(void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
|
||||||
FcPatternAddDouble (pattern, FC_SCALE, scale);
|
FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
|
||||||
}
|
}
|
||||||
size *= scale;
|
size *= scale;
|
||||||
if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) != FcResultMatch)
|
if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
|
||||||
{
|
{
|
||||||
dpi = 75.0;
|
dpi = 75.0;
|
||||||
(void) FcPatternDel (pattern, FC_DPI);
|
(void) FcPatternObjectDel (pattern, FC_DPI_OBJECT);
|
||||||
FcPatternAddDouble (pattern, FC_DPI, dpi);
|
FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi);
|
||||||
}
|
}
|
||||||
size *= dpi / 72.0;
|
size *= dpi / 72.0;
|
||||||
FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size);
|
FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FcPatternGet (pattern, FC_LANG, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_LANG_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
FcPatternAddString (pattern, FC_LANG, FcGetDefaultLang ());
|
FcPatternObjectAddString (pattern, FC_LANG_OBJECT, FcGetDefaultLang ());
|
||||||
}
|
}
|
||||||
if (FcPatternGet (pattern, FC_FONTVERSION, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
FcPatternAddInteger (pattern, FC_FONTVERSION, 0x7fffffff);
|
FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
|
if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
|
||||||
{
|
{
|
||||||
FcPatternAddInteger (pattern, FC_HINT_STYLE, FC_HINT_FULL);
|
FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
129
src/fcfs.c
129
src/fcfs.c
|
@ -81,117 +81,52 @@ FcFontSetAdd (FcFontSet *s, FcPattern *font)
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int * fcfs_pat_count;
|
|
||||||
|
|
||||||
void
|
|
||||||
FcFontSetNewBank (void)
|
|
||||||
{
|
|
||||||
FcPatternNewBank();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcFontSetNeededBytes (FcFontSet *s)
|
|
||||||
{
|
|
||||||
int i, c, cum = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < s->nfont; i++)
|
|
||||||
{
|
|
||||||
c = FcPatternNeededBytes(s->fonts[i]);
|
|
||||||
if (c < 0)
|
|
||||||
return c;
|
|
||||||
cum += c;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cum > 0)
|
|
||||||
return cum + sizeof(int) + FcObjectNeededBytes();
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns an overestimate of the number of bytes that
|
|
||||||
* might later get eaten up by padding in the ALIGN macro. */
|
|
||||||
int
|
|
||||||
FcFontSetNeededBytesAlign (void)
|
|
||||||
{
|
|
||||||
return fc_alignof (int) +
|
|
||||||
FcPatternNeededBytesAlign () + FcObjectNeededBytesAlign ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr)
|
|
||||||
{
|
|
||||||
block_ptr = ALIGN (block_ptr, int);
|
|
||||||
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
|
FcBool
|
||||||
FcFontSetSerialize (int bank, FcFontSet * s)
|
FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
FcPattern * p;
|
|
||||||
*fcfs_pat_count = s->nfont;
|
|
||||||
|
|
||||||
|
if (!FcSerializeAlloc (serialize, s, sizeof (FcFontSet)))
|
||||||
|
return FcFalse;
|
||||||
|
if (!FcSerializeAlloc (serialize, s->fonts, s->nfont * sizeof (FcPattern *)))
|
||||||
|
return FcFalse;
|
||||||
for (i = 0; i < s->nfont; i++)
|
for (i = 0; i < s->nfont; i++)
|
||||||
{
|
{
|
||||||
p = FcPatternSerialize (bank, s->fonts[i]);
|
if (!FcPatternSerializeAlloc (serialize, s->fonts[i]))
|
||||||
if (!p) return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
FcObjectSerialize();
|
|
||||||
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcBool
|
FcFontSet *
|
||||||
FcFontSetUnserialize(FcCache * metadata, FcFontSet * s, void * block_ptr)
|
FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s)
|
||||||
{
|
{
|
||||||
int nfont;
|
int i;
|
||||||
int i, n;
|
FcFontSet *s_serialize;
|
||||||
|
FcPattern **fonts_serialize;
|
||||||
|
FcPattern *p_serialize;
|
||||||
|
|
||||||
block_ptr = ALIGN (block_ptr, int);
|
s_serialize = FcSerializePtr (serialize, s);
|
||||||
nfont = *(int *)block_ptr;
|
if (!s_serialize)
|
||||||
block_ptr = (int *)block_ptr + 1;
|
return NULL;
|
||||||
|
*s_serialize = *s;
|
||||||
|
s_serialize->sfont = s_serialize->nfont;
|
||||||
|
|
||||||
/* comparing nfont and metadata.count is a bit like comparing
|
fonts_serialize = FcSerializePtr (serialize, s->fonts);
|
||||||
apples and oranges. Its just for rejecting totally insane
|
if (!fonts_serialize)
|
||||||
nfont values, and for that its good enough */
|
return NULL;
|
||||||
if (nfont > 0 && nfont < metadata->count / sizeof(void*))
|
s_serialize->fonts = FcPtrToEncodedOffset (s_serialize,
|
||||||
|
fonts_serialize, FcPattern *);
|
||||||
|
|
||||||
|
for (i = 0; i < s->nfont; i++)
|
||||||
{
|
{
|
||||||
FcPattern * p = (FcPattern *)block_ptr;
|
p_serialize = FcPatternSerialize (serialize, s->fonts[i]);
|
||||||
|
if (!p_serialize)
|
||||||
if (s->sfont < s->nfont + nfont)
|
return NULL;
|
||||||
{
|
fonts_serialize[i] = FcPtrToEncodedOffset (s_serialize,
|
||||||
int sfont = s->nfont + nfont;
|
p_serialize,
|
||||||
FcPattern ** pp;
|
FcPattern);
|
||||||
pp = realloc (s->fonts, sfont * sizeof (FcPattern));
|
|
||||||
if (!pp)
|
|
||||||
return FcFalse;
|
|
||||||
s->fonts = pp;
|
|
||||||
s->sfont = sfont;
|
|
||||||
}
|
|
||||||
n = s->nfont;
|
|
||||||
s->nfont += nfont;
|
|
||||||
|
|
||||||
/* The following line is a bit counterintuitive. The usual
|
|
||||||
* convention is that FcPatternUnserialize is responsible for
|
|
||||||
* aligning the FcPattern. However, the FontSet also stores
|
|
||||||
* the FcPatterns in its own array, so we need to align here
|
|
||||||
* too. */
|
|
||||||
p = ALIGN(p, FcPattern);
|
|
||||||
for (i = 0; i < nfont; i++)
|
|
||||||
s->fonts[n + i] = p+i;
|
|
||||||
|
|
||||||
block_ptr = FcPatternUnserialize (metadata, block_ptr);
|
|
||||||
block_ptr = FcObjectUnserialize (metadata, block_ptr);
|
|
||||||
return block_ptr != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FcFalse;
|
return s_serialize;
|
||||||
}
|
}
|
||||||
|
|
465
src/fcint.h
465
src/fcint.h
|
@ -74,6 +74,7 @@
|
||||||
#define FC_DBG_SCANV 256
|
#define FC_DBG_SCANV 256
|
||||||
#define FC_DBG_MEMORY 512
|
#define FC_DBG_MEMORY 512
|
||||||
#define FC_DBG_CONFIG 1024
|
#define FC_DBG_CONFIG 1024
|
||||||
|
#define FC_DBG_LANGSET 2048
|
||||||
|
|
||||||
#define FC_MEM_CHARSET 0
|
#define FC_MEM_CHARSET 0
|
||||||
#define FC_MEM_CHARLEAF 1
|
#define FC_MEM_CHARLEAF 1
|
||||||
|
@ -116,44 +117,94 @@ typedef enum _FcValueBinding {
|
||||||
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
|
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
|
||||||
} FcValueBinding;
|
} FcValueBinding;
|
||||||
|
|
||||||
typedef struct _FcValueListPtr {
|
/*
|
||||||
int bank;
|
* Serialized data structures use only offsets instead of pointers
|
||||||
union {
|
* A low bit of 1 indicates an offset.
|
||||||
int stat;
|
*/
|
||||||
struct _FcValueList *dyn;
|
|
||||||
} u;
|
/* Is the provided pointer actually an offset? */
|
||||||
} FcValueListPtr;
|
#define FcIsEncodedOffset(p) ((((intptr_t) (p)) & 1) != 0)
|
||||||
|
|
||||||
|
/* Encode offset in a pointer of type t */
|
||||||
|
#define FcOffsetEncode(o,t) ((t *) ((o) | 1))
|
||||||
|
|
||||||
|
/* Decode a pointer into an offset */
|
||||||
|
#define FcOffsetDecode(p) (((intptr_t) (p)) & ~1)
|
||||||
|
|
||||||
|
/* Compute pointer offset */
|
||||||
|
#define FcPtrToOffset(b,p) ((intptr_t) (p) - (intptr_t) (b))
|
||||||
|
|
||||||
|
/* Given base address, offset and type, return a pointer */
|
||||||
|
#define FcOffsetToPtr(b,o,t) ((t *) ((intptr_t) (b) + (o)))
|
||||||
|
|
||||||
|
/* Given base address, encoded offset and type, return a pointer */
|
||||||
|
#define FcEncodedOffsetToPtr(b,p,t) FcOffsetToPtr(b,FcOffsetDecode(p),t)
|
||||||
|
|
||||||
|
/* Given base address, pointer and type, return an encoded offset */
|
||||||
|
#define FcPtrToEncodedOffset(b,p,t) FcOffsetEncode(FcPtrToOffset(b,p),t)
|
||||||
|
|
||||||
|
/* Given a structure, offset member and type, return pointer */
|
||||||
|
#define FcOffsetMember(s,m,t) FcOffsetToPtr(s,(s)->m,t)
|
||||||
|
|
||||||
|
/* Given a structure, encoded offset member and type, return pointer to member */
|
||||||
|
#define FcEncodedOffsetMember(s,m,t) FcOffsetToPtr(s,FcOffsetDecode((s)->m), t)
|
||||||
|
|
||||||
|
/* Given a structure, member and type, convert the member to a pointer */
|
||||||
|
#define FcPointerMember(s,m,t) (FcIsEncodedOffset((s)->m) ? \
|
||||||
|
FcEncodedOffsetMember (s,m,t) : \
|
||||||
|
(s)->m)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serialized values may hold strings, charsets and langsets as pointers,
|
||||||
|
* unfortunately FcValue is an exposed type so we can't just always use
|
||||||
|
* offsets
|
||||||
|
*/
|
||||||
|
#define FcValueString(v) FcPointerMember(v,u.s,FcChar8)
|
||||||
|
#define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet)
|
||||||
|
#define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet)
|
||||||
|
|
||||||
|
typedef struct _FcValueList *FcValueListPtr;
|
||||||
|
|
||||||
typedef struct _FcValueList {
|
typedef struct _FcValueList {
|
||||||
FcValueListPtr next;
|
struct _FcValueList *next;
|
||||||
|
|
||||||
FcValue value;
|
FcValue value;
|
||||||
FcValueBinding binding;
|
FcValueBinding binding;
|
||||||
} FcValueList;
|
} FcValueList;
|
||||||
|
|
||||||
typedef int FcObjectPtr;
|
#define FcValueListNext(vl) FcPointerMember(vl,next,FcValueList)
|
||||||
|
|
||||||
typedef struct _FcPatternEltPtr {
|
typedef int FcObject;
|
||||||
int bank;
|
|
||||||
union {
|
|
||||||
int stat;
|
|
||||||
struct _FcPatternElt *dyn;
|
|
||||||
} u;
|
|
||||||
} FcPatternEltPtr;
|
|
||||||
|
|
||||||
|
typedef struct _FcPatternElt *FcPatternEltPtr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pattern elts are stuck in a structure connected to the pattern,
|
||||||
|
* so they get moved around when the pattern is resized. Hence, the
|
||||||
|
* values field must be a pointer/offset instead of just an offset
|
||||||
|
*/
|
||||||
typedef struct _FcPatternElt {
|
typedef struct _FcPatternElt {
|
||||||
FcObjectPtr object;
|
FcObject object;
|
||||||
FcValueListPtr values;
|
FcValueList *values;
|
||||||
} FcPatternElt;
|
} FcPatternElt;
|
||||||
|
|
||||||
|
#define FcPatternEltValues(pe) FcPointerMember(pe,values,FcValueList)
|
||||||
|
|
||||||
struct _FcPattern {
|
struct _FcPattern {
|
||||||
int num;
|
int num;
|
||||||
int size;
|
int size;
|
||||||
FcPatternEltPtr elts;
|
intptr_t elts_offset;
|
||||||
int ref;
|
int ref;
|
||||||
int bank;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt)
|
||||||
|
|
||||||
|
#define FcFontSetFonts(fs) FcPointerMember(fs,fonts,FcPattern *)
|
||||||
|
/*
|
||||||
|
#define FcFontSetFont(fs,i) (FcIsEncodedOffset((fs)->fonts) ? \
|
||||||
|
FcOffsetToPtr(FcFontSetFonts(fs), \
|
||||||
|
FcFontSetFonts(fs)[i]) : \
|
||||||
|
fs->fonts[i])*/
|
||||||
|
|
||||||
typedef enum _FcOp {
|
typedef enum _FcOp {
|
||||||
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
|
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
|
||||||
FcOpNil,
|
FcOpNil,
|
||||||
|
@ -178,7 +229,7 @@ typedef struct _FcExpr {
|
||||||
FcMatrix *mval;
|
FcMatrix *mval;
|
||||||
FcBool bval;
|
FcBool bval;
|
||||||
FcCharSet *cval;
|
FcCharSet *cval;
|
||||||
char *field;
|
FcObject object;
|
||||||
FcChar8 *constant;
|
FcChar8 *constant;
|
||||||
struct {
|
struct {
|
||||||
struct _FcExpr *left, *right;
|
struct _FcExpr *left, *right;
|
||||||
|
@ -196,14 +247,14 @@ typedef struct _FcTest {
|
||||||
struct _FcTest *next;
|
struct _FcTest *next;
|
||||||
FcMatchKind kind;
|
FcMatchKind kind;
|
||||||
FcQual qual;
|
FcQual qual;
|
||||||
const char *field;
|
FcObject object;
|
||||||
FcOp op;
|
FcOp op;
|
||||||
FcExpr *expr;
|
FcExpr *expr;
|
||||||
} FcTest;
|
} FcTest;
|
||||||
|
|
||||||
typedef struct _FcEdit {
|
typedef struct _FcEdit {
|
||||||
struct _FcEdit *next;
|
struct _FcEdit *next;
|
||||||
const char *field;
|
FcObject object;
|
||||||
FcOp op;
|
FcOp op;
|
||||||
FcExpr *expr;
|
FcExpr *expr;
|
||||||
FcValueBinding binding;
|
FcValueBinding binding;
|
||||||
|
@ -224,19 +275,16 @@ typedef struct _FcCharLeaf {
|
||||||
struct _FcCharSet {
|
struct _FcCharSet {
|
||||||
int ref; /* reference count */
|
int ref; /* reference count */
|
||||||
int num; /* size of leaves and numbers arrays */
|
int num; /* size of leaves and numbers arrays */
|
||||||
int bank;
|
intptr_t leaves_offset;
|
||||||
union {
|
intptr_t numbers_offset;
|
||||||
struct {
|
|
||||||
int leafidx_offset;
|
|
||||||
int numbers_offset;
|
|
||||||
} stat;
|
|
||||||
struct {
|
|
||||||
FcCharLeaf **leaves;
|
|
||||||
FcChar16 *numbers;
|
|
||||||
} dyn;
|
|
||||||
} u;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FcCharSetLeaves(c) FcOffsetMember(c,leaves_offset,intptr_t)
|
||||||
|
#define FcCharSetLeaf(c,i) (FcOffsetToPtr(FcCharSetLeaves(c), \
|
||||||
|
FcCharSetLeaves(c)[i], \
|
||||||
|
FcCharLeaf))
|
||||||
|
#define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16)
|
||||||
|
|
||||||
struct _FcStrSet {
|
struct _FcStrSet {
|
||||||
int ref; /* reference count */
|
int ref; /* reference count */
|
||||||
int num;
|
int num;
|
||||||
|
@ -259,21 +307,35 @@ typedef struct _FcStrBuf {
|
||||||
|
|
||||||
typedef struct _FcCache {
|
typedef struct _FcCache {
|
||||||
int magic; /* FC_CACHE_MAGIC */
|
int magic; /* FC_CACHE_MAGIC */
|
||||||
int subdirs; /* number of subdir strings */
|
off_t size; /* size of file */
|
||||||
off_t pos; /* position of data block in file */
|
intptr_t dir; /* offset to dir name */
|
||||||
off_t count; /* number of bytes of data in block */
|
intptr_t dirs; /* offset to subdirs */
|
||||||
int bank; /* bank ID */
|
int dirs_count; /* number of subdir strings */
|
||||||
int pattern_count; /* number of FcPatterns */
|
intptr_t set; /* offset to font set */
|
||||||
int patternelt_count; /* number of FcPatternElts */
|
|
||||||
int valuelist_count; /* number of FcValueLists */
|
|
||||||
int str_count; /* size of strings appearing as FcValues */
|
|
||||||
int langset_count; /* number of FcLangSets */
|
|
||||||
int charset_count; /* number of FcCharSets */
|
|
||||||
int charset_numbers_count;
|
|
||||||
int charset_leaf_count;
|
|
||||||
int charset_leaf_idx_count;
|
|
||||||
} FcCache;
|
} FcCache;
|
||||||
|
|
||||||
|
#define FcCacheDir(c) FcOffsetMember(c,dir,FcChar8)
|
||||||
|
#define FcCacheDirs(c) FcOffsetMember(c,dirs,intptr_t)
|
||||||
|
#define FcCacheSet(c) FcOffsetMember(c,set,FcFontSet)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used while constructing a directory cache object
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FC_SERIALIZE_HASH_SIZE 8191
|
||||||
|
|
||||||
|
typedef struct _FcSerializeBucket {
|
||||||
|
struct _FcSerializeBucket *next;
|
||||||
|
const void *object;
|
||||||
|
intptr_t offset;
|
||||||
|
} FcSerializeBucket;
|
||||||
|
|
||||||
|
typedef struct _FcSerialize {
|
||||||
|
intptr_t size;
|
||||||
|
void *linear;
|
||||||
|
FcSerializeBucket *buckets[FC_SERIALIZE_HASH_SIZE];
|
||||||
|
} FcSerialize;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
@ -317,15 +379,17 @@ typedef struct _FcCaseFold {
|
||||||
|
|
||||||
#define FC_MAX_FILE_LEN 4096
|
#define FC_MAX_FILE_LEN 4096
|
||||||
|
|
||||||
#define FC_STORAGE_STATIC 0x80
|
/* XXX remove these when we're ready */
|
||||||
#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_string(v) FcValueString(v)
|
||||||
#define fc_value_langset(v) (((v)->type & FC_STORAGE_STATIC) ? (const FcLangSet *)(((char *) v) + (v)->u.l_off) : (v) -> u.l)
|
#define fc_value_charset(v) FcValueCharSet(v)
|
||||||
#define fc_storage_type(v) ((v)->type & ~FC_STORAGE_STATIC)
|
#define fc_value_langset(v) FcValueLangSet(v)
|
||||||
|
#define fc_storage_type(v) ((v)->type)
|
||||||
|
|
||||||
#define fc_alignof(type) offsetof (struct { char c; type member; }, member)
|
#define fc_alignof(type) offsetof (struct { char c; type member; }, member)
|
||||||
|
|
||||||
#define FC_CACHE_MAGIC 0xFC02FC04
|
#define FC_CACHE_MAGIC 0xFC02FC04
|
||||||
|
#define FC_CACHE_MAGIC_COPY 0xFC02FC05
|
||||||
|
|
||||||
struct _FcAtomic {
|
struct _FcAtomic {
|
||||||
FcChar8 *file; /* original file name */
|
FcChar8 *file; /* original file name */
|
||||||
|
@ -429,19 +493,6 @@ FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs,
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
|
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
|
||||||
|
|
||||||
extern int *_fcBankId, *_fcBankIdx;
|
|
||||||
int
|
|
||||||
FcCacheBankToIndexMTF (int bank);
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
FcCacheBankToIndex (int bank)
|
|
||||||
{
|
|
||||||
return (_fcBankId[*_fcBankIdx] == bank) ? *_fcBankIdx : FcCacheBankToIndexMTF(bank);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
FcCacheFindBankDir (int bank);
|
|
||||||
|
|
||||||
/* fccfg.c */
|
/* fccfg.c */
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -512,6 +563,33 @@ FcConfigAcceptFont (FcConfig *config,
|
||||||
FcFileTime
|
FcFileTime
|
||||||
FcConfigModifiedTime (FcConfig *config);
|
FcConfigModifiedTime (FcConfig *config);
|
||||||
|
|
||||||
|
intptr_t
|
||||||
|
FcAlignSize (intptr_t size);
|
||||||
|
|
||||||
|
FcSerialize *
|
||||||
|
FcSerializeCreate (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
FcSerializeDestroy (FcSerialize *serialize);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcSerializeAlloc (FcSerialize *serialize, const void *object, int size);
|
||||||
|
|
||||||
|
intptr_t
|
||||||
|
FcSerializeReserve (FcSerialize *serialize, int size);
|
||||||
|
|
||||||
|
intptr_t
|
||||||
|
FcSerializeOffset (FcSerialize *serialize, const void *object);
|
||||||
|
|
||||||
|
void *
|
||||||
|
FcSerializePtr (FcSerialize *serialize, const void *object);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l);
|
||||||
|
|
||||||
|
FcLangSet *
|
||||||
|
FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l);
|
||||||
|
|
||||||
/* fccharset.c */
|
/* fccharset.c */
|
||||||
void
|
void
|
||||||
FcLangCharSetPopulate (void);
|
FcLangCharSetPopulate (void);
|
||||||
|
@ -531,27 +609,11 @@ FcNameParseCharSet (FcChar8 *string);
|
||||||
FcCharLeaf *
|
FcCharLeaf *
|
||||||
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
|
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
|
||||||
|
|
||||||
void
|
FcBool
|
||||||
FcCharSetNewBank (void);
|
FcCharSetSerializeAlloc(FcSerialize *serialize, const FcCharSet *cs);
|
||||||
|
|
||||||
int
|
|
||||||
FcCharSetNeededBytes (const FcCharSet *c);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcCharSetNeededBytesAlign (void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcCharSetDistributeBytes (FcCache * metadata,
|
|
||||||
void * block_ptr);
|
|
||||||
|
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcCharSetSerialize(int bank, FcCharSet *c);
|
FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs);
|
||||||
|
|
||||||
void *
|
|
||||||
FcCharSetUnserialize (FcCache * metadata, void *block_ptr);
|
|
||||||
|
|
||||||
FcCharLeaf *
|
|
||||||
FcCharSetGetLeaf(const FcCharSet *c, int i);
|
|
||||||
|
|
||||||
FcChar16 *
|
FcChar16 *
|
||||||
FcCharSetGetNumbers(const FcCharSet *c);
|
FcCharSetGetNumbers(const FcCharSet *c);
|
||||||
|
@ -578,6 +640,9 @@ FcEditPrint (const FcEdit *edit);
|
||||||
void
|
void
|
||||||
FcSubstPrint (const FcSubst *subst);
|
FcSubstPrint (const FcSubst *subst);
|
||||||
|
|
||||||
|
void
|
||||||
|
FcCharSetPrint (const FcCharSet *c);
|
||||||
|
|
||||||
extern int FcDebugVal;
|
extern int FcDebugVal;
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -633,23 +698,11 @@ FcFreeTypeGetPrivateMap (FT_Encoding encoding);
|
||||||
|
|
||||||
/* fcfs.c */
|
/* fcfs.c */
|
||||||
|
|
||||||
void
|
|
||||||
FcFontSetNewBank (void);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcFontSetNeededBytes (FcFontSet *s);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcFontSetNeededBytesAlign (void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcFontSetDistributeBytes (FcCache * metadata, void * block_ptr);
|
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcFontSetSerialize (int bank, FcFontSet * s);
|
FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s);
|
||||||
|
|
||||||
FcBool
|
FcFontSet *
|
||||||
FcFontSetUnserialize(FcCache * metadata, FcFontSet * s, void * block_ptr);
|
FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s);
|
||||||
|
|
||||||
/* fcgram.y */
|
/* fcgram.y */
|
||||||
int
|
int
|
||||||
|
@ -731,25 +784,6 @@ FcNameParseLangSet (const FcChar8 *string);
|
||||||
FcBool
|
FcBool
|
||||||
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
|
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
|
||||||
|
|
||||||
void
|
|
||||||
FcLangSetNewBank (void);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcLangSetNeededBytes (const FcLangSet *l);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcLangSetNeededBytesAlign (void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcLangSetDistributeBytes (FcCache * metadata,
|
|
||||||
void * block_ptr);
|
|
||||||
|
|
||||||
FcLangSet *
|
|
||||||
FcLangSetSerialize (int bank, FcLangSet *l);
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcLangSetUnserialize (FcCache * metadata, void *block_ptr);
|
|
||||||
|
|
||||||
/* fclist.c */
|
/* fclist.c */
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -760,36 +794,64 @@ FcListPatternMatchAny (const FcPattern *p,
|
||||||
|
|
||||||
/* fcname.c */
|
/* fcname.c */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE -- this ordering is part of the cache file format.
|
||||||
|
* It must also match the ordering in fcname.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FC_FAMILY_OBJECT 1
|
||||||
|
#define FC_FAMILYLANG_OBJECT 2
|
||||||
|
#define FC_STYLE_OBJECT 3
|
||||||
|
#define FC_STYLELANG_OBJECT 4
|
||||||
|
#define FC_FULLNAME_OBJECT 5
|
||||||
|
#define FC_FULLNAMELANG_OBJECT 6
|
||||||
|
#define FC_SLANT_OBJECT 7
|
||||||
|
#define FC_WEIGHT_OBJECT 8
|
||||||
|
#define FC_WIDTH_OBJECT 9
|
||||||
|
#define FC_SIZE_OBJECT 10
|
||||||
|
#define FC_ASPECT_OBJECT 11
|
||||||
|
#define FC_PIXEL_SIZE_OBJECT 12
|
||||||
|
#define FC_SPACING_OBJECT 13
|
||||||
|
#define FC_FOUNDRY_OBJECT 14
|
||||||
|
#define FC_ANTIALIAS_OBJECT 15
|
||||||
|
#define FC_HINT_STYLE_OBJECT 16
|
||||||
|
#define FC_HINTING_OBJECT 17
|
||||||
|
#define FC_VERTICAL_LAYOUT_OBJECT 18
|
||||||
|
#define FC_AUTOHINT_OBJECT 19
|
||||||
|
#define FC_GLOBAL_ADVANCE_OBJECT 20
|
||||||
|
#define FC_FILE_OBJECT 21
|
||||||
|
#define FC_INDEX_OBJECT 22
|
||||||
|
#define FC_RASTERIZER_OBJECT 23
|
||||||
|
#define FC_OUTLINE_OBJECT 24
|
||||||
|
#define FC_SCALABLE_OBJECT 25
|
||||||
|
#define FC_DPI_OBJECT 26
|
||||||
|
#define FC_RGBA_OBJECT 27
|
||||||
|
#define FC_SCALE_OBJECT 28
|
||||||
|
#define FC_MINSPACE_OBJECT 29
|
||||||
|
#define FC_CHAR_WIDTH_OBJECT 30
|
||||||
|
#define FC_CHAR_HEIGHT_OBJECT 31
|
||||||
|
#define FC_MATRIX_OBJECT 32
|
||||||
|
#define FC_CHARSET_OBJECT 33
|
||||||
|
#define FC_LANG_OBJECT 34
|
||||||
|
#define FC_FONTVERSION_OBJECT 35
|
||||||
|
#define FC_CAPABILITY_OBJECT 36
|
||||||
|
#define FC_FONTFORMAT_OBJECT 37
|
||||||
|
#define FC_EMBOLDEN_OBJECT 38
|
||||||
|
#define FC_EMBEDDED_BITMAP_OBJECT 39
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcNameBool (const FcChar8 *v, FcBool *result);
|
FcNameBool (const FcChar8 *v, FcBool *result);
|
||||||
|
|
||||||
void *
|
FcBool
|
||||||
FcObjectDistributeBytes (FcCache * metadata,
|
FcObjectValidType (FcObject object, FcType type);
|
||||||
void * block_ptr);
|
|
||||||
|
|
||||||
FcObjectPtr
|
FcObject
|
||||||
FcObjectToPtr (const char * si);
|
FcObjectFromName (const char * name);
|
||||||
|
|
||||||
int
|
|
||||||
FcObjectNeededBytes (void);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcObjectNeededBytesAlign (void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcObjectUnserialize (FcCache * metadata, void *block_ptr);
|
|
||||||
|
|
||||||
void
|
|
||||||
FcObjectSerialize (void);
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
FcObjectPtrU (FcObjectPtr p);
|
FcObjectName (FcObject object);
|
||||||
|
|
||||||
static inline int
|
#define FcObjectCompare(a, b) ((int) a - (int) b)
|
||||||
FcObjectPtrCompare (const FcObjectPtr a, const FcObjectPtr b)
|
|
||||||
{
|
|
||||||
return a - b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FcObjectStaticNameFini (void);
|
FcObjectStaticNameFini (void);
|
||||||
|
@ -803,18 +865,75 @@ void
|
||||||
FcValueListDestroy (FcValueListPtr l);
|
FcValueListDestroy (FcValueListPtr l);
|
||||||
|
|
||||||
FcPatternElt *
|
FcPatternElt *
|
||||||
FcPatternFindElt (const FcPattern *p, const char *object);
|
FcPatternObjectFindElt (const FcPattern *p, FcObject object);
|
||||||
|
|
||||||
FcPatternElt *
|
FcPatternElt *
|
||||||
FcPatternInsertElt (FcPattern *p, const char *object);
|
FcPatternObjectInsertElt (FcPattern *p, FcObject object);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcPatternAddWithBinding (FcPattern *p,
|
FcPatternObjectAddWithBinding (FcPattern *p,
|
||||||
const char *object,
|
FcObject object,
|
||||||
FcValue value,
|
FcValue value,
|
||||||
FcValueBinding binding,
|
FcValueBinding binding,
|
||||||
FcBool append);
|
FcBool append);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAdd (FcPattern *p, FcObject object, FcValue value, FcBool append);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddWeak (FcPattern *p, FcObject object, FcValue value, FcBool append);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectDel (FcPattern *p, FcObject object);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectRemove (FcPattern *p, FcObject object, int id);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddInteger (FcPattern *p, FcObject object, int i);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddDouble (FcPattern *p, FcObject object, double d);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddString (FcPattern *p, FcObject object, const FcChar8 *s);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddMatrix (FcPattern *p, FcObject object, const FcMatrix *s);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddCharSet (FcPattern *p, FcObject object, const FcCharSet *c);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int n, int *i);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetDouble (const FcPattern *p, FcObject object, int n, double *d);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetString (const FcPattern *p, FcObject object, int n, FcChar8 ** s);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetMatrix (const FcPattern *p, FcObject object, int n, FcMatrix **s);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetCharSet (const FcPattern *p, FcObject object, int n, FcCharSet **c);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b);
|
||||||
|
|
||||||
|
FcResult
|
||||||
|
FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls);
|
||||||
|
|
||||||
void
|
void
|
||||||
FcPatternFini (void);
|
FcPatternFini (void);
|
||||||
|
|
||||||
|
@ -827,49 +946,17 @@ FcStrStaticName (const FcChar8 *name);
|
||||||
FcChar32
|
FcChar32
|
||||||
FcStringHash (const FcChar8 *s);
|
FcStringHash (const FcChar8 *s);
|
||||||
|
|
||||||
void
|
FcBool
|
||||||
FcPatternNewBank (void);
|
FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat);
|
||||||
|
|
||||||
int
|
|
||||||
FcPatternNeededBytes (FcPattern *p);
|
|
||||||
|
|
||||||
int
|
|
||||||
FcPatternNeededBytesAlign (void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcPatternDistributeBytes (FcCache * metadata, void * block_ptr);
|
|
||||||
|
|
||||||
/* please don't access these outside of fcpat.c! only visible so that
|
|
||||||
* *PtrU can be inlined. */
|
|
||||||
extern FcValueList ** _fcValueLists;
|
|
||||||
extern FcPatternElt ** _fcPatternElts;
|
|
||||||
|
|
||||||
static inline FcValueList *
|
|
||||||
FcValueListPtrU (FcValueListPtr pi)
|
|
||||||
{
|
|
||||||
if (pi.bank == FC_BANK_DYNAMIC)
|
|
||||||
return pi.u.dyn;
|
|
||||||
|
|
||||||
return &_fcValueLists[FcCacheBankToIndex(pi.bank)][pi.u.stat];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline FcPatternElt *
|
|
||||||
FcPatternEltU (FcPatternEltPtr pei)
|
|
||||||
{
|
|
||||||
if (pei.bank == FC_BANK_DYNAMIC)
|
|
||||||
return pei.u.dyn;
|
|
||||||
|
|
||||||
return &_fcPatternElts[FcCacheBankToIndex(pei.bank)][pei.u.stat];
|
|
||||||
}
|
|
||||||
|
|
||||||
FcValueListPtr
|
|
||||||
FcValueListPtrCreateDynamic(FcValueList * p);
|
|
||||||
|
|
||||||
FcPattern *
|
FcPattern *
|
||||||
FcPatternSerialize (int bank, FcPattern * p);
|
FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat);
|
||||||
|
|
||||||
void *
|
FcBool
|
||||||
FcPatternUnserialize (FcCache * metadata, void *block_ptr);
|
FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat);
|
||||||
|
|
||||||
|
FcValueList *
|
||||||
|
FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat);
|
||||||
|
|
||||||
/* fcrender.c */
|
/* fcrender.c */
|
||||||
|
|
||||||
|
@ -929,4 +1016,10 @@ FcStrHashIgnoreCase (const FcChar8 *s);
|
||||||
FcChar8 *
|
FcChar8 *
|
||||||
FcStrCanonFilename (const FcChar8 *s);
|
FcStrCanonFilename (const FcChar8 *s);
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str);
|
||||||
|
|
||||||
|
FcChar8 *
|
||||||
|
FcStrSerialize (FcSerialize *serialize, const FcChar8 *str);
|
||||||
|
|
||||||
#endif /* _FC_INT_H_ */
|
#endif /* _FC_INT_H_ */
|
||||||
|
|
118
src/fclang.c
118
src/fclang.c
|
@ -44,8 +44,6 @@ struct _FcLangSet {
|
||||||
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
|
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
|
||||||
#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
|
#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
|
||||||
|
|
||||||
static FcBool langsets_populated = FcFalse;
|
|
||||||
|
|
||||||
FcLangSet *
|
FcLangSet *
|
||||||
FcFreeTypeLangSet (const FcCharSet *charset,
|
FcFreeTypeLangSet (const FcCharSet *charset,
|
||||||
const FcChar8 *exclusiveLang)
|
const FcChar8 *exclusiveLang)
|
||||||
|
@ -55,19 +53,26 @@ FcFreeTypeLangSet (const FcCharSet *charset,
|
||||||
const FcCharSet *exclusiveCharset = 0;
|
const FcCharSet *exclusiveCharset = 0;
|
||||||
FcLangSet *ls;
|
FcLangSet *ls;
|
||||||
|
|
||||||
if (!langsets_populated)
|
|
||||||
{
|
|
||||||
FcLangCharSetPopulate ();
|
|
||||||
langsets_populated = FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exclusiveLang)
|
if (exclusiveLang)
|
||||||
exclusiveCharset = FcCharSetForLang (exclusiveLang);
|
exclusiveCharset = FcCharSetForLang (exclusiveLang);
|
||||||
ls = FcLangSetCreate ();
|
ls = FcLangSetCreate ();
|
||||||
if (!ls)
|
if (!ls)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (FcDebug() & FC_DBG_LANGSET)
|
||||||
|
{
|
||||||
|
printf ("font charset\n");
|
||||||
|
FcCharSetPrint (charset);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
for (i = 0; i < NUM_LANG_CHAR_SET; i++)
|
for (i = 0; i < NUM_LANG_CHAR_SET; i++)
|
||||||
{
|
{
|
||||||
|
if (FcDebug() & FC_DBG_LANGSET)
|
||||||
|
{
|
||||||
|
printf ("%s charset\n", fcLangCharSets[i].lang);
|
||||||
|
FcCharSetPrint (&fcLangCharSets[i].charset);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for Han charsets to make fonts
|
* Check for Han charsets to make fonts
|
||||||
* which advertise support for a single language
|
* which advertise support for a single language
|
||||||
|
@ -80,8 +85,8 @@ FcFreeTypeLangSet (const FcCharSet *charset,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < fcLangCharSets[i].charset.num; j++)
|
for (j = 0; j < fcLangCharSets[i].charset.num; j++)
|
||||||
if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) !=
|
if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) !=
|
||||||
FcCharSetGetLeaf(exclusiveCharset, j))
|
FcCharSetLeaf(exclusiveCharset, j))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
|
missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
|
||||||
|
@ -196,12 +201,6 @@ FcCharSetForLang (const FcChar8 *lang)
|
||||||
int i;
|
int i;
|
||||||
int country = -1;
|
int country = -1;
|
||||||
|
|
||||||
if (!langsets_populated)
|
|
||||||
{
|
|
||||||
FcLangCharSetPopulate ();
|
|
||||||
langsets_populated = FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_LANG_CHAR_SET; i++)
|
for (i = 0; i < NUM_LANG_CHAR_SET; i++)
|
||||||
{
|
{
|
||||||
switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
|
switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
|
||||||
|
@ -710,90 +709,21 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcLangSet ** langsets = 0;
|
FcBool
|
||||||
static int langset_bank_count = 0, langset_ptr = 0, langset_count = 0;
|
FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l)
|
||||||
|
|
||||||
void
|
|
||||||
FcLangSetNewBank (void)
|
|
||||||
{
|
{
|
||||||
langset_count = 0;
|
if (!FcSerializeAlloc (serialize, l, sizeof (FcLangSet)))
|
||||||
}
|
|
||||||
|
|
||||||
/* ideally, should only write one copy of any particular FcLangSet */
|
|
||||||
int
|
|
||||||
FcLangSetNeededBytes (const FcLangSet *l)
|
|
||||||
{
|
|
||||||
langset_count++;
|
|
||||||
return sizeof (FcLangSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcLangSetNeededBytesAlign (void)
|
|
||||||
{
|
|
||||||
return fc_alignof (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;
|
return FcFalse;
|
||||||
|
|
||||||
langsets = tt;
|
|
||||||
for (i = langset_bank_count; i < new_count; i++)
|
|
||||||
langsets[i] = 0;
|
|
||||||
langset_bank_count = new_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndex(metadata->bank);
|
|
||||||
if (!FcLangSetEnsureBank(bi))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
block_ptr = ALIGN(block_ptr, FcLangSet);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcLangSet *
|
FcLangSet *
|
||||||
FcLangSetSerialize(int bank, FcLangSet *l)
|
FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l)
|
||||||
{
|
{
|
||||||
int p = langset_ptr, bi = FcCacheBankToIndex(bank);
|
FcLangSet *l_serialize = FcSerializePtr (serialize, l);
|
||||||
|
|
||||||
if (!l) return 0;
|
if (!l_serialize)
|
||||||
|
return NULL;
|
||||||
langsets[bi][langset_ptr] = *l;
|
*l_serialize = *l;
|
||||||
langsets[bi][langset_ptr].extra = 0;
|
return l_serialize;
|
||||||
langset_ptr++;
|
|
||||||
return &langsets[bi][p];
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcLangSetUnserialize (FcCache * metadata, void *block_ptr)
|
|
||||||
{
|
|
||||||
int bi = FcCacheBankToIndex(metadata->bank);
|
|
||||||
if (!FcLangSetEnsureBank(bi))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
FcMemAlloc (FC_MEM_LANGSET, metadata->langset_count * sizeof(FcLangSet));
|
|
||||||
block_ptr = ALIGN(block_ptr, FcLangSet);
|
|
||||||
langsets[bi] = (FcLangSet *)block_ptr;
|
|
||||||
block_ptr = (void *)((char *)block_ptr +
|
|
||||||
metadata->langset_count * sizeof(FcLangSet));
|
|
||||||
return block_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
86
src/fclist.c
86
src/fclist.c
|
@ -130,23 +130,21 @@ FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
|
||||||
{
|
{
|
||||||
FcValueListPtr pat, fnt;
|
FcValueListPtr pat, fnt;
|
||||||
|
|
||||||
for (pat = patOrig; FcValueListPtrU(pat);
|
for (pat = patOrig; pat != NULL; pat = FcValueListNext(pat))
|
||||||
pat = FcValueListPtrU(pat)->next)
|
|
||||||
{
|
{
|
||||||
for (fnt = fntOrig; FcValueListPtrU(fnt);
|
for (fnt = fntOrig; fnt != NULL; fnt = FcValueListNext(fnt))
|
||||||
fnt = FcValueListPtrU(fnt)->next)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* make sure the font 'contains' the pattern.
|
* make sure the font 'contains' the pattern.
|
||||||
* (OpListing is OpContains except for strings
|
* (OpListing is OpContains except for strings
|
||||||
* where it requires an exact match)
|
* where it requires an exact match)
|
||||||
*/
|
*/
|
||||||
if (FcConfigCompareValue (&FcValueListPtrU(fnt)->value,
|
if (FcConfigCompareValue (&fnt->value,
|
||||||
FcOpListing,
|
FcOpListing,
|
||||||
&FcValueListPtrU(pat)->value))
|
&pat->value))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!FcValueListPtrU(fnt))
|
if (fnt == NULL)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
@ -158,26 +156,22 @@ FcListValueListEqual (FcValueListPtr v1orig,
|
||||||
{
|
{
|
||||||
FcValueListPtr v1, v2;
|
FcValueListPtr v1, v2;
|
||||||
|
|
||||||
for (v1 = v1orig; FcValueListPtrU(v1);
|
for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
|
||||||
v1 = FcValueListPtrU(v1)->next)
|
|
||||||
{
|
{
|
||||||
for (v2 = v2orig; FcValueListPtrU(v2);
|
for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
|
||||||
v2 = FcValueListPtrU(v2)->next)
|
if (FcValueEqual (FcValueCanonicalize(&(v1)->value),
|
||||||
if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
|
FcValueCanonicalize(&(v2)->value)))
|
||||||
FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
|
|
||||||
break;
|
break;
|
||||||
if (!FcValueListPtrU(v2))
|
if (v2 == NULL)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
for (v2 = v2orig; FcValueListPtrU(v2);
|
for (v2 = v2orig; v2 != NULL; v2 = FcValueListNext(v2))
|
||||||
v2 = FcValueListPtrU(v2)->next)
|
|
||||||
{
|
{
|
||||||
for (v1 = v1orig; FcValueListPtrU(v1);
|
for (v1 = v1orig; v1 != NULL; v1 = FcValueListNext(v1))
|
||||||
v1 = FcValueListPtrU(v1)->next)
|
if (FcValueEqual (FcValueCanonicalize(&v1->value),
|
||||||
if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
|
FcValueCanonicalize(&v2->value)))
|
||||||
FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
|
|
||||||
break;
|
break;
|
||||||
if (!FcValueListPtrU(v1))
|
if (v1 == NULL)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
@ -193,13 +187,14 @@ FcListPatternEqual (FcPattern *p1,
|
||||||
|
|
||||||
for (i = 0; i < os->nobject; i++)
|
for (i = 0; i < os->nobject; i++)
|
||||||
{
|
{
|
||||||
e1 = FcPatternFindElt (p1, os->objects[i]);
|
e1 = FcPatternObjectFindElt (p1, FcObjectFromName (os->objects[i]));
|
||||||
e2 = FcPatternFindElt (p2, os->objects[i]);
|
e2 = FcPatternObjectFindElt (p2, FcObjectFromName (os->objects[i]));
|
||||||
if (!e1 && !e2)
|
if (!e1 && !e2)
|
||||||
continue;
|
continue;
|
||||||
if (!e1 || !e2)
|
if (!e1 || !e2)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (!FcListValueListEqual (e1->values, e2->values))
|
if (!FcListValueListEqual (FcPatternEltValues(e1),
|
||||||
|
FcPatternEltValues(e2)))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
@ -214,16 +209,15 @@ FcListPatternMatchAny (const FcPattern *p,
|
||||||
const FcPattern *font)
|
const FcPattern *font)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
FcPatternElt *e;
|
|
||||||
|
|
||||||
for (i = 0; i < p->num; i++)
|
for (i = 0; i < p->num; i++)
|
||||||
{
|
{
|
||||||
e = FcPatternFindElt (font,
|
FcPatternElt *pe = &FcPatternElts(p)[i];
|
||||||
FcObjectPtrU((FcPatternEltU(p->elts)+i)->object));
|
FcPatternElt *fe = FcPatternObjectFindElt (font, pe->object);
|
||||||
if (!e)
|
if (!fe)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (!FcListValueListMatchAny ((FcPatternEltU(p->elts)+i)->values, /* pat elts */
|
if (!FcListValueListMatchAny (FcPatternEltValues(pe), /* pat elts */
|
||||||
e->values)) /* font elts */
|
FcPatternEltValues(fe))) /* font elts */
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
@ -272,10 +266,10 @@ FcListValueListHash (FcValueListPtr list)
|
||||||
{
|
{
|
||||||
FcChar32 h = 0;
|
FcChar32 h = 0;
|
||||||
|
|
||||||
while (FcValueListPtrU(list))
|
while (list != NULL)
|
||||||
{
|
{
|
||||||
h = h ^ FcListValueHash (&FcValueListPtrU(list)->value);
|
h = h ^ FcListValueHash (&list->value);
|
||||||
list = FcValueListPtrU(list)->next;
|
list = FcValueListNext(list);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -290,9 +284,9 @@ FcListPatternHash (FcPattern *font,
|
||||||
|
|
||||||
for (n = 0; n < os->nobject; n++)
|
for (n = 0; n < os->nobject; n++)
|
||||||
{
|
{
|
||||||
e = FcPatternFindElt (font, os->objects[n]);
|
e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[n]));
|
||||||
if (e)
|
if (e)
|
||||||
h = h ^ FcListValueListHash (e->values);
|
h = h ^ FcListValueListHash (FcPatternEltValues(e));
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -338,10 +332,10 @@ FcListHashTableCleanup (FcListHashTable *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
FcGetDefaultObjectLangIndex (FcPattern *font, const char *object)
|
FcGetDefaultObjectLangIndex (FcPattern *font, FcObject object)
|
||||||
{
|
{
|
||||||
FcChar8 *lang = FcGetDefaultLang ();
|
FcChar8 *lang = FcGetDefaultLang ();
|
||||||
FcPatternElt *e = FcPatternFindElt (font, object);
|
FcPatternElt *e = FcPatternObjectFindElt (font, object);
|
||||||
FcValueListPtr v;
|
FcValueListPtr v;
|
||||||
FcValue value;
|
FcValue value;
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
|
@ -349,9 +343,9 @@ FcGetDefaultObjectLangIndex (FcPattern *font, const char *object)
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
for (v = e->values, i = 0; FcValueListPtrU(v); v = FcValueListPtrU(v)->next, ++i)
|
for (v = FcPatternEltValues(e), i = 0; v; v = FcValueListNext(v), ++i)
|
||||||
{
|
{
|
||||||
value = FcValueCanonicalize (&FcValueListPtrU (v)->value);
|
value = FcValueCanonicalize (&v->value);
|
||||||
|
|
||||||
if (value.type == FcTypeString)
|
if (value.type == FcTypeString)
|
||||||
{
|
{
|
||||||
|
@ -404,33 +398,33 @@ FcListAppend (FcListHashTable *table,
|
||||||
if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
|
if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
|
||||||
{
|
{
|
||||||
if (familyidx < 0)
|
if (familyidx < 0)
|
||||||
familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG);
|
familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT);
|
||||||
defidx = familyidx;
|
defidx = familyidx;
|
||||||
}
|
}
|
||||||
else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
|
else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
|
||||||
{
|
{
|
||||||
if (fullnameidx < 0)
|
if (fullnameidx < 0)
|
||||||
fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG);
|
fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT);
|
||||||
defidx = fullnameidx;
|
defidx = fullnameidx;
|
||||||
}
|
}
|
||||||
else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
|
else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
|
||||||
{
|
{
|
||||||
if (styleidx < 0)
|
if (styleidx < 0)
|
||||||
styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG);
|
styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT);
|
||||||
defidx = styleidx;
|
defidx = styleidx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
defidx = 0;
|
defidx = 0;
|
||||||
|
|
||||||
e = FcPatternFindElt (font, os->objects[o]);
|
e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o]));
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
for (v = e->values, idx = 0; FcValueListPtrU(v);
|
for (v = FcPatternEltValues(e), idx = 0; v;
|
||||||
v = FcValueListPtrU(v)->next, ++idx)
|
v = FcValueListNext(v), ++idx)
|
||||||
{
|
{
|
||||||
if (!FcPatternAdd (bucket->pattern,
|
if (!FcPatternAdd (bucket->pattern,
|
||||||
os->objects[o],
|
os->objects[o],
|
||||||
FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx))
|
FcValueCanonicalize(&v->value), defidx != idx))
|
||||||
goto bail2;
|
goto bail2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
163
src/fcmatch.c
163
src/fcmatch.c
|
@ -173,8 +173,7 @@ FcCompareSize (FcValue *value1, FcValue *value2)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _FcMatcher {
|
typedef struct _FcMatcher {
|
||||||
const char *object;
|
FcObject object;
|
||||||
FcObjectPtr objectPtr;
|
|
||||||
double (*compare) (FcValue *value1, FcValue *value2);
|
double (*compare) (FcValue *value1, FcValue *value2);
|
||||||
int strong, weak;
|
int strong, weak;
|
||||||
} FcMatcher;
|
} FcMatcher;
|
||||||
|
@ -185,156 +184,111 @@ typedef struct _FcMatcher {
|
||||||
* later values
|
* later values
|
||||||
*/
|
*/
|
||||||
static FcMatcher _FcMatchers [] = {
|
static FcMatcher _FcMatchers [] = {
|
||||||
{ FC_FOUNDRY, 0, FcCompareString, 0, 0 },
|
{ FC_FOUNDRY_OBJECT, FcCompareString, 0, 0 },
|
||||||
#define MATCH_FOUNDRY 0
|
#define MATCH_FOUNDRY 0
|
||||||
#define MATCH_FOUNDRY_INDEX 0
|
#define MATCH_FOUNDRY_INDEX 0
|
||||||
|
|
||||||
{ FC_CHARSET, 0, FcCompareCharSet, 1, 1 },
|
{ FC_CHARSET_OBJECT, FcCompareCharSet, 1, 1 },
|
||||||
#define MATCH_CHARSET 1
|
#define MATCH_CHARSET 1
|
||||||
#define MATCH_CHARSET_INDEX 1
|
#define MATCH_CHARSET_INDEX 1
|
||||||
|
|
||||||
{ FC_FAMILY, 0, FcCompareFamily, 2, 4 },
|
{ FC_FAMILY_OBJECT, FcCompareFamily, 2, 4 },
|
||||||
#define MATCH_FAMILY 2
|
#define MATCH_FAMILY 2
|
||||||
#define MATCH_FAMILY_STRONG_INDEX 2
|
#define MATCH_FAMILY_STRONG_INDEX 2
|
||||||
#define MATCH_FAMILY_WEAK_INDEX 4
|
#define MATCH_FAMILY_WEAK_INDEX 4
|
||||||
|
|
||||||
{ FC_LANG, 0, FcCompareLang, 3, 3 },
|
{ FC_LANG_OBJECT, FcCompareLang, 3, 3 },
|
||||||
#define MATCH_LANG 3
|
#define MATCH_LANG 3
|
||||||
#define MATCH_LANG_INDEX 3
|
#define MATCH_LANG_INDEX 3
|
||||||
|
|
||||||
{ FC_SPACING, 0, FcCompareNumber, 5, 5 },
|
{ FC_SPACING_OBJECT, FcCompareNumber, 5, 5 },
|
||||||
#define MATCH_SPACING 4
|
#define MATCH_SPACING 4
|
||||||
#define MATCH_SPACING_INDEX 5
|
#define MATCH_SPACING_INDEX 5
|
||||||
|
|
||||||
{ FC_PIXEL_SIZE, 0, FcCompareSize, 6, 6 },
|
{ FC_PIXEL_SIZE_OBJECT, FcCompareSize, 6, 6 },
|
||||||
#define MATCH_PIXEL_SIZE 5
|
#define MATCH_PIXEL_SIZE 5
|
||||||
#define MATCH_PIXEL_SIZE_INDEX 6
|
#define MATCH_PIXEL_SIZE_INDEX 6
|
||||||
|
|
||||||
{ FC_STYLE, 0, FcCompareString, 7, 7 },
|
{ FC_STYLE_OBJECT, FcCompareString, 7, 7 },
|
||||||
#define MATCH_STYLE 6
|
#define MATCH_STYLE 6
|
||||||
#define MATCH_STYLE_INDEX 7
|
#define MATCH_STYLE_INDEX 7
|
||||||
|
|
||||||
{ FC_SLANT, 0, FcCompareNumber, 8, 8 },
|
{ FC_SLANT_OBJECT, FcCompareNumber, 8, 8 },
|
||||||
#define MATCH_SLANT 7
|
#define MATCH_SLANT 7
|
||||||
#define MATCH_SLANT_INDEX 8
|
#define MATCH_SLANT_INDEX 8
|
||||||
|
|
||||||
{ FC_WEIGHT, 0, FcCompareNumber, 9, 9 },
|
{ FC_WEIGHT_OBJECT, FcCompareNumber, 9, 9 },
|
||||||
#define MATCH_WEIGHT 8
|
#define MATCH_WEIGHT 8
|
||||||
#define MATCH_WEIGHT_INDEX 9
|
#define MATCH_WEIGHT_INDEX 9
|
||||||
|
|
||||||
{ FC_WIDTH, 0, FcCompareNumber, 10, 10 },
|
{ FC_WIDTH_OBJECT, FcCompareNumber, 10, 10 },
|
||||||
#define MATCH_WIDTH 9
|
#define MATCH_WIDTH 9
|
||||||
#define MATCH_WIDTH_INDEX 10
|
#define MATCH_WIDTH_INDEX 10
|
||||||
|
|
||||||
{ FC_ANTIALIAS, 0, FcCompareBool, 11, 11 },
|
{ FC_ANTIALIAS_OBJECT, FcCompareBool, 11, 11 },
|
||||||
#define MATCH_ANTIALIAS 10
|
#define MATCH_ANTIALIAS 10
|
||||||
#define MATCH_ANTIALIAS_INDEX 11
|
#define MATCH_ANTIALIAS_INDEX 11
|
||||||
|
|
||||||
{ FC_RASTERIZER, 0, FcCompareString, 12, 12 },
|
{ FC_RASTERIZER_OBJECT, FcCompareString, 12, 12 },
|
||||||
#define MATCH_RASTERIZER 11
|
#define MATCH_RASTERIZER 11
|
||||||
#define MATCH_RASTERIZER_INDEX 12
|
#define MATCH_RASTERIZER_INDEX 12
|
||||||
|
|
||||||
{ FC_OUTLINE, 0, FcCompareBool, 13, 13 },
|
{ FC_OUTLINE_OBJECT, FcCompareBool, 13, 13 },
|
||||||
#define MATCH_OUTLINE 12
|
#define MATCH_OUTLINE 12
|
||||||
#define MATCH_OUTLINE_INDEX 13
|
#define MATCH_OUTLINE_INDEX 13
|
||||||
|
|
||||||
{ FC_FONTVERSION, 0, FcCompareNumber, 14, 14 },
|
{ FC_FONTVERSION_OBJECT, FcCompareNumber, 14, 14 },
|
||||||
#define MATCH_FONTVERSION 13
|
#define MATCH_FONTVERSION 13
|
||||||
#define MATCH_FONTVERSION_INDEX 14
|
#define MATCH_FONTVERSION_INDEX 14
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_MATCH_VALUES 15
|
#define NUM_MATCH_VALUES 15
|
||||||
|
|
||||||
static FcBool matchObjectPtrsInit = FcFalse;
|
|
||||||
|
|
||||||
static void
|
|
||||||
FcMatchObjectPtrsInit (void)
|
|
||||||
{
|
|
||||||
_FcMatchers[MATCH_FOUNDRY].objectPtr = FcObjectToPtr(FC_FOUNDRY);
|
|
||||||
_FcMatchers[MATCH_CHARSET].objectPtr = FcObjectToPtr(FC_CHARSET);
|
|
||||||
_FcMatchers[MATCH_FAMILY].objectPtr = FcObjectToPtr(FC_FAMILY);
|
|
||||||
_FcMatchers[MATCH_LANG].objectPtr = FcObjectToPtr(FC_LANG);
|
|
||||||
_FcMatchers[MATCH_SPACING].objectPtr = FcObjectToPtr(FC_SPACING);
|
|
||||||
_FcMatchers[MATCH_PIXEL_SIZE].objectPtr = FcObjectToPtr(FC_PIXEL_SIZE);
|
|
||||||
_FcMatchers[MATCH_STYLE].objectPtr = FcObjectToPtr(FC_STYLE);
|
|
||||||
_FcMatchers[MATCH_SLANT].objectPtr = FcObjectToPtr(FC_SLANT);
|
|
||||||
_FcMatchers[MATCH_WEIGHT].objectPtr = FcObjectToPtr(FC_WEIGHT);
|
|
||||||
_FcMatchers[MATCH_WIDTH].objectPtr = FcObjectToPtr(FC_WIDTH);
|
|
||||||
_FcMatchers[MATCH_ANTIALIAS].objectPtr = FcObjectToPtr(FC_ANTIALIAS);
|
|
||||||
_FcMatchers[MATCH_RASTERIZER].objectPtr = FcObjectToPtr(FC_RASTERIZER);
|
|
||||||
_FcMatchers[MATCH_OUTLINE].objectPtr = FcObjectToPtr(FC_OUTLINE);
|
|
||||||
_FcMatchers[MATCH_FONTVERSION].objectPtr = FcObjectToPtr(FC_FONTVERSION);
|
|
||||||
matchObjectPtrsInit = FcTrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FcMatcher*
|
static FcMatcher*
|
||||||
FcObjectPtrToMatcher (FcObjectPtr o)
|
FcObjectToMatcher (FcObject object)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *object = FcObjectPtrU(o);
|
|
||||||
|
|
||||||
i = -1;
|
i = -1;
|
||||||
switch (object[0]) {
|
switch (object) {
|
||||||
case 'f':
|
case FC_FOUNDRY_OBJECT:
|
||||||
switch (object[1]) {
|
|
||||||
case 'o':
|
|
||||||
switch (object[2]) {
|
|
||||||
case 'u':
|
|
||||||
i = MATCH_FOUNDRY; break;
|
i = MATCH_FOUNDRY; break;
|
||||||
case 'n':
|
case FC_FONTVERSION_OBJECT:
|
||||||
i = MATCH_FONTVERSION; break;
|
i = MATCH_FONTVERSION; break;
|
||||||
}
|
case FC_FAMILY_OBJECT:
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
i = MATCH_FAMILY; break;
|
i = MATCH_FAMILY; break;
|
||||||
}
|
case FC_CHARSET_OBJECT:
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
i = MATCH_CHARSET; break;
|
i = MATCH_CHARSET; break;
|
||||||
case 'a':
|
case FC_ANTIALIAS_OBJECT:
|
||||||
i = MATCH_ANTIALIAS; break;
|
i = MATCH_ANTIALIAS; break;
|
||||||
case 'l':
|
case FC_LANG_OBJECT:
|
||||||
i = MATCH_LANG; break;
|
i = MATCH_LANG; break;
|
||||||
case 's':
|
case FC_SPACING_OBJECT:
|
||||||
switch (object[1]) {
|
|
||||||
case 'p':
|
|
||||||
i = MATCH_SPACING; break;
|
i = MATCH_SPACING; break;
|
||||||
case 't':
|
case FC_STYLE_OBJECT:
|
||||||
i = MATCH_STYLE; break;
|
i = MATCH_STYLE; break;
|
||||||
case 'l':
|
case FC_SLANT_OBJECT:
|
||||||
i = MATCH_SLANT; break;
|
i = MATCH_SLANT; break;
|
||||||
}
|
case FC_PIXEL_SIZE_OBJECT:
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
i = MATCH_PIXEL_SIZE; break;
|
i = MATCH_PIXEL_SIZE; break;
|
||||||
case 'w':
|
case FC_WIDTH_OBJECT:
|
||||||
switch (object[1]) {
|
|
||||||
case 'i':
|
|
||||||
i = MATCH_WIDTH; break;
|
i = MATCH_WIDTH; break;
|
||||||
case 'e':
|
case FC_WEIGHT_OBJECT:
|
||||||
i = MATCH_WEIGHT; break;
|
i = MATCH_WEIGHT; break;
|
||||||
}
|
case FC_RASTERIZER_OBJECT:
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
i = MATCH_RASTERIZER; break;
|
i = MATCH_RASTERIZER; break;
|
||||||
case 'o':
|
case FC_OUTLINE_OBJECT:
|
||||||
i = MATCH_OUTLINE; break;
|
i = MATCH_OUTLINE; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
if (!matchObjectPtrsInit)
|
|
||||||
FcMatchObjectPtrsInit();
|
|
||||||
|
|
||||||
if (o != _FcMatchers[i].objectPtr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return _FcMatchers+i;
|
return _FcMatchers+i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCompareValueList (FcObjectPtr o,
|
FcCompareValueList (FcObject object,
|
||||||
FcValueListPtr v1orig, /* pattern */
|
FcValueListPtr v1orig, /* pattern */
|
||||||
FcValueListPtr v2orig, /* target */
|
FcValueListPtr v2orig, /* target */
|
||||||
FcValue *bestValue,
|
FcValue *bestValue,
|
||||||
|
@ -342,16 +296,14 @@ FcCompareValueList (FcObjectPtr o,
|
||||||
FcResult *result)
|
FcResult *result)
|
||||||
{
|
{
|
||||||
FcValueListPtr v1, v2;
|
FcValueListPtr v1, v2;
|
||||||
FcValueList *v1_ptrU, *v2_ptrU;
|
|
||||||
double v, best, bestStrong, bestWeak;
|
double v, best, bestStrong, bestWeak;
|
||||||
int j;
|
int j;
|
||||||
const char *object = FcObjectPtrU(o);
|
FcMatcher *match = FcObjectToMatcher(object);
|
||||||
FcMatcher *match = FcObjectPtrToMatcher(o);
|
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
{
|
{
|
||||||
if (bestValue)
|
if (bestValue)
|
||||||
*bestValue = FcValueCanonicalize(&FcValueListPtrU(v2orig)->value);
|
*bestValue = FcValueCanonicalize(&v2orig->value);
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,13 +311,11 @@ FcCompareValueList (FcObjectPtr o,
|
||||||
bestStrong = 1e99;
|
bestStrong = 1e99;
|
||||||
bestWeak = 1e99;
|
bestWeak = 1e99;
|
||||||
j = 0;
|
j = 0;
|
||||||
for (v1 = v1orig, v1_ptrU = FcValueListPtrU(v1); v1_ptrU;
|
for (v1 = v1orig; v1; v1 = FcValueListNext(v1))
|
||||||
v1 = v1_ptrU->next, v1_ptrU = FcValueListPtrU(v1))
|
|
||||||
{
|
{
|
||||||
for (v2 = v2orig, v2_ptrU = FcValueListPtrU(v2); v2_ptrU;
|
for (v2 = v1orig; v2; v2 = FcValueListNext(v2))
|
||||||
v2 = v2_ptrU->next, v2_ptrU = FcValueListPtrU(v2))
|
|
||||||
{
|
{
|
||||||
v = (match->compare) (&v1_ptrU->value, &v2_ptrU->value);
|
v = (match->compare) (&v1->value, &v2->value);
|
||||||
if (v < 0)
|
if (v < 0)
|
||||||
{
|
{
|
||||||
*result = FcResultTypeMismatch;
|
*result = FcResultTypeMismatch;
|
||||||
|
@ -375,10 +325,10 @@ FcCompareValueList (FcObjectPtr o,
|
||||||
if (v < best)
|
if (v < best)
|
||||||
{
|
{
|
||||||
if (bestValue)
|
if (bestValue)
|
||||||
*bestValue = FcValueCanonicalize(&v2_ptrU->value);
|
*bestValue = FcValueCanonicalize(&v2->value);
|
||||||
best = v;
|
best = v;
|
||||||
}
|
}
|
||||||
if (v1_ptrU->binding == FcValueBindingStrong)
|
if (v1->binding == FcValueBindingStrong)
|
||||||
{
|
{
|
||||||
if (v < bestStrong)
|
if (v < bestStrong)
|
||||||
bestStrong = v;
|
bestStrong = v;
|
||||||
|
@ -393,7 +343,7 @@ FcCompareValueList (FcObjectPtr o,
|
||||||
}
|
}
|
||||||
if (FcDebug () & FC_DBG_MATCHV)
|
if (FcDebug () & FC_DBG_MATCHV)
|
||||||
{
|
{
|
||||||
printf (" %s: %g ", object, best);
|
printf (" %s: %g ", FcObjectName (object), best);
|
||||||
FcValueListPrint (v1orig);
|
FcValueListPrint (v1orig);
|
||||||
printf (", ");
|
printf (", ");
|
||||||
FcValueListPrint (v2orig);
|
FcValueListPrint (v2orig);
|
||||||
|
@ -434,10 +384,10 @@ FcCompare (FcPattern *pat,
|
||||||
i2 = 0;
|
i2 = 0;
|
||||||
while (i1 < pat->num && i2 < fnt->num)
|
while (i1 < pat->num && i2 < fnt->num)
|
||||||
{
|
{
|
||||||
FcPatternElt *elt_i1 = FcPatternEltU(pat->elts)+i1;
|
FcPatternElt *elt_i1 = &FcPatternElts(pat)[i1];
|
||||||
FcPatternElt *elt_i2 = FcPatternEltU(fnt->elts)+i2;
|
FcPatternElt *elt_i2 = &FcPatternElts(fnt)[i2];
|
||||||
|
|
||||||
i = FcObjectPtrCompare(elt_i1->object, elt_i2->object);
|
i = FcObjectCompare(elt_i1->object, elt_i2->object);
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
i2++;
|
i2++;
|
||||||
else if (i < 0)
|
else if (i < 0)
|
||||||
|
@ -445,7 +395,8 @@ FcCompare (FcPattern *pat,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!FcCompareValueList (elt_i1->object,
|
if (!FcCompareValueList (elt_i1->object,
|
||||||
elt_i1->values, elt_i2->values,
|
FcPatternEltValues(elt_i1),
|
||||||
|
FcPatternEltValues(elt_i2),
|
||||||
0, value, result))
|
0, value, result))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
i1++;
|
i1++;
|
||||||
|
@ -471,28 +422,30 @@ FcFontRenderPrepare (FcConfig *config,
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < font->num; i++)
|
for (i = 0; i < font->num; i++)
|
||||||
{
|
{
|
||||||
fe = FcPatternEltU(font->elts)+i;
|
fe = &FcPatternElts(font)[i];
|
||||||
pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object));
|
pe = FcPatternObjectFindElt (pat, fe->object);
|
||||||
if (pe)
|
if (pe)
|
||||||
{
|
{
|
||||||
if (!FcCompareValueList (pe->object, pe->values,
|
if (!FcCompareValueList (pe->object, FcPatternEltValues(pe),
|
||||||
fe->values, &v, 0, &result))
|
FcPatternEltValues(fe), &v, 0, &result))
|
||||||
{
|
{
|
||||||
FcPatternDestroy (new);
|
FcPatternDestroy (new);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
v = FcValueCanonicalize(&FcValueListPtrU(fe->values)->value);
|
v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
|
||||||
FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
|
FcPatternObjectAdd (new, fe->object, v, FcFalse);
|
||||||
}
|
}
|
||||||
for (i = 0; i < pat->num; i++)
|
for (i = 0; i < pat->num; i++)
|
||||||
{
|
{
|
||||||
pe = FcPatternEltU(pat->elts)+i;
|
pe = &FcPatternElts(pat)[i];
|
||||||
fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
|
fe = FcPatternObjectFindElt (font, pe->object);
|
||||||
if (!fe)
|
if (!fe)
|
||||||
FcPatternAdd (new, FcObjectPtrU(pe->object),
|
{
|
||||||
FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue);
|
v = FcValueCanonicalize(&FcPatternEltValues(pe)->value);
|
||||||
|
FcPatternObjectAdd (new, pe->object, v, FcTrue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
|
FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
|
||||||
|
|
142
src/fcname.c
142
src/fcname.c
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
/* Please do not revoke any of these bindings. */
|
/* Please do not revoke any of these bindings. */
|
||||||
/* The __DUMMY__ object enables callers to distinguish the error return
|
/* The __DUMMY__ object enables callers to distinguish the error return
|
||||||
* of FcObjectToPtrLookup from FC_FAMILY's FcObjectPtr, which would
|
* of FcObjectToPtrLookup from FC_FAMILY's FcObject, which would
|
||||||
* otherwise be 0. */
|
* otherwise be 0. */
|
||||||
static const FcObjectType _FcBaseObjectTypes[] = {
|
static const FcObjectType _FcBaseObjectTypes[] = {
|
||||||
{ "__DUMMY__", FcTypeVoid, },
|
{ "__DUMMY__", FcTypeVoid, },
|
||||||
|
@ -48,14 +48,12 @@ static const FcObjectType _FcBaseObjectTypes[] = {
|
||||||
{ FC_PIXEL_SIZE, FcTypeDouble, },
|
{ FC_PIXEL_SIZE, FcTypeDouble, },
|
||||||
{ FC_SPACING, FcTypeInteger, },
|
{ FC_SPACING, FcTypeInteger, },
|
||||||
{ FC_FOUNDRY, FcTypeString, },
|
{ FC_FOUNDRY, FcTypeString, },
|
||||||
/* { FC_CORE, FcTypeBool, }, */
|
|
||||||
{ FC_ANTIALIAS, FcTypeBool, },
|
{ FC_ANTIALIAS, FcTypeBool, },
|
||||||
{ FC_HINT_STYLE, FcTypeInteger, },
|
{ FC_HINT_STYLE, FcTypeInteger, },
|
||||||
{ FC_HINTING, FcTypeBool, },
|
{ FC_HINTING, FcTypeBool, },
|
||||||
{ FC_VERTICAL_LAYOUT, FcTypeBool, },
|
{ FC_VERTICAL_LAYOUT, FcTypeBool, },
|
||||||
{ FC_AUTOHINT, FcTypeBool, },
|
{ FC_AUTOHINT, FcTypeBool, },
|
||||||
{ FC_GLOBAL_ADVANCE, FcTypeBool, },
|
{ FC_GLOBAL_ADVANCE, FcTypeBool, },
|
||||||
/* { FC_XLFD, FcTypeString, }, */
|
|
||||||
{ FC_FILE, FcTypeString, },
|
{ FC_FILE, FcTypeString, },
|
||||||
{ FC_INDEX, FcTypeInteger, },
|
{ FC_INDEX, FcTypeInteger, },
|
||||||
{ FC_RASTERIZER, FcTypeString, },
|
{ FC_RASTERIZER, FcTypeString, },
|
||||||
|
@ -65,7 +63,6 @@ static const FcObjectType _FcBaseObjectTypes[] = {
|
||||||
{ FC_RGBA, FcTypeInteger, },
|
{ FC_RGBA, FcTypeInteger, },
|
||||||
{ FC_SCALE, FcTypeDouble, },
|
{ FC_SCALE, FcTypeDouble, },
|
||||||
{ FC_MINSPACE, FcTypeBool, },
|
{ FC_MINSPACE, FcTypeBool, },
|
||||||
/* { FC_RENDER, FcTypeBool, },*/
|
|
||||||
{ FC_CHAR_WIDTH, FcTypeInteger },
|
{ FC_CHAR_WIDTH, FcTypeInteger },
|
||||||
{ FC_CHAR_HEIGHT, FcTypeInteger },
|
{ FC_CHAR_HEIGHT, FcTypeInteger },
|
||||||
{ FC_MATRIX, FcTypeMatrix },
|
{ FC_MATRIX, FcTypeMatrix },
|
||||||
|
@ -182,16 +179,13 @@ static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
|
||||||
/* Design constraint: biggest_known_ntypes must never change
|
/* Design constraint: biggest_known_ntypes must never change
|
||||||
* after any call to FcNameRegisterObjectTypes. */
|
* after any call to FcNameRegisterObjectTypes. */
|
||||||
static const FcObjectType *biggest_known_types = _FcBaseObjectTypes;
|
static const FcObjectType *biggest_known_types = _FcBaseObjectTypes;
|
||||||
static FcBool allocated_biggest_known_types;
|
|
||||||
static int biggest_known_ntypes = NUM_OBJECT_TYPES;
|
static int biggest_known_ntypes = NUM_OBJECT_TYPES;
|
||||||
static int biggest_known_count = 0;
|
|
||||||
static char * biggest_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
static FcObjectPtr
|
static FcObject
|
||||||
FcObjectToPtrLookup (const char * object)
|
FcObjectToPtrLookup (const char * object)
|
||||||
{
|
{
|
||||||
FcObjectPtr i = 0, n;
|
FcObject i = 0, n;
|
||||||
const FcObjectTypeList *l;
|
const FcObjectTypeList *l;
|
||||||
FcObjectType *t = _FcUserObjectNames;
|
FcObjectType *t = _FcUserObjectNames;
|
||||||
FcBool replace;
|
FcBool replace;
|
||||||
|
@ -251,8 +245,16 @@ FcObjectToPtrLookup (const char * object)
|
||||||
return -n;
|
return -n;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcObjectPtr
|
FcBool
|
||||||
FcObjectToPtr (const char * name)
|
FcObjectValidType (FcObject object, FcType type)
|
||||||
|
{
|
||||||
|
if (object < NUM_OBJECT_TYPES && _FcBaseObjectTypes[object].type != type)
|
||||||
|
return FcFalse;
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcObject
|
||||||
|
FcObjectFromName (const char * name)
|
||||||
{
|
{
|
||||||
FcChar32 hash = FcStringHash ((const FcChar8 *) name);
|
FcChar32 hash = FcStringHash ((const FcChar8 *) name);
|
||||||
struct objectBucket **p;
|
struct objectBucket **p;
|
||||||
|
@ -299,112 +301,24 @@ FcObjectStaticNameFini (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
FcObjectPtrU (FcObjectPtr si)
|
FcObjectName (FcObject object)
|
||||||
{
|
{
|
||||||
const FcObjectTypeList *l;
|
const FcObjectTypeList *l;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if (si > 0)
|
if (object > 0)
|
||||||
{
|
{
|
||||||
if (si < biggest_known_ntypes)
|
if (object < biggest_known_ntypes)
|
||||||
return biggest_known_types[si].object;
|
return biggest_known_types[object].object;
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for (l = _FcObjectTypes; l; l = l->next)
|
for (l = _FcObjectTypes; l; l = l->next)
|
||||||
for (i = 0; i < l->ntypes; i++, j++)
|
for (i = 0; i < l->ntypes; i++, j++)
|
||||||
if (j == si)
|
if (j == object)
|
||||||
return l->types[i].object;
|
return l->types[i].object;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _FcUserObjectNames[-si].object;
|
return _FcUserObjectNames[-object].object;
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcObjectNeededBytes ()
|
|
||||||
{
|
|
||||||
int num = 0, i;
|
|
||||||
for (i = 0; i < biggest_known_ntypes; i++)
|
|
||||||
{
|
|
||||||
const char * t = biggest_known_types[i].object;
|
|
||||||
num = num + strlen(t) + 1;
|
|
||||||
}
|
|
||||||
biggest_known_count = num;
|
|
||||||
return num + sizeof(int);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
FcObjectNeededBytesAlign (void)
|
|
||||||
{
|
|
||||||
return fc_alignof (int) + fc_alignof (char);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcObjectDistributeBytes (FcCache * metadata, void * block_ptr)
|
|
||||||
{
|
|
||||||
block_ptr = ALIGN (block_ptr, int);
|
|
||||||
*(int *)block_ptr = biggest_known_ntypes;
|
|
||||||
block_ptr = (int *) block_ptr + 1;
|
|
||||||
block_ptr = ALIGN (block_ptr, char);
|
|
||||||
biggest_ptr = block_ptr;
|
|
||||||
block_ptr = (char *) block_ptr + biggest_known_count;
|
|
||||||
return block_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FcObjectSerialize (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < biggest_known_ntypes; i++)
|
|
||||||
{
|
|
||||||
const char * t = biggest_known_types[i].object;
|
|
||||||
strcpy (biggest_ptr, t);
|
|
||||||
biggest_ptr = biggest_ptr + strlen(t) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
FcObjectUnserialize (FcCache * metadata, void *block_ptr)
|
|
||||||
{
|
|
||||||
int new_biggest;
|
|
||||||
block_ptr = ALIGN (block_ptr, int);
|
|
||||||
new_biggest = *(int *)block_ptr;
|
|
||||||
block_ptr = (int *) block_ptr + 1;
|
|
||||||
if (biggest_known_ntypes < new_biggest)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char * bp = (char *)block_ptr;
|
|
||||||
FcObjectType * bn;
|
|
||||||
|
|
||||||
bn = malloc (sizeof (const FcObjectType) * (new_biggest + 1));
|
|
||||||
if (!bn)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < new_biggest; i++)
|
|
||||||
{
|
|
||||||
const FcObjectType * t = FcNameGetObjectType(bp);
|
|
||||||
if (t)
|
|
||||||
bn[i].type = t->type;
|
|
||||||
else
|
|
||||||
bn[i].type = FcTypeVoid;
|
|
||||||
bn[i].object = bp;
|
|
||||||
bp = bp + strlen(bp) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FcNameUnregisterObjectTypesFree (biggest_known_types, biggest_known_ntypes, FcFalse);
|
|
||||||
if (allocated_biggest_known_types)
|
|
||||||
{
|
|
||||||
free ((FcObjectTypeList *)biggest_known_types);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
allocated_biggest_known_types = FcTrue;
|
|
||||||
|
|
||||||
FcNameRegisterObjectTypes (bn, new_biggest);
|
|
||||||
biggest_known_ntypes = new_biggest;
|
|
||||||
biggest_known_types = (const FcObjectType *)bn;
|
|
||||||
}
|
|
||||||
block_ptr = ALIGN (block_ptr, char);
|
|
||||||
block_ptr = (char *) block_ptr + biggest_known_count;
|
|
||||||
return block_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const FcConstant _FcBaseConstants[] = {
|
static const FcConstant _FcBaseConstants[] = {
|
||||||
|
@ -803,11 +717,11 @@ FcNameUnparseValueList (FcStrBuf *buf,
|
||||||
FcValueListPtr v,
|
FcValueListPtr v,
|
||||||
FcChar8 *escape)
|
FcChar8 *escape)
|
||||||
{
|
{
|
||||||
while (FcValueListPtrU(v))
|
while (v)
|
||||||
{
|
{
|
||||||
if (!FcNameUnparseValue (buf, &FcValueListPtrU(v)->value, escape))
|
if (!FcNameUnparseValue (buf, &v->value, escape))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (FcValueListPtrU(v = FcValueListPtrU(v)->next))
|
if ((v = FcValueListNext(v)) != NULL)
|
||||||
if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
|
if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
@ -834,18 +748,18 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
|
||||||
const FcObjectType *o;
|
const FcObjectType *o;
|
||||||
|
|
||||||
FcStrBufInit (&buf, buf_static, sizeof (buf_static));
|
FcStrBufInit (&buf, buf_static, sizeof (buf_static));
|
||||||
e = FcPatternFindElt (pat, FC_FAMILY);
|
e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
if (!FcNameUnparseValueList (&buf, e->values, escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
|
if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
|
||||||
goto bail0;
|
goto bail0;
|
||||||
}
|
}
|
||||||
e = FcPatternFindElt (pat, FC_SIZE);
|
e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
|
if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0))
|
||||||
goto bail0;
|
goto bail0;
|
||||||
if (!FcNameUnparseValueList (&buf, e->values, escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
|
if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
|
||||||
goto bail0;
|
goto bail0;
|
||||||
}
|
}
|
||||||
for (l = _FcObjectTypes; l; l = l->next)
|
for (l = _FcObjectTypes; l; l = l->next)
|
||||||
|
@ -858,7 +772,7 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
|
||||||
!strcmp (o->object, FC_FILE))
|
!strcmp (o->object, FC_FILE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
e = FcPatternFindElt (pat, o->object);
|
e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object));
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
|
if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
|
||||||
|
@ -867,7 +781,7 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
|
if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
|
||||||
goto bail0;
|
goto bail0;
|
||||||
if (!FcNameUnparseValueList (&buf, e->values, escape ?
|
if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ?
|
||||||
(FcChar8 *) FC_ESCAPE_VARIABLE : 0))
|
(FcChar8 *) FC_ESCAPE_VARIABLE : 0))
|
||||||
goto bail0;
|
goto bail0;
|
||||||
}
|
}
|
||||||
|
|
985
src/fcpat.c
985
src/fcpat.c
File diff suppressed because it is too large
Load Diff
|
@ -1052,3 +1052,4 @@ FcStrListDone (FcStrList *list)
|
||||||
FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));
|
FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));
|
||||||
free (list);
|
free (list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/fcxml.c
15
src/fcxml.c
|
@ -65,7 +65,6 @@ FcTestDestroy (FcTest *test)
|
||||||
if (test->next)
|
if (test->next)
|
||||||
FcTestDestroy (test->next);
|
FcTestDestroy (test->next);
|
||||||
FcExprDestroy (test->expr);
|
FcExprDestroy (test->expr);
|
||||||
FcStrFree ((FcChar8 *) test->field);
|
|
||||||
FcMemFree (FC_MEM_TEST, sizeof (FcTest));
|
FcMemFree (FC_MEM_TEST, sizeof (FcTest));
|
||||||
free (test);
|
free (test);
|
||||||
}
|
}
|
||||||
|
@ -162,7 +161,7 @@ FcExprCreateField (const char *field)
|
||||||
{
|
{
|
||||||
FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
|
FcMemAlloc (FC_MEM_EXPR, sizeof (FcExpr));
|
||||||
e->op = FcOpField;
|
e->op = FcOpField;
|
||||||
e->u.field = (char *) FcStrCopy ((FcChar8 *) field);
|
e->u.object = FcObjectFromName (field);
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +217,6 @@ FcExprDestroy (FcExpr *e)
|
||||||
case FcOpBool:
|
case FcOpBool:
|
||||||
break;
|
break;
|
||||||
case FcOpField:
|
case FcOpField:
|
||||||
FcStrFree ((FcChar8 *) e->u.field);
|
|
||||||
break;
|
break;
|
||||||
case FcOpConst:
|
case FcOpConst:
|
||||||
FcStrFree (e->u.constant);
|
FcStrFree (e->u.constant);
|
||||||
|
@ -269,7 +267,6 @@ FcEditDestroy (FcEdit *e)
|
||||||
{
|
{
|
||||||
if (e->next)
|
if (e->next)
|
||||||
FcEditDestroy (e->next);
|
FcEditDestroy (e->next);
|
||||||
FcStrFree ((FcChar8 *) e->field);
|
|
||||||
if (e->expr)
|
if (e->expr)
|
||||||
FcExprDestroy (e->expr);
|
FcExprDestroy (e->expr);
|
||||||
free (e);
|
free (e);
|
||||||
|
@ -579,7 +576,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
|
||||||
case FcOpNil:
|
case FcOpNil:
|
||||||
break;
|
break;
|
||||||
case FcOpField:
|
case FcOpField:
|
||||||
o = FcNameGetObjectType (expr->u.field);
|
o = FcNameGetObjectType (FcObjectName (expr->u.object));
|
||||||
if (o)
|
if (o)
|
||||||
FcTypecheckValue (parse, o->type, type);
|
FcTypecheckValue (parse, o->type, type);
|
||||||
break;
|
break;
|
||||||
|
@ -659,10 +656,10 @@ FcTestCreate (FcConfigParse *parse,
|
||||||
test->next = 0;
|
test->next = 0;
|
||||||
test->kind = kind;
|
test->kind = kind;
|
||||||
test->qual = qual;
|
test->qual = qual;
|
||||||
test->field = (char *) FcStrCopy (field);
|
test->object = FcObjectFromName ((const char *) field);
|
||||||
test->op = compare;
|
test->op = compare;
|
||||||
test->expr = expr;
|
test->expr = expr;
|
||||||
o = FcNameGetObjectType (test->field);
|
o = FcNameGetObjectType (FcObjectName (test->object));
|
||||||
if (o)
|
if (o)
|
||||||
FcTypecheckExpr (parse, expr, o->type);
|
FcTypecheckExpr (parse, expr, o->type);
|
||||||
}
|
}
|
||||||
|
@ -683,11 +680,11 @@ FcEditCreate (FcConfigParse *parse,
|
||||||
const FcObjectType *o;
|
const FcObjectType *o;
|
||||||
|
|
||||||
e->next = 0;
|
e->next = 0;
|
||||||
e->field = field; /* already saved in grammar */
|
e->object = FcObjectFromName (field);
|
||||||
e->op = op;
|
e->op = op;
|
||||||
e->expr = expr;
|
e->expr = expr;
|
||||||
e->binding = binding;
|
e->binding = binding;
|
||||||
o = FcNameGetObjectType (e->field);
|
o = FcNameGetObjectType (FcObjectName (e->object));
|
||||||
if (o)
|
if (o)
|
||||||
FcTypecheckExpr (parse, expr, o->type);
|
FcTypecheckExpr (parse, expr, o->type);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue