https://git.reactos.org/?p=reactos.git;a=commitdiff;h=806fe486fb3598e3bdb336...
commit 806fe486fb3598e3bdb336226cd93751fe0719c5 Author: winesync ros-dev@reactos.org AuthorDate: Mon Sep 21 23:06:33 2020 +0200 Commit: Jérôme Gardou jerome.gardou@reactos.org CommitDate: Thu Feb 4 16:37:06 2021 +0100
[WINESYNC] d3dx9: Handle word breaks 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
wine commit id e6a1116c2a3b196dea496f77747209f67982652c by Sven Baars sbaars@codeweavers.com --- dll/directx/wine/d3dx9_36/d3dx9.cmake | 2 +- dll/directx/wine/d3dx9_36/font.c | 61 ++++++++++++++++++++++++++++-- dll/directx/wine/d3dx9_36/precomp.h | 1 + modules/rostests/winetests/d3dx9_36/core.c | 22 +++++------ sdk/tools/winesync/d3dx9.cfg | 2 +- 5 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/dll/directx/wine/d3dx9_36/d3dx9.cmake b/dll/directx/wine/d3dx9_36/d3dx9.cmake index cb8d937a561..082c03e5201 100644 --- a/dll/directx/wine/d3dx9_36/d3dx9.cmake +++ b/dll/directx/wine/d3dx9_36/d3dx9.cmake @@ -40,7 +40,7 @@ function(add_d3dx9_target __version) set_module_type(${module} win32dll) add_dependencies(${module} d3d_idl_headers) target_link_libraries(${module} dxguid wine) - add_importlibs(${module} d3dcompiler_43 d3dxof user32 ole32 gdi32 msvcrt kernel32 ntdll) + add_importlibs(${module} d3dcompiler_43 d3dxof usp10 user32 ole32 gdi32 msvcrt kernel32 ntdll) add_delay_importlibs(${module} windowscodecs) add_pch(${module} ../d3dx9_36/precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET ${module} DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3dx9_36/font.c b/dll/directx/wine/d3dx9_36/font.c index 8b122abd14f..28ad573cda9 100644 --- a/dll/directx/wine/d3dx9_36/font.c +++ b/dll/directx/wine/d3dx9_36/font.c @@ -22,6 +22,8 @@
#include "d3dx9_private.h" + +#include "usp10.h" #endif /* __REACTOS__ */
WINE_DEFAULT_DEBUG_CHANNEL(d3dx); @@ -513,10 +515,53 @@ static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, return ret; }
+static void word_break(HDC hdc, const WCHAR *str, unsigned int *str_len, + unsigned int chars_fit, unsigned int *chars_used, SIZE *size) +{ + SCRIPT_LOGATTR *sla; + SCRIPT_ANALYSIS sa; + unsigned int i; + + *chars_used = 0; + + sla = heap_alloc(*str_len * sizeof(*sla)); + if (!sla) + return; + + memset(&sa, 0, sizeof(sa)); + sa.eScript = SCRIPT_UNDEFINED; + + ScriptBreak(str, *str_len, &sa, sla); + + /* Work back from the last character that did fit to a place where we can break */ + i = chars_fit; + while (i > 0 && !sla[i].fSoftBreak) /* chars_fit < *str_len so this is valid */ + --i; + + /* If the there is no word that fits put in all characters that do fit */ + if (!sla[i].fSoftBreak) + i = chars_fit; + + *chars_used = i; + if (sla[i].fWhiteSpace) + ++(*chars_used); + + /* Remove extra spaces */ + while (i > 0 && sla[i-1].fWhiteSpace) + --i; + *str_len = i; + + /* Remeasure the string */ + GetTextExtentExPointW(hdc, str, *str_len, 0, NULL, NULL, size); + heap_free(sla); +} + static const WCHAR *read_line(HDC hdc, const WCHAR *str, int *count, - WCHAR *dest, unsigned int *dest_len, int width) + WCHAR *dest, unsigned int *dest_len, int width, DWORD format) { unsigned int i = 0; + int orig_count = *count; + int num_fit; SIZE size;
*dest_len = 0; @@ -528,7 +573,17 @@ static const WCHAR *read_line(HDC hdc, const WCHAR *str, int *count, ++i; }
- GetTextExtentExPointW(hdc, dest, *dest_len, width, NULL, NULL, &size); + num_fit = 0; + GetTextExtentExPointW(hdc, dest, *dest_len, width, &num_fit, NULL, &size); + + if (num_fit < *dest_len && (format & DT_WORDBREAK)) + { + unsigned int chars_used; + + word_break(hdc, dest, dest_len, num_fit, &chars_used, &size); + *count = orig_count - chars_used; + i = chars_used; + }
if (*count && str[i] == '\n') { @@ -598,7 +653,7 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, { unsigned int line_len;
- string = read_line(font->hdc, string, &count, line, &line_len, width); + string = read_line(font->hdc, string, &count, line, &line_len, width, format);
if (!(format & DT_CALCRECT)) { diff --git a/dll/directx/wine/d3dx9_36/precomp.h b/dll/directx/wine/d3dx9_36/precomp.h index b6a35522a31..4325ad715c5 100644 --- a/dll/directx/wine/d3dx9_36/precomp.h +++ b/dll/directx/wine/d3dx9_36/precomp.h @@ -20,6 +20,7 @@ #include <winbase.h> #include <wingdi.h> #include <winuser.h> +#include <usp10.h>
#include <wine/winternl.h>
diff --git a/modules/rostests/winetests/d3dx9_36/core.c b/modules/rostests/winetests/d3dx9_36/core.c index c79f5c1f728..45cde62b3a8 100644 --- a/modules/rostests/winetests/d3dx9_36/core.c +++ b/modules/rostests/winetests/d3dx9_36/core.c @@ -722,7 +722,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 60, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, long_text, -1, &rect, DT_WORDBREAK | DT_NOCLIP, 0xff00ff); - todo_wine ok(height == 96, "Got unexpected height %d.\n", height); + ok(height == 96, "Got unexpected height %d.\n", height);
SetRect(&rect, 10, 10, 200, 200);
@@ -759,7 +759,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 60, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, long_textW, -1, &rect, DT_WORDBREAK | DT_NOCLIP, 0xff00ff); - todo_wine ok(height == 96, "Got unexpected height %d.\n", height); + ok(height == 96, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, 0, 0xff00ff); ok(height == 24, "Got unexpected height %d.\n", height); @@ -777,7 +777,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) 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); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"1\n2\n3\n4\n5\n6", -1, &rect, 0, 0xff00ff); ok(height == 48, "Got unexpected height %d.\n", height); @@ -789,16 +789,16 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 0, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"\t\t\t\t\t\t\t\t\t\ta", -1, &rect, DT_WORDBREAK, 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"\taaaaaaaaaa", -1, &rect, DT_WORDBREAK, 0xff00ff); todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"\taaaaaaaaaa", -1, &rect, DT_EXPANDTABS | DT_WORDBREAK, 0xff00ff); - todo_wine ok(height == 36, "Got unexpected height %d.\n", height); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"\taaa\taaa\taaa", -1, &rect, DT_WORDBREAK, 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"\taaa\taaa\taaa", -1, &rect, DT_EXPANDTABS | DT_WORDBREAK, 0xff00ff); todo_wine ok(height == 48, "Got unexpected height %d.\n", height); @@ -813,19 +813,19 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaaaaaaaaaaaaaaaaaa", -1, &rect, DT_WORDBREAK, 0xff00ff); - todo_wine ok(height == 36, "Got unexpected height %d.\n", height); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"a a", -1, &rect, DT_WORDBREAK, 0xff00ff); - todo_wine ok(height == 36, "Got unexpected height %d.\n", height); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa aaaa", -1, &rect, DT_WORDBREAK, 0xff00ff); - todo_wine ok(height == 36, "Got unexpected height %d.\n", height); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa aaaa", -1, &rect, DT_WORDBREAK | DT_RIGHT, 0xff00ff); - todo_wine ok(height == 36, "Got unexpected height %d.\n", height); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa aaaa", -1, &rect, DT_WORDBREAK | DT_RIGHT, 0xff00ff); - todo_wine ok(height == 36, "Got unexpected height %d.\n", height); + ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_BOTTOM, 0xff00ff); todo_wine ok(height == 40, "Got unexpected height %d.\n", height); diff --git a/sdk/tools/winesync/d3dx9.cfg b/sdk/tools/winesync/d3dx9.cfg index 135d55d8c2f..3d6a83cd72a 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: 6da3e904a1efc921030fdbe34070b981bf57524c} +tags: {wine: e6a1116c2a3b196dea496f77747209f67982652c}