gdi32: Add helper functions for GetTextExtentExPoint and fix handling of text justification.
This commit is contained in:
parent
17f098869f
commit
1c2f23cf2f
|
@ -308,6 +308,83 @@ static UINT get_default_smoothing( HKEY key )
|
||||||
return GGO_GRAY4_BITMAP;
|
return GGO_GRAY4_BITMAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* compute positions for text rendering, in device coords */
|
||||||
|
static BOOL get_char_positions( DC *dc, const WCHAR *str, INT count, INT *dx, SIZE *size )
|
||||||
|
{
|
||||||
|
TEXTMETRICW tm;
|
||||||
|
PHYSDEV dev = GET_DC_PHYSDEV( dc, pGetTextExtentExPoint );
|
||||||
|
|
||||||
|
size->cx = size->cy = 0;
|
||||||
|
if (!count) return TRUE;
|
||||||
|
|
||||||
|
dev = GET_DC_PHYSDEV( dc, pGetTextMetrics );
|
||||||
|
dev->funcs->pGetTextMetrics( dev, &tm );
|
||||||
|
|
||||||
|
if (!dev->funcs->pGetTextExtentExPoint( dev, str, count, 0, NULL, dx, size )) return FALSE;
|
||||||
|
|
||||||
|
if (dc->breakExtra || dc->breakRem)
|
||||||
|
{
|
||||||
|
int i, space = 0, rem = dc->breakRem;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (str[i] == tm.tmBreakChar)
|
||||||
|
{
|
||||||
|
space += dc->breakExtra;
|
||||||
|
if (rem > 0)
|
||||||
|
{
|
||||||
|
space++;
|
||||||
|
rem--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dx[i] += space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size->cx = dx[count - 1];
|
||||||
|
size->cy = tm.tmHeight;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compute positions for text rendering, in device coords */
|
||||||
|
static BOOL get_char_positions_indices( DC *dc, const WORD *indices, INT count, INT *dx, SIZE *size )
|
||||||
|
{
|
||||||
|
TEXTMETRICW tm;
|
||||||
|
PHYSDEV dev = GET_DC_PHYSDEV( dc, pGetTextExtentExPoint );
|
||||||
|
|
||||||
|
size->cx = size->cy = 0;
|
||||||
|
if (!count) return TRUE;
|
||||||
|
|
||||||
|
dev = GET_DC_PHYSDEV( dc, pGetTextMetrics );
|
||||||
|
dev->funcs->pGetTextMetrics( dev, &tm );
|
||||||
|
|
||||||
|
if (!dev->funcs->pGetTextExtentExPointI( dev, indices, count, 0, NULL, dx, size )) return FALSE;
|
||||||
|
|
||||||
|
if (dc->breakExtra || dc->breakRem)
|
||||||
|
{
|
||||||
|
WORD space_index;
|
||||||
|
int i, space = 0, rem = dc->breakRem;
|
||||||
|
|
||||||
|
dev = GET_DC_PHYSDEV( dc, pGetGlyphIndices );
|
||||||
|
dev->funcs->pGetGlyphIndices( dev, &tm.tmBreakChar, 1, &space_index, 0 );
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (indices[i] == space_index)
|
||||||
|
{
|
||||||
|
space += dc->breakExtra;
|
||||||
|
if (rem > 0)
|
||||||
|
{
|
||||||
|
space++;
|
||||||
|
rem--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dx[i] += space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size->cx = dx[count - 1];
|
||||||
|
size->cy = tm.tmHeight;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GdiGetCodePage (GDI32.@)
|
* GdiGetCodePage (GDI32.@)
|
||||||
|
@ -1015,20 +1092,45 @@ BOOL WINAPI GetTextExtentPoint32W(
|
||||||
BOOL WINAPI GetTextExtentExPointI( HDC hdc, const WORD *indices, INT count, INT max_ext,
|
BOOL WINAPI GetTextExtentExPointI( HDC hdc, const WORD *indices, INT count, INT max_ext,
|
||||||
LPINT nfit, LPINT dxs, LPSIZE size )
|
LPINT nfit, LPINT dxs, LPSIZE size )
|
||||||
{
|
{
|
||||||
PHYSDEV dev;
|
|
||||||
BOOL ret;
|
|
||||||
DC *dc;
|
DC *dc;
|
||||||
|
int i;
|
||||||
|
BOOL ret;
|
||||||
|
INT buffer[256], *pos = dxs;
|
||||||
|
|
||||||
if (count < 0) return FALSE;
|
if (count < 0) return FALSE;
|
||||||
|
|
||||||
dc = get_dc_ptr( hdc );
|
dc = get_dc_ptr( hdc );
|
||||||
if (!dc) return FALSE;
|
if (!dc) return FALSE;
|
||||||
|
|
||||||
dev = GET_DC_PHYSDEV( dc, pGetTextExtentExPointI );
|
if (!dxs)
|
||||||
ret = dev->funcs->pGetTextExtentExPointI( dev, indices, count, max_ext, nfit, dxs, size );
|
{
|
||||||
size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
|
pos = buffer;
|
||||||
size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
|
if (count > 256 && !(pos = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pos) )))
|
||||||
size->cx += count * dc->charExtra;
|
{
|
||||||
|
release_dc_ptr( dc );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = get_char_positions_indices( dc, indices, count, pos, size );
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (dxs || nfit)
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
unsigned int dx = abs( INTERNAL_XDSTOWS( dc, pos[i] )) + (i + 1) * dc->charExtra;
|
||||||
|
if (dx > (unsigned int)max_ext) break;
|
||||||
|
if (dxs) dxs[i] = dx;
|
||||||
|
}
|
||||||
|
if (nfit) *nfit = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
size->cx = abs( INTERNAL_XDSTOWS( dc, size->cx )) + count * dc->charExtra;
|
||||||
|
size->cy = abs( INTERNAL_YDSTOWS( dc, size->cy ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos != buffer && pos != dxs) HeapFree( GetProcessHeap(), 0, pos );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
|
|
||||||
TRACE("(%p %p %d %p): returning %d x %d\n",
|
TRACE("(%p %p %d %p): returning %d x %d\n",
|
||||||
|
@ -1091,6 +1193,7 @@ BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
|
||||||
LPWSTR p = NULL;
|
LPWSTR p = NULL;
|
||||||
|
|
||||||
if (count < 0) return FALSE;
|
if (count < 0) return FALSE;
|
||||||
|
if (maxExt < -1) return FALSE;
|
||||||
|
|
||||||
if (alpDx)
|
if (alpDx)
|
||||||
{
|
{
|
||||||
|
@ -1122,126 +1225,52 @@ BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
|
||||||
*
|
*
|
||||||
* Return the size of the string as it would be if it was output properly by
|
* Return the size of the string as it would be if it was output properly by
|
||||||
* e.g. TextOut.
|
* e.g. TextOut.
|
||||||
*
|
|
||||||
* This should include
|
|
||||||
* - Intercharacter spacing
|
|
||||||
* - justification spacing (not yet done)
|
|
||||||
* - kerning? see below
|
|
||||||
*
|
|
||||||
* Kerning. Since kerning would be carried out by the rendering code it should
|
|
||||||
* be done by the driver. However they don't support it yet. Also I am not
|
|
||||||
* yet persuaded that (certainly under Win95) any kerning is actually done.
|
|
||||||
*
|
|
||||||
* str: According to MSDN this should be null-terminated. That is not true; a
|
|
||||||
* null will not terminate it early.
|
|
||||||
* size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
|
|
||||||
* than count. I have seen it be either the size of the full string or
|
|
||||||
* 1 less than the size of the full string. I have not seen it bear any
|
|
||||||
* resemblance to the portion that would fit.
|
|
||||||
* lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
|
|
||||||
* trailing intercharacter spacing and any trailing justification.
|
|
||||||
*
|
|
||||||
* FIXME
|
|
||||||
* Currently we do this by measuring each character etc. We should do it by
|
|
||||||
* passing the request to the driver, perhaps by extending the
|
|
||||||
* pGetTextExtentPoint function to take the alpDx argument. That would avoid
|
|
||||||
* thinking about kerning issues and rounding issues in the justification.
|
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count, INT max_ext,
|
||||||
BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
|
LPINT nfit, LPINT dxs, LPSIZE size )
|
||||||
INT maxExt, LPINT lpnFit,
|
|
||||||
LPINT alpDx, LPSIZE size )
|
|
||||||
{
|
{
|
||||||
INT nFit = 0;
|
|
||||||
LPINT dxs = NULL;
|
|
||||||
DC *dc;
|
DC *dc;
|
||||||
BOOL ret = FALSE;
|
int i;
|
||||||
TEXTMETRICW tm;
|
BOOL ret;
|
||||||
PHYSDEV dev;
|
INT buffer[256], *pos = dxs;
|
||||||
|
|
||||||
TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
|
|
||||||
|
|
||||||
if (count < 0) return FALSE;
|
if (count < 0) return FALSE;
|
||||||
|
|
||||||
dc = get_dc_ptr(hdc);
|
dc = get_dc_ptr(hdc);
|
||||||
if (!dc) return FALSE;
|
if (!dc) return FALSE;
|
||||||
|
|
||||||
GetTextMetricsW(hdc, &tm);
|
if (!dxs)
|
||||||
|
|
||||||
/* If we need to calculate nFit, then we need the partial extents even if
|
|
||||||
the user hasn't provided us with an array. */
|
|
||||||
if (lpnFit)
|
|
||||||
{
|
{
|
||||||
dxs = alpDx ? alpDx : HeapAlloc(GetProcessHeap(), 0, count * sizeof alpDx[0]);
|
pos = buffer;
|
||||||
if (! dxs)
|
if (count > 256 && !(pos = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pos) )))
|
||||||
{
|
{
|
||||||
release_dc_ptr(dc);
|
release_dc_ptr( dc );
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
dxs = alpDx;
|
|
||||||
|
|
||||||
dev = GET_DC_PHYSDEV( dc, pGetTextExtentExPoint );
|
ret = get_char_positions( dc, str, count, pos, size );
|
||||||
ret = dev->funcs->pGetTextExtentExPoint(dev, str, count, 0, NULL, dxs, size);
|
|
||||||
|
|
||||||
/* Perform device size to world size transformations. */
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
INT extra = abs(INTERNAL_XWSTODS(dc, dc->charExtra)),
|
if (dxs || nfit)
|
||||||
breakExtra = dc->breakExtra,
|
|
||||||
breakRem = dc->breakRem,
|
|
||||||
i;
|
|
||||||
|
|
||||||
if (dxs)
|
|
||||||
{
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
dxs[i] += (i+1) * extra;
|
|
||||||
if (count > 1 && (breakExtra || breakRem) && str[i] == tm.tmBreakChar)
|
|
||||||
{
|
|
||||||
dxs[i] += breakExtra;
|
|
||||||
if (breakRem > 0)
|
|
||||||
{
|
|
||||||
breakRem--;
|
|
||||||
dxs[i]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dxs[i] = abs(INTERNAL_XDSTOWS(dc, dxs[i]));
|
|
||||||
if (dxs[i] <= maxExt)
|
|
||||||
++nFit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (count > 1 && (breakExtra || breakRem))
|
|
||||||
{
|
{
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (str[i] == tm.tmBreakChar)
|
unsigned int dx = abs( INTERNAL_XDSTOWS( dc, pos[i] )) + (i + 1) * dc->charExtra;
|
||||||
{
|
if (dx > (unsigned int)max_ext) break;
|
||||||
size->cx += breakExtra;
|
if (dxs) dxs[i] = dx;
|
||||||
if (breakRem > 0)
|
|
||||||
{
|
|
||||||
breakRem--;
|
|
||||||
(size->cx)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (nfit) *nfit = i;
|
||||||
}
|
}
|
||||||
size->cx += count * extra;
|
|
||||||
size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
|
size->cx = abs( INTERNAL_XDSTOWS( dc, size->cx )) + count * dc->charExtra;
|
||||||
size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
|
size->cy = abs( INTERNAL_YDSTOWS( dc, size->cy ));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpnFit)
|
if (pos != buffer && pos != dxs) HeapFree( GetProcessHeap(), 0, pos );
|
||||||
*lpnFit = nFit;
|
|
||||||
|
|
||||||
if (! alpDx)
|
|
||||||
HeapFree(GetProcessHeap(), 0, dxs);
|
|
||||||
|
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
|
|
||||||
TRACE("returning %d %d x %d\n",nFit,size->cx,size->cy);
|
TRACE("(%p, %s, %d) returning %dx%d\n", hdc, debugstr_wn(str,count), max_ext, size->cx, size->cy );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ static BOOL (WINAPI *pGetCharABCWidthsFloatW)(HDC hdc, UINT first, UINT last, L
|
||||||
static DWORD (WINAPI *pGetFontUnicodeRanges)(HDC hdc, LPGLYPHSET lpgs);
|
static DWORD (WINAPI *pGetFontUnicodeRanges)(HDC hdc, LPGLYPHSET lpgs);
|
||||||
static DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi, DWORD flags);
|
static DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi, DWORD flags);
|
||||||
static DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
|
static DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
|
||||||
|
static BOOL (WINAPI *pGetTextExtentExPointI)(HDC hdc, const WORD *indices, INT count, INT max_ext,
|
||||||
|
LPINT nfit, LPINT dxs, LPSIZE size );
|
||||||
static BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *);
|
static BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *);
|
||||||
static HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *);
|
static HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *);
|
||||||
static HANDLE (WINAPI *pAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
|
static HANDLE (WINAPI *pAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
|
||||||
|
@ -69,6 +71,7 @@ static void init(void)
|
||||||
pGetFontUnicodeRanges = (void *)GetProcAddress(hgdi32, "GetFontUnicodeRanges");
|
pGetFontUnicodeRanges = (void *)GetProcAddress(hgdi32, "GetFontUnicodeRanges");
|
||||||
pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA");
|
pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA");
|
||||||
pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW");
|
pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW");
|
||||||
|
pGetTextExtentExPointI = (void *)GetProcAddress(hgdi32, "GetTextExtentExPointI");
|
||||||
pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo");
|
pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo");
|
||||||
pCreateFontIndirectExA = (void *)GetProcAddress(hgdi32, "CreateFontIndirectExA");
|
pCreateFontIndirectExA = (void *)GetProcAddress(hgdi32, "CreateFontIndirectExA");
|
||||||
pAddFontMemResourceEx = (void *)GetProcAddress(hgdi32, "AddFontMemResourceEx");
|
pAddFontMemResourceEx = (void *)GetProcAddress(hgdi32, "AddFontMemResourceEx");
|
||||||
|
@ -1294,20 +1297,20 @@ static void test_text_extents(void)
|
||||||
fit1 = fit2 = -215;
|
fit1 = fit2 = -215;
|
||||||
ret = GetTextExtentExPointA(hdc, "One", 3, -1, &fit1, NULL, &sz);
|
ret = GetTextExtentExPointA(hdc, "One", 3, -1, &fit1, NULL, &sz);
|
||||||
ok(ret == TRUE, "got %d\n", ret);
|
ok(ret == TRUE, "got %d\n", ret);
|
||||||
todo_wine ok(fit1 == 3, "fit = %d\n", fit1);
|
ok(fit1 == 3, "fit = %d\n", fit1);
|
||||||
ret = GetTextExtentExPointW(hdc, wt, 3, -1, &fit2, NULL, &sz);
|
ret = GetTextExtentExPointW(hdc, wt, 3, -1, &fit2, NULL, &sz);
|
||||||
ok(ret == TRUE, "got %d\n", ret);
|
ok(ret == TRUE, "got %d\n", ret);
|
||||||
todo_wine ok(fit2 == 3, "fit = %d\n", fit2);
|
ok(fit2 == 3, "fit = %d\n", fit2);
|
||||||
|
|
||||||
/* max_extent = -2 is interpreted similarly, but the Ansi version
|
/* max_extent = -2 is interpreted similarly, but the Ansi version
|
||||||
* rejects it while the Unicode one accepts it */
|
* rejects it while the Unicode one accepts it */
|
||||||
fit1 = fit2 = -215;
|
fit1 = fit2 = -215;
|
||||||
ret = GetTextExtentExPointA(hdc, "One", 3, -2, &fit1, NULL, &sz);
|
ret = GetTextExtentExPointA(hdc, "One", 3, -2, &fit1, NULL, &sz);
|
||||||
todo_wine ok(ret == FALSE, "got %d\n", ret);
|
ok(ret == FALSE, "got %d\n", ret);
|
||||||
todo_wine ok(fit1 == -215, "fit = %d\n", fit1);
|
ok(fit1 == -215, "fit = %d\n", fit1);
|
||||||
ret = GetTextExtentExPointW(hdc, wt, 3, -2, &fit2, NULL, &sz);
|
ret = GetTextExtentExPointW(hdc, wt, 3, -2, &fit2, NULL, &sz);
|
||||||
ok(ret == TRUE, "got %d\n", ret);
|
ok(ret == TRUE, "got %d\n", ret);
|
||||||
todo_wine ok(fit2 == 3, "fit = %d\n", fit2);
|
ok(fit2 == 3, "fit = %d\n", fit2);
|
||||||
|
|
||||||
hfont = SelectObject(hdc, hfont);
|
hfont = SelectObject(hdc, hfont);
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
|
@ -1834,6 +1837,9 @@ static void test_SetTextJustification(void)
|
||||||
LOGFONTA lf;
|
LOGFONTA lf;
|
||||||
HFONT hfont;
|
HFONT hfont;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
SIZE size, expect;
|
||||||
|
int i;
|
||||||
|
WORD indices[2];
|
||||||
static char testText[] =
|
static char testText[] =
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
|
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
|
||||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
|
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
|
||||||
|
@ -1859,17 +1865,74 @@ static void test_SetTextJustification(void)
|
||||||
|
|
||||||
testJustification(hdc, testText, &clientArea);
|
testJustification(hdc, testText, &clientArea);
|
||||||
|
|
||||||
|
if (!pGetGlyphIndicesA || !pGetTextExtentExPointI) goto done;
|
||||||
|
pGetGlyphIndicesA( hdc, "A ", 2, indices, 0 );
|
||||||
|
|
||||||
|
SetTextJustification(hdc, 0, 0);
|
||||||
|
GetTextExtentPoint32(hdc, " ", 1, &expect);
|
||||||
|
GetTextExtentPoint32(hdc, " ", 3, &size);
|
||||||
|
ok( size.cx == 3 * expect.cx, "wrong size %d/%d\n", size.cx, expect.cx );
|
||||||
|
SetTextJustification(hdc, 4, 1);
|
||||||
|
GetTextExtentPoint32(hdc, " ", 1, &size);
|
||||||
|
ok( size.cx == expect.cx + 4, "wrong size %d/%d\n", size.cx, expect.cx );
|
||||||
|
SetTextJustification(hdc, 9, 2);
|
||||||
|
GetTextExtentPoint32(hdc, " ", 2, &size);
|
||||||
|
ok( size.cx == 2 * expect.cx + 9, "wrong size %d/%d\n", size.cx, expect.cx );
|
||||||
|
SetTextJustification(hdc, 7, 3);
|
||||||
|
GetTextExtentPoint32(hdc, " ", 3, &size);
|
||||||
|
ok( size.cx == 3 * expect.cx + 7, "wrong size %d/%d\n", size.cx, expect.cx );
|
||||||
|
SetTextJustification(hdc, 7, 3);
|
||||||
|
SetTextCharacterExtra(hdc, 2 );
|
||||||
|
GetTextExtentPoint32(hdc, " ", 3, &size);
|
||||||
|
ok( size.cx == 3 * (expect.cx + 2) + 7, "wrong size %d/%d\n", size.cx, expect.cx );
|
||||||
|
SetTextJustification(hdc, 0, 0);
|
||||||
|
SetTextCharacterExtra(hdc, 0);
|
||||||
|
size.cx = size.cy = 1234;
|
||||||
|
GetTextExtentPoint32(hdc, " ", 0, &size);
|
||||||
|
ok( size.cx == 0 && size.cy == 0, "wrong size %d,%d\n", size.cx, size.cy );
|
||||||
|
pGetTextExtentExPointI(hdc, indices, 2, -1, NULL, NULL, &expect);
|
||||||
|
SetTextJustification(hdc, 5, 1);
|
||||||
|
pGetTextExtentExPointI(hdc, indices, 2, -1, NULL, NULL, &size);
|
||||||
|
ok( size.cx == expect.cx + 5, "wrong size %d/%d\n", size.cx, expect.cx );
|
||||||
|
SetTextJustification(hdc, 0, 0);
|
||||||
|
|
||||||
SetMapMode( hdc, MM_ANISOTROPIC );
|
SetMapMode( hdc, MM_ANISOTROPIC );
|
||||||
SetWindowExtEx( hdc, 2, 2, NULL );
|
SetWindowExtEx( hdc, 2, 2, NULL );
|
||||||
GetClientRect( hwnd, &clientArea );
|
GetClientRect( hwnd, &clientArea );
|
||||||
DPtoLP( hdc, (POINT *)&clientArea, 2 );
|
DPtoLP( hdc, (POINT *)&clientArea, 2 );
|
||||||
testJustification(hdc, testText, &clientArea);
|
testJustification(hdc, testText, &clientArea);
|
||||||
|
|
||||||
|
GetTextExtentPoint32(hdc, "A", 1, &expect);
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
SetTextCharacterExtra(hdc, i);
|
||||||
|
GetTextExtentPoint32(hdc, "A", 1, &size);
|
||||||
|
ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
|
||||||
|
}
|
||||||
|
SetTextCharacterExtra(hdc, 0);
|
||||||
|
pGetTextExtentExPointI(hdc, indices, 1, -1, NULL, NULL, &expect);
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
SetTextCharacterExtra(hdc, i);
|
||||||
|
pGetTextExtentExPointI(hdc, indices, 1, -1, NULL, NULL, &size);
|
||||||
|
ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
|
||||||
|
}
|
||||||
|
SetTextCharacterExtra(hdc, 0);
|
||||||
|
|
||||||
SetViewportExtEx( hdc, 3, 3, NULL );
|
SetViewportExtEx( hdc, 3, 3, NULL );
|
||||||
GetClientRect( hwnd, &clientArea );
|
GetClientRect( hwnd, &clientArea );
|
||||||
DPtoLP( hdc, (POINT *)&clientArea, 2 );
|
DPtoLP( hdc, (POINT *)&clientArea, 2 );
|
||||||
testJustification(hdc, testText, &clientArea);
|
testJustification(hdc, testText, &clientArea);
|
||||||
|
|
||||||
|
GetTextExtentPoint32(hdc, "A", 1, &expect);
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
SetTextCharacterExtra(hdc, i);
|
||||||
|
GetTextExtentPoint32(hdc, "A", 1, &size);
|
||||||
|
ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
DeleteObject(hfont);
|
DeleteObject(hfont);
|
||||||
ReleaseDC(hwnd, hdc);
|
ReleaseDC(hwnd, hdc);
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
|
|
|
@ -3074,7 +3074,7 @@ static void test_string_functions(void)
|
||||||
expectf(0.0, bounds.X);
|
expectf(0.0, bounds.X);
|
||||||
expectf(0.0, bounds.Y);
|
expectf(0.0, bounds.Y);
|
||||||
expectf_(char_bounds.Width, bounds.Width, 0.01);
|
expectf_(char_bounds.Width, bounds.Width, 0.01);
|
||||||
todo_wine expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05);
|
expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05);
|
||||||
expect(6, codepointsfitted);
|
expect(6, codepointsfitted);
|
||||||
todo_wine expect(4, linesfilled);
|
todo_wine expect(4, linesfilled);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue