From e6a1116c2a3b196dea496f77747209f67982652c Mon Sep 17 00:00:00 2001 From: Sven Baars Date: Thu, 5 Mar 2020 22:39:59 +0100 Subject: [PATCH] d3dx9: Handle word breaks in ID3DXFont_DrawText. Signed-off-by: Sven Baars Signed-off-by: Matteo Bruni Signed-off-by: Alexandre Julliard --- dlls/d3dx9_24/Makefile.in | 2 +- dlls/d3dx9_25/Makefile.in | 2 +- dlls/d3dx9_26/Makefile.in | 2 +- dlls/d3dx9_27/Makefile.in | 2 +- dlls/d3dx9_28/Makefile.in | 2 +- dlls/d3dx9_29/Makefile.in | 2 +- dlls/d3dx9_30/Makefile.in | 2 +- dlls/d3dx9_31/Makefile.in | 2 +- dlls/d3dx9_32/Makefile.in | 2 +- dlls/d3dx9_33/Makefile.in | 2 +- dlls/d3dx9_34/Makefile.in | 2 +- dlls/d3dx9_35/Makefile.in | 2 +- dlls/d3dx9_36/Makefile.in | 2 +- dlls/d3dx9_36/font.c | 61 ++++++++++++++++++++++++++++++++++++-- dlls/d3dx9_36/tests/core.c | 22 +++++++------- dlls/d3dx9_37/Makefile.in | 2 +- dlls/d3dx9_38/Makefile.in | 2 +- dlls/d3dx9_39/Makefile.in | 2 +- dlls/d3dx9_40/Makefile.in | 2 +- dlls/d3dx9_41/Makefile.in | 2 +- dlls/d3dx9_42/Makefile.in | 2 +- dlls/d3dx9_43/Makefile.in | 2 +- 22 files changed, 89 insertions(+), 34 deletions(-) diff --git a/dlls/d3dx9_24/Makefile.in b/dlls/d3dx9_24/Makefile.in index faad4c49acc..f80541a9aa3 100644 --- a/dlls/d3dx9_24/Makefile.in +++ b/dlls/d3dx9_24/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=24 MODULE = d3dx9_24.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_25/Makefile.in b/dlls/d3dx9_25/Makefile.in index 292b33db2be..e3144f0d45d 100644 --- a/dlls/d3dx9_25/Makefile.in +++ b/dlls/d3dx9_25/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=25 MODULE = d3dx9_25.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_26/Makefile.in b/dlls/d3dx9_26/Makefile.in index 22bb54a4985..1b432afb21c 100644 --- a/dlls/d3dx9_26/Makefile.in +++ b/dlls/d3dx9_26/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=26 MODULE = d3dx9_26.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_27/Makefile.in b/dlls/d3dx9_27/Makefile.in index 4ed104a170d..65d8cad9d63 100644 --- a/dlls/d3dx9_27/Makefile.in +++ b/dlls/d3dx9_27/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=27 MODULE = d3dx9_27.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_28/Makefile.in b/dlls/d3dx9_28/Makefile.in index 94e059ae9d1..ff7ba564c13 100644 --- a/dlls/d3dx9_28/Makefile.in +++ b/dlls/d3dx9_28/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=28 MODULE = d3dx9_28.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_29/Makefile.in b/dlls/d3dx9_29/Makefile.in index 94b39aee373..7e53415c436 100644 --- a/dlls/d3dx9_29/Makefile.in +++ b/dlls/d3dx9_29/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=29 MODULE = d3dx9_29.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_30/Makefile.in b/dlls/d3dx9_30/Makefile.in index 6beadbc47ea..9bc955753f7 100644 --- a/dlls/d3dx9_30/Makefile.in +++ b/dlls/d3dx9_30/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=30 MODULE = d3dx9_30.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_31/Makefile.in b/dlls/d3dx9_31/Makefile.in index b73f32872c3..58b72c527c2 100644 --- a/dlls/d3dx9_31/Makefile.in +++ b/dlls/d3dx9_31/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=31 MODULE = d3dx9_31.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_32/Makefile.in b/dlls/d3dx9_32/Makefile.in index 50bc9d0e26b..88cc083bbe2 100644 --- a/dlls/d3dx9_32/Makefile.in +++ b/dlls/d3dx9_32/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=32 MODULE = d3dx9_32.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_33/Makefile.in b/dlls/d3dx9_33/Makefile.in index 7be34e1d4b0..f6de942ed8a 100644 --- a/dlls/d3dx9_33/Makefile.in +++ b/dlls/d3dx9_33/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=33 MODULE = d3dx9_33.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_34/Makefile.in b/dlls/d3dx9_34/Makefile.in index 248735a5311..5d0bc9b3a47 100644 --- a/dlls/d3dx9_34/Makefile.in +++ b/dlls/d3dx9_34/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=34 MODULE = d3dx9_34.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_35/Makefile.in b/dlls/d3dx9_35/Makefile.in index 01c809dab25..5eb00327c14 100644 --- a/dlls/d3dx9_35/Makefile.in +++ b/dlls/d3dx9_35/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=35 MODULE = d3dx9_35.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in index 825e5ddfbc4..6a08c411592 100644 --- a/dlls/d3dx9_36/Makefile.in +++ b/dlls/d3dx9_36/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=36 MODULE = d3dx9_36.dll IMPORTLIB = d3dx9 IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c index 9e9cb658db0..5d4c0a5786a 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -20,6 +20,8 @@ #include "d3dx9_private.h" +#include "usp10.h" + WINE_DEFAULT_DEBUG_CHANNEL(d3dx); struct d3dx_glyph @@ -509,10 +511,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; @@ -524,7 +569,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') { @@ -594,7 +649,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/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index c79f5c1f728..45cde62b3a8 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/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/dlls/d3dx9_37/Makefile.in b/dlls/d3dx9_37/Makefile.in index a0896df82ed..b9dda315f22 100644 --- a/dlls/d3dx9_37/Makefile.in +++ b/dlls/d3dx9_37/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=37 MODULE = d3dx9_37.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_38/Makefile.in b/dlls/d3dx9_38/Makefile.in index 24bbc3f0cf5..adeb4f245a9 100644 --- a/dlls/d3dx9_38/Makefile.in +++ b/dlls/d3dx9_38/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=38 MODULE = d3dx9_38.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_39/Makefile.in b/dlls/d3dx9_39/Makefile.in index a3f7626f33f..0e210488f6a 100644 --- a/dlls/d3dx9_39/Makefile.in +++ b/dlls/d3dx9_39/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=39 MODULE = d3dx9_39.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_40/Makefile.in b/dlls/d3dx9_40/Makefile.in index fbbcb0c04eb..05349e4b407 100644 --- a/dlls/d3dx9_40/Makefile.in +++ b/dlls/d3dx9_40/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=40 MODULE = d3dx9_40.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_41/Makefile.in b/dlls/d3dx9_41/Makefile.in index 9b44213117b..587e94b7d11 100644 --- a/dlls/d3dx9_41/Makefile.in +++ b/dlls/d3dx9_41/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=41 MODULE = d3dx9_41.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_42/Makefile.in b/dlls/d3dx9_42/Makefile.in index f725e87471f..bb837c4e398 100644 --- a/dlls/d3dx9_42/Makefile.in +++ b/dlls/d3dx9_42/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=42 MODULE = d3dx9_42.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/d3dx9_43/Makefile.in b/dlls/d3dx9_43/Makefile.in index dbebc51ad07..0701cde7b77 100644 --- a/dlls/d3dx9_43/Makefile.in +++ b/dlls/d3dx9_43/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=43 MODULE = d3dx9_43.dll IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 ucrtbase PARENTSRC = ../d3dx9_36 -DELAYIMPORTS = windowscodecs +DELAYIMPORTS = windowscodecs usp10 EXTRADLLFLAGS = -mno-cygwin