Aric Stewart : usp10: Use a bsearch function to find a glyph in the LogClust array.

Alexandre Julliard julliard at winehq.org
Mon Jan 30 14:05:57 CST 2012


Module: wine
Branch: master
Commit: 4df4929198696161e1daf7ee006997e425654a15
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4df4929198696161e1daf7ee006997e425654a15

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Jan 30 07:30:08 2012 -0600

usp10: Use a bsearch function to find a glyph in the LogClust array.

---

 dlls/usp10/opentype.c       |    7 +++-
 dlls/usp10/shape.c          |   60 +++++++++++++++++-------------------------
 dlls/usp10/usp10.c          |   52 +++++++++++++++++++++++++++++++++---
 dlls/usp10/usp10_internal.h |    2 +
 4 files changed, 78 insertions(+), 43 deletions(-)

diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c
index c30d513..3c0af41 100644
--- a/dlls/usp10/opentype.c
+++ b/dlls/usp10/opentype.c
@@ -438,9 +438,12 @@ void OpenType_GDEF_UpdateGlyphProps(HDC hdc, ScriptCache *psc, const WORD *pwGly
         int char_count = 0;
         int k;
 
-        for (k = 0; k < cChars; k++)
-            if (pwLogClust[k] == i)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k >= 0)
+        {
+            for (; k < cChars && pwLogClust[k] == i; k++)
                 char_count++;
+        }
 
         class = GDEF_get_glyph_class(psc->GDEF_Table, pwGlyphs[i]);
 
diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c
index a893f7e..5ba6e6f 100644
--- a/dlls/usp10/shape.c
+++ b/dlls/usp10/shape.c
@@ -2359,13 +2359,11 @@ static void ShapeCharGlyphProp_Default( HDC hdc, ScriptCache* psc, SCRIPT_ANALYS
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
         {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2425,13 +2423,11 @@ static void ShapeCharGlyphProp_Arabic( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSI
         int char_count = 0;
         BOOL isInit, isFinal;
 
-        for (k = 0; k < cChars; k++)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
         {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         isInit = (i == initGlyph || (i+dirR > 0 && i+dirR < cGlyphs && spaces[i+dirR]));
@@ -2534,13 +2530,11 @@ static void ShapeCharGlyphProp_Thai( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
         {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2581,13 +2575,11 @@ static void ShapeCharGlyphProp_None( HDC hdc, ScriptCache* psc, SCRIPT_ANALYSIS*
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
         {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2614,13 +2606,11 @@ static void ShapeCharGlyphProp_Tibet( HDC hdc, ScriptCache* psc, SCRIPT_ANALYSIS
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
         {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (char_count == 0)
@@ -2658,13 +2648,11 @@ static void ShapeCharGlyphProp_BaseIndic( HDC hdc, ScriptCache *psc, SCRIPT_ANAL
         int char_index[20];
         int char_count = 0;
 
-        for (k = 0; k < cChars; k++)
+        k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
+        if (k>=0)
         {
-            if (pwLogClust[k] == i)
-            {
-                char_index[char_count] = k;
-                char_count++;
-            }
+            for (; k < cChars && pwLogClust[k] == i; k++)
+                char_index[char_count++] = k;
         }
 
         if (override_gsub)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index ef8a7ac..beecce9 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -25,6 +25,7 @@
  */
 
 #include <stdarg.h>
+#include <stdlib.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -703,6 +704,11 @@ typedef struct {
     int* logical2visual;
 } StringAnalysis;
 
+typedef struct {
+    BOOL ascending;
+    WORD target;
+} FindGlyph_struct;
+
 static inline void *heap_alloc(SIZE_T size)
 {
     return HeapAlloc(GetProcessHeap(), 0, size);
@@ -881,6 +887,46 @@ static WORD get_char_script( LPCWSTR str, INT index, INT end, INT *consumed)
     return SCRIPT_UNDEFINED;
 }
 
+static int compare_FindGlyph(const void *a, const void* b)
+{
+    const FindGlyph_struct *find = (FindGlyph_struct*)a;
+    const WORD *idx= (WORD*)b;
+    int rc = 0;
+
+    if ( find->target > *idx)
+        rc = 1;
+    else if (find->target < *idx)
+        rc = -1;
+
+    if (!find->ascending)
+        rc *= -1;
+    return rc;
+}
+
+int USP10_FindGlyphInLogClust(const WORD* pwLogClust, int cChars, WORD target)
+{
+    FindGlyph_struct fgs;
+    WORD *ptr;
+    INT k;
+
+    if (pwLogClust[0] < pwLogClust[cChars-1])
+        fgs.ascending = TRUE;
+    else
+        fgs.ascending = FALSE;
+
+    fgs.target = target;
+    ptr = bsearch(&fgs, pwLogClust, cChars, sizeof(WORD), compare_FindGlyph);
+
+    if (!ptr)
+        return -1;
+
+    for (k = (ptr - pwLogClust)-1; k >= 0 && pwLogClust[k] == target; k--)
+    ;
+    k++;
+
+    return k;
+}
+
 /***********************************************************************
  *      DllMain
  *
@@ -1873,13 +1919,9 @@ error:
 
 static inline BOOL does_glyph_start_cluster(const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cChars, int glyph, int direction)
 {
-    int i;
-
     if (pva[glyph].fClusterStart)
         return TRUE;
-    for (i = 0; i < cChars; i++)
-        if (pwLogClust[i] == glyph) break;
-    if (i != cChars)
+    if (USP10_FindGlyphInLogClust(pwLogClust, cChars, glyph) >= 0)
         return TRUE;
 
     return FALSE;
diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h
index 02beaf6..558eb55 100644
--- a/dlls/usp10/usp10_internal.h
+++ b/dlls/usp10/usp10_internal.h
@@ -204,6 +204,8 @@ typedef void (*reorder_function)(LPWSTR pwChar, IndicSyllable *syllable, lexical
 #define BIDI_WEAK    2
 #define BIDI_NEUTRAL 0
 
+int USP10_FindGlyphInLogClust(const WORD* pwLogClust, int cChars, WORD target) DECLSPEC_HIDDEN;
+
 BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
                 const SCRIPT_CONTROL *c, WORD *lpOutLevels ) DECLSPEC_HIDDEN;
 BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,




More information about the wine-cvs mailing list