From 4f8b266fd97e36961639c40d93225265c0f849c7 Mon Sep 17 00:00:00 2001 From: Patrick Lam Date: Thu, 24 Nov 2005 20:20:26 +0000 Subject: [PATCH] Make FcCompareString and FcCompareFamily less expensive. Only add a value for FC_FAMILY if the proposed value is a string. reviewed by: plam --- ChangeLog | 11 ++++++++++- src/fcmatch.c | 24 +++++++++++++++++------- src/fcpat.c | 7 +++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index ac81063..bea96dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -2005-11-24 Dirk Mueller +2005-11-24 Dirk Mueller + reviewed by: plam + + * src/fcmatch.c (FcCompareNumber, FcCompareString, FcCompareFamily): + * src/fcpat.c (FcPatternAddWithBinding): + + Make FcCompareString and FcCompareFamily less expensive. + Only add a value for FC_FAMILY if the proposed value is a string. + +2005-11-24 Dirk Mueller reviewed by: plam * src/fcdbg.c (FcDebug, FcDebugInit, FcPatternPrint): diff --git a/src/fcmatch.c b/src/fcmatch.c index 49d41a4..8b0bd01 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -55,25 +55,35 @@ FcCompareNumber (const char *object, FcValue *value1, FcValue *value2) v = v2 - v1; if (v < 0) v = -v; - return (double) v; + return v; } static double FcCompareString (const char *object, FcValue *v1, FcValue *v2) { - FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2); - if (value2.type != FcTypeString || value1.type != FcTypeString) + FcValue value1, value2; + if ((v2->type & ~FC_STORAGE_STATIC) != FcTypeString || + (v1->type & ~FC_STORAGE_STATIC) != FcTypeString) return -1.0; + value1 = FcValueCanonicalize(v1); value2 = FcValueCanonicalize(v2); return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0; } static double FcCompareFamily (const char *object, FcValue *v1, FcValue *v2) { - FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2); - if (value2.type != FcTypeString || value1.type != FcTypeString) - return -1.0; - return (double) FcStrCmpIgnoreBlanksAndCase (value1.u.s, value2.u.s) != 0; + /* rely on the guarantee in FcPatternAddWithBinding that + * families are always FcTypeString. */ + + /* assert ((v2->type & ~FC_STORAGE_STATIC) == FcTypeString && + (v1->type & ~FC_STORAGE_STATIC) == FcTypeString); */ + const FcChar8* v1_string = fc_value_string(v1); + const FcChar8* v2_string = fc_value_string(v2); + + if (FcToLower(*v1_string) != FcToLower(*v2_string)) + return 1.0; + + return (double) FcStrCmpIgnoreBlanksAndCase (v1_string, v2_string) != 0; } static double diff --git a/src/fcpat.c b/src/fcpat.c index a82fb6f..c37936f 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -872,6 +872,13 @@ FcPatternAddWithBinding (FcPattern *p, if (value.type == FcTypeVoid) goto bail1; + /* quick and dirty hack to enable FcCompareFamily speedup: + * only allow strings to be added under the FC_FAMILY key. + * a better hack would use FcBaseObjectTypes to check all objects. */ + if (FcObjectToPtr(object) == FcObjectToPtr(FC_FAMILY) && + value.type != FcTypeString) + goto bail1; + FcValueListPtrU(new)->value = value; FcValueListPtrU(new)->binding = binding; FcValueListPtrU(new)->next = FcValueListPtrCreateDynamic(0);