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
458
src/fccfg.c
458
src/fccfg.c
|
@ -934,35 +934,45 @@ FcConfigAddRule (FcConfig *config,
|
||||||
static FcValue
|
static FcValue
|
||||||
FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
|
FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
|
||||||
{
|
{
|
||||||
if (v.type == FcTypeInteger)
|
switch (v.type)
|
||||||
{
|
{
|
||||||
v.type = FcTypeDouble;
|
case FcTypeInteger:
|
||||||
v.u.d = (double) v.u.i;
|
v.type = FcTypeDouble;
|
||||||
}
|
v.u.d = (double) v.u.i;
|
||||||
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
|
break;
|
||||||
{
|
case FcTypeVoid:
|
||||||
v.u.m = &FcIdentityMatrix;
|
if (u.type == FcTypeMatrix)
|
||||||
v.type = FcTypeMatrix;
|
{
|
||||||
}
|
v.u.m = &FcIdentityMatrix;
|
||||||
else if (buf && v.type == FcTypeString && u.type == FcTypeLangSet)
|
v.type = FcTypeMatrix;
|
||||||
{
|
}
|
||||||
v.u.l = FcLangSetPromote (v.u.s, buf);
|
else if (u.type == FcTypeLangSet && buf)
|
||||||
v.type = FcTypeLangSet;
|
{
|
||||||
}
|
v.u.l = FcLangSetPromote (NULL, buf);
|
||||||
else if (buf && v.type == FcTypeVoid && u.type == FcTypeLangSet)
|
v.type = FcTypeLangSet;
|
||||||
{
|
}
|
||||||
v.u.l = FcLangSetPromote (NULL, buf);
|
else if (u.type == FcTypeCharSet && buf)
|
||||||
v.type = FcTypeLangSet;
|
{
|
||||||
}
|
v.u.c = FcCharSetPromote (buf);
|
||||||
else if (buf && v.type == FcTypeVoid && u.type == FcTypeCharSet)
|
v.type = FcTypeCharSet;
|
||||||
{
|
}
|
||||||
v.u.c = FcCharSetPromote (buf);
|
break;
|
||||||
v.type = FcTypeCharSet;
|
case FcTypeString:
|
||||||
}
|
if (u.type == FcTypeLangSet && buf)
|
||||||
if (buf && v.type == FcTypeDouble && u.type == FcTypeRange)
|
{
|
||||||
{
|
v.u.l = FcLangSetPromote (v.u.s, buf);
|
||||||
v.u.r = FcRangePromote (v.u.d, buf);
|
v.type = FcTypeLangSet;
|
||||||
v.type = FcTypeRange;
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeDouble:
|
||||||
|
if (u.type == FcTypeRange && buf)
|
||||||
|
{
|
||||||
|
v.u.r = FcRangePromote (v.u.d, buf);
|
||||||
|
v.type = FcTypeRange;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -972,195 +982,221 @@ FcConfigCompareValue (const FcValue *left_o,
|
||||||
unsigned int op_,
|
unsigned int op_,
|
||||||
const FcValue *right_o)
|
const FcValue *right_o)
|
||||||
{
|
{
|
||||||
FcValue left = FcValueCanonicalize(left_o);
|
FcValue left = FcValueCanonicalize(left_o);
|
||||||
FcValue right = FcValueCanonicalize(right_o);
|
FcValue right = FcValueCanonicalize(right_o);
|
||||||
FcBool ret = FcFalse;
|
FcBool ret = FcFalse;
|
||||||
FcOp op = FC_OP_GET_OP (op_);
|
FcOp op = FC_OP_GET_OP (op_);
|
||||||
int flags = FC_OP_GET_FLAGS (op_);
|
int flags = FC_OP_GET_FLAGS (op_);
|
||||||
FcValuePromotionBuffer buf1, buf2;
|
|
||||||
|
|
||||||
left = FcConfigPromote (left, right, &buf1);
|
if (left.type != right.type)
|
||||||
right = FcConfigPromote (right, left, &buf2);
|
|
||||||
if (left.type == right.type)
|
|
||||||
{
|
{
|
||||||
switch (left.type) {
|
FcValuePromotionBuffer buf1, buf2;
|
||||||
case FcTypeUnknown:
|
left = FcConfigPromote (left, right, &buf1);
|
||||||
break; /* No way to guess how to compare for this object */
|
right = FcConfigPromote (right, left, &buf2);
|
||||||
case FcTypeInteger:
|
if (left.type != right.type)
|
||||||
break; /* FcConfigPromote prevents this from happening */
|
{
|
||||||
case FcTypeDouble:
|
if (op == FcOpNotEqual || op == FcOpNotContains)
|
||||||
switch ((int) op) {
|
ret = FcTrue;
|
||||||
case FcOpEqual:
|
return ret;
|
||||||
case FcOpContains:
|
}
|
||||||
case FcOpListing:
|
|
||||||
ret = left.u.d == right.u.d;
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
case FcOpNotContains:
|
|
||||||
ret = left.u.d != right.u.d;
|
|
||||||
break;
|
|
||||||
case FcOpLess:
|
|
||||||
ret = left.u.d < right.u.d;
|
|
||||||
break;
|
|
||||||
case FcOpLessEqual:
|
|
||||||
ret = left.u.d <= right.u.d;
|
|
||||||
break;
|
|
||||||
case FcOpMore:
|
|
||||||
ret = left.u.d > right.u.d;
|
|
||||||
break;
|
|
||||||
case FcOpMoreEqual:
|
|
||||||
ret = left.u.d >= right.u.d;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeBool:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpEqual:
|
|
||||||
ret = left.u.b == right.u.b;
|
|
||||||
break;
|
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
ret = left.u.b == right.u.b || left.u.b >= FcDontCare;
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
ret = left.u.b != right.u.b;
|
|
||||||
break;
|
|
||||||
case FcOpNotContains:
|
|
||||||
ret = !(left.u.b == right.u.b || left.u.b >= FcDontCare);
|
|
||||||
break;
|
|
||||||
case FcOpLess:
|
|
||||||
ret = left.u.b != right.u.b && right.u.b >= FcDontCare;
|
|
||||||
break;
|
|
||||||
case FcOpLessEqual:
|
|
||||||
ret = left.u.b == right.u.b || right.u.b >= FcDontCare;
|
|
||||||
break;
|
|
||||||
case FcOpMore:
|
|
||||||
ret = left.u.b != right.u.b && left.u.b >= FcDontCare;
|
|
||||||
break;
|
|
||||||
case FcOpMoreEqual:
|
|
||||||
ret = left.u.b == right.u.b || left.u.b >= FcDontCare;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeString:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpEqual:
|
|
||||||
case FcOpListing:
|
|
||||||
if (flags & FcOpFlagIgnoreBlanks)
|
|
||||||
ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) == 0;
|
|
||||||
else
|
|
||||||
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
|
|
||||||
break;
|
|
||||||
case FcOpContains:
|
|
||||||
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
if (flags & FcOpFlagIgnoreBlanks)
|
|
||||||
ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) != 0;
|
|
||||||
else
|
|
||||||
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
|
|
||||||
break;
|
|
||||||
case FcOpNotContains:
|
|
||||||
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeMatrix:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpEqual:
|
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
ret = FcMatrixEqual (left.u.m, right.u.m);
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
case FcOpNotContains:
|
|
||||||
ret = !FcMatrixEqual (left.u.m, right.u.m);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeCharSet:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
/* left contains right if right is a subset of left */
|
|
||||||
ret = FcCharSetIsSubset (right.u.c, left.u.c);
|
|
||||||
break;
|
|
||||||
case FcOpNotContains:
|
|
||||||
/* left contains right if right is a subset of left */
|
|
||||||
ret = !FcCharSetIsSubset (right.u.c, left.u.c);
|
|
||||||
break;
|
|
||||||
case FcOpEqual:
|
|
||||||
ret = FcCharSetEqual (left.u.c, right.u.c);
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
ret = !FcCharSetEqual (left.u.c, right.u.c);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeLangSet:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
ret = FcLangSetContains (left.u.l, right.u.l);
|
|
||||||
break;
|
|
||||||
case FcOpNotContains:
|
|
||||||
ret = !FcLangSetContains (left.u.l, right.u.l);
|
|
||||||
break;
|
|
||||||
case FcOpEqual:
|
|
||||||
ret = FcLangSetEqual (left.u.l, right.u.l);
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
ret = !FcLangSetEqual (left.u.l, right.u.l);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeVoid:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpEqual:
|
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
ret = FcTrue;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeFTFace:
|
|
||||||
switch ((int) op) {
|
|
||||||
case FcOpEqual:
|
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
ret = left.u.f == right.u.f;
|
|
||||||
break;
|
|
||||||
case FcOpNotEqual:
|
|
||||||
case FcOpNotContains:
|
|
||||||
ret = left.u.f != right.u.f;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FcTypeRange:
|
|
||||||
ret = FcRangeCompare (op, left.u.r, right.u.r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
switch (left.type) {
|
||||||
{
|
case FcTypeUnknown:
|
||||||
if (op == FcOpNotEqual || op == FcOpNotContains)
|
break; /* No way to guess how to compare for this object */
|
||||||
ret = FcTrue;
|
case FcTypeInteger:
|
||||||
|
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:
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = left.u.d == right.u.d;
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = left.u.d != right.u.d;
|
||||||
|
break;
|
||||||
|
case FcOpLess:
|
||||||
|
ret = left.u.d < right.u.d;
|
||||||
|
break;
|
||||||
|
case FcOpLessEqual:
|
||||||
|
ret = left.u.d <= right.u.d;
|
||||||
|
break;
|
||||||
|
case FcOpMore:
|
||||||
|
ret = left.u.d > right.u.d;
|
||||||
|
break;
|
||||||
|
case FcOpMoreEqual:
|
||||||
|
ret = left.u.d >= right.u.d;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeBool:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpEqual:
|
||||||
|
ret = left.u.b == right.u.b;
|
||||||
|
break;
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = left.u.b == right.u.b || left.u.b >= FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
ret = left.u.b != right.u.b;
|
||||||
|
break;
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = !(left.u.b == right.u.b || left.u.b >= FcDontCare);
|
||||||
|
break;
|
||||||
|
case FcOpLess:
|
||||||
|
ret = left.u.b != right.u.b && right.u.b >= FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpLessEqual:
|
||||||
|
ret = left.u.b == right.u.b || right.u.b >= FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpMore:
|
||||||
|
ret = left.u.b != right.u.b && left.u.b >= FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpMoreEqual:
|
||||||
|
ret = left.u.b == right.u.b || left.u.b >= FcDontCare;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeString:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpEqual:
|
||||||
|
case FcOpListing:
|
||||||
|
if (flags & FcOpFlagIgnoreBlanks)
|
||||||
|
ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) == 0;
|
||||||
|
else
|
||||||
|
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
|
||||||
|
break;
|
||||||
|
case FcOpContains:
|
||||||
|
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
if (flags & FcOpFlagIgnoreBlanks)
|
||||||
|
ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) != 0;
|
||||||
|
else
|
||||||
|
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
|
||||||
|
break;
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeMatrix:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpEqual:
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = FcMatrixEqual (left.u.m, right.u.m);
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = !FcMatrixEqual (left.u.m, right.u.m);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeCharSet:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
/* left contains right if right is a subset of left */
|
||||||
|
ret = FcCharSetIsSubset (right.u.c, left.u.c);
|
||||||
|
break;
|
||||||
|
case FcOpNotContains:
|
||||||
|
/* left contains right if right is a subset of left */
|
||||||
|
ret = !FcCharSetIsSubset (right.u.c, left.u.c);
|
||||||
|
break;
|
||||||
|
case FcOpEqual:
|
||||||
|
ret = FcCharSetEqual (left.u.c, right.u.c);
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
ret = !FcCharSetEqual (left.u.c, right.u.c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeLangSet:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = FcLangSetContains (left.u.l, right.u.l);
|
||||||
|
break;
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = !FcLangSetContains (left.u.l, right.u.l);
|
||||||
|
break;
|
||||||
|
case FcOpEqual:
|
||||||
|
ret = FcLangSetEqual (left.u.l, right.u.l);
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
ret = !FcLangSetEqual (left.u.l, right.u.l);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeVoid:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpEqual:
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = FcTrue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeFTFace:
|
||||||
|
switch ((int) op) {
|
||||||
|
case FcOpEqual:
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = left.u.f == right.u.f;
|
||||||
|
break;
|
||||||
|
case FcOpNotEqual:
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = left.u.f != right.u.f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FcTypeRange:
|
||||||
|
ret = FcRangeCompare (op, left.u.r, right.u.r);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue