From bc9469baadc6b5f9a920a476e460113bab518208 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 May 2002 22:07:33 +0000 Subject: [PATCH] Optimize after profiling. Fix FcStrCmp to return correct sign --- src/fccharset.c | 103 ++++++++++++++++++++++++++-------- src/fcint.h | 1 + src/fcmatch.c | 143 +++++++++++++++++++++++++++++++++++------------- src/fcname.c | 4 +- src/fcpat.c | 13 ++--- src/fcstr.c | 6 +- 6 files changed, 197 insertions(+), 73 deletions(-) diff --git a/src/fccharset.c b/src/fccharset.c index f154346..23cf35b 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/lib/fontconfig/src/fccharset.c,v 1.7 2002/05/24 05:20:02 keithp Exp $ + * $XFree86: xc/lib/fontconfig/src/fccharset.c,v 1.8 2002/05/29 08:21:33 keithp Exp $ * * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. * @@ -697,39 +697,94 @@ FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b) return count; } +typedef struct { + FcCharBranch *ab, *bb; + FcChar32 byte; +} FcCharSetPairStack; + /* * return FcTrue iff a is a subset of b */ FcBool FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) { - FcCharSetIter ai, bi; - - FcCharSetIterStart (a, &ai); - while (ai.leaf) + FcCharSetPairStack stack[5], *stackp; + FcChar32 byte; + FcCharBranch *ab, *bb; + int level; + FcCharNode an, bn; + + if (a->levels > b->levels) + return FcFalse; + + level = b->levels; + an = a->node; + bn = b->node; + while (level != a->levels) { - bi.ucs4 = ai.ucs4; - FcCharSetIterSet (b, &bi); - /* - * Check if a has a page that b does not - */ - if (ai.ucs4 < bi.ucs4) - return FcFalse; - /* - * Check if they have a page in common, if so, - * look to see if there any bits in a not in b - */ - if (ai.ucs4 == bi.ucs4) + bn = bn.branch->nodes[0]; + level--; + } + + if (level == 0) + ; + if (level == 1) + { + FcChar32 *am = an.leaf->map; + FcChar32 *bm = bn.leaf->map; + int i = 256/32; + + while (i--) + if (*am++ & ~*bm++) + return FcFalse; + } + else + { + byte = 0; + stackp = stack; + ab = an.branch; + bb = bn.branch; + for (;;) { - FcChar32 *am = ai.leaf->map; - FcChar32 *bm = bi.leaf->map; - int i = 256/32; - - while (i--) - if (*am++ & ~*bm++) + an = ab->nodes[byte]; + if (an.branch) + { + bn = bb->nodes[byte]; + if (!bn.branch) return FcFalse; + if (level == 2) + { + FcChar32 *am = an.leaf->map; + FcChar32 *bm = bn.leaf->map; + int i = 256/32; + + while (i--) + if (*am++ & ~*bm++) + return FcFalse; + } + else + { + level--; + stackp->ab = ab; + stackp->bb = bb; + stackp->byte = byte; + stackp++; + byte = 0; + continue; + } + } + byte = ab->next[byte]; + if (!byte) + { + if (stackp == stack) + break; + level++; + --stackp; + ab = stackp->ab; + bb = stackp->bb; + byte = stackp->byte; + } } - FcCharSetIterNext (a, &ai); } return FcTrue; } diff --git a/src/fcint.h b/src/fcint.h index 334883a..4414325 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -43,6 +43,7 @@ typedef struct _FcMatcher { char *object; double (*compare) (char *object, FcValue value1, FcValue value2); + int priority; } FcMatcher; typedef struct _FcSymbolic { diff --git a/src/fcmatch.c b/src/fcmatch.c index 62fb403..6d5566b 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.2 2002/02/15 06:01:28 keithp Exp $ + * $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.6 2002/05/29 08:21:33 keithp Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * @@ -104,17 +104,40 @@ FcCompareSize (char *object, FcValue value1, FcValue value2) */ static FcMatcher _FcMatchers [] = { { FC_FOUNDRY, FcCompareString, }, +#define MATCH_FOUNDRY 0 + { FC_CHARSET, FcCompareCharSet }, +#define MATCH_CHARSET 1 + { FC_ANTIALIAS, FcCompareBool, }, +#define MATCH_ANTIALIAS 2 + { FC_LANG, FcCompareString }, +#define MATCH_LANG 3 + { FC_FAMILY, FcCompareString, }, +#define MATCH_FAMILY 4 + { FC_SPACING, FcCompareInteger, }, +#define MATCH_SPACING 5 + { FC_PIXEL_SIZE, FcCompareSize, }, +#define MATCH_PIXEL_SIZE 6 + { FC_STYLE, FcCompareString, }, +#define MATCH_STYLE 7 + { FC_SLANT, FcCompareInteger, }, +#define MATCH_SLANT 8 + { FC_WEIGHT, FcCompareInteger, }, +#define MATCH_WEIGHT 9 + { FC_RASTERIZER, FcCompareString, }, +#define MATCH_RASTERIZER 10 + { FC_OUTLINE, FcCompareBool, }, +#define MATCH_OUTLINE 11 }; #define NUM_MATCHER (sizeof _FcMatchers / sizeof _FcMatchers[0]) @@ -132,6 +155,54 @@ FcCompareValueList (const char *object, int j; int i; + /* + * Locate the possible matching entry by examining the + * first few characters in object + */ + i = -1; + switch (FcToLower (object[0])) { + case 'f': + switch (FcToLower (object[1])) { + case 'o': + i = MATCH_FOUNDRY; break; + case 'a': + i = MATCH_FAMILY; break; + } + break; + case 'c': + i = MATCH_CHARSET; break; + case 'a': + i = MATCH_ANTIALIAS; break; + case 'l': + i = MATCH_LANG; break; + case 's': + switch (FcToLower (object[1])) { + case 'p': + i = MATCH_SPACING; break; + case 't': + i = MATCH_STYLE; break; + case 'l': + i = MATCH_SLANT; break; + } + break; + case 'p': + i = MATCH_PIXEL_SIZE; break; + case 'w': + i = MATCH_WEIGHT; break; + case 'r': + i = MATCH_RASTERIZER; break; + case 'o': + i = MATCH_OUTLINE; break; + } + if (i == -1 || + FcStrCmpIgnoreCase ((FcChar8 *) _FcMatchers[i].object, + (FcChar8 *) object) != 0) + { + if (bestValue) + *bestValue = v2orig->value; + return FcTrue; + } +#if 0 for (i = 0; i < NUM_MATCHER; i++) { if (!FcStrCmpIgnoreCase ((FcChar8 *) _FcMatchers[i].object, @@ -144,7 +215,7 @@ FcCompareValueList (const char *object, *bestValue = v2orig->value; return FcTrue; } - +#endif best = 1e99; j = 0; for (v1 = v1orig; v1; v1 = v1->next) @@ -199,43 +270,42 @@ FcCompare (FcPattern *pat, for (i = 0; i < NUM_MATCHER; i++) value[i] = 0.0; - for (i1 = 0; i1 < pat->num; i1++) + i1 = 0; + i2 = 0; + while (i1 < pat->num && i2 < fnt->num) { - for (i2 = 0; i2 < fnt->num; i2++) + i = strcmp (pat->elts[i1].object, fnt->elts[i2].object); + if (i > 0) + i2++; + else if (i < 0) + i1++; + else { - if (!FcStrCmpIgnoreCase ((FcChar8 *) pat->elts[i1].object, - (FcChar8 *) fnt->elts[i2].object)) - { - if (!FcCompareValueList (pat->elts[i1].object, - pat->elts[i1].values, - fnt->elts[i2].values, - 0, - value, - result)) - return FcFalse; - break; - } + if (!FcCompareValueList (pat->elts[i1].object, + pat->elts[i1].values, + fnt->elts[i2].values, + 0, + value, + result)) + return FcFalse; + i1++; + i2++; } + } + return FcTrue; #if 0 - /* - * Overspecified patterns are slightly penalized in - * case some other font includes the requested field - */ - if (i2 == fnt->num) + for (i1 = 0; i1 < pat->num; i1++) + { + for (i2 = 0; i2 < fnt->num; i2++) { - for (i2 = 0; i2 < NUM_MATCHER; i2++) + if (!strcmp (pat->elts[i1].object, fnt->elts[i2].object)) { - if (!FcStrCmpIgnoreCase (_FcMatchers[i2].object, - pat->elts[i1].object)) - { - value[i2] = 1.0; - break; - } + break; } } -#endif } return FcTrue; +#endif } FcPattern * @@ -393,16 +463,15 @@ FcSortCompare (const void *aa, const void *ab) { FcSortNode *a = *(FcSortNode **) aa; FcSortNode *b = *(FcSortNode **) ab; + double *as = &a->score[0]; + double *bs = &b->score[0]; + double ad, bd; int i; - for (i = 0; i < NUM_MATCHER; i++) - { - if (a->score[i] > b->score[i]) - return 1; - if (a->score[i] < b->score[i]) - return -1; - } - return 0; + i = NUM_MATCHER; + while (i-- && (ad = *as++) == (bd = *bs++)) + ; + return ad < bd ? -1 : ad > bd ? 1 : 0; } static FcBool diff --git a/src/fcname.c b/src/fcname.c index 57a72c8..c477149 100644 --- a/src/fcname.c +++ b/src/fcname.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/lib/fontconfig/src/fcname.c,v 1.2 2002/02/15 06:01:28 keithp Exp $ + * $XFree86: xc/lib/fontconfig/src/fcname.c,v 1.3 2002/02/18 22:29:28 keithp Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * @@ -120,7 +120,7 @@ FcNameGetObjectType (const char *object) for (i = 0; i < l->ntypes; i++) { t = &l->types[i]; - if (!FcStrCmpIgnoreCase ((FcChar8 *) object, (FcChar8 *) t->object)) + if (!strcmp (object, t->object)) return t; } } diff --git a/src/fcpat.c b/src/fcpat.c index b360165..164bea1 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/lib/fontconfig/src/fcpat.c,v 1.3 2002/02/19 07:50:44 keithp Exp $ + * $XFree86: xc/lib/fontconfig/src/fcpat.c,v 1.4 2002/05/22 04:12:35 keithp Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * @@ -197,10 +197,10 @@ FcPatternFind (FcPattern *p, const char *object, FcBool insert) while (low + 1 < high) { i = (low + high) >> 1; - s = FcStrCmpIgnoreCase ((FcChar8 *) object, (FcChar8 *) p->elts[i].object); + s = strcmp (object, p->elts[i].object); if (s == 0) return &p->elts[i]; - if (s < 0) + if (s > 0) low = i; else high = i; @@ -209,10 +209,10 @@ FcPatternFind (FcPattern *p, const char *object, FcBool insert) i = low; while (i < high) { - s = FcStrCmpIgnoreCase ((FcChar8 *) object, (FcChar8 *) p->elts[i].object); + s = strcmp (object, p->elts[i].object); if (s == 0) return &p->elts[i]; - if (s > 0) + if (s < 0) break; i++; } @@ -266,8 +266,7 @@ FcPatternEqual (FcPattern *pa, FcPattern *pb) return FcFalse; for (i = 0; i < pa->num; i++) { - if (FcStrCmpIgnoreCase ((FcChar8 *) pa->elts[i].object, - (FcChar8 *) pb->elts[i].object) != 0) + if (strcmp (pa->elts[i].object, pb->elts[i].object) != 0) return FcFalse; if (!FcValueListEqual (pa->elts[i].values, pb->elts[i].values)) return FcFalse; diff --git a/src/fcstr.c b/src/fcstr.c index 796ccc3..3d4a592 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.3 2002/02/18 22:29:28 keithp Exp $ + * $XFree86: xc/lib/fontconfig/src/fcstr.c,v 1.4 2002/05/21 17:06:22 keithp Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * @@ -79,7 +79,7 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2) if (c1 != c2) break; } - return (int) c2 - (int) c1; + return (int) c1 - (int) c2; } int @@ -98,7 +98,7 @@ FcStrCmp (const FcChar8 *s1, const FcChar8 *s2) if (c1 != c2) break; } - return (int) c2 - (int) c1; + return (int) c1 - (int) c2; } int -- 2.39.2