[USP10] Sync with Wine Staging 3.9. CORE-14656
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 4 Jun 2018 02:51:34 +0000 (03:51 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 4 Jun 2018 02:51:34 +0000 (03:51 +0100)
dll/win32/usp10/bidi.c
dll/win32/usp10/opentype.c
dll/win32/usp10/shape.c
dll/win32/usp10/usp10.c
dll/win32/usp10/usp10_internal.h
media/doc/README.WINE

index b0df781..0fb03ef 100644 (file)
@@ -998,7 +998,7 @@ static void computeIsolatingRunsSet(unsigned baselevel, WORD *pcls, const WORD *
     Run *runs;
     IsolatedRun *current_isolated;
 
-    if (!(runs = heap_alloc(uCount * sizeof(*runs))))
+    if (!(runs = heap_calloc(uCount, sizeof(*runs))))
         return;
 
     list_init(set);
index 2d708a8..5363271 100644 (file)
@@ -2565,6 +2565,23 @@ unsigned int OpenType_apply_GPOS_lookup(const ScriptCache *script_cache, const O
             lookup_index, glyphs, glyph_index, glyph_count, goffset);
 }
 
+static LoadedScript *usp10_script_cache_add_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
+{
+    LoadedScript *script;
+
+    if (!usp10_array_reserve((void **)&script_cache->scripts, &script_cache->scripts_size,
+            script_cache->script_count + 1, sizeof(*script_cache->scripts)))
+    {
+        ERR("Failed to grow scripts array.\n");
+        return NULL;
+    }
+
+    script = &script_cache->scripts[script_cache->script_count++];
+    script->tag = tag;
+
+    return script;
+}
+
 static LoadedScript *usp10_script_cache_get_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
 {
     size_t i;
@@ -2578,94 +2595,53 @@ static LoadedScript *usp10_script_cache_get_script(ScriptCache *script_cache, OP
     return NULL;
 }
 
-static void GSUB_initialize_script_cache(ScriptCache *psc)
+static void usp10_script_cache_add_script_list(ScriptCache *script_cache,
+        enum usp10_script_table table, const OT_ScriptList *list)
 {
-    int i;
-
-    if (psc->GSUB_Table)
-    {
-        const OT_ScriptList *script;
-        const GSUB_Header* header = (const GSUB_Header*)psc->GSUB_Table;
-        script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
-        psc->script_count = GET_BE_WORD(script->ScriptCount);
-        TRACE("initializing %li scripts in this font\n",psc->script_count);
-        if (psc->script_count)
-        {
-            psc->scripts = heap_alloc_zero(psc->script_count * sizeof(*psc->scripts));
-            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].gsub_table = ((const BYTE*)script + offset);
-            }
-        }
-    }
-}
+    SIZE_T initial_count, count, i;
+    LoadedScript *script;
+    OPENTYPE_TAG tag;
 
-static void GPOS_expand_script_cache(ScriptCache *psc)
-{
-    int i, count;
-    const OT_ScriptList *script;
-    const GPOS_Header* header = (const GPOS_Header*)psc->GPOS_Table;
-    LoadedScript *loaded_script;
+    TRACE("script_cache %p, table %#x, list %p.\n", script_cache, table, list);
 
-    if (!header)
+    if (!(count = GET_BE_WORD(list->ScriptCount)))
         return;
 
-    script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
-    count = GET_BE_WORD(script->ScriptCount);
+    TRACE("Adding %lu scripts.\n", count);
 
-    if (!count)
-        return;
-
-    if (!psc->script_count)
-    {
-        psc->script_count = count;
-        TRACE("initializing %li scripts in this font\n",psc->script_count);
-        if (psc->script_count)
-        {
-            psc->scripts = heap_alloc_zero(psc->script_count * sizeof(*psc->scripts));
-            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].gpos_table = ((const BYTE*)script + offset);
-            }
-        }
-    }
-    else
+    initial_count = script_cache->script_count;
+    for (i = 0; i < count; ++i)
     {
-        for (i = 0; i < count; i++)
-        {
-            int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
-            OPENTYPE_TAG tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]);
+        tag = MS_MAKE_TAG(list->ScriptRecord[i].ScriptTag[0],
+                list->ScriptRecord[i].ScriptTag[1],
+                list->ScriptRecord[i].ScriptTag[2],
+                list->ScriptRecord[i].ScriptTag[3]);
 
