Aric Stewart : usp10: Cache FontScriptTags information.

Alexandre Julliard julliard at winehq.org
Fri Dec 30 10:27:02 CST 2011


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Thu Dec 29 14:50:12 2011 -0600

usp10: Cache FontScriptTags information.

---

 dlls/usp10/shape.c          |   46 ++++++++++++++++++++++++++++---------------
 dlls/usp10/usp10.c          |    1 +
 dlls/usp10/usp10_internal.h |    7 ++++++
 3 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c
index 0574591..fcf765e 100644
--- a/dlls/usp10/shape.c
+++ b/dlls/usp10/shape.c
@@ -3779,39 +3779,53 @@ DWORD CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWORD pgi, DW
     return 0;
 }
 
-static HRESULT GSUB_GetFontScriptTags(LPCVOID table, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags, LPCVOID* script_table)
+static void GSUB_initialize_script_cache(ScriptCache *psc)
 {
-    const GSUB_ScriptList *script;
-    const GSUB_Header* header = (const GSUB_Header*)table;
     int i;
-    HRESULT rc = S_OK;
 
-    script = (const GSUB_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
+    if (!psc->script_count)
+    {
+        const GSUB_ScriptList *script;
+        const GSUB_Header* header = (const GSUB_Header*)psc->GSUB_Table;
+        script = (const GSUB_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
+        psc->script_count = GET_BE_WORD(script->ScriptCount);
+        TRACE("initializing %i scripts in this font\n",psc->script_count);
+        psc->scripts = HeapAlloc(GetProcessHeap(),0,sizeof(LoadedScript) * psc->script_count);
+        for (i = 0; i < psc->script_count; i++)
+        {
+            int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
+            psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
+            psc->scripts[i].table = ((const BYTE*)script + offset);
+        }
+    }
+}
 
-    *pcTags = GET_BE_WORD(script->ScriptCount);
-    TRACE("%i scripts in this font\n",*pcTags);
+static HRESULT GSUB_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags, LPCVOID* script_table)
+{
+    int i;
+    HRESULT rc = S_OK;
+
+    GSUB_initialize_script_cache(psc);
+    *pcTags = psc->script_count;
 
     if (!searchingFor && cMaxTags < *pcTags)
         rc = E_OUTOFMEMORY;
     else if (searchingFor)
         rc = USP_E_SCRIPT_NOT_IN_FONT;
 
-    for (i = 0; i < *pcTags; i++)
+    for (i = 0; i < psc->script_count; i++)
     {
         if (i < cMaxTags)
-            pScriptTags[i] = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
+            pScriptTags[i] = psc->scripts[i].tag;
 
         if (searchingFor)
         {
-            if (strncmp(script->ScriptRecord[i].ScriptTag, (char*)&searchingFor,4)==0)
+            if (searchingFor == psc->scripts[i].tag)
             {
-                pScriptTags[0] = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
+                pScriptTags[0] = psc->scripts[i].tag;
                 *pcTags = 1;
                 if (script_table)
-                {
-                    int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
-                    *script_table = ((const BYTE*)script + offset);
-                }
+                    *script_table = psc->scripts[i].table;
                 rc = S_OK;
                 break;
             }
@@ -3836,7 +3850,7 @@ HRESULT SHAPE_GetFontScriptTags( HDC hdc, ScriptCache *psc,
             searching = MS_MAKE_TAG(ShapingData[psa->eScript].otTag[0], ShapingData[psa->eScript].otTag[1], ShapingData[psa->eScript].otTag[2], ShapingData[psa->eScript].otTag[3]);
     }
 
-    hr = GSUB_GetFontScriptTags(psc->GSUB_Table, searching, cMaxTags, pScriptTags, pcTags, NULL);
+    hr = GSUB_GetFontScriptTags(psc, searching, cMaxTags, pScriptTags, pcTags, NULL);
     if (FAILED(hr))
         *pcTags = 0;
     return hr;
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 2e2efb5..e9278b3 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -933,6 +933,7 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
         heap_free(((ScriptCache *)*psc)->GSUB_Table);
         heap_free(((ScriptCache *)*psc)->GDEF_Table);
         heap_free(((ScriptCache *)*psc)->CMAP_Table);
+        heap_free(((ScriptCache *)*psc)->scripts);
         heap_free(((ScriptCache *)*psc)->features);
         heap_free(*psc);
         *psc = NULL;
diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h
index fb98377..6243877 100644
--- a/dlls/usp10/usp10_internal.h
+++ b/dlls/usp10/usp10_internal.h
@@ -132,6 +132,11 @@ typedef struct {
 } LoadedFeature;
 
 typedef struct {
+    OPENTYPE_TAG tag;
+    LPCVOID table;
+} LoadedScript;
+
+typedef struct {
     LOGFONTW lf;
     TEXTMETRICW tm;
     BOOL sfnt;
@@ -143,6 +148,8 @@ typedef struct {
     LPVOID CMAP_format12_Table;
     INT feature_count;
     LoadedFeature *features;
+    INT script_count;
+    LoadedScript *scripts;
 
     OPENTYPE_TAG userScript;
     OPENTYPE_TAG userLang;




More information about the wine-cvs mailing list