[3/8] gdi32: Fix for GetCharacterPlacement (bug 13094)

Nikolay Sivov bunglehead at gmail.com
Mon Jun 23 16:56:56 CDT 2008


Changelog:
    - GetCharacterPlacement fix for bug 13094 (with test). A call should accept NULL as lpResults.

---
 dlls/gdi32/font.c       |   34 ++++++++++++++++++++++++----------
 dlls/gdi32/tests/font.c |   17 +++++++++++++++++
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 1bfd97a..34aabd1 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -2709,27 +2709,35 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
     WCHAR *lpStringW;
     INT uCountW;
     GCP_RESULTSW resultsW;
+    GCP_RESULTSW *presults = NULL;
     DWORD ret;
     UINT font_cp;
 
     TRACE("%s, %d, %d, 0x%08x\n",
           debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
 
-    /* both structs are equal in size */
-    memcpy(&resultsW, lpResults, sizeof(resultsW));
+    if(lpResults){
+        /* both structs are equal in size */
+        memcpy(&resultsW, lpResults, sizeof(resultsW));
+
+        if(lpResults->lpOutString)
+            resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
+
+        presults = &resultsW;
+    }
 
     lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
-    if(lpResults->lpOutString)
-        resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
 
-    ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
+    ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, presults, dwFlags);
 
-    lpResults->nGlyphs = resultsW.nGlyphs;
-    lpResults->nMaxFit = resultsW.nMaxFit;
+    if(lpResults){
+        lpResults->nGlyphs = resultsW.nGlyphs;
+        lpResults->nMaxFit = resultsW.nMaxFit;
 
-    if(lpResults->lpOutString) {
-        WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
-                            lpResults->lpOutString, uCount, NULL, NULL );
+        if(lpResults->lpOutString) {
+            WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
+                                lpResults->lpOutString, uCount, NULL, NULL );
+        }
     }
 
     HeapFree(GetProcessHeap(), 0, lpStringW);
@@ -2780,6 +2788,10 @@ GetCharacterPlacementW(
 	    lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
 
     if(dwFlags&(~GCP_REORDER))			FIXME("flags 0x%08x ignored\n", dwFlags);
+
+    /* with NULL lpResults return GetTextExtentPoint32 result */
+    if(!lpResults)  goto nullres;
+
     if(lpResults->lpClass)	FIXME("classes not implemented\n");
     if (lpResults->lpCaretPos && (dwFlags & GCP_REORDER))
         FIXME("Caret positions for complex scripts not implemented\n");
@@ -2833,6 +2845,8 @@ GetCharacterPlacementW(
     if(lpResults->lpGlyphs)
 	GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
 
+nullres:
+
     if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
       ret = MAKELONG(size.cx, size.cy);
 
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 710148a..4d48bae 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1930,6 +1930,22 @@ static void test_GdiRealizationInfo(void)
     ReleaseDC(0, hdc);
 }
 
+static void test_GetCharacterPlacement(void)
+{
+    HDC hdc = GetDC(0);
+    CHAR str[] = "deadbeef"; 
+    DWORD ret;
+    SIZE sz;
+
+    /* when lpResults == NULL return value equals to MAKELONG(sz.cx, sz.cy) */
+    ret = GetCharacterPlacement(hdc, str, strlen(str), 0, NULL, GCP_USEKERNING);
+    GetTextExtentPoint32(hdc, str, strlen(str), &sz);
+
+    expect(MAKELONG(sz.cx, sz.cy), ret);
+
+    ReleaseDC(0, hdc);
+}
+
 START_TEST(font)
 {
     init();
@@ -1947,6 +1963,7 @@ START_TEST(font)
     test_font_charset();
     test_GetFontUnicodeRanges();
     test_nonexistent_font();
+    test_GetCharacterPlacement();
 
     /* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
      * I'd like to avoid them in this test.
-- 
1.4.4.4






More information about the wine-patches mailing list