-            if (!(loaded_script = usp10_script_cache_get_script(psc, tag)))
-            {
-                if (!usp10_array_reserve((void **)&psc->scripts, &psc->scripts_size,
-                        psc->script_count + 1, sizeof(*psc->scripts)))
-                {
-                    ERR("Failed grow scripts array.\n");
-                    return;
-                }
+        if (!(initial_count && (script = usp10_script_cache_get_script(script_cache, tag)))
+                && !(script = usp10_script_cache_add_script(script_cache, tag)))
+            return;
 
-                loaded_script = &psc->scripts[psc->script_count];
-                ++psc->script_count;
-                loaded_script->tag = tag;
-            }
-            loaded_script->gpos_table = (const BYTE *)script + offset;
-        }
+        script->table[table] = (const BYTE *)list + GET_BE_WORD(list->ScriptRecord[i].Script);
     }
 }
 
-static void _initialize_script_cache(ScriptCache *psc)
+static void _initialize_script_cache(ScriptCache *script_cache)
 {
-    if (!psc->scripts_initialized)
-    {
-        GSUB_initialize_script_cache(psc);
-        GPOS_expand_script_cache(psc);
-        psc->scripts_initialized = TRUE;
-    }
+    const GPOS_Header *gpos_header;
+    const GSUB_Header *gsub_header;
+
+    if (script_cache->scripts_initialized)
+        return;
+
+    if ((gsub_header = script_cache->GSUB_Table))
+        usp10_script_cache_add_script_list(script_cache, USP10_SCRIPT_TABLE_GSUB,
+                (const OT_ScriptList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->ScriptList)));
+
+    if ((gpos_header = script_cache->GPOS_Table))
+        usp10_script_cache_add_script_list(script_cache, USP10_SCRIPT_TABLE_GPOS,
+                (const OT_ScriptList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->ScriptList)));
+
+    script_cache->scripts_initialized = TRUE;
 }
 
 HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
@@ -2699,120 +2675,87 @@ HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor,
     return rc;
 }
 
-static LoadedLanguage *usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag)
+static LoadedLanguage *usp10_script_add_language(LoadedScript *script, OPENTYPE_TAG tag)
 {
-    size_t i;
+    LoadedLanguage *language;
 
-    for (i = 0; i < script->language_count; ++i)
+    if (!usp10_array_reserve((void **)&script->languages, &script->languages_size,
+            script->language_count + 1, sizeof(*script->languages)))
     {
-        if (script->languages[i].tag == tag)
-            return &script->languages[i];
+        ERR("Failed to grow languages array.\n");
+        return NULL;
     }
 
-    return NULL;
+    language = &script->languages[script->language_count++];
+    language->tag = tag;
+
+    return language;
 }
 
-static void GSUB_initialize_language_cache(LoadedScript *script)
+static LoadedLanguage *usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag)
 {
-    int i;
+    size_t i;
 
-    if (script->gsub_table)
+    for (i = 0; i < script->language_count; ++i)
     {
-        DWORD offset;
-        const OT_Script* table = script->gsub_table;
-        script->language_count = GET_BE_WORD(table->LangSysCount);
-        offset = GET_BE_WORD(table->DefaultLangSys);
-        if (offset)
-        {
-            script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
-            script->default_language.gsub_table = (const BYTE*)table + offset;
-        }
-
-        if (script->language_count)
-        {
-            TRACE("Deflang %p, LangCount %li\n",script->default_language.gsub_table, script->language_count);
-
-            script->languages = heap_alloc_zero(script->language_count * sizeof(*script->languages));
-
-            for (i = 0; i < script->language_count; i++)
-            {
-                int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
-                script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
-                script->languages[i].gsub_table = ((const BYTE*)table + offset);
-            }
-        }
+        if (script->languages[i].tag == tag)
+            return &script->languages[i];
     }
+
+    return NULL;
 }
 
