]> git.wh0rd.org - fontconfig.git/commitdiff
Optimize after profiling. Fix FcStrCmp to return correct sign
authorKeith Packard <keithp@keithp.com>
Wed, 29 May 2002 22:07:33 +0000 (22:07 +0000)
committerKeith Packard <keithp@keithp.com>
Wed, 29 May 2002 22:07:33 +0000 (22:07 +0000)
src/fccharset.c
src/fcint.h
src/fcmatch.c
src/fcname.c
src/fcpat.c
src/fcstr.c

index f15434685ce15e920291a95edd930c98170b9702..23cf35bb8f13c1320dfe5ff5701f2af22f8c16a5 100644 (file)
@@ -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;
 }
index 334883a4c344644e46de3c63af2ee15b1cfff2af..4414325e13e1bdcf402c8d033faa0e650d89c499 100644 (file)
@@ -43,6 +43,7 @@
 typedef struct _FcMatcher {
     char    *object;
     double  (*compare) (char *object, FcValue value1, FcValue value2);
+    int            priority;
 } FcMatcher;
 
 typedef struct _FcSymbolic {
index 62fb403d3fb5c091a93f9986c69ac8de26795546..6d5566b42b9aa8d128942486cdc227182a079c90 100644 (file)
@@ -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
index 57a72c8e66f1db0774fb8f30c6fb3a94bc314dc4..c4771498bc8ebab8ac2e872c34d482588db1f15b 100644 (file)
@@ -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;
        }
     }
index b3601654dbd8097f25c772df84831fb6eb194acf..164bea1611e529b8904c8050deba56291be8c8f2 100644 (file)
@@ -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;
index 796ccc320b33762ae3d5435a7c0e76711218bd00..3d4a592e108a4f8b8176027d73bde1820e71b96f 100644 (file)
@@ -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