https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9363eac228ec6734f15d5…
commit 9363eac228ec6734f15d5434701acf3ee91cc1cc
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Mon Sep 21 23:03:28 2020 +0200
Commit: Jérôme Gardou <jerome.gardou(a)reactos.org>
CommitDate: Thu Feb 4 16:37:06 2021 +0100
[WINESYNC] d3dx9: Handle newlines in ID3DXFont_DrawText.
Signed-off-by: Sven Baars <sbaars(a)codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
wine commit id 330c3f9108191feb6eb888384befb5cb54645233 by Sven Baars
<sbaars(a)codeweavers.com>
---
dll/directx/wine/d3dx9_36/font.c | 109 ++++++++++++++++++++---------
modules/rostests/winetests/d3dx9_36/core.c | 14 ++--
sdk/tools/winesync/d3dx9.cfg | 2 +-
3 files changed, 84 insertions(+), 41 deletions(-)
diff --git a/dll/directx/wine/d3dx9_36/font.c b/dll/directx/wine/d3dx9_36/font.c
index 23e2682c75c..d5907d15d94 100644
--- a/dll/directx/wine/d3dx9_36/font.c
+++ b/dll/directx/wine/d3dx9_36/font.c
@@ -513,13 +513,42 @@ static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface,
ID3DXSprite *sprite,
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,
const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color)
{
struct d3dx_font *font = impl_from_ID3DXFont(iface);
ID3DXSprite *target = sprite;
+ WCHAR *line;
RECT textrect = {0};
- int lh, x, y;
+ int lh, x, y, width;
int ret = 0;
TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color
0x%08x.\n",
@@ -548,59 +577,71 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface,
ID3DXSprite *sprite,
x = textrect.left;
y = textrect.top;
+ width = textrect.right - textrect.left;
lh = font->metrics.tmHeight;
+ line = heap_alloc(count * sizeof(*line));
+ if (!line)
+ return 0;
+
if (!(format & DT_CALCRECT) && !sprite)
{
D3DXCreateSprite(font->device, &target);
ID3DXSprite_Begin(target, 0);
}
- if (!(format & DT_CALCRECT))
+ while (string)
{
- GCP_RESULTSW results;
- D3DXVECTOR3 pos;
- int i;
-
- memset(&results, 0, sizeof(results));
- results.nGlyphs = count;
+ unsigned int line_len;
- results.lpCaretPos = heap_alloc(count * sizeof(*results.lpCaretPos));
- if (!results.lpCaretPos)
- goto cleanup;
+ string = read_line(font->hdc, string, &count, line, &line_len,
width);
- results.lpGlyphs = heap_alloc(count * sizeof(*results.lpGlyphs));
- if (!results.lpGlyphs)
+ if (!(format & DT_CALCRECT))
{
- heap_free(results.lpCaretPos);
- goto cleanup;
- }
+ GCP_RESULTSW results;
+ D3DXVECTOR3 pos;
+ unsigned int i;
- GetCharacterPlacementW(font->hdc, string, count, 0, &results, 0);
+ memset(&results, 0, sizeof(results));
+ results.nGlyphs = line_len;
- for (i = 0; i < results.nGlyphs; ++i)
- {
- IDirect3DTexture9 *texture;
- POINT cell_inc;
- RECT black_box;
+ results.lpCaretPos = heap_alloc(line_len * sizeof(*results.lpCaretPos));
+ if (!results.lpCaretPos)
+ goto cleanup;
- ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture,
&black_box, &cell_inc);
+ results.lpGlyphs = heap_alloc(line_len * sizeof(*results.lpGlyphs));
+ if (!results.lpGlyphs)
+ {
+ heap_free(results.lpCaretPos);
+ goto cleanup;
+ }
- if (!texture)
- continue;
+ GetCharacterPlacementW(font->hdc, line, line_len, 0, &results, 0);
- pos.x = cell_inc.x + x + results.lpCaretPos[i];
- pos.y = cell_inc.y + y;
+ for (i = 0; i < results.nGlyphs; ++i)
+ {
+ IDirect3DTexture9 *texture;
+ POINT cell_inc;
+ RECT black_box;
- ID3DXSprite_Draw(target, texture, &black_box, NULL, &pos, color);
- IDirect3DTexture9_Release(texture);
- }
+ ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture,
&black_box, &cell_inc);
- heap_free(results.lpCaretPos);
- heap_free(results.lpGlyphs);
+ 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;
}
- y += lh;
ret = y - textrect.top;
@@ -611,6 +652,8 @@ cleanup:
ID3DXSprite_Release(target);
}
+ heap_free(line);
+
return ret;
}
diff --git a/modules/rostests/winetests/d3dx9_36/core.c
b/modules/rostests/winetests/d3dx9_36/core.c
index c1e0eac0c8f..c6f5beff433 100644
--- a/modules/rostests/winetests/d3dx9_36/core.c
+++ b/modules/rostests/winetests/d3dx9_36/core.c
@@ -762,19 +762,19 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
todo_wine ok(height == 96, "Got unexpected height %d.\n", height);
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);
- 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);
ok(height == 12, "Got unexpected height %d.\n", height);
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);
- 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);
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);
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);
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);
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);
- todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
+ ok(height == 24, "Got unexpected height %d.\n", height);
ID3DXFont_Release(font);
}
diff --git a/sdk/tools/winesync/d3dx9.cfg b/sdk/tools/winesync/d3dx9.cfg
index 4bbd42bf86c..6a43210e9fe 100644
--- a/sdk/tools/winesync/d3dx9.cfg
+++ b/sdk/tools/winesync/d3dx9.cfg
@@ -15,4 +15,4 @@ files: {include/d3dx9.h: sdk/include/dxsdk/d3dx9.h, include/d3dx9anim.h:
sdk/inc
include/d3dx9mesh.h: sdk/include/dxsdk/d3dx9mesh.h, include/d3dx9of.h:
sdk/include/dxsdk/d3dx9of.h,
include/d3dx9shader.h: sdk/include/dxsdk/d3dx9shader.h, include/d3dx9shape.h:
sdk/include/dxsdk/d3dx9shape.h,
include/d3dx9tex.h: sdk/include/dxsdk/d3dx9tex.h, include/d3dx9xof.h:
sdk/include/dxsdk/d3dx9xof.h}
-tags: {wine: 316a8d0ae11ae1a9654bc731d2c9dc23febc7a2d}
+tags: {wine: 330c3f9108191feb6eb888384befb5cb54645233}