-static void GPOS_expand_language_cache(LoadedScript *script)
+static void usp10_script_add_language_list(LoadedScript *script,
+        enum usp10_language_table table, const OT_Script *list)
 {
-    int count;
-    const OT_Script* table = script->gpos_table;
+    SIZE_T initial_count, count, i;
     LoadedLanguage *language;
+    OPENTYPE_TAG tag;
     DWORD offset;
 
-    if (!table)
-        return;
-
-    offset = GET_BE_WORD(table->DefaultLangSys);
-    if (offset)
-        script->default_language.gpos_table = (const BYTE*)table + offset;
-
-    count = GET_BE_WORD(table->LangSysCount);
+    TRACE("script %p, table %#x, list %p.\n", script, table, list);
 
-    TRACE("Deflang %p, LangCount %i\n",script->default_language.gpos_table, count);
+    if ((offset = GET_BE_WORD(list->DefaultLangSys)))
+    {
+        script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
+        script->default_language.table[table] = (const BYTE *)list + offset;
+        TRACE("Default language %p.\n", script->default_language.table[table]);
+    }
 
-    if (!count)
+    if (!(count = GET_BE_WORD(list->LangSysCount)))
         return;
 
-    if (!script->language_count)
-    {
-        int i;
-        script->language_count = count;
-
-        script->languages = heap_alloc_zero(script->language_count * sizeof(*script->languages));
+    TRACE("Adding %lu languages.\n", count);
 
-        for (i = 0; i < script->language_count; i++)
-        {
-            int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
-            script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
-            script->languages[i].gpos_table = ((const BYTE*)table + offset);
-        }
-    }
-    else if (count)
+    initial_count = script->language_count;
+    for (i = 0; i < count; ++i)
     {
-        int i;
-        for (i = 0; i < count; i++)
-        {
-            int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys);
-            OPENTYPE_TAG tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]);
+        tag = MS_MAKE_TAG(list->LangSysRecord[i].LangSysTag[0],
+                list->LangSysRecord[i].LangSysTag[1],
+                list->LangSysRecord[i].LangSysTag[2],
+                list->LangSysRecord[i].LangSysTag[3]);
 
-            if (!(language = usp10_script_get_language(script, tag)))
-            {
-                if (!usp10_array_reserve((void **)&script->languages, &script->languages_size,
-                        script->language_count + 1, sizeof(*script->languages)))
-                {
-                    ERR("Failed grow languages array.\n");
-                    return;
-                }
+        if (!(initial_count && (language = usp10_script_get_language(script, tag)))
+                && !(language = usp10_script_add_language(script, tag)))
+            return;
 
-                language = &script->languages[script->language_count];
-                ++script->language_count;
-                language->tag = tag;
-            }
-            language->gpos_table = (const BYTE *)table + offset;
-        }
+        language->table[table] = (const BYTE *)list + GET_BE_WORD(list->LangSysRecord[i].LangSys);
     }
 }
 
 static void _initialize_language_cache(LoadedScript *script)
 {
-    if (!script->languages_initialized)
-    {
-        GSUB_initialize_language_cache(script);
-        GPOS_expand_language_cache(script);
-        script->languages_initialized = TRUE;
-    }
+    const OT_Script *list;
+
+    if (script->languages_initialized)
+        return;
+
+    if ((list = script->table[USP10_SCRIPT_TABLE_GSUB]))
+        usp10_script_add_language_list(script, USP10_LANGUAGE_TABLE_GSUB, list);
+    if ((list = script->table[USP10_SCRIPT_TABLE_GPOS]))
+        usp10_script_add_language_list(script, USP10_LANGUAGE_TABLE_GPOS, list);
+
+    script->languages_initialized = TRUE;
 }
 
 HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags)
@@ -2851,7 +2794,7 @@ HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag,
         }
     }
 
