https://git.reactos.org/?p=reactos.git;a=commitdiff;h=806fe486fb3598e3bdb336226cd93751fe0719c5

commit 806fe486fb3598e3bdb336226cd93751fe0719c5
Author:     winesync <[email protected]>
AuthorDate: Mon Sep 21 23:06:33 2020 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Thu Feb 4 16:37:06 2021 +0100

    [WINESYNC] d3dx9: Handle word breaks in ID3DXFont_DrawText.
    
    Signed-off-by: Sven Baars <[email protected]>
    Signed-off-by: Matteo Bruni <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id e6a1116c2a3b196dea496f77747209f67982652c by Sven Baars 
<[email protected]>
---
 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}

Reply via email to