gdi32: fix for GetCharacterPlacement[A/W] to handle NULL lpResults (with test)
Nikolay Sivov
bunglehead at gmail.com
Mon Oct 6 17:57:56 CDT 2008
Changelog:
- fixes GetCharacterPlacement to handle NULL lpResults (bug 13094)
- fix some indentations
>From 3a538ef94155e07e4dc6c026fa629cb2ac2cfeec Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Tue, 7 Oct 2008 02:52:15 +0400
Subject: Fix for GetCharacterPlacement[A/W] for NULL lpResults pointer
---
dlls/gdi32/font.c | 135 ++++++++++++++++++++++++++---------------------
dlls/gdi32/tests/font.c | 21 +++++++
2 files changed, 95 insertions(+), 61 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 21d2ebb..189e009 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -2718,27 +2718,33 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
WCHAR *lpStringW;
INT uCountW;
GCP_RESULTSW resultsW;
+ GCP_RESULTSW *presultsW = NULL;
DWORD ret;
UINT font_cp;
- TRACE("%s, %d, %d, 0x%08x\n",
- debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
+ TRACE("%s, %d, %d, %p, 0x%08x\n",
+ debugstr_an(lpString, uCount), uCount, nMaxExtent, lpResults, 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));
+ presultsW = &resultsW;
+ }
lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
- if(lpResults->lpOutString)
+ if(lpResults && lpResults->lpOutString)
resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
- ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
+ ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, presultsW, 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);
@@ -2767,67 +2773,72 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
*/
DWORD WINAPI
GetCharacterPlacementW(
- HDC hdc, /* [in] Device context for which the rendering is to be done */
- LPCWSTR lpString, /* [in] The string for which information is to be returned */
- INT uCount, /* [in] Number of WORDS in string. */
- INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
+ HDC hdc, /* [in] Device context for which the rendering is to be done */
+ LPCWSTR lpString,/* [in] The string for which information is to be returned */
+ INT uCount, /* [in] Number of WORDS in string. */
+ INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
- DWORD dwFlags /* [in] Flags specifying how to process the string */
+ DWORD dwFlags /* [in] Flags specifying how to process the string */
)
{
DWORD ret=0;
SIZE size;
UINT i, nSet;
- TRACE("%s, %d, %d, 0x%08x\n",
- debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
+ TRACE("%s, %d, %d, %p, 0x%08x\n",
+ debugstr_wn(lpString, uCount), uCount, nMaxExtent, lpResults, dwFlags);
+
+ if(lpResults)
+ TRACE("lStructSize=%d, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
+ "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
+ lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
+ lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
+ lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
- TRACE("lStructSize=%d, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
- "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
- lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
- lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
- lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
+ if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08x ignored\n", dwFlags);
- if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08x ignored\n", dwFlags);
- if(lpResults->lpClass) FIXME("classes not implemented\n");
+ /* 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");
- nSet = (UINT)uCount;
- if(nSet > lpResults->nGlyphs)
- nSet = lpResults->nGlyphs;
+ nSet = (UINT)uCount;
+ if(nSet > lpResults->nGlyphs)
+ nSet = lpResults->nGlyphs;
- /* return number of initialized fields */
- lpResults->nGlyphs = nSet;
+ /* return number of initialized fields */
+ lpResults->nGlyphs = nSet;
- if((dwFlags&GCP_REORDER)==0 )
- {
- /* Treat the case where no special handling was requested in a fastpath way */
+ if((dwFlags&GCP_REORDER)==0 )
+ {
+ /* Treat the case where no special handling was requested in a fastpath way */
/* copy will do if the GCP_REORDER flag is not set */
- if(lpResults->lpOutString)
- memcpy( lpResults->lpOutString, lpString, nSet * sizeof(WCHAR));
-
- if(lpResults->lpOrder)
- {
- for(i = 0; i < nSet; i++)
- lpResults->lpOrder[i] = i;
- }
- } else
- {
- BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
- nSet, lpResults->lpOrder );
- }
+ if(lpResults->lpOutString)
+ memcpy(lpResults->lpOutString, lpString, nSet * sizeof(WCHAR));
- /* FIXME: Will use the placement chars */
- if (lpResults->lpDx)
- {
- int c;
- for (i = 0; i < nSet; i++)
- {
- if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
- lpResults->lpDx[i]= c;
- }
- }
+ if(lpResults->lpOrder)
+ {
+ for(i = 0; i < nSet; i++)
+ lpResults->lpOrder[i] = i;
+ }
+ } else
+ {
+ BIDI_Reorder(lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
+ nSet, lpResults->lpOrder );
+ }
+
+ /* FIXME: Will use the placement chars */
+ if (lpResults->lpDx)
+ {
+ int c;
+ for (i = 0; i < nSet; i++)
+ {
+ if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
+ lpResults->lpDx[i]= c;
+ }
+ }
if (lpResults->lpCaretPos && !(dwFlags & GCP_REORDER))
{
@@ -2838,9 +2849,11 @@ GetCharacterPlacementW(
if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
lpResults->lpCaretPos[i] = (pos += size.cx);
}
-
+
if(lpResults->lpGlyphs)
- GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
+ GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
+
+nullres:
if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
ret = MAKELONG(size.cx, size.cy);
@@ -2952,9 +2965,9 @@ BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
/***********************************************************************
- * *
- * Font Resource API *
- * *
+ * *
+ * Font Resource API *
+ * *
***********************************************************************/
/***********************************************************************
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index bbcdf0b..c3ebefa 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -2464,6 +2464,26 @@ static void test_orientation(void)
DeleteDC(hdc);
}
+static void test_GetCharacterPlacement(void)
+{
+ HDC hdc = GetDC(0);
+ CHAR str[] = "deadbeef";
+ WCHAR strW[] = {'d','e','a','d','b','e','e','f','\0'};
+ DWORD ret;
+ SIZE sz;
+
+ /* when lpResults == NULL return value equals to MAKELONG(sz.cx, sz.cy) */
+ ret = GetCharacterPlacementA(hdc, str, lstrlenA(str), 0, NULL, GCP_USEKERNING);
+ GetTextExtentPoint32A(hdc, str, lstrlen(str), &sz);
+ expect(MAKELONG(sz.cx, sz.cy), ret);
+
+ ret = GetCharacterPlacementW(hdc, strW, lstrlenW(strW), 0, NULL, GCP_USEKERNING);
+ GetTextExtentPoint32W(hdc, strW, lstrlenW(strW), &sz);
+ expect(MAKELONG(sz.cx, sz.cy), ret);
+
+ ReleaseDC(0, hdc);
+}
+
START_TEST(font)
{
init();
@@ -2501,4 +2521,5 @@ START_TEST(font)
test_GetTextMetrics();
test_GdiRealizationInfo();
test_GetTextFace();
+ test_GetCharacterPlacement();
}
--
1.4.4.4
More information about the wine-patches
mailing list