-    if (script->default_language.gsub_table)
+    if (script->default_language.table[USP10_LANGUAGE_TABLE_GSUB])
     {
         if (i < cMaxTags)
             pLanguageTags[i] = script->default_language.tag;
@@ -2875,15 +2818,10 @@ static void usp10_language_add_feature_list(LoadedLanguage *language, char table
 
     TRACE("table_type %#x, %u features.\n", table_type, count);
 
-    if (!count)
+    if (!count || !usp10_array_reserve((void **)&language->features, &language->features_size,
+            language->feature_count + count, sizeof(*language->features)))
         return;
 
-    if (!language->feature_count)
-        language->features = heap_alloc(count * sizeof(*language->features));
-    else
-        language->features = HeapReAlloc(GetProcessHeap(), 0, language->features,
-                (language->feature_count + count) * sizeof(*language->features));
-
     for (i = 0; i < count; ++i)
     {
         const OT_FeatureRecord *record;
@@ -2899,7 +2837,7 @@ static void usp10_language_add_feature_list(LoadedLanguage *language, char table
         loaded_feature->tableType = table_type;
         loaded_feature->feature = feature;
         loaded_feature->lookup_count = GET_BE_WORD(feature->LookupCount);
-        loaded_feature->lookups = heap_alloc(loaded_feature->lookup_count * sizeof(*loaded_feature->lookups));
+        loaded_feature->lookups = heap_calloc(loaded_feature->lookup_count, sizeof(*loaded_feature->lookups));
         for (j = 0; j < loaded_feature->lookup_count; ++j)
             loaded_feature->lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
     }
@@ -2916,13 +2854,13 @@ static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language
     if (language->features_initialized)
         return;
 
-    if ((lang = language->gsub_table))
+    if ((lang = language->table[USP10_LANGUAGE_TABLE_GSUB]))
     {
         feature_list = (const OT_FeatureList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->FeatureList));
         usp10_language_add_feature_list(language, FEATURE_GSUB_TABLE, lang, feature_list);
     }
 
-    if ((lang = language->gpos_table))
+    if ((lang = language->table[USP10_LANGUAGE_TABLE_GPOS]))
     {
         feature_list = (const OT_FeatureList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->FeatureList));
         usp10_language_add_feature_list(language, FEATURE_GPOS_TABLE, lang, feature_list);
@@ -2934,9 +2872,9 @@ static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language
 HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature)
 {
     int i;
+    LoadedLanguage *language;
     LoadedScript *script;
     HRESULT rc = S_OK;
-    LoadedLanguage *language = NULL;
 
     _initialize_script_cache(psc);
     if (!(script = usp10_script_cache_get_script(psc, script_tag)))
@@ -2950,9 +2888,9 @@ HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, O
 
     _initialize_language_cache(script);
 
-    if ((script->default_language.gsub_table || script->default_language.gpos_table) && script->default_language.tag == language_tag)
-        language = &script->default_language;
-    else
+    language = &script->default_language;
+    if (language->tag != language_tag || (!language->table[USP10_LANGUAGE_TABLE_GSUB]
+            && !language->table[USP10_LANGUAGE_TABLE_GPOS]))
         language = usp10_script_get_language(script, language_tag);
 
     if (!language)
index ca084e7..3827000 100644 (file)
@@ -712,13 +712,14 @@ static VOID load_ot_tables(HDC hdc, ScriptCache *psc)
         psc->GDEF_Table = load_gdef_table(hdc);
 }
 
-INT SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, const WCHAR *chars, INT write_dir, INT count, const char* feature)
+int SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache *psc,
+        const WCHAR *chars, int write_dir, int count, const char *feature)
 {
     WORD *glyphs;
     INT glyph_count = count;
     INT rc;
 
-    glyphs = heap_alloc(2 * count * sizeof(*glyphs));
+    glyphs = heap_calloc(count, 2 * sizeof(*glyphs));
     GetGlyphIndicesW(hdc, chars, count, glyphs, 0);
     rc = apply_GSUB_feature_to_glyph(hdc, psa, psc, glyphs, 0, write_dir, &glyph_count, feature);
     if (rc > GSUB_E_NOGLYPH)
@@ -1695,7 +1696,7 @@ static void ComposeConsonants(HDC hdc, WCHAR *pwOutChars, INT *pcChars, const Co
     int offset = 0;
     int cWalk;
 
-    for (cWalk = 0; cWalk < *pcChars; cWalk++)
+    for (cWalk = 0; cWalk < *pcChars; cWalk += 2)
     {
         for (i = 0; consonants[i].output!= 0x0; i++)
         {
@@ -1720,7 +1721,6 @@ static void ComposeConsonants(HDC hdc, WCHAR *pwOutChars, INT *pcChars, const Co
                 break;
             }
         }
-        cWalk++;
     }
 }
 
index fe83722..ab3af43 100644 (file)
@@ -1373,7 +1373,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
     if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
         return E_INVALIDARG;
 
-    if (!(scripts = heap_alloc(cInChars * sizeof(*scripts))))
+    if (!(scripts = heap_calloc(cInChars, sizeof(*scripts))))
         return E_OUTOFMEMORY;
 
     for (i = 0; i < cInChars; i++)
@@ -1464,16 +1464,13 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
 
     if (psState && psControl)
     {
-        levels = heap_alloc_zero(cInChars * sizeof(WORD));
-        if (!levels)
+        if (!(levels = heap_calloc(cInChars, sizeof(*levels))))
             goto nomemory;
 
-        overrides = heap_alloc_zero(cInChars * sizeof(WORD));
-        if (!overrides)
+        if (!(overrides = heap_calloc(cInChars, sizeof(*overrides))))
             goto nomemory;
 
-        layout_levels = heap_alloc_zero(cInChars * sizeof(WORD));
-        if (!layout_levels)
+        if (!(layout_levels = heap_calloc(cInChars, sizeof(*layout_levels))))
             goto nomemory;
 
         if (psState->fOverrideDirection)
@@ -1519,8 +1516,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
             static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0};
             static const WCHAR repeatable_math_punc[] = {'#','$','%','+','-','/',0x2212, 0x2044,0};
 
-            strength = heap_alloc_zero(cInChars * sizeof(WORD));
-            if (!strength)
+            if (!(strength = heap_calloc(cInChars, sizeof(*strength))))
                 goto nomemory;
             BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength);
 
