Add functionality to allow fontconfig data structure serialization.
This patch allows the fundamental fontconfig data structures to be serialized. I've converted everything from FcPattern down to be able to use *Ptr objects, which can be either static or dynamic (using a union which either contains a pointer or an index) and replaced storage of pointers in the heap with the appropriate *Ptr object. I then changed all writes of pointers to the heap with a *CreateDynamic call, which creates a dynamic Ptr object pointing to the same object as before. This way, the fundamental fontconfig semantics should be unchanged; I did not have to change external signatures this way, although I did change some internal signatures. When given a *Ptr object, just run *U to get back to a normal pointer; it gives the right answer regardless of whether we're using static or dynamic storage. I've also implemented a Fc*Serialize call. Calling FcFontSetSerialize converts the dynamic FcFontSets contained in the config object to static FcFontSets and also converts its dependencies (e.g. everything you'd need to write to disk) to static objects. Note that you have to call Fc*PrepareSerialize first; this call will count the number of objects that actually needs to be allocated, so that we can avoid realloc. The Fc*Serialize calls then check the static pointers for nullness, and allocate the buffers if necessary. I've tested the execution of fc-list and fc-match after Fc*Serialize and they appear to work the same way.
This commit is contained in:
parent
f1a42f6b5f
commit
cd2ec1a940
|
@ -220,7 +220,7 @@ main (int argc, char **argv)
|
|||
FILE *f;
|
||||
int ncountry = 0;
|
||||
int i = 0;
|
||||
FcCharLeaf **leaves, **sleaves;
|
||||
FcCharLeaf **leaves;
|
||||
int total_leaves = 0;
|
||||
int l, sl, tl;
|
||||
int c;
|
||||
|
@ -268,14 +268,13 @@ main (int argc, char **argv)
|
|||
*/
|
||||
for (i = 0; sets[i]; i++)
|
||||
{
|
||||
sleaves = sets[i]->leaves;
|
||||
for (sl = 0; sl < sets[i]->num; sl++)
|
||||
{
|
||||
for (l = 0; l < tl; l++)
|
||||
if (leaves[l] == sleaves[sl])
|
||||
if (leaves[l] == FcCharSetGetLeaf(sets[i], sl))
|
||||
break;
|
||||
if (l == tl)
|
||||
leaves[tl++] = sleaves[sl];
|
||||
leaves[tl++] = FcCharSetGetLeaf(sets[i], sl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +357,7 @@ main (int argc, char **argv)
|
|||
if (n % 8 == 0)
|
||||
printf (" ");
|
||||
for (l = 0; l < tl; l++)
|
||||
if (leaves[l] == sets[i]->leaves[n])
|
||||
if (leaves[l] == FcCharSetGetLeaf(sets[i], n))
|
||||
break;
|
||||
if (l == tl)
|
||||
fatal (names[i], 0, "can't find leaf");
|
||||
|
@ -377,7 +376,7 @@ main (int argc, char **argv)
|
|||
{
|
||||
if (n % 8 == 0)
|
||||
printf (" ");
|
||||
printf (" 0x%04x,", sets[i]->numbers[n]);
|
||||
printf (" 0x%04x,", FcCharSetGetNumbers(sets[i])[n]);
|
||||
if (n % 8 == 7)
|
||||
printf ("\n");
|
||||
}
|
||||
|
@ -399,9 +398,9 @@ main (int argc, char **argv)
|
|||
if (j < 0)
|
||||
j = i;
|
||||
printf (" { (FcChar8 *) \"%s\",\n"
|
||||
" { FC_REF_CONSTANT, %d, "
|
||||
"(FcCharLeaf **) leaves_%s, "
|
||||
"(FcChar16 *) numbers_%s } },\n",
|
||||
" { FC_REF_CONSTANT, %d, FcStorageDynamic, "
|
||||
"{ { (FcCharLeaf **) leaves_%s, "
|
||||
"(FcChar16 *) numbers_%s } } } },\n",
|
||||
langs[i],
|
||||
sets[j]->num, names[j], names[j]);
|
||||
}
|
||||
|
|
|
@ -59,22 +59,22 @@
|
|||
__v__.u.d = va_arg (va, double); \
|
||||
break; \
|
||||
case FcTypeString: \
|
||||
__v__.u.s = va_arg (va, FcChar8 *); \
|
||||
__v__.u.si = va_arg (va, FcObjectPtr); \
|
||||
break; \
|
||||
case FcTypeBool: \
|
||||
__v__.u.b = va_arg (va, FcBool); \
|
||||
break; \
|
||||
case FcTypeMatrix: \
|
||||
__v__.u.m = va_arg (va, FcMatrix *); \
|
||||
__v__.u.mi = va_arg (va, FcMatrixPtr); \
|
||||
break; \
|
||||
case FcTypeCharSet: \
|
||||
__v__.u.c = va_arg (va, FcCharSet *); \
|
||||
__v__.u.ci = va_arg (va, FcCharSetPtr); \
|
||||
break; \
|
||||
case FcTypeFTFace: \
|
||||
__v__.u.f = va_arg (va, FT_Face); \
|
||||
break; \
|
||||
case FcTypeLangSet: \
|
||||
__v__.u.l = va_arg (va, FcLangSet *); \
|
||||
__v__.u.li = va_arg (va, FcLangSetPtr); \
|
||||
break; \
|
||||
} \
|
||||
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
|
||||
|
|
|
@ -196,22 +196,59 @@ typedef enum _FcResult {
|
|||
FcResultOutOfMemory
|
||||
} FcResult;
|
||||
|
||||
typedef enum _FcStorage {
|
||||
FcStorageStatic, FcStorageDynamic
|
||||
} FcStorage;
|
||||
|
||||
typedef struct _FcPattern FcPattern;
|
||||
|
||||
typedef struct _FcLangSet FcLangSet;
|
||||
|
||||
typedef struct _FcMatrixPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
FcMatrix *dyn;
|
||||
} u;
|
||||
} FcMatrixPtr;
|
||||
|
||||
typedef struct _FcCharSetPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
FcCharSet *dyn;
|
||||
} u;
|
||||
} FcCharSetPtr;
|
||||
|
||||
typedef struct _FcLangSetPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
FcLangSet *dyn;
|
||||
} u;
|
||||
} FcLangSetPtr;
|
||||
|
||||
typedef struct _FcObjectPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
const FcChar8 * dyn;
|
||||
} u;
|
||||
FcChar32 hash;
|
||||
} FcObjectPtr;
|
||||
|
||||
typedef struct _FcValue {
|
||||
FcType type;
|
||||
union {
|
||||
const FcChar8 *s;
|
||||
FcObjectPtr si;
|
||||
int i;
|
||||
FcBool b;
|
||||
double d;
|
||||
const FcMatrix *m;
|
||||
const FcCharSet *c;
|
||||
FcMatrixPtr mi;
|
||||
FcCharSetPtr ci;
|
||||
void *f;
|
||||
const FcPattern *p;
|
||||
const FcLangSet *l;
|
||||
FcLangSetPtr li;
|
||||
} u;
|
||||
} FcValue;
|
||||
|
||||
|
@ -224,7 +261,7 @@ typedef struct _FcFontSet {
|
|||
typedef struct _FcObjectSet {
|
||||
int nobject;
|
||||
int sobject;
|
||||
const char **objects;
|
||||
FcObjectPtr *objects;
|
||||
} FcObjectSet;
|
||||
|
||||
typedef enum _FcMatchKind {
|
||||
|
@ -618,6 +655,9 @@ FcMatrixScale (FcMatrix *m, double sx, double sy);
|
|||
void
|
||||
FcMatrixShear (FcMatrix *m, double sh, double sv);
|
||||
|
||||
FcMatrix *
|
||||
FcMatrixPtrU (FcMatrixPtr mi);
|
||||
|
||||
/* fcname.c */
|
||||
|
||||
FcBool
|
||||
|
|
|
@ -1166,3 +1166,35 @@ bail1:
|
|||
bail0:
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
void
|
||||
FcCacheClearStatic()
|
||||
{
|
||||
FcFontSetClearStatic();
|
||||
FcPatternClearStatic();
|
||||
FcValueListClearStatic();
|
||||
FcObjectClearStatic();
|
||||
FcMatrixClearStatic();
|
||||
FcCharSetClearStatic();
|
||||
FcLangSetClearStatic();
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcCachePrepareSerialize (FcConfig * config)
|
||||
{
|
||||
int i;
|
||||
for (i = FcSetSystem; i <= FcSetApplication; i++)
|
||||
if (config->fonts[i] && !FcFontSetPrepareSerialize(config->fonts[i]))
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcCacheSerialize (FcConfig * config)
|
||||
{
|
||||
int i;
|
||||
for (i = FcSetSystem; i <= FcSetApplication; i++)
|
||||
if (config->fonts[i] && !FcFontSetSerialize(config->fonts[i]))
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
|
129
src/fccfg.c
129
src/fccfg.c
|
@ -550,12 +550,13 @@ FcConfigPromote (FcValue v, FcValue u)
|
|||
}
|
||||
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
|
||||
{
|
||||
v.u.m = &FcIdentityMatrix;
|
||||
v.u.mi = FcIdentityMatrix;
|
||||
v.type = FcTypeMatrix;
|
||||
}
|
||||
else if (v.type == FcTypeString && u.type == FcTypeLangSet)
|
||||
{
|
||||
v.u.l = FcLangSetPromote (v.u.s);
|
||||
v.u.li = FcLangSetPtrCreateDynamic(FcLangSetPromote
|
||||
(FcObjectPtrU(v.u.si)));
|
||||
v.type = FcTypeLangSet;
|
||||
}
|
||||
return v;
|
||||
|
@ -623,16 +624,19 @@ FcConfigCompareValue (const FcValue left_o,
|
|||
switch (op) {
|
||||
case FcOpEqual:
|
||||
case FcOpListing:
|
||||
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
|
||||
ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
|
||||
FcObjectPtrU(right.u.si)) == 0;
|
||||
break;
|
||||
case FcOpContains:
|
||||
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
|
||||
ret = FcStrStrIgnoreCase (FcObjectPtrU(left.u.si),
|
||||
FcObjectPtrU(right.u.si)) != 0;
|
||||
break;
|
||||
case FcOpNotEqual:
|
||||
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
|
||||
break;
|
||||
case FcOpNotContains:
|
||||
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
|
||||
ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
|
||||
FcObjectPtrU(right.u.si)) == 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -643,11 +647,11 @@ FcConfigCompareValue (const FcValue left_o,
|
|||
case FcOpEqual:
|
||||
case FcOpContains:
|
||||
case FcOpListing:
|
||||
ret = FcMatrixEqual (left.u.m, right.u.m);
|
||||
ret = FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
|
||||
break;
|
||||
case FcOpNotEqual:
|
||||
case FcOpNotContains:
|
||||
ret = !FcMatrixEqual (left.u.m, right.u.m);
|
||||
ret = !FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -658,17 +662,17 @@ FcConfigCompareValue (const FcValue left_o,
|
|||
case FcOpContains:
|
||||
case FcOpListing:
|
||||
/* left contains right if right is a subset of left */
|
||||
ret = FcCharSetIsSubset (right.u.c, left.u.c);
|
||||
ret = FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
|
||||
break;
|
||||
case FcOpNotContains:
|
||||
/* left contains right if right is a subset of left */
|
||||
ret = !FcCharSetIsSubset (right.u.c, left.u.c);
|
||||
ret = !FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
|
||||
break;
|
||||
case FcOpEqual:
|
||||
ret = FcCharSetEqual (left.u.c, right.u.c);
|
||||
ret = FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
|
||||
break;
|
||||
case FcOpNotEqual:
|
||||
ret = !FcCharSetEqual (left.u.c, right.u.c);
|
||||
ret = !FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -678,16 +682,16 @@ FcConfigCompareValue (const FcValue left_o,
|
|||
switch (op) {
|
||||
case FcOpContains:
|
||||
case FcOpListing:
|
||||
ret = FcLangSetContains (left.u.l, right.u.l);
|
||||
ret = FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
|
||||
break;
|
||||
case FcOpNotContains:
|
||||
ret = !FcLangSetContains (left.u.l, right.u.l);
|
||||
ret = !FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
|
||||
break;
|
||||
case FcOpEqual:
|
||||
ret = FcLangSetEqual (left.u.l, right.u.l);
|
||||
ret = FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
|
||||
break;
|
||||
case FcOpNotEqual:
|
||||
ret = !FcLangSetEqual (left.u.l, right.u.l);
|
||||
ret = !FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -755,17 +759,17 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
|
|||
break;
|
||||
case FcOpString:
|
||||
v.type = FcTypeString;
|
||||
v.u.s = e->u.sval;
|
||||
v.u.si = FcObjectPtrCreateDynamic(e->u.sval);
|
||||
v = FcValueSave (v);
|
||||
break;
|
||||
case FcOpMatrix:
|
||||
v.type = FcTypeMatrix;
|
||||
v.u.m = e->u.mval;
|
||||
v.u.mi = FcMatrixPtrCreateDynamic(e->u.mval);
|
||||
v = FcValueSave (v);
|
||||
break;
|
||||
case FcOpCharSet:
|
||||
v.type = FcTypeCharSet;
|
||||
v.u.c = e->u.cval;
|
||||
v.u.ci = FcCharSetPtrCreateDynamic(e->u.cval);
|
||||
v = FcValueSave (v);
|
||||
break;
|
||||
case FcOpBool:
|
||||
|
@ -873,8 +877,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
|
|||
switch (e->op) {
|
||||
case FcOpPlus:
|
||||
v.type = FcTypeString;
|
||||
v.u.s = FcStrPlus (vl.u.s, vr.u.s);
|
||||
if (!v.u.s)
|
||||
v.u.si = FcObjectPtrCreateDynamic
|
||||
(FcStrPlus (FcObjectPtrU(vl.u.si),
|
||||
FcObjectPtrU(vr.u.si)));
|
||||
|
||||
if (!FcObjectPtrU(v.u.si))
|
||||
v.type = FcTypeVoid;
|
||||
break;
|
||||
default:
|
||||
|
@ -890,8 +897,9 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
|
|||
if (m)
|
||||
{
|
||||
FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix));
|
||||
FcMatrixMultiply (m, vl.u.m, vr.u.m);
|
||||
v.u.m = m;
|
||||
FcMatrixMultiply (m, FcMatrixPtrU(vl.u.mi),
|
||||
FcMatrixPtrU(vr.u.mi));
|
||||
v.u.mi = FcMatrixPtrCreateDynamic(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1021,7 +1029,7 @@ FcConfigMatchValueList (FcPattern *p,
|
|||
e = 0;
|
||||
}
|
||||
|
||||
for (v = values; v; v = v->next)
|
||||
for (v = values; v; v = FcValueListPtrU(v->next))
|
||||
{
|
||||
/* Compare the pattern value to the match expression value */
|
||||
if (FcConfigCompareValue (v->value, t->op, value))
|
||||
|
@ -1047,6 +1055,7 @@ static FcValueList *
|
|||
FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
|
||||
{
|
||||
FcValueList *l;
|
||||
FcValueListPtr lp;
|
||||
|
||||
if (!e)
|
||||
return 0;
|
||||
|
@ -1057,56 +1066,63 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
|
|||
if (e->op == FcOpComma)
|
||||
{
|
||||
l->value = FcConfigEvaluate (p, e->u.tree.left);
|
||||
l->next = FcConfigValues (p, e->u.tree.right, binding);
|
||||
l->next = FcValueListPtrCreateDynamic(FcConfigValues (p, e->u.tree.right, binding));
|
||||
}
|
||||
else
|
||||
{
|
||||
l->value = FcConfigEvaluate (p, e);
|
||||
l->next = 0;
|
||||
l->next = FcValueListPtrCreateDynamic(0);
|
||||
}
|
||||
l->binding = binding;
|
||||
while (l && l->value.type == FcTypeVoid)
|
||||
lp = FcValueListPtrCreateDynamic(l);
|
||||
while (FcValueListPtrU(lp) && FcValueListPtrU(lp)->value.type == FcTypeVoid)
|
||||
{
|
||||
FcValueList *next = l->next;
|
||||
FcValueListPtr next = FcValueListPtrU(lp)->next;
|
||||
|
||||
if (lp.storage == FcStorageDynamic)
|
||||
{
|
||||
FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
|
||||
free (l);
|
||||
l = next;
|
||||
}
|
||||
lp = next;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcConfigAdd (FcValueList **head,
|
||||
FcConfigAdd (FcValueListPtr *head,
|
||||
FcValueList *position,
|
||||
FcBool append,
|
||||
FcValueList *new)
|
||||
{
|
||||
FcValueList **prev, *last, *v;
|
||||
FcValueListPtr *prev, last, v;
|
||||
FcValueBinding sameBinding;
|
||||
|
||||
if (position)
|
||||
sameBinding = position->binding;
|
||||
else
|
||||
sameBinding = FcValueBindingWeak;
|
||||
for (v = new; v; v = v->next)
|
||||
if (v->binding == FcValueBindingSame)
|
||||
v->binding = sameBinding;
|
||||
for (v = FcValueListPtrCreateDynamic(new); FcValueListPtrU(v);
|
||||
v = FcValueListPtrU(v)->next)
|
||||
if (FcValueListPtrU(v)->binding == FcValueBindingSame)
|
||||
FcValueListPtrU(v)->binding = sameBinding;
|
||||
if (append)
|
||||
{
|
||||
if (position)
|
||||
prev = &position->next;
|
||||
else
|
||||
for (prev = head; *prev; prev = &(*prev)->next)
|
||||
for (prev = head; FcValueListPtrU(*prev);
|
||||
prev = &(FcValueListPtrU(*prev)->next))
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (position)
|
||||
{
|
||||
for (prev = head; *prev; prev = &(*prev)->next)
|
||||
for (prev = head; FcValueListPtrU(*prev);
|
||||
prev = &(FcValueListPtrU(*prev)->next))
|
||||
{
|
||||
if (*prev == position)
|
||||
if (FcValueListPtrU(*prev) == position)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1115,7 +1131,7 @@ FcConfigAdd (FcValueList **head,
|
|||
|
||||
if (FcDebug () & FC_DBG_EDIT)
|
||||
{
|
||||
if (!*prev)
|
||||
if (!FcValueListPtrU(*prev))
|
||||
printf ("position not on list\n");
|
||||
}
|
||||
}
|
||||
|
@ -1129,12 +1145,12 @@ FcConfigAdd (FcValueList **head,
|
|||
|
||||
if (new)
|
||||
{
|
||||
last = new;
|
||||
while (last->next)
|
||||
last = last->next;
|
||||
last = FcValueListPtrCreateDynamic(new);
|
||||
while (FcValueListPtrU(FcValueListPtrU(last)->next))
|
||||
last = FcValueListPtrU(last)->next;
|
||||
|
||||
last->next = *prev;
|
||||
*prev = new;
|
||||
FcValueListPtrU(last)->next = *prev;
|
||||
*prev = FcValueListPtrCreateDynamic(new);
|
||||
}
|
||||
|
||||
if (FcDebug () & FC_DBG_EDIT)
|
||||
|
@ -1148,18 +1164,19 @@ FcConfigAdd (FcValueList **head,
|
|||
}
|
||||
|
||||
static void
|
||||
FcConfigDel (FcValueList **head,
|
||||
FcConfigDel (FcValueListPtr *head,
|
||||
FcValueList *position)
|
||||
{
|
||||
FcValueList **prev;
|
||||
FcValueListPtr *prev;
|
||||
|
||||
for (prev = head; *prev; prev = &(*prev)->next)
|
||||
for (prev = head; FcValueListPtrU(*prev);
|
||||
prev = &(FcValueListPtrU(*prev)->next))
|
||||
{
|
||||
if (*prev == position)
|
||||
if (FcValueListPtrU(*prev) == position)
|
||||
{
|
||||
*prev = position->next;
|
||||
position->next = 0;
|
||||
FcValueListDestroy (position);
|
||||
position->next = FcValueListPtrCreateDynamic(0);
|
||||
FcValueListDestroy (FcValueListPtrCreateDynamic(position));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1191,8 +1208,8 @@ FcConfigPatternDel (FcPattern *p,
|
|||
FcPatternElt *e = FcPatternFindElt (p, object);
|
||||
if (!e)
|
||||
return;
|
||||
while (e->values)
|
||||
FcConfigDel (&e->values, e->values);
|
||||
while (FcValueListPtrU(e->values))
|
||||
FcConfigDel (&e->values, FcValueListPtrU(e->values));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1202,7 +1219,7 @@ FcConfigPatternCanon (FcPattern *p,
|
|||
FcPatternElt *e = FcPatternFindElt (p, object);
|
||||
if (!e)
|
||||
return;
|
||||
if (!e->values)
|
||||
if (!FcValueListPtrU(e->values))
|
||||
FcPatternDel (p, object);
|
||||
}
|
||||
|
||||
|
@ -1281,12 +1298,12 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
|||
* Check to see if there is a match, mark the location
|
||||
* to apply match-relative edits
|
||||
*/
|
||||
st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
|
||||
st[i].value = FcConfigMatchValueList (m, t, FcValueListPtrU(st[i].elt->values));
|
||||
if (!st[i].value)
|
||||
break;
|
||||
if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
|
||||
if (t->qual == FcQualFirst && st[i].value != FcValueListPtrU(st[i].elt->values))
|
||||
break;
|
||||
if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values)
|
||||
if (t->qual == FcQualNotFirst && st[i].value == FcValueListPtrU(st[i].elt->values))
|
||||
break;
|
||||
}
|
||||
if (t)
|
||||
|
@ -1339,7 +1356,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
|
|||
if (t)
|
||||
{
|
||||
FcValueList *thisValue = st[i].value;
|
||||
FcValueList *nextValue = thisValue ? thisValue->next : 0;
|
||||
FcValueList *nextValue = thisValue ? FcValueListPtrU(thisValue->next) : 0;
|
||||
|
||||
/*
|
||||
* Append the new list of values after the current value
|
||||
|
@ -1840,7 +1857,7 @@ FcConfigGlobsMatch (const FcStrSet *globs,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < globs->num; i++)
|
||||
if (FcConfigGlobMatch (globs->strs[i], string))
|
||||
if (FcConfigGlobMatch (FcStrSetGet(globs, i), string))
|
||||
return FcTrue;
|
||||
return FcFalse;
|
||||
}
|
||||
|
|
307
src/fccharset.c
307
src/fccharset.c
|
@ -29,6 +29,27 @@
|
|||
|
||||
/* #define CHATTY */
|
||||
|
||||
static FcCharSet * charsets = 0;
|
||||
static FcChar16 * numbers = 0;
|
||||
static int 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;
|
||||
|
||||
void
|
||||
FcCharSetClearStatic()
|
||||
{
|
||||
charsets = 0;
|
||||
numbers = 0;
|
||||
charset_ptr = 0; charset_count = 0;
|
||||
leaves = 0;
|
||||
charset_leaf_ptr = 0; charset_leaf_count = 0;
|
||||
leaf_idx = 0;
|
||||
charset_leaf_idx_ptr = 0; charset_leaf_idx_count = 0;
|
||||
}
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetCreate (void)
|
||||
{
|
||||
|
@ -40,8 +61,9 @@ FcCharSetCreate (void)
|
|||
FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||
fcs->ref = 1;
|
||||
fcs->num = 0;
|
||||
fcs->leaves = 0;
|
||||
fcs->numbers = 0;
|
||||
fcs->storage = FcStorageDynamic;
|
||||
fcs->u.dyn.leaves = 0;
|
||||
fcs->u.dyn.numbers = 0;
|
||||
return fcs;
|
||||
}
|
||||
|
||||
|
@ -54,6 +76,17 @@ FcCharSetNew (void)
|
|||
return FcCharSetCreate ();
|
||||
}
|
||||
|
||||
void
|
||||
FcCharSetPtrDestroy (FcCharSetPtr fcs)
|
||||
{
|
||||
FcCharSetDestroy (FcCharSetPtrU(fcs));
|
||||
if (fcs.storage == FcStorageDynamic &&
|
||||
FcCharSetPtrU(fcs)->ref != FC_REF_CONSTANT)
|
||||
{
|
||||
free (fcs.u.dyn);
|
||||
FcMemFree (FC_MEM_CHARSET, sizeof(FcCharSet));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FcCharSetDestroy (FcCharSet *fcs)
|
||||
|
@ -63,20 +96,23 @@ FcCharSetDestroy (FcCharSet *fcs)
|
|||
return;
|
||||
if (--fcs->ref > 0)
|
||||
return;
|
||||
if (fcs->storage == FcStorageDynamic)
|
||||
{
|
||||
for (i = 0; i < fcs->num; i++)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
|
||||
free (fcs->leaves[i]);
|
||||
free (fcs->u.dyn.leaves[i]);
|
||||
}
|
||||
if (fcs->leaves)
|
||||
if (fcs->u.dyn.leaves)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
|
||||
free (fcs->leaves);
|
||||
free (fcs->u.dyn.leaves);
|
||||
}
|
||||
if (fcs->numbers)
|
||||
if (fcs->u.dyn.numbers)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
||||
free (fcs->numbers);
|
||||
free (fcs->u.dyn.numbers);
|
||||
}
|
||||
}
|
||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||
free (fcs);
|
||||
|
@ -91,7 +127,7 @@ FcCharSetDestroy (FcCharSet *fcs)
|
|||
static int
|
||||
FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4)
|
||||
{
|
||||
FcChar16 *numbers = fcs->numbers;
|
||||
FcChar16 *numbers = FcCharSetGetNumbers(fcs);
|
||||
FcChar16 page;
|
||||
int low = 0;
|
||||
int high = fcs->num - 1;
|
||||
|
@ -120,7 +156,7 @@ FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4)
|
|||
{
|
||||
int pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||
if (pos >= 0)
|
||||
return fcs->leaves[pos];
|
||||
return FcCharSetGetLeaf(fcs, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -136,33 +172,55 @@ FcCharSetPutLeaf (FcCharSet *fcs,
|
|||
ucs4 >>= 8;
|
||||
if (ucs4 >= 0x10000)
|
||||
return FcFalse;
|
||||
if (!fcs->leaves)
|
||||
if (fcs->storage == FcStorageStatic)
|
||||
{
|
||||
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)
|
||||
return FcFalse;
|
||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
|
||||
|
||||
for (i = 0; i < fcs->num; i++)
|
||||
leaves[i] = FcCharSetGetLeaf(fcs, i);
|
||||
memcpy (numbers, FcCharSetGetNumbers(fcs),
|
||||
fcs->num * sizeof (FcChar16));
|
||||
fcs->storage = FcStorageDynamic;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fcs->u.dyn.leaves)
|
||||
leaves = malloc (sizeof (FcCharLeaf *));
|
||||
else
|
||||
leaves = realloc (fcs->leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
||||
leaves = realloc (fcs->u.dyn.leaves, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
||||
if (!leaves)
|
||||
return FcFalse;
|
||||
if (fcs->num)
|
||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcCharLeaf *));
|
||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
|
||||
fcs->leaves = leaves;
|
||||
if (!fcs->numbers)
|
||||
fcs->u.dyn.leaves = leaves;
|
||||
if (!fcs->u.dyn.numbers)
|
||||
numbers = malloc (sizeof (FcChar16));
|
||||
else
|
||||
numbers = realloc (fcs->numbers, (fcs->num + 1) * sizeof (FcChar16));
|
||||
numbers = realloc (fcs->u.dyn.numbers, (fcs->num + 1) * sizeof (FcChar16));
|
||||
if (!numbers)
|
||||
return FcFalse;
|
||||
if (fcs->num)
|
||||
FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16));
|
||||
FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
|
||||
fcs->numbers = numbers;
|
||||
fcs->u.dyn.numbers = numbers;
|
||||
}
|
||||
|
||||
memmove (fcs->leaves + pos + 1, fcs->leaves + pos,
|
||||
memmove (fcs->u.dyn.leaves + pos + 1, fcs->u.dyn.leaves + pos,
|
||||
(fcs->num - pos) * sizeof (FcCharLeaf *));
|
||||
memmove (fcs->numbers + pos + 1, fcs->numbers + pos,
|
||||
memmove (fcs->u.dyn.numbers + pos + 1, fcs->u.dyn.numbers + pos,
|
||||
(fcs->num - pos) * sizeof (FcChar16));
|
||||
fcs->numbers[pos] = (FcChar16) ucs4;
|
||||
fcs->leaves[pos] = leaf;
|
||||
fcs->u.dyn.numbers[pos] = (FcChar16) ucs4;
|
||||
fcs->u.dyn.leaves[pos] = leaf;
|
||||
fcs->num++;
|
||||
return FcTrue;
|
||||
}
|
||||
|
@ -180,7 +238,7 @@ FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4)
|
|||
|
||||
pos = FcCharSetFindLeafPos (fcs, ucs4);
|
||||
if (pos >= 0)
|
||||
return fcs->leaves[pos];
|
||||
return FcCharSetGetLeaf(fcs, pos);
|
||||
|
||||
leaf = calloc (1, sizeof (FcCharLeaf));
|
||||
if (!leaf)
|
||||
|
@ -205,8 +263,15 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf)
|
|||
if (pos >= 0)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
|
||||
free (fcs->leaves[pos]);
|
||||
fcs->leaves[pos] = leaf;
|
||||
if (fcs->storage == FcStorageDynamic)
|
||||
{
|
||||
free (fcs->u.dyn.leaves[pos]);
|
||||
fcs->u.dyn.leaves[pos] = leaf;
|
||||
}
|
||||
else
|
||||
{
|
||||
leaves[leaf_idx[fcs->u.stat.leafidx_offset]+pos] = *leaf;
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
pos = -pos - 1;
|
||||
|
@ -257,9 +322,9 @@ FcCharSetIterSet (const FcCharSet *fcs, FcCharSetIter *iter)
|
|||
iter->leaf = 0;
|
||||
return;
|
||||
}
|
||||
iter->ucs4 = (FcChar32) fcs->numbers[pos] << 8;
|
||||
iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
|
||||
}
|
||||
iter->leaf = fcs->leaves[pos];
|
||||
iter->leaf = FcCharSetGetLeaf(fcs, pos);
|
||||
iter->pos = pos;
|
||||
#ifdef CHATTY
|
||||
printf ("set %08x: %08x\n", iter->ucs4, (FcChar32) iter->leaf);
|
||||
|
@ -277,8 +342,8 @@ FcCharSetIterNext (const FcCharSet *fcs, FcCharSetIter *iter)
|
|||
}
|
||||
else
|
||||
{
|
||||
iter->ucs4 = (FcChar32) fcs->numbers[pos] << 8;
|
||||
iter->leaf = fcs->leaves[pos];
|
||||
iter->ucs4 = (FcChar32) FcCharSetGetNumbers(fcs)[pos] << 8;
|
||||
iter->leaf = FcCharSetGetLeaf(fcs, pos);
|
||||
iter->pos = pos;
|
||||
}
|
||||
}
|
||||
|
@ -594,15 +659,15 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
|||
ai = 0;
|
||||
while (ai < a->num && bi < b->num)
|
||||
{
|
||||
an = a->numbers[ai];
|
||||
bn = b->numbers[bi];
|
||||
an = FcCharSetGetNumbers(a)[ai];
|
||||
bn = FcCharSetGetNumbers(b)[bi];
|
||||
/*
|
||||
* Check matching pages
|
||||
*/
|
||||
if (an == bn)
|
||||
{
|
||||
FcChar32 *am = a->leaves[ai]->map;
|
||||
FcChar32 *bm = b->leaves[bi]->map;
|
||||
FcChar32 *am = FcCharSetGetLeaf(a, ai)->map;
|
||||
FcChar32 *bm = FcCharSetGetLeaf(b, bi)->map;
|
||||
|
||||
if (am != bm)
|
||||
{
|
||||
|
@ -633,7 +698,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
|||
while (low <= high)
|
||||
{
|
||||
int mid = (low + high) >> 1;
|
||||
bn = b->numbers[mid];
|
||||
bn = FcCharSetGetNumbers(b)[mid];
|
||||
if (bn == an)
|
||||
{
|
||||
high = mid;
|
||||
|
@ -645,7 +710,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b)
|
|||
high = mid - 1;
|
||||
}
|
||||
bi = high;
|
||||
while (bi < b->num && b->numbers[bi] < an)
|
||||
while (bi < b->num && FcCharSetGetNumbers(b)[bi] < an)
|
||||
bi++;
|
||||
}
|
||||
}
|
||||
|
@ -949,16 +1014,14 @@ static FcChar32
|
|||
FcCharSetHash (FcCharSet *fcs)
|
||||
{
|
||||
FcChar32 hash = 0;
|
||||
FcChar32 *p;
|
||||
int i;
|
||||
|
||||
/* hash in leaves */
|
||||
p = (FcChar32 *) fcs->leaves;
|
||||
for (i = 0; i < fcs->num * sizeof (FcCharLeaf *) / sizeof (FcChar32); i++)
|
||||
hash = ((hash << 1) | (hash >> 31)) ^ *p++;
|
||||
hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map);
|
||||
/* hash in numbers */
|
||||
for (i = 0; i < fcs->num; i++)
|
||||
hash = ((hash << 1) | (hash >> 31)) ^ fcs->numbers[i];
|
||||
hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetGetNumbers(fcs);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -982,11 +1045,17 @@ FcCharSetFreezeBase (FcCharSet *fcs)
|
|||
{
|
||||
if (ent->hash == hash &&
|
||||
ent->set.num == fcs->num &&
|
||||
!memcmp (ent->set.leaves, fcs->leaves,
|
||||
fcs->num * sizeof (FcCharLeaf *)) &&
|
||||
!memcmp (ent->set.numbers, fcs->numbers,
|
||||
!memcmp (FcCharSetGetNumbers(&ent->set),
|
||||
FcCharSetGetNumbers(fcs),
|
||||
fcs->num * sizeof (FcChar16)))
|
||||
{
|
||||
FcBool ok = FcTrue;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fcs->num; i++)
|
||||
if (FcCharSetGetLeaf(&ent->set, i) != FcCharSetGetLeaf(fcs, i))
|
||||
ok = FcFalse;
|
||||
if (ok)
|
||||
return &ent->set;
|
||||
}
|
||||
}
|
||||
|
@ -1003,17 +1072,26 @@ FcCharSetFreezeBase (FcCharSet *fcs)
|
|||
|
||||
ent->set.ref = FC_REF_CONSTANT;
|
||||
ent->set.num = fcs->num;
|
||||
ent->set.storage = fcs->storage;
|
||||
if (fcs->storage == FcStorageDynamic)
|
||||
{
|
||||
if (fcs->num)
|
||||
{
|
||||
ent->set.leaves = (FcCharLeaf **) (ent + 1);
|
||||
ent->set.numbers = (FcChar16 *) (ent->set.leaves + fcs->num);
|
||||
memcpy (ent->set.leaves, fcs->leaves, fcs->num * sizeof (FcCharLeaf *));
|
||||
memcpy (ent->set.numbers, fcs->numbers, fcs->num * sizeof (FcChar16));
|
||||
ent->set.u.dyn.leaves = (FcCharLeaf **) (ent + 1);
|
||||
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 *));
|
||||
memcpy (ent->set.u.dyn.numbers, fcs->u.dyn.numbers, fcs->num * sizeof (FcChar16));
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->set.leaves = 0;
|
||||
ent->set.numbers = 0;
|
||||
ent->set.u.dyn.leaves = 0;
|
||||
ent->set.u.dyn.numbers = 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;
|
||||
|
@ -1059,23 +1137,26 @@ FcCharSetFreeze (FcCharSet *fcs)
|
|||
goto bail0;
|
||||
for (i = 0; i < fcs->num; i++)
|
||||
{
|
||||
l = FcCharSetFreezeLeaf (fcs->leaves[i]);
|
||||
l = FcCharSetFreezeLeaf (FcCharSetGetLeaf(fcs, i));
|
||||
if (!l)
|
||||
goto bail1;
|
||||
if (!FcCharSetInsertLeaf (b, fcs->numbers[i] << 8, l))
|
||||
if (!FcCharSetInsertLeaf (b, FcCharSetGetNumbers(fcs)[i] << 8, l))
|
||||
goto bail1;
|
||||
}
|
||||
n = FcCharSetFreezeBase (b);
|
||||
bail1:
|
||||
if (b->leaves)
|
||||
if (b->storage == FcStorageDynamic)
|
||||
{
|
||||
if (b->u.dyn.leaves)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcCharLeaf *));
|
||||
free (b->leaves);
|
||||
free (b->u.dyn.leaves);
|
||||
}
|
||||
if (b->numbers)
|
||||
if (b->u.dyn.numbers)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARSET, b->num * sizeof (FcChar16));
|
||||
free (b->numbers);
|
||||
free (b->u.dyn.numbers);
|
||||
}
|
||||
}
|
||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||
free (b);
|
||||
|
@ -1141,17 +1222,20 @@ FcNameParseCharSet (FcChar8 *string)
|
|||
#endif
|
||||
n = FcCharSetFreezeBase (c);
|
||||
bail1:
|
||||
if (c->leaves)
|
||||
if (c->storage == FcStorageDynamic)
|
||||
{
|
||||
if (c->u.dyn.leaves)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcCharLeaf *));
|
||||
free (c->leaves);
|
||||
free (c->u.dyn.leaves);
|
||||
}
|
||||
if (c->numbers)
|
||||
if (c->u.dyn.numbers)
|
||||
{
|
||||
FcMemFree (FC_MEM_CHARSET, c->num * sizeof (FcChar16));
|
||||
free (c->numbers);
|
||||
free (c->u.dyn.numbers);
|
||||
}
|
||||
FcMemFree (FC_MEM_CHARSET, sizeof (FcCharSet));
|
||||
}
|
||||
free (c);
|
||||
bail0:
|
||||
return n;
|
||||
|
@ -1229,3 +1313,116 @@ FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c)
|
|||
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetPtrU (FcCharSetPtr ci)
|
||||
{
|
||||
switch (ci.storage)
|
||||
{
|
||||
case FcStorageDynamic:
|
||||
return ci.u.dyn;
|
||||
case FcStorageStatic:
|
||||
return &charsets[ci.u.stat];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FcCharSetPtr
|
||||
FcCharSetPtrCreateDynamic(FcCharSet *c)
|
||||
{
|
||||
FcCharSetPtr new;
|
||||
|
||||
new.storage = FcStorageDynamic;
|
||||
new.u.dyn = c;
|
||||
return new;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcCharSetPrepareSerialize(FcCharSet *c)
|
||||
{
|
||||
/* note the redundancy */
|
||||
charset_count++;
|
||||
charset_leaf_idx_count++;
|
||||
charset_leaf_count += c->num;
|
||||
charset_numbers_count += c->num;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcCharSetPtr
|
||||
FcCharSetSerialize(FcCharSet *c)
|
||||
{
|
||||
int i;
|
||||
FcCharSetPtr newp;
|
||||
FcCharSet new;
|
||||
|
||||
if (!charsets)
|
||||
{
|
||||
charsets = malloc(sizeof(FcCharSet) * charset_count);
|
||||
if (!charsets) goto bail;
|
||||
numbers = malloc(sizeof(FcChar16) * charset_numbers_count);
|
||||
if (!numbers) goto bail1;
|
||||
leaves = malloc(sizeof(FcCharLeaf) * charset_leaf_count);
|
||||
if (!leaves) goto bail2;
|
||||
leaf_idx = malloc(sizeof(int)*charset_leaf_idx_count);
|
||||
if (!leaf_idx) goto bail3;
|
||||
}
|
||||
|
||||
new.ref = c->ref;
|
||||
new.storage = FcStorageStatic;
|
||||
new.u.stat.leafidx_offset = charset_leaf_ptr;
|
||||
new.u.stat.numbers_offset = charset_numbers_ptr;
|
||||
|
||||
newp.storage = FcStorageStatic;
|
||||
newp.u.stat = charset_ptr;
|
||||
charsets[charset_ptr++] = new;
|
||||
|
||||
leaf_idx[charset_leaf_idx_ptr++] = charset_leaf_ptr;
|
||||
for (i = 0; i < c->num; i++)
|
||||
{
|
||||
memcpy (&leaves[charset_leaf_ptr++],
|
||||
c->u.dyn.leaves[i], sizeof(FcCharLeaf));
|
||||
numbers[charset_numbers_ptr++] = c->u.dyn.numbers[i];
|
||||
}
|
||||
|
||||
return newp;
|
||||
|
||||
bail3:
|
||||
free (leaves);
|
||||
bail2:
|
||||
free (numbers);
|
||||
bail1:
|
||||
free (charsets);
|
||||
bail:
|
||||
return FcCharSetPtrCreateDynamic(0);
|
||||
}
|
||||
|
||||
FcCharLeaf *
|
||||
FcCharSetGetLeaf(const FcCharSet *c, int i)
|
||||
{
|
||||
switch (c->storage)
|
||||
{
|
||||
case FcStorageDynamic:
|
||||
return c->u.dyn.leaves[i];
|
||||
case FcStorageStatic:
|
||||
return &leaves[leaf_idx[c->u.stat.leafidx_offset]+i];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FcChar16 *
|
||||
FcCharSetGetNumbers(const FcCharSet *c)
|
||||
{
|
||||
switch (c->storage)
|
||||
{
|
||||
case FcStorageDynamic:
|
||||
return c->u.dyn.numbers;
|
||||
case FcStorageStatic:
|
||||
return &numbers[c->u.stat.numbers_offset];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
22
src/fcdbg.c
22
src/fcdbg.c
|
@ -40,20 +40,24 @@ FcValuePrint (const FcValue v)
|
|||
printf (" %g(f)", v.u.d);
|
||||
break;
|
||||
case FcTypeString:
|
||||
printf (" \"%s\"", v.u.s);
|
||||
printf (" \"%s\"", FcObjectPtrU(v.u.si));
|
||||
break;
|
||||
case FcTypeBool:
|
||||
printf (" %s", v.u.b ? "FcTrue" : "FcFalse");
|
||||
break;
|
||||
case FcTypeMatrix:
|
||||
printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
||||
{
|
||||
FcMatrix *m = FcMatrixPtrU(v.u.mi);
|
||||
|
||||
printf (" (%f %f; %f %f)", m->xx, m->xy, m->yx, m->yy);
|
||||
break;
|
||||
}
|
||||
case FcTypeCharSet: /* XXX */
|
||||
printf (" set");
|
||||
break;
|
||||
case FcTypeLangSet:
|
||||
printf (" ");
|
||||
FcLangSetPrint (v.u.l);
|
||||
FcLangSetPrint (FcLangSetPtrU(v.u.li));
|
||||
break;
|
||||
case FcTypeFTFace:
|
||||
printf (" face");
|
||||
|
@ -62,12 +66,12 @@ FcValuePrint (const FcValue v)
|
|||
}
|
||||
|
||||
void
|
||||
FcValueListPrint (const FcValueList *l)
|
||||
FcValueListPrint (FcValueListPtr l)
|
||||
{
|
||||
for (; l; l = l->next)
|
||||
for (; FcValueListPtrU(l); l = FcValueListPtrU(l)->next)
|
||||
{
|
||||
FcValuePrint (l->value);
|
||||
switch (l->binding) {
|
||||
FcValuePrint (FcValueListPtrU(l)->value);
|
||||
switch (FcValueListPtrU(l)->binding) {
|
||||
case FcValueBindingWeak:
|
||||
printf ("(w)");
|
||||
break;
|
||||
|
@ -109,8 +113,8 @@ FcPatternPrint (const FcPattern *p)
|
|||
printf ("Pattern %d of %d\n", p->num, p->size);
|
||||
for (i = 0; i < p->num; i++)
|
||||
{
|
||||
e = &p->elts[i];
|
||||
printf ("\t%s:", e->object);
|
||||
e = FcPatternEltU(p->elts) + i;
|
||||
printf ("\t%s:", FcObjectPtrU(e->object));
|
||||
FcValueListPrint (e->values);
|
||||
printf ("\n");
|
||||
}
|
||||
|
|
36
src/fcfs.c
36
src/fcfs.c
|
@ -80,3 +80,39 @@ FcFontSetAdd (FcFontSet *s, FcPattern *font)
|
|||
s->fonts[s->nfont++] = font;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcFontSetPrepareSerialize (FcFontSet *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->nfont; i++)
|
||||
if (!FcPatternPrepareSerialize(s->fonts[i]))
|
||||
return FcFalse;
|
||||
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcFontSetSerialize (FcFontSet * s)
|
||||
{
|
||||
int i;
|
||||
FcPattern * p;
|
||||
|
||||
for (i = 0; i < s->nfont; i++)
|
||||
{
|
||||
p = FcPatternSerialize (s->fonts[i]);
|
||||
if (!p) return FcFalse;
|
||||
FcPatternDestroy (s->fonts[i]);
|
||||
|
||||
s->fonts[i] = p;
|
||||
}
|
||||
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
void
|
||||
FcFontSetClearStatic (void)
|
||||
{
|
||||
FcPatternClearStatic();
|
||||
}
|
||||
|
|
206
src/fcint.h
206
src/fcint.h
|
@ -41,6 +41,7 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/* unused */
|
||||
typedef struct _FcSymbolic {
|
||||
const char *name;
|
||||
int value;
|
||||
|
@ -108,22 +109,46 @@ typedef enum _FcValueBinding {
|
|||
FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame
|
||||
} FcValueBinding;
|
||||
|
||||
typedef struct _FcStrSetPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
struct _FcStrSet *dyn;
|
||||
} u;
|
||||
} FcStrSetPtr;
|
||||
|
||||
typedef struct _FcValueListPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
struct _FcValueList *dyn;
|
||||
} u;
|
||||
} FcValueListPtr;
|
||||
|
||||
typedef struct _FcValueList {
|
||||
struct _FcValueList *next;
|
||||
FcValueListPtr next;
|
||||
|
||||
FcValue value;
|
||||
FcValueBinding binding;
|
||||
} FcValueList;
|
||||
|
||||
typedef struct _FcPatternElt {
|
||||
const char *object;
|
||||
FcValueList *values;
|
||||
} FcPatternElt;
|
||||
typedef struct _FcPatternEltPtr {
|
||||
FcStorage storage;
|
||||
union {
|
||||
int stat;
|
||||
struct _FcPatternElt *dyn;
|
||||
} u;
|
||||
} FcPatternEltPtr;
|
||||
|
||||
typedef struct _FcPatternElt {
|
||||
FcObjectPtr object;
|
||||
FcValueListPtr values;
|
||||
} FcPatternElt;
|
||||
|
||||
struct _FcPattern {
|
||||
int num;
|
||||
int size;
|
||||
FcPatternElt *elts;
|
||||
FcPatternEltPtr elts;
|
||||
int ref;
|
||||
};
|
||||
|
||||
|
@ -197,15 +222,28 @@ typedef struct _FcCharLeaf {
|
|||
struct _FcCharSet {
|
||||
int ref; /* reference count */
|
||||
int num; /* size of leaves and numbers arrays */
|
||||
FcStorage storage;
|
||||
union {
|
||||
struct {
|
||||
FcCharLeaf **leaves;
|
||||
FcChar16 *numbers;
|
||||
} dyn;
|
||||
struct {
|
||||
int leafidx_offset;
|
||||
int numbers_offset;
|
||||
} stat;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct _FcStrSet {
|
||||
int ref; /* reference count */
|
||||
int num;
|
||||
int size;
|
||||
FcStorage storage;
|
||||
union {
|
||||
FcChar8 **strs;
|
||||
int stridx_offset;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct _FcStrList {
|
||||
|
@ -527,9 +565,30 @@ FcNameParseCharSet (FcChar8 *string);
|
|||
FcCharLeaf *
|
||||
FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4);
|
||||
|
||||
void
|
||||
FcCharSetPtrDestroy (FcCharSetPtr fcs);
|
||||
|
||||
void
|
||||
FcCharSetClearStatic(void);
|
||||
|
||||
FcBool
|
||||
FcCharSetPrepareSerialize(FcCharSet *c);
|
||||
|
||||
FcCharSetPtr
|
||||
FcCharSetSerialize(FcCharSet *c);
|
||||
|
||||
FcCharSetPtr
|
||||
FcCharSetPtrCreateDynamic(FcCharSet *c);
|
||||
|
||||
FcCharLeaf *
|
||||
FcCharSetGetLeaf(const FcCharSet *c, int i);
|
||||
|
||||
FcChar16 *
|
||||
FcCharSetGetNumbers(const FcCharSet *c);
|
||||
|
||||
/* fcdbg.c */
|
||||
void
|
||||
FcValueListPrint (const FcValueList *l);
|
||||
FcValueListPrint (const FcValueListPtr l);
|
||||
|
||||
void
|
||||
FcLangSetPrint (const FcLangSet *ls);
|
||||
|
@ -552,6 +611,9 @@ FcSubstPrint (const FcSubst *subst);
|
|||
int
|
||||
FcDebug (void);
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetPtrU (FcCharSetPtr mi);
|
||||
|
||||
/* fcdir.c */
|
||||
|
||||
FcBool
|
||||
|
@ -596,6 +658,16 @@ const FcCharMap *
|
|||
FcFreeTypeGetPrivateMap (FT_Encoding encoding);
|
||||
|
||||
/* fcfs.c */
|
||||
|
||||
void
|
||||
FcFontSetClearStatic (void);
|
||||
|
||||
FcBool
|
||||
FcFontSetPrepareSerialize (FcFontSet * s);
|
||||
|
||||
FcBool
|
||||
FcFontSetSerialize (FcFontSet * s);
|
||||
|
||||
/* fcgram.y */
|
||||
int
|
||||
FcConfigparse (void);
|
||||
|
@ -676,6 +748,24 @@ FcNameParseLangSet (const FcChar8 *string);
|
|||
FcBool
|
||||
FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
|
||||
|
||||
void
|
||||
FcLangSetClearStatic (void);
|
||||
|
||||
FcBool
|
||||
FcLangSetPrepareSerialize (FcLangSet *l);
|
||||
|
||||
FcLangSetPtr
|
||||
FcLangSetSerialize (FcLangSet *l);
|
||||
|
||||
FcLangSet *
|
||||
FcLangSetPtrU (FcLangSetPtr li);
|
||||
|
||||
FcLangSetPtr
|
||||
FcLangSetPtrCreateDynamic (FcLangSet *l);
|
||||
|
||||
void
|
||||
FcLangSetPtrDestroy (FcLangSetPtr li);
|
||||
|
||||
/* fclist.c */
|
||||
|
||||
FcBool
|
||||
|
@ -684,6 +774,18 @@ FcListPatternMatchAny (const FcPattern *p,
|
|||
|
||||
/* fcmatch.c */
|
||||
|
||||
/* fcmmap.c */
|
||||
|
||||
void
|
||||
FcCacheClearStatic(void);
|
||||
|
||||
FcBool
|
||||
FcCachePrepareSerialize(FcConfig * config);
|
||||
|
||||
FcBool
|
||||
FcCacheSerialize (FcConfig * config);
|
||||
|
||||
|
||||
/* fcname.c */
|
||||
|
||||
FcBool
|
||||
|
@ -691,7 +793,7 @@ FcNameBool (const FcChar8 *v, FcBool *result);
|
|||
|
||||
/* fcpat.c */
|
||||
void
|
||||
FcValueListDestroy (FcValueList *l);
|
||||
FcValueListDestroy (FcValueListPtr l);
|
||||
|
||||
FcPatternElt *
|
||||
FcPatternFindElt (const FcPattern *p, const char *object);
|
||||
|
@ -715,19 +817,100 @@ FcPatternThawAll (void);
|
|||
FcBool
|
||||
FcPatternAppend (FcPattern *p, FcPattern *s);
|
||||
|
||||
const char *
|
||||
void
|
||||
FcObjectClearStatic(void);
|
||||
|
||||
FcObjectPtr
|
||||
FcObjectStaticName (const char *name);
|
||||
|
||||
FcBool
|
||||
FcObjectPrepareSerialize (FcObjectPtr si);
|
||||
|
||||
const char *
|
||||
FcObjectPtrU (FcObjectPtr p);
|
||||
|
||||
int
|
||||
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
|
||||
|
||||
FcObjectPtr
|
||||
FcObjectPtrCreateDynamic (const char * s);
|
||||
|
||||
void
|
||||
FcObjectPtrDestroy (FcObjectPtr p);
|
||||
|
||||
FcBool
|
||||
FcPatternPrepareSerialize (FcPattern *p);
|
||||
|
||||
void
|
||||
FcValueListClearStatic (void);
|
||||
|
||||
void
|
||||
FcPatternClearStatic (void);
|
||||
|
||||
FcValueList *
|
||||
FcValueListPtrU(FcValueListPtr p);
|
||||
|
||||
FcPatternElt *
|
||||
FcPatternEltU (FcPatternEltPtr pei);
|
||||
|
||||
FcValueListPtr
|
||||
FcValueListPtrCreateDynamic(FcValueList * p);
|
||||
|
||||
FcBool
|
||||
FcValueListPrepareSerialize (FcValueList *p);
|
||||
|
||||
FcValueListPtr
|
||||
FcValueListSerialize(FcValueList *pi);
|
||||
|
||||
FcPattern *
|
||||
FcPatternSerialize (FcPattern * p);
|
||||
|
||||
/* fcrender.c */
|
||||
|
||||
/* fcmatrix.c */
|
||||
|
||||
extern const FcMatrix FcIdentityMatrix;
|
||||
extern const FcMatrixPtr FcIdentityMatrix;
|
||||
|
||||
void
|
||||
FcMatrixFree (FcMatrix *mat);
|
||||
|
||||
void
|
||||
FcMatrixPtrDestroy (FcMatrixPtr mi);
|
||||
|
||||
FcBool
|
||||
FcMatrixPrepareSerialize(FcMatrix *m);
|
||||
|
||||
FcMatrixPtr
|
||||
FcMatrixSerialize(FcMatrix *m);
|
||||
|
||||
FcMatrix *
|
||||
FcMatrixPtrU (FcMatrixPtr mi);
|
||||
|
||||
FcMatrixPtr
|
||||
FcMatrixPtrCreateDynamic (FcMatrix *m);
|
||||
|
||||
void
|
||||
FcMatrixClearStatic (void);
|
||||
|
||||
/* fcstr.c */
|
||||
FcStrSet *
|
||||
FcStrSetPtrU (const FcStrSetPtr set);
|
||||
|
||||
FcStrSetPtr
|
||||
FcStrSetPtrCreateDynamic (const FcStrSet * set);
|
||||
|
||||
void
|
||||
FcStrSetClearStatic (void);
|
||||
|
||||
FcBool
|
||||
FcStrSetPrepareSerialize (const FcStrSet *set);
|
||||
|
||||
void
|
||||
FcStrSetSort (FcStrSet * set);
|
||||
|
||||
FcChar8 *
|
||||
FcStrSetGet (const FcStrSet *set, int i);
|
||||
|
||||
FcChar8 *
|
||||
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
|
||||
|
||||
|
@ -752,6 +935,9 @@ FcStrBufString (FcStrBuf *buf, const FcChar8 *s);
|
|||
FcBool
|
||||
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
|
||||
|
||||
FcStrSetPtr
|
||||
FcStrSetSerialize (FcStrSet *set);
|
||||
|
||||
int
|
||||
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
|
||||
|
||||
|
|
162
src/fclang.c
162
src/fclang.c
|
@ -22,6 +22,8 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include "fcint.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -38,7 +40,7 @@ typedef struct {
|
|||
|
||||
struct _FcLangSet {
|
||||
FcChar32 map[NUM_LANG_SET_MAP];
|
||||
FcStrSet *extra;
|
||||
FcStrSetPtr extra;
|
||||
};
|
||||
|
||||
#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
|
||||
|
@ -48,7 +50,7 @@ FcLangSet *
|
|||
FcFreeTypeLangSet (const FcCharSet *charset,
|
||||
const FcChar8 *exclusiveLang)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
FcChar32 missing;
|
||||
const FcCharSet *exclusiveCharset = 0;
|
||||
FcLangSet *ls;
|
||||
|
@ -67,9 +69,14 @@ FcFreeTypeLangSet (const FcCharSet *charset,
|
|||
* not support other Han languages
|
||||
*/
|
||||
if (exclusiveCharset &&
|
||||
FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang) &&
|
||||
fcLangCharSets[i].charset.leaves != exclusiveCharset->leaves)
|
||||
FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang))
|
||||
{
|
||||
if (fcLangCharSets[i].charset.num != exclusiveCharset->num)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < fcLangCharSets[i].charset.num; j++)
|
||||
if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) !=
|
||||
FcCharSetGetLeaf(exclusiveCharset, j))
|
||||
continue;
|
||||
}
|
||||
missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
|
||||
|
@ -210,15 +217,22 @@ FcLangSetCreate (void)
|
|||
return 0;
|
||||
FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet));
|
||||
memset (ls->map, '\0', sizeof (ls->map));
|
||||
ls->extra = 0;
|
||||
ls->extra = FcStrSetPtrCreateDynamic(0);
|
||||
return ls;
|
||||
}
|
||||
|
||||
void
|
||||
FcLangSetPtrDestroy (FcLangSetPtr li)
|
||||
{
|
||||
if (li.storage == FcStorageDynamic)
|
||||
FcLangSetDestroy(FcLangSetPtrU(li));
|
||||
}
|
||||
|
||||
void
|
||||
FcLangSetDestroy (FcLangSet *ls)
|
||||
{
|
||||
if (ls->extra)
|
||||
FcStrSetDestroy (ls->extra);
|
||||
if (FcStrSetPtrU(ls->extra))
|
||||
FcStrSetDestroy (FcStrSetPtrU(ls->extra));
|
||||
FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet));
|
||||
free (ls);
|
||||
}
|
||||
|
@ -232,21 +246,21 @@ FcLangSetCopy (const FcLangSet *ls)
|
|||
if (!new)
|
||||
goto bail0;
|
||||
memcpy (new->map, ls->map, sizeof (new->map));
|
||||
if (ls->extra)
|
||||
if (FcStrSetPtrU(ls->extra))
|
||||
{
|
||||
FcStrList *list;
|
||||
FcChar8 *extra;
|
||||
|
||||
new->extra = FcStrSetCreate ();
|
||||
if (!new->extra)
|
||||
new->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
|
||||
if (!FcStrSetPtrU(new->extra))
|
||||
goto bail1;
|
||||
|
||||
list = FcStrListCreate (ls->extra);
|
||||
list = FcStrListCreate (FcStrSetPtrU(ls->extra));
|
||||
if (!list)
|
||||
goto bail1;
|
||||
|
||||
while ((extra = FcStrListNext (list)))
|
||||
if (!FcStrSetAdd (new->extra, extra))
|
||||
if (!FcStrSetAdd (FcStrSetPtrU(new->extra), extra))
|
||||
{
|
||||
FcStrListDone (list);
|
||||
goto bail1;
|
||||
|
@ -327,13 +341,13 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
|
|||
FcLangSetBitSet (ls, id);
|
||||
return FcTrue;
|
||||
}
|
||||
if (!ls->extra)
|
||||
if (!FcStrSetPtrU(ls->extra))
|
||||
{
|
||||
ls->extra = FcStrSetCreate ();
|
||||
if (!ls->extra)
|
||||
ls->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
|
||||
if (!FcStrSetPtrU(ls->extra))
|
||||
return FcFalse;
|
||||
}
|
||||
return FcStrSetAdd (ls->extra, lang);
|
||||
return FcStrSetAdd (FcStrSetPtrU(ls->extra), lang);
|
||||
}
|
||||
|
||||
FcLangResult
|
||||
|
@ -365,9 +379,9 @@ FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
|
|||
if (FcLangSetBitGet (ls, i) && r < best)
|
||||
best = r;
|
||||
}
|
||||
if (ls->extra)
|
||||
if (FcStrSetPtrU(ls->extra))
|
||||
{
|
||||
FcStrList *list = FcStrListCreate (ls->extra);
|
||||
FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
|
||||
FcChar8 *extra;
|
||||
FcLangResult r;
|
||||
|
||||
|
@ -423,15 +437,15 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb)
|
|||
best = FcLangDifferentCountry;
|
||||
break;
|
||||
}
|
||||
if (lsa->extra)
|
||||
if (FcStrSetPtrU(lsa->extra))
|
||||
{
|
||||
r = FcLangSetCompareStrSet (lsb, lsa->extra);
|
||||
r = FcLangSetCompareStrSet (lsb, FcStrSetPtrU(lsa->extra));
|
||||
if (r < best)
|
||||
best = r;
|
||||
}
|
||||
if (best > FcLangEqual && lsb->extra)
|
||||
if (best > FcLangEqual && FcStrSetPtrU(lsb->extra))
|
||||
{
|
||||
r = FcLangSetCompareStrSet (lsa, lsb->extra);
|
||||
r = FcLangSetCompareStrSet (lsa, FcStrSetPtrU(lsb->extra));
|
||||
if (r < best)
|
||||
best = r;
|
||||
}
|
||||
|
@ -450,7 +464,7 @@ FcLangSetPromote (const FcChar8 *lang)
|
|||
int id;
|
||||
|
||||
memset (ls.map, '\0', sizeof (ls.map));
|
||||
ls.extra = 0;
|
||||
ls.extra = FcStrSetPtrCreateDynamic(0);
|
||||
id = FcLangSetIndex (lang);
|
||||
if (id > 0)
|
||||
{
|
||||
|
@ -458,10 +472,11 @@ FcLangSetPromote (const FcChar8 *lang)
|
|||
}
|
||||
else
|
||||
{
|
||||
ls.extra = &strs;
|
||||
ls.extra = FcStrSetPtrCreateDynamic(&strs);
|
||||
strs.num = 1;
|
||||
strs.size = 1;
|
||||
strs.strs = &str;
|
||||
strs.storage = FcStorageDynamic;
|
||||
strs.u.strs = &str;
|
||||
strs.ref = 1;
|
||||
str = (FcChar8 *) lang;
|
||||
}
|
||||
|
@ -476,8 +491,8 @@ FcLangSetHash (const FcLangSet *ls)
|
|||
|
||||
for (i = 0; i < NUM_LANG_SET_MAP; i++)
|
||||
h ^= ls->map[i];
|
||||
if (ls->extra)
|
||||
h ^= ls->extra->num;
|
||||
if (FcStrSetPtrU(ls->extra))
|
||||
h ^= FcStrSetPtrU(ls->extra)->num;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
@ -538,9 +553,9 @@ FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (ls->extra)
|
||||
if (FcStrSetPtrU(ls->extra))
|
||||
{
|
||||
FcStrList *list = FcStrListCreate (ls->extra);
|
||||
FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
|
||||
FcChar8 *extra;
|
||||
|
||||
if (!list)
|
||||
|
@ -568,10 +583,10 @@ FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb)
|
|||
if (lsa->map[i] != lsb->map[i])
|
||||
return FcFalse;
|
||||
}
|
||||
if (!lsa->extra && !lsb->extra)
|
||||
if (!FcStrSetPtrU(lsa->extra) && !FcStrSetPtrU(lsb->extra))
|
||||
return FcTrue;
|
||||
if (lsa->extra && lsb->extra)
|
||||
return FcStrSetEqual (lsa->extra, lsb->extra);
|
||||
if (FcStrSetPtrU(lsa->extra) && FcStrSetPtrU(lsb->extra))
|
||||
return FcStrSetEqual (FcStrSetPtrU(lsa->extra), FcStrSetPtrU(lsb->extra));
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
|
@ -605,9 +620,9 @@ FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
|
|||
FcLangContains (fcLangCharSets[i].lang, lang))
|
||||
return FcTrue;
|
||||
}
|
||||
if (ls->extra)
|
||||
if (FcStrSetPtrU(ls->extra))
|
||||
{
|
||||
FcStrList *list = FcStrListCreate (ls->extra);
|
||||
FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
|
||||
FcChar8 *extra;
|
||||
|
||||
if (list)
|
||||
|
@ -661,9 +676,9 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (lsb->extra)
|
||||
if (FcStrSetPtrU(lsb->extra))
|
||||
{
|
||||
FcStrList *list = FcStrListCreate (lsb->extra);
|
||||
FcStrList *list = FcStrListCreate (FcStrSetPtrU(lsb->extra));
|
||||
FcChar8 *extra;
|
||||
|
||||
if (list)
|
||||
|
@ -684,3 +699,78 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
|
|||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcLangSet * langsets = 0;
|
||||
static int langset_ptr = 0, langset_count = 0;
|
||||
|
||||
FcLangSet *
|
||||
FcLangSetPtrU (FcLangSetPtr li)
|
||||
{
|
||||
switch (li.storage)
|
||||
{
|
||||
case FcStorageDynamic:
|
||||
return li.u.dyn;
|
||||
case FcStorageStatic:
|
||||
return &langsets[li.u.stat];
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
FcLangSetPtr
|
||||
FcLangSetPtrCreateDynamic (FcLangSet *li)
|
||||
{
|
||||
FcLangSetPtr new;
|
||||
new.storage = FcStorageDynamic;
|
||||
new.u.dyn = li;
|
||||
return new;
|
||||
}
|
||||
|
||||
void
|
||||
FcLangSetClearStatic (void)
|
||||
{
|
||||
FcStrSetClearStatic();
|
||||
langset_ptr = 0;
|
||||
langset_count = 0;
|
||||
}
|
||||
|
||||
/* should only write one copy of any particular FcLangSet */
|
||||
FcBool
|
||||
FcLangSetPrepareSerialize (FcLangSet *l)
|
||||
{
|
||||
langset_count++;
|
||||
if (l && FcStrSetPtrU(l->extra))
|
||||
return FcStrSetPrepareSerialize (FcStrSetPtrU(l->extra));
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcLangSetPtr
|
||||
FcLangSetSerialize(FcLangSet *l)
|
||||
{
|
||||
FcLangSetPtr new;
|
||||
int p = langset_ptr;
|
||||
|
||||
if (!l) return FcLangSetPtrCreateDynamic(0);
|
||||
|
||||
if (!langsets)
|
||||
{
|
||||
FcLangSet* t;
|
||||
t = (FcLangSet *)malloc(langset_count * sizeof(FcLangSet));
|
||||
if (!t)
|
||||
return FcLangSetPtrCreateDynamic(0);
|
||||
langsets = t;
|
||||
langset_ptr = 0;
|
||||
}
|
||||
|
||||
langsets[langset_ptr] = *l;
|
||||
if (FcStrSetPtrU(l->extra))
|
||||
langsets[langset_ptr].extra =
|
||||
FcStrSetSerialize(FcStrSetPtrU(l->extra));
|
||||
else
|
||||
langsets[langset_ptr].extra = FcStrSetPtrCreateDynamic(0);
|
||||
langset_ptr++;
|
||||
new.storage = FcStorageStatic;
|
||||
new.u.stat = p;
|
||||
return new;
|
||||
}
|
||||
|
|
104
src/fclist.c
104
src/fclist.c
|
@ -23,6 +23,9 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include "fcint.h"
|
||||
|
||||
FcObjectSet *
|
||||
|
@ -44,17 +47,18 @@ FcBool
|
|||
FcObjectSetAdd (FcObjectSet *os, const char *object)
|
||||
{
|
||||
int s;
|
||||
const char **objects;
|
||||
FcObjectPtr *objects;
|
||||
FcObjectPtr obj;
|
||||
int high, low, mid, c;
|
||||
|
||||
if (os->nobject == os->sobject)
|
||||
{
|
||||
s = os->sobject + 4;
|
||||
if (os->objects)
|
||||
objects = (const char **) realloc ((void *) os->objects,
|
||||
s * sizeof (const char *));
|
||||
objects = (FcObjectPtr *) realloc ((void *) os->objects,
|
||||
s * sizeof (FcObjectPtr));
|
||||
else
|
||||
objects = (const char **) malloc (s * sizeof (const char *));
|
||||
objects = (FcObjectPtr *) malloc (s * sizeof (FcObjectPtr));
|
||||
if (!objects)
|
||||
return FcFalse;
|
||||
if (os->sobject)
|
||||
|
@ -67,11 +71,11 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
|
|||
low = 0;
|
||||
mid = 0;
|
||||
c = 1;
|
||||
object = FcObjectStaticName (object);
|
||||
obj = FcObjectStaticName (object);
|
||||
while (low <= high)
|
||||
{
|
||||
mid = (low + high) >> 1;
|
||||
c = os->objects[mid] - object;
|
||||
c = FcObjectPtrCompare(os->objects[mid], obj);
|
||||
if (c == 0)
|
||||
return FcTrue;
|
||||
if (c < 0)
|
||||
|
@ -82,8 +86,8 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
|
|||
if (c < 0)
|
||||
mid++;
|
||||
memmove (os->objects + mid + 1, os->objects + mid,
|
||||
(os->nobject - mid) * sizeof (const char *));
|
||||
os->objects[mid] = object;
|
||||
(os->nobject - mid) * sizeof (FcObjectPtr));
|
||||
os->objects[mid] = obj;
|
||||
os->nobject++;
|
||||
return FcTrue;
|
||||
}
|
||||
|
@ -125,51 +129,59 @@ FcObjectSetBuild (const char *first, ...)
|
|||
* Font must have a containing value for every value in the pattern
|
||||
*/
|
||||
static FcBool
|
||||
FcListValueListMatchAny (FcValueList *patOrig, /* pattern */
|
||||
FcValueList *fntOrig) /* font */
|
||||
FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
|
||||
FcValueListPtr fntOrig) /* font */
|
||||
{
|
||||
FcValueList *pat, *fnt;
|
||||
FcValueListPtr pat, fnt;
|
||||
|
||||
for (pat = patOrig; pat; pat = pat->next)
|
||||
for (pat = patOrig; FcValueListPtrU(pat);
|
||||
pat = FcValueListPtrU(pat)->next)
|
||||
{
|
||||
for (fnt = fntOrig; fnt; fnt = fnt->next)
|
||||
for (fnt = fntOrig; FcValueListPtrU(fnt);
|
||||
fnt = FcValueListPtrU(fnt)->next)
|
||||
{
|
||||
/*
|
||||
* make sure the font 'contains' the pattern.
|
||||
* (OpListing is OpContains except for strings
|
||||
* where it requires an exact match)
|
||||
*/
|
||||
if (FcConfigCompareValue (fnt->value,
|
||||
if (FcConfigCompareValue (FcValueListPtrU(fnt)->value,
|
||||
FcOpListing,
|
||||
pat->value))
|
||||
FcValueListPtrU(pat)->value))
|
||||
break;
|
||||
}
|
||||
if (!fnt)
|
||||
if (!FcValueListPtrU(fnt))
|
||||
return FcFalse;
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcListValueListEqual (FcValueList *v1orig,
|
||||
FcValueList *v2orig)
|
||||
FcListValueListEqual (FcValueListPtr v1orig,
|
||||
FcValueListPtr v2orig)
|
||||
{
|
||||
FcValueList *v1, *v2;
|
||||
FcValueListPtr v1, v2;
|
||||
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
for (v1 = v1orig; FcValueListPtrU(v1);
|
||||
v1 = FcValueListPtrU(v1)->next)
|
||||
{
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
if (FcValueEqual (v1->value, v2->value))
|
||||
for (v2 = v2orig; FcValueListPtrU(v2);
|
||||
v2 = FcValueListPtrU(v2)->next)
|
||||
if (FcValueEqual (FcValueListPtrU(v1)->value,
|
||||
FcValueListPtrU(v2)->value))
|
||||
break;
|
||||
if (!v2)
|
||||
if (!FcValueListPtrU(v2))
|
||||
return FcFalse;
|
||||
}
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
for (v2 = v2orig; FcValueListPtrU(v2);
|
||||
v2 = FcValueListPtrU(v2)->next)
|
||||
{
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
if (FcValueEqual (v1->value, v2->value))
|
||||
for (v1 = v1orig; FcValueListPtrU(v1);
|
||||
v1 = FcValueListPtrU(v1)->next)
|
||||
if (FcValueEqual (FcValueListPtrU(v1)->value,
|
||||
FcValueListPtrU(v2)->value))
|
||||
break;
|
||||
if (!v1)
|
||||
if (!FcValueListPtrU(v1))
|
||||
return FcFalse;
|
||||
}
|
||||
return FcTrue;
|
||||
|
@ -185,8 +197,8 @@ FcListPatternEqual (FcPattern *p1,
|
|||
|
||||
for (i = 0; i < os->nobject; i++)
|
||||
{
|
||||
e1 = FcPatternFindElt (p1, os->objects[i]);
|
||||
e2 = FcPatternFindElt (p2, os->objects[i]);
|
||||
e1 = FcPatternFindElt (p1, FcObjectPtrU(os->objects[i]));
|
||||
e2 = FcPatternFindElt (p2, FcObjectPtrU(os->objects[i]));
|
||||
if (!e1 && !e2)
|
||||
continue;
|
||||
if (!e1 || !e2)
|
||||
|
@ -210,10 +222,11 @@ FcListPatternMatchAny (const FcPattern *p,
|
|||
|
||||
for (i = 0; i < p->num; i++)
|
||||
{
|
||||
e = FcPatternFindElt (font, p->elts[i].object);
|
||||
e = FcPatternFindElt (font,
|
||||
FcObjectPtrU((FcPatternEltU(p->elts)+i)->object));
|
||||
if (!e)
|
||||
return FcFalse;
|
||||
if (!FcListValueListMatchAny (p->elts[i].values, /* pat elts */
|
||||
if (!FcListValueListMatchAny ((FcPatternEltU(p->elts)+i)->values, /* pat elts */
|
||||
e->values)) /* font elts */
|
||||
return FcFalse;
|
||||
}
|
||||
|
@ -242,30 +255,30 @@ FcListValueHash (FcValue v)
|
|||
case FcTypeDouble:
|
||||
return (FcChar32) (int) v.u.d;
|
||||
case FcTypeString:
|
||||
return FcStrHashIgnoreCase (v.u.s);
|
||||
return FcStrHashIgnoreCase (FcObjectPtrU(v.u.si));
|
||||
case FcTypeBool:
|
||||
return (FcChar32) v.u.b;
|
||||
case FcTypeMatrix:
|
||||
return FcListMatrixHash (v.u.m);
|
||||
return FcListMatrixHash (FcMatrixPtrU(v.u.mi));
|
||||
case FcTypeCharSet:
|
||||
return FcCharSetCount (v.u.c);
|
||||
return FcCharSetCount (FcCharSetPtrU(v.u.ci));
|
||||
case FcTypeFTFace:
|
||||
return (long) v.u.f;
|
||||
case FcTypeLangSet:
|
||||
return FcLangSetHash (v.u.l);
|
||||
return FcLangSetHash (FcLangSetPtrU(v.u.li));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcListValueListHash (FcValueList *list)
|
||||
FcListValueListHash (FcValueListPtr list)
|
||||
{
|
||||
FcChar32 h = 0;
|
||||
|
||||
while (list)
|
||||
while (FcValueListPtrU(list))
|
||||
{
|
||||
h = h ^ FcListValueHash (list->value);
|
||||
list = list->next;
|
||||
h = h ^ FcListValueHash (FcValueListPtrU(list)->value);
|
||||
list = FcValueListPtrU(list)->next;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
@ -280,7 +293,7 @@ FcListPatternHash (FcPattern *font,
|
|||
|
||||
for (n = 0; n < os->nobject; n++)
|
||||
{
|
||||
e = FcPatternFindElt (font, os->objects[n]);
|
||||
e = FcPatternFindElt (font, FcObjectPtrU(os->objects[n]));
|
||||
if (e)
|
||||
h = h ^ FcListValueListHash (e->values);
|
||||
}
|
||||
|
@ -334,7 +347,7 @@ FcListAppend (FcListHashTable *table,
|
|||
{
|
||||
int o;
|
||||
FcPatternElt *e;
|
||||
FcValueList *v;
|
||||
FcValueListPtr v;
|
||||
FcChar32 hash;
|
||||
FcListBucket **prev, *bucket;
|
||||
|
||||
|
@ -358,14 +371,15 @@ FcListAppend (FcListHashTable *table,
|
|||
|
||||
for (o = 0; o < os->nobject; o++)
|
||||
{
|
||||
e = FcPatternFindElt (font, os->objects[o]);
|
||||
e = FcPatternFindElt (font, FcObjectPtrU(os->objects[o]));
|
||||
if (e)
|
||||
{
|
||||
for (v = e->values; v; v = v->next)
|
||||
for (v = e->values; FcValueListPtrU(v);
|
||||
v = FcValueListPtrU(v)->next)
|
||||
{
|
||||
if (!FcPatternAdd (bucket->pattern,
|
||||
os->objects[o],
|
||||
v->value, FcTrue))
|
||||
FcObjectPtrU(os->objects[o]),
|
||||
FcValueListPtrU(v)->value, FcTrue))
|
||||
goto bail2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ FcCompareString (char *object, FcValue value1, FcValue value2)
|
|||
{
|
||||
if (value2.type != FcTypeString || value1.type != FcTypeString)
|
||||
return -1.0;
|
||||
return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
|
||||
return (double) FcStrCmpIgnoreCase
|
||||
(FcObjectPtrU(value1.u.si), FcObjectPtrU(value2.u.si)) != 0;
|
||||
}
|
||||
|
||||
static double
|
||||
|
@ -71,7 +72,8 @@ FcCompareFamily (char *object, FcValue value1, FcValue value2)
|
|||
{
|
||||
if (value2.type != FcTypeString || value1.type != FcTypeString)
|
||||
return -1.0;
|
||||
return (double) FcStrCmpIgnoreBlanksAndCase (value1.u.s, value2.u.s) != 0;
|
||||
return (double) FcStrCmpIgnoreBlanksAndCase
|
||||
(FcObjectPtrU(value1.u.si), FcObjectPtrU(value2.u.si)) != 0;
|
||||
}
|
||||
|
||||
static double
|
||||
|
@ -83,10 +85,12 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
|
|||
case FcTypeLangSet:
|
||||
switch (value2.type) {
|
||||
case FcTypeLangSet:
|
||||
result = FcLangSetCompare (value1.u.l, value2.u.l);
|
||||
result = FcLangSetCompare (FcLangSetPtrU(value1.u.li),
|
||||
FcLangSetPtrU(value2.u.li));
|
||||
break;
|
||||
case FcTypeString:
|
||||
result = FcLangSetHasLang (value1.u.l, value2.u.s);
|
||||
result = FcLangSetHasLang (FcLangSetPtrU(value1.u.li),
|
||||
FcObjectPtrU(value2.u.si));
|
||||
break;
|
||||
default:
|
||||
return -1.0;
|
||||
|
@ -95,10 +99,12 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
|
|||
case FcTypeString:
|
||||
switch (value2.type) {
|
||||
case FcTypeLangSet:
|
||||
result = FcLangSetHasLang (value2.u.l, value1.u.s);
|
||||
result = FcLangSetHasLang (FcLangSetPtrU(value2.u.li),
|
||||
FcObjectPtrU(value1.u.si));
|
||||
break;
|
||||
case FcTypeString:
|
||||
result = FcLangCompare (value1.u.s, value2.u.s);
|
||||
result = FcLangCompare (FcObjectPtrU(value1.u.si),
|
||||
FcObjectPtrU(value2.u.si));
|
||||
break;
|
||||
default:
|
||||
return -1.0;
|
||||
|
@ -131,7 +137,8 @@ FcCompareCharSet (char *object, FcValue value1, FcValue value2)
|
|||
{
|
||||
if (value2.type != FcTypeCharSet || value1.type != FcTypeCharSet)
|
||||
return -1.0;
|
||||
return (double) FcCharSetSubtractCount (value1.u.c, value2.u.c);
|
||||
return (double) FcCharSetSubtractCount (FcCharSetPtrU(value1.u.ci),
|
||||
FcCharSetPtrU(value2.u.ci));
|
||||
}
|
||||
|
||||
static double
|
||||
|
@ -241,13 +248,13 @@ static FcMatcher _FcMatchers [] = {
|
|||
|
||||
static FcBool
|
||||
FcCompareValueList (const char *object,
|
||||
FcValueList *v1orig, /* pattern */
|
||||
FcValueList *v2orig, /* target */
|
||||
FcValueListPtr v1orig, /* pattern */
|
||||
FcValueListPtr v2orig, /* target */
|
||||
FcValue *bestValue,
|
||||
double *value,
|
||||
FcResult *result)
|
||||
{
|
||||
FcValueList *v1, *v2;
|
||||
FcValueListPtr v1, v2;
|
||||
double v, best, bestStrong, bestWeak;
|
||||
int i;
|
||||
int j;
|
||||
|
@ -308,7 +315,7 @@ FcCompareValueList (const char *object,
|
|||
(FcChar8 *) object) != 0)
|
||||
{
|
||||
if (bestValue)
|
||||
*bestValue = v2orig->value;
|
||||
*bestValue = FcValueListPtrU(v2orig)->value;
|
||||
return FcTrue;
|
||||
}
|
||||
#if 0
|
||||
|
@ -329,13 +336,15 @@ FcCompareValueList (const char *object,
|
|||
bestStrong = 1e99;
|
||||
bestWeak = 1e99;
|
||||
j = 0;
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
for (v1 = v1orig; FcValueListPtrU(v1);
|
||||
v1 = FcValueListPtrU(v1)->next)
|
||||
{
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
for (v2 = v2orig; FcValueListPtrU(v2);
|
||||
v2 = FcValueListPtrU(v2)->next)
|
||||
{
|
||||
v = (*_FcMatchers[i].compare) (_FcMatchers[i].object,
|
||||
v1->value,
|
||||
v2->value);
|
||||
FcValueListPtrU(v1)->value,
|
||||
FcValueListPtrU(v2)->value);
|
||||
if (v < 0)
|
||||
{
|
||||
*result = FcResultTypeMismatch;
|
||||
|
@ -347,10 +356,10 @@ FcCompareValueList (const char *object,
|
|||
if (v < best)
|
||||
{
|
||||
if (bestValue)
|
||||
*bestValue = v2->value;
|
||||
*bestValue = FcValueListPtrU(v2)->value;
|
||||
best = v;
|
||||
}
|
||||
if (v1->binding == FcValueBindingStrong)
|
||||
if (FcValueListPtrU(v1)->binding == FcValueBindingStrong)
|
||||
{
|
||||
if (v < bestStrong)
|
||||
bestStrong = v;
|
||||
|
@ -406,16 +415,17 @@ FcCompare (FcPattern *pat,
|
|||
i2 = 0;
|
||||
while (i1 < pat->num && i2 < fnt->num)
|
||||
{
|
||||
i = pat->elts[i1].object - fnt->elts[i2].object;
|
||||
i = FcObjectPtrCompare((FcPatternEltU(pat->elts)+i1)->object,
|
||||
(FcPatternEltU(fnt->elts)+i2)->object);
|
||||
if (i > 0)
|
||||
i2++;
|
||||
else if (i < 0)
|
||||
i1++;
|
||||
else
|
||||
{
|
||||
if (!FcCompareValueList (pat->elts[i1].object,
|
||||
pat->elts[i1].values,
|
||||
fnt->elts[i2].values,
|
||||
if (!FcCompareValueList (FcObjectPtrU((FcPatternEltU(pat->elts)+i1)->object),
|
||||
(FcPatternEltU(pat->elts)+i1)->values,
|
||||
(FcPatternEltU(fnt->elts)+i2)->values,
|
||||
0,
|
||||
value,
|
||||
result))
|
||||
|
@ -456,11 +466,11 @@ FcFontRenderPrepare (FcConfig *config,
|
|||
return 0;
|
||||
for (i = 0; i < font->num; i++)
|
||||
{
|
||||
fe = &font->elts[i];
|
||||
pe = FcPatternFindElt (pat, fe->object);
|
||||
fe = FcPatternEltU(font->elts)+i;
|
||||
pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object));
|
||||
if (pe)
|
||||
{
|
||||
if (!FcCompareValueList (pe->object, pe->values,
|
||||
if (!FcCompareValueList (FcObjectPtrU(pe->object), pe->values,
|
||||
fe->values, &v, 0, &result))
|
||||
{
|
||||
FcPatternDestroy (new);
|
||||
|
@ -468,15 +478,16 @@ FcFontRenderPrepare (FcConfig *config,
|
|||
}
|
||||
}
|
||||
else
|
||||
v = fe->values->value;
|
||||
FcPatternAdd (new, fe->object, v, FcFalse);
|
||||
v = FcValueListPtrU(fe->values)->value;
|
||||
FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
|
||||
}
|
||||
for (i = 0; i < pat->num; i++)
|
||||
{
|
||||
pe = &pat->elts[i];
|
||||
fe = FcPatternFindElt (font, pe->object);
|
||||
pe = FcPatternEltU(pat->elts)+i;
|
||||
fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
|
||||
if (!fe)
|
||||
FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
|
||||
FcPatternAdd (new, FcObjectPtrU(pe->object),
|
||||
FcValueListPtrU(pe->values)->value, FcTrue);
|
||||
}
|
||||
FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
|
||||
return new;
|
||||
|
|
|
@ -27,7 +27,11 @@
|
|||
#include <ctype.h>
|
||||
#include "fcint.h"
|
||||
|
||||
const FcMatrix FcIdentityMatrix = { 1, 0, 0, 1 };
|
||||
FcMatrix _id = { 1, 0, 0, 1 };
|
||||
const FcMatrixPtr FcIdentityMatrix = {
|
||||
.storage = FcStorageDynamic,
|
||||
.u.dyn = &_id
|
||||
};
|
||||
|
||||
FcMatrix *
|
||||
FcMatrixCopy (const FcMatrix *mat)
|
||||
|
@ -43,10 +47,17 @@ FcMatrixCopy (const FcMatrix *mat)
|
|||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
FcMatrixPtrDestroy (FcMatrixPtr mi)
|
||||
{
|
||||
if (mi.storage == FcStorageDynamic)
|
||||
FcMatrixFree (mi.u.dyn);
|
||||
}
|
||||
|
||||
void
|
||||
FcMatrixFree (FcMatrix *mat)
|
||||
{
|
||||
if (mat != &FcIdentityMatrix)
|
||||
if (mat != FcMatrixPtrU(FcIdentityMatrix))
|
||||
{
|
||||
FcMemFree (FC_MEM_MATRIX, sizeof (FcMatrix));
|
||||
free (mat);
|
||||
|
@ -115,3 +126,59 @@ FcMatrixShear (FcMatrix *m, double sh, double sv)
|
|||
r.yy = 1;
|
||||
FcMatrixMultiply (m, &r, m);
|
||||
}
|
||||
|
||||
static FcMatrix * matrices = 0;
|
||||
static int matrix_ptr = 0, matrix_count = 0;
|
||||
|
||||
void
|
||||
FcMatrixClearStatic (void)
|
||||
{
|
||||
matrices = 0;
|
||||
matrix_ptr = 0;
|
||||
matrix_count = 0;
|
||||
}
|
||||
|
||||
FcMatrix *
|
||||
FcMatrixPtrU (FcMatrixPtr mi)
|
||||
{
|
||||
switch (mi.storage)
|
||||
{
|
||||
case FcStorageDynamic:
|
||||
return mi.u.dyn;
|
||||
case FcStorageStatic:
|
||||
return &matrices[mi.u.stat];
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
FcMatrixPtr
|
||||
FcMatrixPtrCreateDynamic (FcMatrix *mi)
|
||||
{
|
||||
FcMatrixPtr new;
|
||||
new.storage = FcStorageDynamic;
|
||||
new.u.dyn = mi;
|
||||
return new;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcMatrixPrepareSerialize(FcMatrix *m)
|
||||
{
|
||||
matrix_count++;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcMatrixPtr
|
||||
FcMatrixSerialize(FcMatrix *m)
|
||||
{
|
||||
FcMatrixPtr new;
|
||||
|
||||
if (matrix_count == matrix_ptr)
|
||||
return FcMatrixPtrCreateDynamic(0);
|
||||
|
||||
new.storage = FcStorageStatic;
|
||||
new.u.stat = matrix_ptr++;
|
||||
return new;
|
||||
}
|
||||
|
||||
|
|
35
src/fcname.c
35
src/fcname.c
|
@ -321,7 +321,7 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
|
|||
v.u.i = atoi ((char *) string);
|
||||
break;
|
||||
case FcTypeString:
|
||||
v.u.s = string;
|
||||
v.u.si = FcObjectPtrCreateDynamic(string);
|
||||
break;
|
||||
case FcTypeBool:
|
||||
if (!FcNameBool (string, &v.u.b))
|
||||
|
@ -331,14 +331,14 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
|
|||
v.u.d = strtod ((char *) string, 0);
|
||||
break;
|
||||
case FcTypeMatrix:
|
||||
v.u.m = m;
|
||||
v.u.mi = FcMatrixPtrCreateDynamic(m);
|
||||
sscanf ((char *) string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
|
||||
break;
|
||||
case FcTypeCharSet:
|
||||
v.u.c = FcNameParseCharSet (string);
|
||||
v.u.ci = FcCharSetPtrCreateDynamic(FcNameParseCharSet (string));
|
||||
break;
|
||||
case FcTypeLangSet:
|
||||
v.u.l = FcNameParseLangSet (string);
|
||||
v.u.li = FcLangSetPtrCreateDynamic(FcNameParseLangSet (string));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -436,10 +436,10 @@ FcNameParse (const FcChar8 *name)
|
|||
{
|
||||
switch (v.type) {
|
||||
case FcTypeCharSet:
|
||||
FcCharSetDestroy ((FcCharSet *) v.u.c);
|
||||
FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
|
||||
break;
|
||||
case FcTypeLangSet:
|
||||
FcLangSetDestroy ((FcLangSet *) v.u.l);
|
||||
FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -448,10 +448,10 @@ FcNameParse (const FcChar8 *name)
|
|||
}
|
||||
switch (v.type) {
|
||||
case FcTypeCharSet:
|
||||
FcCharSetDestroy ((FcCharSet *) v.u.c);
|
||||
FcCharSetDestroy ((FcCharSet *) FcCharSetPtrU(v.u.ci));
|
||||
break;
|
||||
case FcTypeLangSet:
|
||||
FcLangSetDestroy ((FcLangSet *) v.u.l);
|
||||
FcLangSetDestroy ((FcLangSet *) FcLangSetPtrU(v.u.li));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -518,17 +518,20 @@ FcNameUnparseValue (FcStrBuf *buf,
|
|||
sprintf ((char *) temp, "%g", v.u.d);
|
||||
return FcNameUnparseString (buf, temp, 0);
|
||||
case FcTypeString:
|
||||
return FcNameUnparseString (buf, v.u.s, escape);
|
||||
return FcNameUnparseString (buf, FcObjectPtrU(v.u.si), escape);
|
||||
case FcTypeBool:
|
||||
return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
|
||||
case FcTypeMatrix:
|
||||
{
|
||||
FcMatrix * m = FcMatrixPtrU(v.u.mi);
|
||||
sprintf ((char *) temp, "%g %g %g %g",
|
||||
v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
||||
m->xx, m->xy, m->yx, m->yy);
|
||||
return FcNameUnparseString (buf, temp, 0);
|
||||
}
|
||||
case FcTypeCharSet:
|
||||
return FcNameUnparseCharSet (buf, v.u.c);
|
||||
return FcNameUnparseCharSet (buf, FcCharSetPtrU(v.u.ci));
|
||||
case FcTypeLangSet:
|
||||
return FcNameUnparseLangSet (buf, v.u.l);
|
||||
return FcNameUnparseLangSet (buf, FcLangSetPtrU(v.u.li));
|
||||
case FcTypeFTFace:
|
||||
return FcTrue;
|
||||
}
|
||||
|
@ -537,14 +540,14 @@ FcNameUnparseValue (FcStrBuf *buf,
|
|||
|
||||
static FcBool
|
||||
FcNameUnparseValueList (FcStrBuf *buf,
|
||||
FcValueList *v,
|
||||
FcValueListPtr v,
|
||||
FcChar8 *escape)
|
||||
{
|
||||
while (v)
|
||||
while (FcValueListPtrU(v))
|
||||
{
|
||||
if (!FcNameUnparseValue (buf, v->value, escape))
|
||||
if (!FcNameUnparseValue (buf, FcValueListPtrU(v)->value, escape))
|
||||
return FcFalse;
|
||||
if ((v = v->next))
|
||||
if (FcValueListPtrU(v = FcValueListPtrU(v)->next))
|
||||
if (!FcNameUnparseString (buf, (FcChar8 *) ",", 0))
|
||||
return FcFalse;
|
||||
}
|
||||
|
|
858
src/fcpat.c
858
src/fcpat.c
File diff suppressed because it is too large
Load Diff
209
src/fcstr.c
209
src/fcstr.c
|
@ -848,10 +848,67 @@ FcStrSetCreate (void)
|
|||
set->ref = 1;
|
||||
set->num = 0;
|
||||
set->size = 0;
|
||||
set->strs = 0;
|
||||
set->storage = FcStorageDynamic;
|
||||
set->u.strs = 0;
|
||||
return set;
|
||||
}
|
||||
|
||||
static FcChar8 * strset_buf = 0;
|
||||
static int strset_buf_ptr = 0, strset_buf_count = 0;
|
||||
static int * strset_idx = 0;
|
||||
static int strset_idx_ptr = 0, strset_idx_count = 0;
|
||||
static FcStrSet * strsets = 0;
|
||||
static int strset_ptr = 0, strset_count = 0;
|
||||
|
||||
void FcStrSetClearStatic()
|
||||
{
|
||||
strset_buf = 0; strset_buf_ptr = 0; strset_buf_count = 0;
|
||||
strset_idx = 0; strset_idx_ptr = 0; strset_idx_count = 0;
|
||||
strsets = 0; strset_ptr = 0; strset_count = 0;
|
||||
}
|
||||
|
||||
FcChar8 *
|
||||
FcStrSetGet (const FcStrSet *set, int i)
|
||||
{
|
||||
int index;
|
||||
switch (set->storage)
|
||||
{
|
||||
case FcStorageStatic:
|
||||
index = strset_idx[set->u.stridx_offset];
|
||||
if (index == -1)
|
||||
return 0;
|
||||
return &strset_buf[index];
|
||||
case FcStorageDynamic:
|
||||
return set->u.strs[i];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FcStrSet *
|
||||
FcStrSetPtrU (const FcStrSetPtr set)
|
||||
{
|
||||
switch (set.storage)
|
||||
{
|
||||
case FcStorageStatic:
|
||||
return &strsets[set.u.stat];
|
||||
case FcStorageDynamic:
|
||||
return (FcStrSet *)set.u.dyn;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FcStrSetPtr
|
||||
FcStrSetPtrCreateDynamic (const FcStrSet * set)
|
||||
{
|
||||
FcStrSetPtr new;
|
||||
|
||||
new.storage = FcStorageDynamic;
|
||||
new.u.dyn = (FcStrSet *)set;
|
||||
return new;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
||||
{
|
||||
|
@ -860,7 +917,7 @@ _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
|||
FcStrFree (s);
|
||||
return FcTrue;
|
||||
}
|
||||
if (set->num == set->size)
|
||||
if (set->num == set->size || set->storage == FcStorageStatic)
|
||||
{
|
||||
FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *));
|
||||
|
||||
|
@ -868,14 +925,24 @@ _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
|||
return FcFalse;
|
||||
FcMemAlloc (FC_MEM_STRSET, (set->size + 2) * sizeof (FcChar8 *));
|
||||
set->size = set->size + 1;
|
||||
if (set->storage == FcStorageDynamic)
|
||||
{
|
||||
if (set->num)
|
||||
memcpy (strs, set->strs, set->num * sizeof (FcChar8 *));
|
||||
if (set->strs)
|
||||
free (set->strs);
|
||||
set->strs = strs;
|
||||
memcpy (strs, set->u.strs, set->num * sizeof (FcChar8 *));
|
||||
if (set->u.strs)
|
||||
free (set->u.strs);
|
||||
}
|
||||
set->strs[set->num++] = s;
|
||||
set->strs[set->num] = 0;
|
||||
else
|
||||
{
|
||||
if (set->num)
|
||||
memcpy (strs, strset_idx+set->u.stridx_offset,
|
||||
set->num * sizeof (FcChar8 *));
|
||||
set->storage = FcStorageDynamic;
|
||||
}
|
||||
set->u.strs = strs;
|
||||
}
|
||||
set->u.strs[set->num++] = s;
|
||||
set->u.strs[set->num] = 0;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
|
@ -885,7 +952,7 @@ FcStrSetMember (FcStrSet *set, const FcChar8 *s)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < set->num; i++)
|
||||
if (!FcStrCmp (set->strs[i], s))
|
||||
if (!FcStrCmp (FcStrSetGet(set, i), s))
|
||||
return FcTrue;
|
||||
return FcFalse;
|
||||
}
|
||||
|
@ -897,7 +964,7 @@ FcStrSetEqual (FcStrSet *sa, FcStrSet *sb)
|
|||
if (sa->num != sb->num)
|
||||
return FcFalse;
|
||||
for (i = 0; i < sa->num; i++)
|
||||
if (!FcStrSetMember (sb, sa->strs[i]))
|
||||
if (!FcStrSetMember (sb, FcStrSetGet(sa, i)))
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
@ -936,14 +1003,15 @@ FcStrSetDel (FcStrSet *set, const FcChar8 *s)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < set->num; i++)
|
||||
if (!FcStrCmp (set->strs[i], s))
|
||||
if (!FcStrCmp (FcStrSetGet(set, i), s))
|
||||
{
|
||||
FcStrFree (set->strs[i]);
|
||||
if (set->storage == FcStorageDynamic)
|
||||
FcStrFree (set->u.strs[i]);
|
||||
/*
|
||||
* copy remaining string pointers and trailing
|
||||
* NULL
|
||||
*/
|
||||
memmove (&set->strs[i], &set->strs[i+1],
|
||||
memmove (FcStrSetGet(set, i), FcStrSetGet(set, i+1),
|
||||
(set->num - i) * sizeof (FcChar8 *));
|
||||
set->num--;
|
||||
return FcTrue;
|
||||
|
@ -958,16 +1026,123 @@ FcStrSetDestroy (FcStrSet *set)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (set->storage == FcStorageDynamic)
|
||||
{
|
||||
for (i = 0; i < set->num; i++)
|
||||
FcStrFree (set->strs[i]);
|
||||
FcStrFree (set->u.strs[i]);
|
||||
FcMemFree (FC_MEM_STRSET, (set->size) * sizeof (FcChar8 *));
|
||||
if (set->strs)
|
||||
free (set->strs);
|
||||
if (set->u.strs)
|
||||
free (set->u.strs);
|
||||
FcMemFree (FC_MEM_STRSET, sizeof (FcStrSet));
|
||||
}
|
||||
free (set);
|
||||
}
|
||||
}
|
||||
|
||||
static int _FcStrSetSort_helper (const void * a, const void * b)
|
||||
{
|
||||
return FcStrCmp (&strset_buf[(int)a],
|
||||
&strset_buf[(int)b]);
|
||||
}
|
||||
|
||||
void
|
||||
FcStrSetSort (FcStrSet * set)
|
||||
{
|
||||
switch (set->storage)
|
||||
{
|
||||
case FcStorageDynamic:
|
||||
qsort (set->u.strs, set->num, sizeof (FcChar8 *),
|
||||
(int (*)(const void *, const void *)) FcStrCmp);
|
||||
break;
|
||||
case FcStorageStatic:
|
||||
qsort (strset_idx+set->u.stridx_offset, set->num, sizeof (int),
|
||||
_FcStrSetSort_helper);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcStrSetPrepareSerialize (const FcStrSet *set)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!set)
|
||||
return FcTrue;
|
||||
|
||||
strset_count ++;
|
||||
strset_idx_count += set->num;
|
||||
for (i = 0; i < set->num; i++)
|
||||
{
|
||||
if (FcStrSetGet(set, i))
|
||||
strset_buf_count += strlen(FcStrSetGet(set, i));
|
||||
}
|
||||
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcStrSetPtr
|
||||
FcStrSetSerialize (FcStrSet *set)
|
||||
{
|
||||
FcStrSet * new;
|
||||
FcStrSetPtr newp;
|
||||
int i;
|
||||
|
||||
if (!strsets)
|
||||
{
|
||||
strsets = malloc (strset_count * sizeof(FcStrSet));
|
||||
if (!strsets) goto bail1;
|
||||
strset_idx = malloc (strset_idx_count * sizeof(int));
|
||||
if (!strset_idx) goto bail2;
|
||||
strset_buf = malloc (strset_buf_count * sizeof (FcChar8));
|
||||
if (!strset_buf) goto bail3;
|
||||
}
|
||||
|
||||
if (!set)
|
||||
return FcStrSetPtrCreateDynamic(0);
|
||||
|
||||
newp.storage = FcStorageStatic;
|
||||
newp.u.stat = strset_ptr;
|
||||
|
||||
new = &strsets[strset_ptr++];
|
||||
new->ref = set->ref;
|
||||
new->num = set->num;
|
||||
new->size = set->num;
|
||||
new->storage = FcStorageStatic;
|
||||
new->u.stridx_offset = strset_idx_ptr;
|
||||
for (i = 0; i < set->num; i++)
|
||||
{
|
||||
FcChar8 * s = FcStrSetGet(set, i);
|
||||
|
||||
if (s)
|
||||
{
|
||||
memcpy(strset_buf+strset_buf_ptr, s,
|
||||
strlen((char *)s));
|
||||
strset_idx[strset_idx_ptr++] = strset_buf_ptr;
|
||||
strset_buf_ptr += strlen((char *)s)+1;
|
||||
}
|
||||
else
|
||||
strset_idx[strset_idx_ptr++] = -1;
|
||||
}
|
||||
|
||||
if (strset_ptr > strset_count || strset_idx_ptr > strset_idx_count)
|
||||
return FcStrSetPtrCreateDynamic(0);
|
||||
|
||||
// problem with multiple ptrs to the same LangSet.
|
||||
// should hash LangSets or something.
|
||||
// FcStrSetDestroy (set);
|
||||
|
||||
return newp;
|
||||
|
||||
bail3:
|
||||
free (strset_idx);
|
||||
bail2:
|
||||
free (strsets);
|
||||
bail1:
|
||||
return FcStrSetPtrCreateDynamic(0);
|
||||
}
|
||||
|
||||
FcStrList *
|
||||
FcStrListCreate (FcStrSet *set)
|
||||
{
|
||||
|
@ -988,7 +1163,7 @@ FcStrListNext (FcStrList *list)
|
|||
{
|
||||
if (list->n >= list->set->num)
|
||||
return 0;
|
||||
return list->set->strs[list->n++];
|
||||
return FcStrSetGet(list->set, list->n++);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
13
src/fcxml.c
13
src/fcxml.c
|
@ -1878,8 +1878,8 @@ FcPopValue (FcConfigParse *parse)
|
|||
|
||||
switch (vstack->tag) {
|
||||
case FcVStackString:
|
||||
value.u.s = FcStrCopy (vstack->u.string);
|
||||
if (value.u.s)
|
||||
value.u.si = FcObjectPtrCreateDynamic(FcStrCopy (vstack->u.string));
|
||||
if (FcObjectPtrU(value.u.si))
|
||||
value.type = FcTypeString;
|
||||
break;
|
||||
case FcVStackConstant:
|
||||
|
@ -1895,8 +1895,8 @@ FcPopValue (FcConfigParse *parse)
|
|||
value.type = FcTypeInteger;
|
||||
break;
|
||||
case FcVStackMatrix:
|
||||
value.u.m = FcMatrixCopy (vstack->u.matrix);
|
||||
if (value.u.m)
|
||||
value.u.mi = FcMatrixPtrCreateDynamic(FcMatrixCopy (vstack->u.matrix));
|
||||
if (FcMatrixPtrU(value.u.mi))
|
||||
value.type = FcTypeMatrix;
|
||||
break;
|
||||
case FcVStackBool:
|
||||
|
@ -2281,10 +2281,9 @@ FcConfigParseAndLoadDir (FcConfig *config,
|
|||
if (ret)
|
||||
{
|
||||
int i;
|
||||
qsort (files->strs, files->num, sizeof (FcChar8 *),
|
||||
(int (*)(const void *, const void *)) FcStrCmp);
|
||||
FcStrSetSort (files);
|
||||
for (i = 0; ret && i < files->num; i++)
|
||||
ret = FcConfigParseAndLoad (config, files->strs[i], complain);
|
||||
ret = FcConfigParseAndLoad (config, FcStrSetGet(files, i), complain);
|
||||
}
|
||||
bail3:
|
||||
FcStrSetDestroy (files);
|
||||
|
|
Loading…
Reference in New Issue