Speed up FcConfigCompareValue
Make FcConfigPromote use a switch instead of an if-else cascade, and avoid calling it when we can. Note that we need to add a case for integers in FcConfigCompareValue, since we are no longer promoting integers to doubles unconditionally.
This commit is contained in:
parent
922168afe8
commit
9d4e5d0f25
76
src/fccfg.c
76
src/fccfg.c
|
@ -934,36 +934,46 @@ FcConfigAddRule (FcConfig *config,
|
|||
static FcValue
|
||||
FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
|
||||
{
|
||||
if (v.type == FcTypeInteger)
|
||||
switch (v.type)
|
||||
{
|
||||
case FcTypeInteger:
|
||||
v.type = FcTypeDouble;
|
||||
v.u.d = (double) v.u.i;
|
||||
}
|
||||
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
|
||||
break;
|
||||
case FcTypeVoid:
|
||||
if (u.type == FcTypeMatrix)
|
||||
{
|
||||
v.u.m = &FcIdentityMatrix;
|
||||
v.type = FcTypeMatrix;
|
||||
}
|
||||
else if (buf && v.type == FcTypeString && u.type == FcTypeLangSet)
|
||||
{
|
||||
v.u.l = FcLangSetPromote (v.u.s, buf);
|
||||
v.type = FcTypeLangSet;
|
||||
}
|
||||
else if (buf && v.type == FcTypeVoid && u.type == FcTypeLangSet)
|
||||
else if (u.type == FcTypeLangSet && buf)
|
||||
{
|
||||
v.u.l = FcLangSetPromote (NULL, buf);
|
||||
v.type = FcTypeLangSet;
|
||||
}
|
||||
else if (buf && v.type == FcTypeVoid && u.type == FcTypeCharSet)
|
||||
else if (u.type == FcTypeCharSet && buf)
|
||||
{
|
||||
v.u.c = FcCharSetPromote (buf);
|
||||
v.type = FcTypeCharSet;
|
||||
}
|
||||
if (buf && v.type == FcTypeDouble && u.type == FcTypeRange)
|
||||
break;
|
||||
case FcTypeString:
|
||||
if (u.type == FcTypeLangSet && buf)
|
||||
{
|
||||
v.u.l = FcLangSetPromote (v.u.s, buf);
|
||||
v.type = FcTypeLangSet;
|
||||
}
|
||||
break;
|
||||
case FcTypeDouble:
|
||||
if (u.type == FcTypeRange && buf)
|
||||
{
|
||||
v.u.r = FcRangePromote (v.u.d, buf);
|
||||
v.type = FcTypeRange;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -977,17 +987,49 @@ FcConfigCompareValue (const FcValue *left_o,
|
|||
FcBool ret = FcFalse;
|
||||
FcOp op = FC_OP_GET_OP (op_);
|
||||
int flags = FC_OP_GET_FLAGS (op_);
|
||||
FcValuePromotionBuffer buf1, buf2;
|
||||
|
||||
if (left.type != right.type)
|
||||
{
|
||||
FcValuePromotionBuffer buf1, buf2;
|
||||
left = FcConfigPromote (left, right, &buf1);
|
||||
right = FcConfigPromote (right, left, &buf2);
|
||||
if (left.type == right.type)
|
||||
if (left.type != right.type)
|
||||
{
|
||||
if (op == FcOpNotEqual || op == FcOpNotContains)
|
||||
ret = FcTrue;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
switch (left.type) {
|
||||
case FcTypeUnknown:
|
||||
break; /* No way to guess how to compare for this object */
|
||||
case FcTypeInteger:
|
||||
break; /* FcConfigPromote prevents this from happening */
|
||||
switch ((int) op) {
|
||||
case FcOpEqual:
|
||||
case FcOpContains:
|
||||
case FcOpListing:
|
||||
ret = left.u.i == right.u.i;
|
||||
break;
|
||||
case FcOpNotEqual:
|
||||
case FcOpNotContains:
|
||||
ret = left.u.i != right.u.i;
|
||||
break;
|
||||
case FcOpLess:
|
||||
ret = left.u.i < right.u.i;
|
||||
break;
|
||||
case FcOpLessEqual:
|
||||
ret = left.u.i <= right.u.i;
|
||||
break;
|
||||
case FcOpMore:
|
||||
ret = left.u.i > right.u.i;
|
||||
break;
|
||||
case FcOpMoreEqual:
|
||||
ret = left.u.i >= right.u.i;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FcTypeDouble:
|
||||
switch ((int) op) {
|
||||
case FcOpEqual:
|
||||
|
@ -1156,12 +1198,6 @@ FcConfigCompareValue (const FcValue *left_o,
|
|||
ret = FcRangeCompare (op, left.u.r, right.u.r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (op == FcOpNotEqual || op == FcOpNotContains)
|
||||
ret = FcTrue;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue