d3dx9: Handle newlines in ID3DXFont_DrawText.
Signed-off-by: Sven Baars <sbaars@codeweavers.com> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cf40d5a398
commit
330c3f9108
|
@ -509,13 +509,42 @@ static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const WCHAR *read_line(HDC hdc, const WCHAR *str, int *count,
|
||||||
|
WCHAR *dest, unsigned int *dest_len, int width)
|
||||||
|
{
|
||||||
|
unsigned int i = 0;
|
||||||
|
SIZE size;
|
||||||
|
|
||||||
|
*dest_len = 0;
|
||||||
|
while (*count && str[i] != '\n')
|
||||||
|
{
|
||||||
|
--(*count);
|
||||||
|
if (str[i] != '\r')
|
||||||
|
dest[(*dest_len)++] = str[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTextExtentExPointW(hdc, dest, *dest_len, width, NULL, NULL, &size);
|
||||||
|
|
||||||
|
if (*count && str[i] == '\n')
|
||||||
|
{
|
||||||
|
--(*count);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*count)
|
||||||
|
return str + i;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
|
static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
|
||||||
const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color)
|
const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color)
|
||||||
{
|
{
|
||||||
struct d3dx_font *font = impl_from_ID3DXFont(iface);
|
struct d3dx_font *font = impl_from_ID3DXFont(iface);
|
||||||
ID3DXSprite *target = sprite;
|
ID3DXSprite *target = sprite;
|
||||||
|
WCHAR *line;
|
||||||
RECT textrect = {0};
|
RECT textrect = {0};
|
||||||
int lh, x, y;
|
int lh, x, y, width;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x.\n",
|
TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x.\n",
|
||||||
|
@ -544,59 +573,71 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
|
||||||
|
|
||||||
x = textrect.left;
|
x = textrect.left;
|
||||||
y = textrect.top;
|
y = textrect.top;
|
||||||
|
width = textrect.right - textrect.left;
|
||||||
|
|
||||||
lh = font->metrics.tmHeight;
|
lh = font->metrics.tmHeight;
|
||||||
|
|
||||||
|
line = heap_alloc(count * sizeof(*line));
|
||||||
|
if (!line)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!(format & DT_CALCRECT) && !sprite)
|
if (!(format & DT_CALCRECT) && !sprite)
|
||||||
{
|
{
|
||||||
D3DXCreateSprite(font->device, &target);
|
D3DXCreateSprite(font->device, &target);
|
||||||
ID3DXSprite_Begin(target, 0);
|
ID3DXSprite_Begin(target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(format & DT_CALCRECT))
|
while (string)
|
||||||
{
|
{
|
||||||
GCP_RESULTSW results;
|
unsigned int line_len;
|
||||||
D3DXVECTOR3 pos;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(&results, 0, sizeof(results));
|
string = read_line(font->hdc, string, &count, line, &line_len, width);
|
||||||
results.nGlyphs = count;
|
|
||||||
|
|
||||||
results.lpCaretPos = heap_alloc(count * sizeof(*results.lpCaretPos));
|
if (!(format & DT_CALCRECT))
|
||||||
if (!results.lpCaretPos)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
results.lpGlyphs = heap_alloc(count * sizeof(*results.lpGlyphs));
|
|
||||||
if (!results.lpGlyphs)
|
|
||||||
{
|
{
|
||||||
|
GCP_RESULTSW results;
|
||||||
|
D3DXVECTOR3 pos;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
memset(&results, 0, sizeof(results));
|
||||||
|
results.nGlyphs = line_len;
|
||||||
|
|
||||||
|
results.lpCaretPos = heap_alloc(line_len * sizeof(*results.lpCaretPos));
|
||||||
|
if (!results.lpCaretPos)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
results.lpGlyphs = heap_alloc(line_len * sizeof(*results.lpGlyphs));
|
||||||
|
if (!results.lpGlyphs)
|
||||||
|
{
|
||||||
|
heap_free(results.lpCaretPos);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetCharacterPlacementW(font->hdc, line, line_len, 0, &results, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < results.nGlyphs; ++i)
|
||||||
|
{
|
||||||
|
IDirect3DTexture9 *texture;
|
||||||
|
POINT cell_inc;
|
||||||
|
RECT black_box;
|
||||||
|
|
||||||
|
ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture, &black_box, &cell_inc);
|
||||||
|
|
||||||
|
if (!texture)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pos.x = cell_inc.x + x + results.lpCaretPos[i];
|
||||||
|
pos.y = cell_inc.y + y;
|
||||||
|
|
||||||
|
ID3DXSprite_Draw(target, texture, &black_box, NULL, &pos, color);
|
||||||
|
IDirect3DTexture9_Release(texture);
|
||||||
|
}
|
||||||
|
|
||||||
heap_free(results.lpCaretPos);
|
heap_free(results.lpCaretPos);
|
||||||
goto cleanup;
|
heap_free(results.lpGlyphs);
|
||||||
}
|
}
|
||||||
|
y += lh;
|
||||||
GetCharacterPlacementW(font->hdc, string, count, 0, &results, 0);
|
|
||||||
|
|
||||||
for (i = 0; i < results.nGlyphs; ++i)
|
|
||||||
{
|
|
||||||
IDirect3DTexture9 *texture;
|
|
||||||
POINT cell_inc;
|
|
||||||
RECT black_box;
|
|
||||||
|
|
||||||
ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture, &black_box, &cell_inc);
|
|
||||||
|
|
||||||
if (!texture)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pos.x = cell_inc.x + x + results.lpCaretPos[i];
|
|
||||||
pos.y = cell_inc.y + y;
|
|
||||||
|
|
||||||
ID3DXSprite_Draw(target, texture, &black_box, NULL, &pos, color);
|
|
||||||
IDirect3DTexture9_Release(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
heap_free(results.lpCaretPos);
|
|
||||||
heap_free(results.lpGlyphs);
|
|
||||||
}
|
}
|
||||||
y += lh;
|
|
||||||
|
|
||||||
ret = y - textrect.top;
|
ret = y - textrect.top;
|
||||||
|
|
||||||
|
@ -607,6 +648,8 @@ cleanup:
|
||||||
ID3DXSprite_Release(target);
|
ID3DXSprite_Release(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
heap_free(line);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -762,19 +762,19 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
|
||||||
todo_wine ok(height == 96, "Got unexpected height %d.\n", height);
|
todo_wine ok(height == 96, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, 0, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, 0, 0xff00ff);
|
||||||
todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
|
ok(height == 24, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"a\r\na", -1, &rect, 0, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"a\r\na", -1, &rect, 0, 0xff00ff);
|
||||||
todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
|
ok(height == 24, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"a\ra", -1, &rect, 0, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"a\ra", -1, &rect, 0, 0xff00ff);
|
||||||
ok(height == 12, "Got unexpected height %d.\n", height);
|
ok(height == 12, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, DT_SINGLELINE, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, DT_SINGLELINE, 0xff00ff);
|
||||||
ok(height == 12, "Got unexpected height %d.\n", height);
|
todo_wine ok(height == 12, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"a\naaaaa aaaa", -1, &rect, 0, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"a\naaaaa aaaa", -1, &rect, 0, 0xff00ff);
|
||||||
todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
|
ok(height == 24, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"a\naaaaa aaaa", -1, &rect, DT_WORDBREAK, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"a\naaaaa aaaa", -1, &rect, DT_WORDBREAK, 0xff00ff);
|
||||||
todo_wine ok(height == 36, "Got unexpected height %d.\n", height);
|
todo_wine ok(height == 36, "Got unexpected height %d.\n", height);
|
||||||
|
@ -783,7 +783,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
|
||||||
todo_wine ok(height == 48, "Got unexpected height %d.\n", height);
|
todo_wine ok(height == 48, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"1\n2\n3\n4\n5\n6", -1, &rect, DT_NOCLIP, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"1\n2\n3\n4\n5\n6", -1, &rect, DT_NOCLIP, 0xff00ff);
|
||||||
todo_wine ok(height == 72, "Got unexpected height %d.\n", height);
|
ok(height == 72, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"\t\t\t\t\t\t\t\t\t\t", -1, &rect, DT_WORDBREAK, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"\t\t\t\t\t\t\t\t\t\t", -1, &rect, DT_WORDBREAK, 0xff00ff);
|
||||||
todo_wine ok(height == 0, "Got unexpected height %d.\n", height);
|
todo_wine ok(height == 0, "Got unexpected height %d.\n", height);
|
||||||
|
@ -834,10 +834,10 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
|
||||||
todo_wine ok(height == 32, "Got unexpected height %d.\n", height);
|
todo_wine ok(height == 32, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_RIGHT, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_RIGHT, 0xff00ff);
|
||||||
todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
|
ok(height == 24, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_CENTER, 0xff00ff);
|
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_CENTER, 0xff00ff);
|
||||||
todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
|
ok(height == 24, "Got unexpected height %d.\n", height);
|
||||||
|
|
||||||
ID3DXFont_Release(font);
|
ID3DXFont_Release(font);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue