[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