@@ -1948,8 +1944,7 @@ static BOOL requires_fallback(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa,
     if (SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa) != S_OK)
         return TRUE;
 
-    glyphs = heap_alloc(sizeof(WORD) * cChars);
-    if (!glyphs)
+    if (!(glyphs = heap_calloc(cChars, sizeof(*glyphs))))
         return FALSE;
     if (ScriptGetCMap(hdc, psc, pwcInChars, cChars, 0, glyphs) != S_OK)
     {
@@ -2012,8 +2007,10 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
     if (cString < 1 || !pString) return E_INVALIDARG;
     if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING;
 
-    if (!(analysis = heap_alloc_zero(sizeof(StringAnalysis)))) return E_OUTOFMEMORY;
-    if (!(analysis->pItem = heap_alloc_zero(num_items * sizeof(SCRIPT_ITEM) + 1))) goto error;
+    if (!(analysis = heap_alloc_zero(sizeof(*analysis))))
+        return E_OUTOFMEMORY;
+    if (!(analysis->pItem = heap_calloc(num_items + 1, sizeof(*analysis->pItem))))
+        goto error;
 
     /* FIXME: handle clipping */
     analysis->clip_len = cString;
@@ -2032,8 +2029,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
 
     if (dwFlags & SSA_PASSWORD)
     {
-        iString = heap_alloc(sizeof(WCHAR)*cString);
-        if (!iString)
+        if (!(iString = heap_calloc(cString, sizeof(*iString))))
         {
             hr = E_OUTOFMEMORY;
             goto error;
@@ -2058,18 +2054,16 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
 
     if (dwFlags & SSA_BREAK)
     {
-        if ((analysis->logattrs = heap_alloc(sizeof(SCRIPT_LOGATTR) * cString)))
-        {
-            for (i = 0; i < analysis->numItems; i++)
-                ScriptBreak(&((WCHAR *)pString)[analysis->pItem[i].iCharPos],
-                        analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos,
-                        &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]);
-        }
-        else
+        if (!(analysis->logattrs = heap_calloc(cString, sizeof(*analysis->logattrs))))
             goto error;
+
+        for (i = 0; i < analysis->numItems; ++i)
+            ScriptBreak(&((const WCHAR *)pString)[analysis->pItem[i].iCharPos],
+                    analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos,
+                    &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]);
     }
 
-    if (!(analysis->logical2visual = heap_alloc_zero(sizeof(int) * analysis->numItems)))
+    if (!(analysis->logical2visual = heap_calloc(analysis->numItems, sizeof(*analysis->logical2visual))))
         goto error;
     if (!(BidiLevel = heap_alloc_zero(analysis->numItems)))
         goto error;
@@ -2077,7 +2071,8 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
     if (dwFlags & SSA_GLYPHS)
     {
         int tab_x = 0;
-        if (!(analysis->glyphs = heap_alloc_zero(sizeof(StringGlyphs) * analysis->numItems)))
+
+        if (!(analysis->glyphs = heap_calloc(analysis->numItems, sizeof(*analysis->glyphs))))
         {
             heap_free(BidiLevel);
             goto error;
@@ -2088,11 +2083,11 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
             SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc;
             int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos;
             int numGlyphs = 1.5 * cChar + 16;
-            WORD *glyphs = heap_alloc_zero(sizeof(WORD) * numGlyphs);
-            WORD *pwLogClust = heap_alloc_zero(sizeof(WORD) * cChar);
-            int *piAdvance = heap_alloc_zero(sizeof(int) * numGlyphs);
-            SCRIPT_VISATTR *psva = heap_alloc_zero(sizeof(SCRIPT_VISATTR) * numGlyphs);
-            GOFFSET *pGoffset = heap_alloc_zero(sizeof(GOFFSET) * numGlyphs);
+            WORD *glyphs = heap_calloc(numGlyphs, sizeof(*glyphs));
+            WORD *pwLogClust = heap_calloc(cChar, sizeof(*pwLogClust));
+            int *piAdvance = heap_calloc(numGlyphs, sizeof(*piAdvance));
+            SCRIPT_VISATTR *psva = heap_calloc(numGlyphs, sizeof(*psva));
+            GOFFSET *pGoffset = heap_calloc(numGlyphs, sizeof(*pGoffset));
             int numGlyphsReturned;
             HFONT originalFont = 0x0;
 
@@ -3188,8 +3183,9 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
         WCHAR *rChars;
         if ((hr = SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa)) != S_OK) return hr;
 
-        rChars = heap_alloc(sizeof(WCHAR) * cChars);
-        if (!rChars) return E_OUTOFMEMORY;
+        if (!(rChars = heap_calloc(cChars, sizeof(*rChars))))
+            return E_OUTOFMEMORY;
+
         for (i = 0, g = 0, cluster = 0; i < cChars; i++)
         {
             int idx = i;
@@ -3333,10 +3329,10 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
     if (!psva || !pcGlyphs) return E_INVALIDARG;
     if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
 
-    charProps = heap_alloc_zero(sizeof(SCRIPT_CHARPROP)*cChars);
-    if (!charProps) return E_OUTOFMEMORY;
-    glyphProps = heap_alloc_zero(sizeof(SCRIPT_GLYPHPROP)*cMaxGlyphs);
-    if (!glyphProps)
+    if (!(charProps = heap_calloc(cChars, sizeof(*charProps))))
+        return E_OUTOFMEMORY;
+
+    if (!(glyphProps = heap_calloc(cMaxGlyphs, sizeof(*glyphProps))))
     {
         heap_free(charProps);
         return E_OUTOFMEMORY;
@@ -3501,8 +3497,8 @@ HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs,
     if (!psva) return E_INVALIDARG;
     if (!pGoffset) return E_FAIL;
 
-    glyphProps = heap_alloc(sizeof(SCRIPT_GLYPHPROP)*cGlyphs);
-    if (!glyphProps) return E_OUTOFMEMORY;
+    if (!(glyphProps = heap_calloc(cGlyphs, sizeof(*glyphProps))))
+        return E_OUTOFMEMORY;
 
     for (i = 0; i < cGlyphs; i++)
         glyphProps[i].sva = psva[i];
index 2229513..fea6891 100644 (file)
@@ -154,19 +154,32 @@ typedef struct {
     WORD *lookups;
 } LoadedFeature;
 
+enum usp10_language_table
+{
+    USP10_LANGUAGE_TABLE_GSUB = 0,
+    USP10_LANGUAGE_TABLE_GPOS,
+    USP10_LANGUAGE_TABLE_COUNT
+};
+
 typedef struct {
     OPENTYPE_TAG tag;
-    const void *gsub_table;
-    const void *gpos_table;
+    const void *table[USP10_LANGUAGE_TABLE_COUNT];
     BOOL features_initialized;
-    INT feature_count;
     LoadedFeature *features;
+    SIZE_T features_size;
+    SIZE_T feature_count;
 } LoadedLanguage;
 
+enum usp10_script_table
+{
+    USP10_SCRIPT_TABLE_GSUB = 0,
+    USP10_SCRIPT_TABLE_GPOS,
+    USP10_SCRIPT_TABLE_COUNT
+};
+
 typedef struct {
     OPENTYPE_TAG tag;
-    const void *gsub_table;
-    const void *gpos_table;
+    const void *table[USP10_SCRIPT_TABLE_COUNT];
     LoadedLanguage default_language;
     BOOL languages_initialized;
     LoadedLanguage *languages;
index 6ebb064..20f1cfb 100644 (file)
@@ -189,7 +189,7 @@ reactos/dll/win32/twain_32            # Synced to WineStaging-3.3
 reactos/dll/win32/updspapi            # Synced to WineStaging-3.3
 reactos/dll/win32/url                 # Synced to WineStaging-3.3
 reactos/dll/win32/urlmon              # Synced to WineStaging-3.9
-reactos/dll/win32/usp10               # Synced to WineStaging-3.3
+reactos/dll/win32/usp10               # Synced to WineStaging-3.9
 reactos/dll/win32/uxtheme             # Forked
 reactos/dll/win32/vbscript            # Synced to WineStaging-3.3
 reactos/dll/win32/version             # Synced to WineStaging-3.3