Guy Albertelli : usp10: Use passed hdc instead of cached one for ScriptTextOut with test to check.

Alexandre Julliard julliard at winehq.org
Thu May 1 06:39:20 CDT 2008


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

Author: Guy Albertelli <galberte at neo.rr.com>
Date:   Tue Apr 29 00:15:23 2008 -0400

usp10: Use passed hdc instead of cached one for ScriptTextOut with test to check.

---

 dlls/usp10/tests/usp10.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/usp10/usp10.c       |    2 +-
 2 files changed, 89 insertions(+), 1 deletions(-)

diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index f054e62..b0a0b85 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -526,6 +526,93 @@ static void test_ScriptTextOut(HDC hdc)
     }
 }
 
+static void test_ScriptTextOut2(HDC hdc)
+{
+/*  Intent is to validate that the HDC passed into ScriptTextOut is
+ *  used instead of the (possibly) invalid cached one
+ */
+    HRESULT         hr;
+
+    HDC             hdc1, hdc2;
+    int             cInChars;
+    int             cMaxItems;
+    SCRIPT_ITEM     pItem[255];
+    int             pcItems;
+    WCHAR           TestItem1[] = {'T', 'e', 's', 't', 'a', 0};
+
+    SCRIPT_CACHE    psc;
+    int             cChars;
+    int             cMaxGlyphs;
+    unsigned short  pwOutGlyphs1[256];
+    WORD            pwLogClust[256];
+    SCRIPT_VISATTR  psva[256];
+    int             pcGlyphs;
+    int             piAdvance[256];
+    GOFFSET         pGoffset[256];
+    ABC             pABC[256];
+
+    /* Create an extra DC that will be used until the ScriptTextOut */
+    hdc1 = CreateCompatibleDC(hdc);
+    ok (hdc1 != 0, "CreateCompatibleDC failed to create a DC\n");
+    hdc2 = CreateCompatibleDC(hdc);
+    ok (hdc2 != 0, "CreateCompatibleDC failed to create a DC\n");
+
+    /* This is a valid test that will cause parsing to take place                             */
+    cInChars = 5;
+    cMaxItems = 255;
+    hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
+    ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", hr);
+    /*  This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is *
+     *  returned.                                                                             */
+    ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n");
+    if (pcItems > 0)
+        ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
+            "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
+            pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
+
+    /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue
+     * ie. ScriptItemize has succeeded and that pItem has been set                            */
+    cInChars = 5;
+    cMaxItems = 255;
+    if (hr == 0) {
+        psc = NULL;                                   /* must be null on first call           */
+        cChars = cInChars;
+        cMaxGlyphs = cInChars;
+        cMaxGlyphs = 256;
+        hr = ScriptShape(hdc2, &psc, TestItem1, cChars,
+                         cMaxGlyphs, &pItem[0].a,
+                         pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
+        ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", hr);
+        ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
+        ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
+        if (hr ==0) {
+            /* Note hdc is needed as glyph info is not yet in psc                  */
+            hr = ScriptPlace(hdc2, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
+                             pGoffset, pABC);
+            ok (hr == 0, "Should return 0 not (%08x)\n", hr);
+
+            /*   key part!!!   cached dc is being deleted  */
+            hr = DeleteDC(hdc2);
+            ok(hr == 1, "DeleteDC should return 1 not %08x\n", hr);
+
+            /* At this point the cached hdc (hdc2) has been destroyed,
+             * however, we are passing in a *real* hdc (the original hdc).
+             * The text should be written to that DC
+             */
+            hr = ScriptTextOut(hdc1, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
+                               piAdvance, NULL, pGoffset);
+            ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", hr);
+            ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
+
+            DeleteDC(hdc1);
+
+            /* Clean up and go   */
+            ScriptFreeCache(&psc);
+            ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
+        }
+    }
+}
+
 static void test_ScriptXtoX(void)
 /****************************************************************************************
  *  This routine tests the ScriptXtoCP and ScriptCPtoX functions using static variables *
@@ -1282,6 +1369,7 @@ START_TEST(usp10)
 
     test_ScriptGetFontProperties(hdc);
     test_ScriptTextOut(hdc);
+    test_ScriptTextOut2(hdc);
     test_ScriptXtoX();
     test_ScriptString(hdc);
     test_ScriptStringXtoCP_CPtoX(hdc);
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 3f0c896..e8e9bf0 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -1424,7 +1424,7 @@ HRESULT WINAPI ScriptTextOut(const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UIN
     if  (!psa->fNoGlyphIndex)                                     /* Have Glyphs?                      */
         fuOptions |= ETO_GLYPH_INDEX;                             /* Say don't do translation to glyph */
 
-    if (!ExtTextOutW(get_cache_hdc(psc), x, y, fuOptions, lprc, pwGlyphs, cGlyphs, NULL))
+    if (!ExtTextOutW(hdc, x, y, fuOptions, lprc, pwGlyphs, cGlyphs, NULL))
         hr = S_FALSE;
 
     unselect_cached_font(psc, hfont);




More information about the wine-cvs mailing list