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>
feature/deterministic
Sven Baars 2020-03-05 22:39:59 +01:00 committed by Alexandre Julliard
parent 6da3e904a1
commit e6a1116c2a
22 changed files with 89 additions and 34 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))
{

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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