[USP10] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / reactos / dll / win32 / usp10 / usp10.c
index 3310b94..2b11afc 100644 (file)
  * and filtering characters and bi-directional text with custom line breaks.
  */
 
-#include <stdarg.h>
-//#include <stdlib.h>
+#include "usp10_internal.h"
 
-#include <windef.h>
-//#include "winbase.h"
-#include <wingdi.h>
 #include <winuser.h>
-//#include "winnls.h"
 #include <winreg.h>
-#include <usp10.h>
-
-#include "usp10_internal.h"
-
-#include <wine/debug.h>
-#include <wine/unicode.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
 
@@ -500,23 +489,23 @@ const scriptData scriptInformation[] = {
     {{Script_Tai_Le, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('t','a','l','e'),
-     {'M','i','c','r','o','s','o','f','t',' ','T','a','i',' ','L','e'}},
+     {'M','i','c','r','o','s','o','f','t',' ','T','a','i',' ','L','e',0}},
     {{Script_New_Tai_Lue, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('t','a','l','u'),
-     {'M','i','c','r','o','s','o','f','t',' ','N','e','w',' ','T','a','i',' ','L','u','e'}},
+     {'M','i','c','r','o','s','o','f','t',' ','N','e','w',' ','T','a','i',' ','L','u','e',0}},
     {{Script_New_Tai_Lue_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('t','a','l','u'),
-     {'M','i','c','r','o','s','o','f','t',' ','N','e','w',' ','T','a','i',' ','L','u','e'}},
+     {'M','i','c','r','o','s','o','f','t',' ','N','e','w',' ','T','a','i',' ','L','u','e',0}},
     {{Script_Khmer, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0x53, 0, 1, 1, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0},
      MS_MAKE_TAG('k','h','m','r'),
-     {'D','a','u','n','P','e','n','h'}},
+     {'D','a','u','n','P','e','n','h',0}},
     {{Script_Khmer_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0x53, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('k','h','m','r'),
-     {'D','a','u','n','P','e','n','h'}},
+     {'D','a','u','n','P','e','n','h',0}},
     {{Script_CJK_Han, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
      MS_MAKE_TAG('h','a','n','i'),
@@ -540,59 +529,59 @@ const scriptData scriptInformation[] = {
     {{Script_Yi, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_ENGLISH, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
      MS_MAKE_TAG('y','i',' ',' '),
-     {'M','i','c','r','o','s','o','f','t',' ','Y','i',' ','B','a','i','t','i'}},
+     {'M','i','c','r','o','s','o','f','t',' ','Y','i',' ','B','a','i','t','i',0}},
     {{Script_Ethiopic, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0x5e, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('e','t','h','i'),
-     {'N','y','a','l','a'}},
+     {'N','y','a','l','a',0}},
     {{Script_Ethiopic_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0x5e, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('e','t','h','i'),
-     {'N','y','a','l','a'}},
+     {'N','y','a','l','a',0}},
     {{Script_Mongolian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_MONGOLIAN, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('m','o','n','g'),
-     {'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i'}},
+     {'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i',0}},
     {{Script_Mongolian_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_MONGOLIAN, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('m','o','n','g'),
-     {'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i'}},
+     {'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i',0}},
     {{Script_Tifinagh, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('t','f','n','g'),
-     {'E','b','r','i','m','a'}},
+     {'E','b','r','i','m','a',0}},
     {{Script_NKo, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('n','k','o',' '),
-     {'E','b','r','i','m','a'}},
+     {'E','b','r','i','m','a',0}},
     {{Script_Vai, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('v','a','i',' '),
-     {'E','b','r','i','m','a'}},
+     {'E','b','r','i','m','a',0}},
     {{Script_Vai_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('v','a','i',' '),
-     {'E','b','r','i','m','a'}},
+     {'E','b','r','i','m','a',0}},
     {{Script_Cherokee, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0x5c, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('c','h','e','r'),
-     {'P','l','a','n','t','a','g','e','n','e','t',' ','C','h','e','r','o','k','e','e'}},
+     {'P','l','a','n','t','a','g','e','n','e','t',' ','C','h','e','r','o','k','e','e',0}},
     {{Script_Canadian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0x5d, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('c','a','n','s'),
-     {'E','u','p','h','e','m','i','a'}},
+     {'E','u','p','h','e','m','i','a',0}},
     {{Script_Ogham, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('o','g','a','m'),
-     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l'}},
+     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
     {{Script_Runic, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('r','u','n','r'),
-     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l'}},
+     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
     {{Script_Braille, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_ENGLISH, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('b','r','a','i'),
-     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l'}},
+     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
     {{Script_Surrogates, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_ENGLISH, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0},
      0x00000000,
@@ -604,19 +593,19 @@ const scriptData scriptInformation[] = {
     {{Script_Deseret, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('d','s','r','t'),
-     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l'}},
+     {'S','e','g','o','e',' ','U','I',' ','S','y','m','b','o','l',0}},
     {{Script_Osmanya, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('o','s','m','a'),
-     {'E','b','r','i','m','a'}},
+     {'E','b','r','i','m','a',0}},
     {{Script_Osmanya_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('o','s','m','a'),
-     {'E','b','r','i','m','a'}},
+     {'E','b','r','i','m','a',0}},
     {{Script_MathAlpha, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {0, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('m','a','t','h'),
-     {'C','a','m','b','r','i','a',' ','M','a','t','h'}},
+     {'C','a','m','b','r','i','a',' ','M','a','t','h',0}},
     {{Script_Hebrew_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
      {LANG_HEBREW, 0, 1, 0, 0, HEBREW_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('h','e','b','r'),
@@ -904,7 +893,7 @@ static WORD get_char_script( LPCWSTR str, INT index, INT end, INT *consumed)
     if (str[index] == 0xc || str[index] == 0x20 || str[index] == 0x202f)
         return Script_CR;
 
-    /* These punctuation are separated out as Latin punctuation */
+    /* These punctuation characters are separated out as Latin punctuation */
     if (strchrW(latin_punc,str[index]))
         return Script_Punctuation2;
 
@@ -1017,13 +1006,14 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
     if (psc && *psc)
     {
         unsigned int i;
+        INT n;
         for (i = 0; i < GLYPH_MAX / GLYPH_BLOCK_SIZE; i++)
         {
             heap_free(((ScriptCache *)*psc)->widths[i]);
         }
         for (i = 0; i < 0x10; i++)
         {
-            int j;
+            unsigned int j;
             if (((ScriptCache *)*psc)->page[i])
                 for (j = 0; j < GLYPH_MAX / GLYPH_BLOCK_SIZE; j++)
                     heap_free(((ScriptCache *)*psc)->page[i]->glyphs[j]);
@@ -1033,20 +1023,20 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
         heap_free(((ScriptCache *)*psc)->GDEF_Table);
         heap_free(((ScriptCache *)*psc)->CMAP_Table);
         heap_free(((ScriptCache *)*psc)->GPOS_Table);
-        for (i = 0; i < ((ScriptCache *)*psc)->script_count; i++)
+        for (n = 0; n < ((ScriptCache *)*psc)->script_count; n++)
         {
             int j;
-            for (j = 0; j < ((ScriptCache *)*psc)->scripts[i].language_count; j++)
+            for (j = 0; j < ((ScriptCache *)*psc)->scripts[n].language_count; j++)
             {
                 int k;
-                for (k = 0; k < ((ScriptCache *)*psc)->scripts[i].languages[j].feature_count; k++)
-                    heap_free(((ScriptCache *)*psc)->scripts[i].languages[j].features[k].lookups);
-                heap_free(((ScriptCache *)*psc)->scripts[i].languages[j].features);
+                for (k = 0; k < ((ScriptCache *)*psc)->scripts[n].languages[j].feature_count; k++)
+                    heap_free(((ScriptCache *)*psc)->scripts[n].languages[j].features[k].lookups);
+                heap_free(((ScriptCache *)*psc)->scripts[n].languages[j].features);
             }
-            for (j = 0; j < ((ScriptCache *)*psc)->scripts[i].default_language.feature_count; j++)
-                heap_free(((ScriptCache *)*psc)->scripts[i].default_language.features[j].lookups);
-            heap_free(((ScriptCache *)*psc)->scripts[i].default_language.features);
-            heap_free(((ScriptCache *)*psc)->scripts[i].languages);
+            for (j = 0; j < ((ScriptCache *)*psc)->scripts[n].default_language.feature_count; j++)
+                heap_free(((ScriptCache *)*psc)->scripts[n].default_language.features[j].lookups);
+            heap_free(((ScriptCache *)*psc)->scripts[n].default_language.features);
+            heap_free(((ScriptCache *)*psc)->scripts[n].languages);
         }
         heap_free(((ScriptCache *)*psc)->scripts);
         heap_free(((ScriptCache *)*psc)->otm);
@@ -1279,6 +1269,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
     WORD layoutRTL = 0;
     BOOL forceLevels = FALSE;
     INT consumed = 0;
+    HRESULT res = E_OUTOFMEMORY;
 
     TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems, 
           psControl, psState, pItems, pcItems);
@@ -1340,7 +1331,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
                         if (original == Script_Punctuation2)
                             break;
                     }
-                    if (scriptInformation[scripts[j]].props.fComplex || asian)
+                    if (j >= 0 && (scriptInformation[scripts[j]].props.fComplex || asian))
                         scripts[i] = scripts[j];
                 }
             }
@@ -1373,10 +1364,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
     {
         levels = heap_alloc_zero(cInChars * sizeof(WORD));
         if (!levels)
-        {
-            heap_free(scripts);
-            return E_OUTOFMEMORY;
-        }
+            goto nomemory;
 
         BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels);
         baselevel = levels[0];
@@ -1391,15 +1379,11 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
         else
         {
             BOOL inNumber = FALSE;
-            static WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0};
+            static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0};
 
             strength = heap_alloc_zero(cInChars * sizeof(WORD));
             if (!strength)
-            {
-                heap_free(scripts);
-                heap_free(levels);
-                return E_OUTOFMEMORY;
-            }
+                goto nomemory;
             BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength);
 
             /* We currently mis-level leading Diacriticals */
@@ -1482,7 +1466,8 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
         }
     }
 
-    while ((!levels || (levels && levels[cnt+1] == levels[0])) && (pwcInChars[cnt] == Numeric_space) && cnt < cInChars)
+    while ((!levels || (levels && cnt+1 < cInChars && levels[cnt+1] == levels[0]))
+            && (cnt < cInChars && pwcInChars[cnt] == Numeric_space))
         cnt++;
 
     if (cnt == cInChars) /* All Spaces */
@@ -1579,7 +1564,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
 
             index++;
             if  (index+1 > cMaxItems)
-                return E_OUTOFMEMORY;
+                goto nomemory;
 
             if (strength)
                 str = strength[cnt];
@@ -1615,20 +1600,22 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
      * item is set up to prevent random behaviour if the caller erroneously
      * checks the n+1 structure                                              */
     index++;
+    if (index + 1 > cMaxItems) goto nomemory;
     memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
 
     TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
 
     /*  Set one SCRIPT_STATE item being returned  */
-    if  (index + 1 > cMaxItems) return E_OUTOFMEMORY;
     if (pcItems) *pcItems = index;
 
     /*  Set SCRIPT_ITEM                                     */
     pItems[index].iCharPos = cnt;         /* the last item contains the ptr to the lastchar */
+    res = S_OK;
+nomemory:
     heap_free(levels);
     heap_free(strength);
     heap_free(scripts);
-    return S_OK;
+    return res;
 }
 
 /***********************************************************************
@@ -1955,9 +1942,8 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
             if ((dwFlags & SSA_LINK) && !analysis->glyphs[i].fallbackFont && !scriptInformation[analysis->pItem[i].a.eScript].props.fComplex && !analysis->pItem[i].a.fRTL)
                 analysis->pItem[i].a.fNoGlyphIndex = TRUE;
 
-            hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos],
-                             cChar, numGlyphs, &analysis->pItem[i].a,
-                             glyphs, pwLogClust, psva, &numGlyphsReturned);
+            ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], cChar, numGlyphs,
+                        &analysis->pItem[i].a, glyphs, pwLogClust, psva, &numGlyphsReturned);
             hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
                              piAdvance, pGoffset, abc);
             if (originalFont)
@@ -2534,8 +2520,9 @@ HRESULT WINAPI ScriptCPtoX(int iCP,
 
             if (check >= cChars && !iMaxPos)
             {
-                for (check = clust; check < cChars; check++)
-                    special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, check, 1);
+                int glyph;
+                for (glyph = clust; glyph < cGlyphs; glyph++)
+                    special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, 1);
                 iSpecial = item;
                 special_size /= (cChars - item);
                 iPosX += special_size;
@@ -2666,8 +2653,9 @@ HRESULT WINAPI ScriptXtoCP(int iX,
 
             if (check >= cChars && direction > 0)
             {
-                for (check = clust; check < cChars; check++)
-                    special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, check, direction);
+                int glyph;
+                for (glyph = clust; glyph < cGlyphs; glyph++)
+                    special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, direction);
                 iSpecial = item;
                 special_size /= (cChars - item);
                 iPosX += special_size;
@@ -2841,9 +2829,11 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
                                     SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs)
 {
     HRESULT hr;
-    unsigned int i,g;
+    int i;
+    unsigned int g;
     BOOL rtl;
     int cluster;
+    static int once = 0;
 
     TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %d, %d, %p, %p, %p, %p, %p )\n",
      hdc, psc, psa,
@@ -2858,7 +2848,7 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
     if (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
 
     if (cRanges)
-        FIXME("Ranges not supported yet\n");
+        if(!once++) FIXME("Ranges not supported yet\n");
 
     rtl = (psa && !psa->fLogicalOrder && psa->fRTL);
 
@@ -2967,6 +2957,15 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
             /* No mirroring done here */
             if (rtl) idx = cChars - 1 - i;
             pwOutGlyphs[i] = pwcChars[idx];
+
+            /* overwrite some basic control glyphs to blank */
+            if (psa && psa->eScript == Script_Control &&
+                pwcChars[idx] < ((ScriptCache *)*psc)->tm.tmFirstChar)
+            {
+                if (pwcChars[idx] == 0x0009 || pwcChars[idx] == 0x000A ||
+                    pwcChars[idx] == 0x000D || pwcChars[idx] >= 0x001C)
+                    pwOutGlyphs[i] = ((ScriptCache *)*psc)->sfp.wgBlank;
+            }
         }
     }
 
@@ -3073,6 +3072,7 @@ HRESULT WINAPI ScriptPlaceOpenType( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS
 {
     HRESULT hr;
     int i;
+    static int once = 0;
 
     TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %p, %p, %d, %p, %p, %d, %p %p %p)\n",
      hdc, psc, psa,
@@ -3086,7 +3086,7 @@ HRESULT WINAPI ScriptPlaceOpenType( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS
     if (!pGoffset) return E_FAIL;
 
     if (cRanges)
-        FIXME("Ranges not supported yet\n");
+        if (!once++) FIXME("Ranges not supported yet\n");
 
     ((ScriptCache *)*psc)->userScript = tagScript;
     ((ScriptCache *)*psc)->userLang = tagLangSys;
@@ -3405,10 +3405,6 @@ HRESULT WINAPI ScriptGetGlyphABCWidth(HDC hdc, SCRIPT_CACHE *psc, WORD glyph, AB
  *  Success: S_OK
  *  Failure: Non-zero HRESULT value.
  *
- * BUGS
- *  This stub works correctly for any sequence of a single
- *  embedding level but not for sequences of different
- *  embedding levels, i.e. mixtures of RTL and LTR scripts.
  */
 HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
 {
@@ -3747,8 +3743,10 @@ HRESULT WINAPI ScriptGetFontFeatureTags( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANAL
     return SHAPE_GetFontFeatureTags(hdc, (ScriptCache *)*psc, psa, tagScript, tagLangSys, cMaxTags, pFeatureTags, pcTags);
 }
 
+#ifdef __REACTOS__
 BOOL gbLpkPresent = FALSE;
 VOID WINAPI LpkPresent()
 {
     gbLpkPresent = TRUE; /* Turn it on this way! Wine is out of control! */
 }
+#endif