From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Sven Baars sbaars@codeweavers.com --- I'm sending this series mostly so it can be reviewed, but I sent the tests first so they may still be committed during code freeze, if they are acceptable.
dlls/d3dx9_36/tests/core.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index fa874a5ef5..8b90f0ef5f 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -637,6 +637,69 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
ID3DXFont_Release(font); } + + /* ID3DXFont_DrawTextA, ID3DXFont_DrawTextW */ + hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font); + if (SUCCEEDED(hr)) { + RECT rect; + int height; + + todo_wine { + SetRect(&rect, 10, 10, 200, 200); + + height = ID3DXFont_DrawTextA(font, NULL, "test", -2, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextA returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "test", -1, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextA returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "test", 0, &rect, 0, 0xFF00FF); + ok(height == 0, "DrawTextA returned %d, expected 0.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "test", 1, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextA returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "test", 2, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextA returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "test", -1, NULL, 0, 0xFF00FF); + ok(height == 12, "DrawTextA returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "test", -1, NULL, DT_CALCRECT, 0xFF00FF); + ok(height == 12, "DrawTextA returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, NULL, -1, NULL, 0, 0xFF00FF); + ok(height == 0, "DrawTextA returned %d, expected 0.\n", height); + +if (0) { /* Causes a lockup on windows 7. */ + height = ID3DXFont_DrawTextW(font, NULL, testW, -2, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); +} + + height = ID3DXFont_DrawTextW(font, NULL, testW, -1, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, testW, 0, &rect, 0, 0xFF00FF); + ok(height == 0, "DrawTextW returned %d, expected 0.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, testW, 1, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, testW, 2, &rect, 0, 0xFF00FF); + ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, testW, -1, NULL, 0, 0xFF00FF); + ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, testW, -1, NULL, DT_CALCRECT, 0xFF00FF); + ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, NULL, -1, NULL, 0, 0xFF00FF); + ok(height == 0, "DrawTextW returned %d, expected 0.\n", height); + } + + ID3DXFont_Release(font); + } }
static void test_D3DXCreateRenderToSurface(IDirect3DDevice9 *device)
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/tests/core.c | 127 ++++++++++++++++++++++++++++++------- 1 file changed, 104 insertions(+), 23 deletions(-)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index 8b90f0ef5f..7edc47eb77 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -306,19 +306,34 @@ static void test_ID3DXSprite(IDirect3DDevice9 *device) static void test_ID3DXFont(IDirect3DDevice9 *device) { static const WCHAR testW[] = {'t','e','s','t',0}; + static const WCHAR emptyW[] = {0}; + static const char longText[] = "Example text to test clipping and other related things"; + static const WCHAR longTextW[] = {'E', 'x', 'a', 'm', 'p', 'l', 'e', ' ', + 't', 'e', 'x', 't', ' ', 't', 'o', ' ', + 't', 'e', 's', 't', ' ', 'c', 'l', 'i', 'p', 'p', 'i', 'n', 'g', ' ', + 'a', 'n', 'd', ' ', 'o', 't', 'h', 'e', 'r', ' ', + 'r', 'e', 'l', 'a', 't', 'e', 'd', ' ', 't', 'h', 'i', 'n', 'g', 's', 0}; + static const struct { int font_height; + unsigned int expected_height; unsigned int expected_size; unsigned int expected_levels; } tests[] = { - { 6, 128, 4 }, - { 8, 128, 4 }, - { 10, 256, 5 }, - { 12, 256, 5 }, - { 72, 256, 8 }, + { 2, 2, 32, 2 }, + { 4, 4, 64, 3 }, + { 6, 6, 128, 4 }, + { 8, 8, 128, 4 }, + { 10, 10, 256, 5 }, + { 12, 12, 256, 5 }, + { 72, 72, 256, 8 }, + { 256, 255, 256, 9 }, + { 257, 255, 256, 9 }, + { 258, 258, 512, 10 }, + { 512, 512, 512, 10 }, }; const unsigned int size = ARRAY_SIZE(testW); D3DXFONT_DESCA desc; @@ -477,6 +492,10 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXFont_PreloadTextA(font, "test", -1); ok(hr == D3D_OK, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXFont_PreloadTextA(font, "", 0); + ok(hr == D3D_OK, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXFont_PreloadTextA(font, "", -1); + ok(hr == D3D_OK, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3D_OK);
hr = ID3DXFont_PreloadTextW(font, NULL, -1); ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); @@ -486,6 +505,10 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXFont_PreloadTextW(font, testW, -1); ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXFont_PreloadTextW(font, emptyW, 0); + ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK); + hr = ID3DXFont_PreloadTextW(font, emptyW, -1); + ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK); }
check_release((IUnknown*)font, 0); @@ -498,6 +521,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) char c; HDC hdc; DWORD ret; + WORD glyph; HRESULT hr; RECT blackbox; POINT cellinc; @@ -524,26 +548,42 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK);
for(c = 'b'; c <= 'z'; c++) { - WORD glyph; - ret = GetGlyphIndicesA(hdc, &c, 1, &glyph, 0); ok(ret != GDI_ERROR, "GetGlyphIndicesA failed\n");
hr = ID3DXFont_GetGlyphData(font, glyph, &texture, &blackbox, &cellinc); todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); if(SUCCEEDED(hr)) { - DWORD levels; + DWORD ret, levels; + TEXTMETRICW tm; D3DSURFACE_DESC desc; + GLYPHMETRICS metrics; + MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
levels = IDirect3DTexture9_GetLevelCount(texture); - ok(levels == 5, "Got levels %u, expected %u\n", levels, 5); + todo_wine ok(levels == 5, "Character %c, got levels %u, expected %u\n", c, levels, 5); hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc); ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc failed\n"); - ok(desc.Format == D3DFMT_A8R8G8B8, "Got format %#x, expected %#x\n", desc.Format, D3DFMT_A8R8G8B8); - ok(desc.Usage == 0, "Got usage %#x, expected %#x\n", desc.Usage, 0); - ok(desc.Width == 256, "Got width %u, expected %u\n", desc.Width, 256); - ok(desc.Height == 256, "Got height %u, expected %u\n", desc.Height, 256); - ok(desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected %u\n", desc.Pool, D3DPOOL_MANAGED); + ok(desc.Format == D3DFMT_A8R8G8B8, "Character %c, got format %#x, expected %#x\n", c, desc.Format, D3DFMT_A8R8G8B8); + ok(desc.Usage == 0, "Character %c, got usage %#x, expected %#x\n", c, desc.Usage, 0); + ok(desc.Width == 256, "Character %c, got width %u, expected %u\n", c, desc.Width, 256); + ok(desc.Height == 256, "Character %c, got height %u, expected %u\n", c, desc.Height, 256); + ok(desc.Pool == D3DPOOL_MANAGED, "Character %c, got pool %u, expected %u\n", c, desc.Pool, D3DPOOL_MANAGED); + + /* Check blackbox and cellinc, but skip f, j and t, because these + are apparently smaller */ + ret = GetGlyphOutlineW(hdc, glyph, GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP | GGO_METRICS, &metrics, 0, NULL, &mat); + if (ret != GDI_ERROR && c != 'f' && c != 'j' && c != 't') { + ID3DXFont_GetTextMetricsW(font, &tm); + todo_wine ok(blackbox.right - blackbox.left == metrics.gmBlackBoxX + 2, "Character %c, got %d, expected %d\n", + c, blackbox.right - blackbox.left, metrics.gmBlackBoxX + 2); + todo_wine ok(blackbox.bottom - blackbox.top == metrics.gmBlackBoxY + 2, "Character %c, got %d, expected %d\n", + c, blackbox.bottom - blackbox.top, metrics.gmBlackBoxY + 2); + ok(cellinc.x == metrics.gmptGlyphOrigin.x - 1, "Character %c, got %d, expected %d\n", + c, cellinc.x, metrics.gmptGlyphOrigin.x - 1); + ok(cellinc.y == tm.tmAscent - metrics.gmptGlyphOrigin.y - 1, "Character %c, got %d, expected %d\n", + c, cellinc.y, tm.tmAscent - metrics.gmptGlyphOrigin.y - 1); + } else if (ret == GDI_ERROR) skip("Failed to obtain glyph metrics\n");
check_release((IUnknown*)texture, 1); } @@ -552,6 +592,18 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) hr = ID3DXFont_PreloadCharacters(font, 'a', 'z'); ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK);
+ /* Test multiple textures */ + hr = ID3DXFont_PreloadGlyphs(font, 0, 1000); + todo_wine ok(hr == D3D_OK, "ID3DXFont_PreloadGlyphs returned %#x, expected %#x\n", hr, D3D_OK); + + /* Test glyphs that are not rendered */ + for (glyph = 1; glyph < 4; glyph++) + { + hr = ID3DXFont_GetGlyphData(font, glyph, &texture, &blackbox, &cellinc); + todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); + ok(!texture, "Got unexpected texture\n"); + } + check_release((IUnknown*)font, 0); } else skip("Failed to create a ID3DXFont object\n");
@@ -608,27 +660,26 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) hr = ID3DXSprite_Begin(sprite, D3DXSPRITE_ALPHABLEND); ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- todo_wine - { + todo_wine { height = ID3DXFont_DrawTextW(font, sprite, testW, -1, &rect, DT_TOP, 0xffffffff); - ok(height == tests[i].font_height, "Got unexpected height %u.\n", height); + ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_TOP, 0xffffffff); - ok(height == tests[i].font_height, "Got unexpected height %u.\n", height); + ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_RIGHT, 0xffffffff); - ok(height == tests[i].font_height, "Got unexpected height %u.\n", height); + ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_NOCLIP, 0xffffffff); - ok(height == tests[i].font_height, "Got unexpected height %u.\n", height); + ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); }
SetRectEmpty(&rect); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_CALCRECT, 0xffffffff); - todo_wine ok(height == tests[i].font_height, "Got unexpected height %u.\n", height); + todo_wine ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); ok(!rect.left, "Got unexpected rect left %d.\n", rect.left); ok(!rect.top, "Got unexpected rect top %d.\n", rect.top); todo_wine ok(rect.right, "Got unexpected rect right %d.\n", rect.right); - todo_wine ok(rect.bottom == tests[i].font_height, "Got unexpected rect bottom %d.\n", rect.bottom); + todo_wine ok(rect.bottom == tests[i].expected_height, "Got unexpected rect bottom %d.\n", rect.bottom);
hr = ID3DXSprite_End(sprite); ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr); @@ -662,6 +713,12 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) height = ID3DXFont_DrawTextA(font, NULL, "test", 2, &rect, 0, 0xFF00FF); ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
+ height = ID3DXFont_DrawTextA(font, NULL, "", 0, &rect, 0, 0xFF00FF); + ok(height == 0, "DrawTextA returned %d, expected 0.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, "", -1, &rect, 0, 0xFF00FF); + ok(height == 0, "DrawTextA returned %d, expected 0.\n", height); + height = ID3DXFont_DrawTextA(font, NULL, "test", -1, NULL, 0, 0xFF00FF); ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
@@ -671,7 +728,17 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) height = ID3DXFont_DrawTextA(font, NULL, NULL, -1, NULL, 0, 0xFF00FF); ok(height == 0, "DrawTextA returned %d, expected 0.\n", height);
-if (0) { /* Causes a lockup on windows 7. */ + SetRect(&rect, 10, 10, 50, 50); + + height = ID3DXFont_DrawTextA(font, NULL, longText, -1, &rect, DT_WORDBREAK, 0xFF00FF); + ok(height == 60, "DrawTextA returned %d, expected 60.\n", height); + + height = ID3DXFont_DrawTextA(font, NULL, longText, -1, &rect, DT_WORDBREAK | DT_NOCLIP, 0xFF00FF); + ok(height == 96, "DrawTextA returned %d, expected 96.\n", height); + + SetRect(&rect, 10, 10, 200, 200); + +if (0) { /* Causes a lockup on Windows 7+ */ height = ID3DXFont_DrawTextW(font, NULL, testW, -2, &rect, 0, 0xFF00FF); ok(height == 12, "DrawTextW returned %d, expected 12.\n", height); } @@ -688,6 +755,12 @@ if (0) { /* Causes a lockup on windows 7. */ height = ID3DXFont_DrawTextW(font, NULL, testW, 2, &rect, 0, 0xFF00FF); ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
+ height = ID3DXFont_DrawTextW(font, NULL, emptyW, 0, &rect, 0, 0xFF00FF); + ok(height == 0, "DrawTextW returned %d, expected 0.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, emptyW, -1, &rect, 0, 0xFF00FF); + ok(height == 0, "DrawTextW returned %d, expected 0.\n", height); + height = ID3DXFont_DrawTextW(font, NULL, testW, -1, NULL, 0, 0xFF00FF); ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
@@ -696,6 +769,14 @@ if (0) { /* Causes a lockup on windows 7. */
height = ID3DXFont_DrawTextW(font, NULL, NULL, -1, NULL, 0, 0xFF00FF); ok(height == 0, "DrawTextW returned %d, expected 0.\n", height); + + SetRect(&rect, 10, 10, 50, 50); + + height = ID3DXFont_DrawTextW(font, NULL, longTextW, -1, &rect, DT_WORDBREAK, 0xFF00FF); + ok(height == 60, "DrawTextW returned %d, expected 60.\n", height); + + height = ID3DXFont_DrawTextW(font, NULL, longTextW, -1, &rect, DT_WORDBREAK | DT_NOCLIP, 0xFF00FF); + ok(height == 96, "DrawTextW returned %d, expected 96.\n", height); }
ID3DXFont_Release(font);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62857
Your paranoid android.
=== debian10 (32 bit report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit French report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit Japanese:Japan report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit Chinese:China report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit WoW report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (64 bit WoW report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
Based on a patch by Tony Wasserka.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 2 + dlls/d3dx9_36/font.c | 239 +++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/core.c | 4 +- dlls/d3dx9_36/texture.c | 2 +- 4 files changed, 228 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 61ec320ba5..4f92b914ef 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -225,6 +225,8 @@ static inline BOOL is_param_type_sampler(D3DXPARAMETER_TYPE type) || type == D3DXPT_SAMPLER3D || type == D3DXPT_SAMPLERCUBE; }
+UINT make_pow2(UINT num) DECLSPEC_HIDDEN; + struct d3dx_parameter;
enum pres_reg_tables diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c index cb09af22f5..fe645a51c0 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -22,6 +22,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
+typedef struct _GLYPH +{ + UINT id; + RECT blackbox; + POINT cellinc; + IDirect3DTexture9 *texture; +} GLYPH; + struct d3dx_font { ID3DXFont ID3DXFont_iface; @@ -32,6 +40,14 @@ struct d3dx_font
HDC hdc; HFONT hfont; + + GLYPH *glyphs; + UINT allocated_glyphs, glyph_count; + + IDirect3DTexture9 **textures; + UINT texture_count, texture_pos; + + UINT texture_size, glyph_size, glyphs_per_texture; };
static inline struct d3dx_font *impl_from_ID3DXFont(ID3DXFont *iface) @@ -72,11 +88,21 @@ static ULONG WINAPI ID3DXFontImpl_Release(ID3DXFont *iface)
TRACE("%p decreasing refcount to %u\n", iface, ref);
- if(ref==0) { + if (!ref) + { + UINT i; + for(i = 0; i < This->texture_count; i++) + IDirect3DTexture9_Release(This->textures[i]); + + if (This->textures) + heap_free(This->textures); + + heap_free(This->glyphs); + DeleteObject(This->hfont); DeleteDC(This->hdc); IDirect3DDevice9_Release(This->device); - HeapFree(GetProcessHeap(), 0, This); + heap_free(This); } return ref; } @@ -154,10 +180,164 @@ static HRESULT WINAPI ID3DXFontImpl_PreloadCharacters(ID3DXFont *iface, UINT fir return S_OK; }
+/************************************************************ + * ID3DXFont_PreloadGlyphs + * + * Preloads the specified glyph series into the internal texture + * + * PARAMS + * first [I] first glyph to be preloaded + * last [I] last glyph to be preloaded + * + * RETURNS + * Success: D3D_OK + * + * NOTES + * The glyphs are stored in a grid. + * Cell sizes vary between different font sizes. + * The grid is filled in this order: + * 1 2 5 6 17 18 21 22 + * 3 4 7 8 19 20 23 24 + * 9 10 13 14 25 26 29 30 + * 11 12 15 16 27 28 31 32 + * 33 34 ... + * ... + * i.e. we try to fill one small square, then three equal-sized squares so that we get one big square, etc... + * + * The glyphs are positioned around their baseline, which is located at y position glyph_size * i + tmAscent. + * Concerning the x position, the glyphs are centered around glyph_size * (i + 0.5). + * + */ static HRESULT WINAPI ID3DXFontImpl_PreloadGlyphs(ID3DXFont *iface, UINT first, UINT last) { - FIXME("iface %p, first %u, last %u stub!\n", iface, first, last); - return E_NOTIMPL; + struct d3dx_font *This = impl_from_ID3DXFont(iface); + UINT glyph, i, x, y; + TEXTMETRICW tm; + HRESULT hr; + + TRACE("iface %p, first %u, last %u\n", iface, first, last); + + if (last < first) + return D3D_OK; + + ID3DXFont_GetTextMetricsW(iface, &tm); + + for (glyph = first; glyph <= last; glyph++) + { + DWORD ret; + BYTE *buffer; + GLYPHMETRICS metrics; + D3DLOCKED_RECT lockrect; + MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} }; + UINT stride, offx = 0, offy = 0; + GLYPH *current_glyph; + IDirect3DTexture9 *current_texture; + + /* Check whether the glyph is already preloaded */ + for (i = 0; i < This->glyph_count; i++) + if (This->glyphs[i].id == glyph) + break; + if (i < This->glyph_count) + continue; + + /* Calculate glyph position */ + for (i = 0; i < 16; i++) + { + if (This->texture_pos & (1 << (2*i))) + offx += This->glyph_size * (1 << i); + if (i < 15 && This->texture_pos & (1 << (2*i + 1))) + offy += This->glyph_size * (1 << i); + } + + /* Make sure we have enough memory */ + if (This->glyph_count + 1 > This->allocated_glyphs) + { + This->allocated_glyphs <<= 1; + This->glyphs = heap_realloc(This->glyphs, This->allocated_glyphs * sizeof(GLYPH)); + if (!This->glyphs) + return E_OUTOFMEMORY; + } + + current_glyph = This->glyphs + This->glyph_count++; + current_glyph->id = glyph; + current_glyph->texture = NULL; + + /* Spaces are handled separately */ + if (glyph > 0 && glyph < 4) + continue; + + /* Get the glyph data */ + ret = GetGlyphOutlineW(This->hdc, glyph, GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP, &metrics, 0, NULL, &mat); + if (ret == GDI_ERROR) + continue; + + buffer = heap_alloc(ret); + if (!buffer) + return E_OUTOFMEMORY; + + GetGlyphOutlineW(This->hdc, glyph, GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP, &metrics, ret, buffer, &mat); + + /* Create a new texture if necessary */ + if (This->texture_pos % This->glyphs_per_texture == 0) + { + This->textures = heap_realloc(This->textures, (This->texture_count + 1) * sizeof(IDirect3DTexture9 *)); + if (!This->textures) + { + heap_free(buffer); + return E_OUTOFMEMORY; + } + + if (FAILED(hr = IDirect3DDevice9_CreateTexture(This->device, This->texture_size, + This->texture_size, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, + &This->textures[This->texture_count], NULL))) + { + heap_free(buffer); + return hr; + } + + This->texture_count++; + This->texture_pos = 0; + offx = 0; + offy = 0; + } + + current_texture = This->textures[This->texture_count - 1]; + + /* Fill in glyph data */ + current_glyph->blackbox.left = offx - metrics.gmptGlyphOrigin.x + This->glyph_size / 2 - metrics.gmBlackBoxX / 2; + current_glyph->blackbox.top = offy - metrics.gmptGlyphOrigin.y + tm.tmAscent; + current_glyph->blackbox.right = current_glyph->blackbox.left + metrics.gmBlackBoxX; + current_glyph->blackbox.bottom = current_glyph->blackbox.top + metrics.gmBlackBoxY; + current_glyph->cellinc.x = metrics.gmptGlyphOrigin.x - 1; + current_glyph->cellinc.y = tm.tmAscent - metrics.gmptGlyphOrigin.y - 1; + current_glyph->texture = current_texture; + + /* Copy glyph data to the texture */ + if (FAILED(hr = IDirect3DTexture9_LockRect(current_texture, 0, &lockrect, ¤t_glyph->blackbox, 0))) + { + heap_free(buffer); + return hr; + } + + stride = (metrics.gmBlackBoxX + 3) & ~3; + + for (y = 0; y < metrics.gmBlackBoxY; y++) + for (x = 0; x < metrics.gmBlackBoxX; x++) + { + ((BYTE*)lockrect.pBits)[4 * x + y * lockrect.Pitch ] = 255; + ((BYTE*)lockrect.pBits)[4 * x + y * lockrect.Pitch + 1] = 255; + ((BYTE*)lockrect.pBits)[4 * x + y * lockrect.Pitch + 2] = 255; + ((BYTE*)lockrect.pBits)[4 * x + y * lockrect.Pitch + 3] = buffer[x + y * stride] * 255 / 64; + } + + IDirect3DTexture9_UnlockRect(current_texture, 0); + + heap_free(buffer); + + This->texture_pos++; + } + + return D3D_OK; }
static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, const char *string, INT count) @@ -294,6 +474,7 @@ HRESULT WINAPI D3DXCreateFontIndirectW(IDirect3DDevice9 *device, const D3DXFONT_ D3DDISPLAYMODE mode; struct d3dx_font *object; IDirect3D9 *d3d; + TEXTMETRICW metrics; HRESULT hr;
TRACE("(%p, %p, %p)\n", device, desc, font); @@ -305,39 +486,65 @@ HRESULT WINAPI D3DXCreateFontIndirectW(IDirect3DDevice9 *device, const D3DXFONT_ IDirect3DDevice9_GetCreationParameters(device, &cpars); IDirect3DDevice9_GetDisplayMode(device, 0, &mode); hr = IDirect3D9_CheckDeviceFormat(d3d, cpars.AdapterOrdinal, cpars.DeviceType, mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8); - if(FAILED(hr)) { + if (FAILED(hr)) + { IDirect3D9_Release(d3d); return D3DXERR_INVALIDDATA; } IDirect3D9_Release(d3d);
- object = HeapAlloc(GetProcessHeap(), 0, sizeof(struct d3dx_font)); - if(object==NULL) { - *font=NULL; + object = heap_alloc_zero(sizeof(struct d3dx_font)); + if (!object) + { + *font = NULL; return E_OUTOFMEMORY; } object->ID3DXFont_iface.lpVtbl = &D3DXFont_Vtbl; - object->ref=1; - object->device=device; - object->desc=*desc; + object->ref = 1; + object->device = device; + object->desc = *desc;
object->hdc = CreateCompatibleDC(NULL); - if( !object->hdc ) { - HeapFree(GetProcessHeap(), 0, object); + if (!object->hdc) + { + heap_free(object); return D3DXERR_INVALIDDATA; }
object->hfont = CreateFontW(desc->Height, desc->Width, 0, 0, desc->Weight, desc->Italic, FALSE, FALSE, desc->CharSet, desc->OutputPrecision, CLIP_DEFAULT_PRECIS, desc->Quality, desc->PitchAndFamily, desc->FaceName); - if( !object->hfont ) { + if (!object->hfont) + { DeleteDC(object->hdc); - HeapFree(GetProcessHeap(), 0, object); + heap_free(object); return D3DXERR_INVALIDDATA; } SelectObject(object->hdc, object->hfont);
+ /* allocate common memory usage */ + object->allocated_glyphs = 32; + object->glyphs = heap_alloc(object->allocated_glyphs * sizeof(GLYPH)); + if (!object->glyphs) + { + DeleteObject(object->hfont); + DeleteDC(object->hdc); + heap_free(object); + *font = NULL; + return E_OUTOFMEMORY; + } + + GetTextMetricsW(object->hdc, &metrics); + + object->glyph_size = make_pow2(metrics.tmHeight); + + object->texture_size = make_pow2(object->glyph_size); + if (object->glyph_size < 256) + object->texture_size = min(256, object->texture_size << 4); + + object->glyphs_per_texture = object->texture_size * object->texture_size / object->glyph_size / object->glyph_size; + IDirect3DDevice9_AddRef(device); - *font=&object->ID3DXFont_iface; + *font = &object->ID3DXFont_iface;
return D3D_OK; } diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index 7edc47eb77..dc4a9873e9 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -542,7 +542,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) hr = ID3DXFont_PreloadCharacters(font, 'b', 'a'); ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXFont_PreloadGlyphs(font, 1, 0); - todo_wine ok(hr == D3D_OK, "ID3DXFont_PreloadGlyphs returned %#x, expected %#x\n", hr, D3D_OK); + ok(hr == D3D_OK, "ID3DXFont_PreloadGlyphs returned %#x, expected %#x\n", hr, D3D_OK);
hr = ID3DXFont_PreloadCharacters(font, 'a', 'a'); ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK); @@ -594,7 +594,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
/* Test multiple textures */ hr = ID3DXFont_PreloadGlyphs(font, 0, 1000); - todo_wine ok(hr == D3D_OK, "ID3DXFont_PreloadGlyphs returned %#x, expected %#x\n", hr, D3D_OK); + ok(hr == D3D_OK, "ID3DXFont_PreloadGlyphs returned %#x, expected %#x\n", hr, D3D_OK);
/* Test glyphs that are not rendered */ for (glyph = 1; glyph < 4; glyph++) diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index d96ade9aed..47acf42aa1 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -31,7 +31,7 @@ static BOOL is_pow2(UINT num) }
/* Returns the smallest power of 2 which is greater than or equal to num */ -static UINT make_pow2(UINT num) +UINT make_pow2(UINT num) { UINT result = 1;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62858
Your paranoid android.
=== debian10 (32 bit report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit French report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit Japanese:Japan report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit Chinese:China report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (32 bit WoW report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
=== debian10 (64 bit WoW report) ===
d3dx9_36: core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture core.c:604: Test failed: Got unexpected texture
Based on a patch by Tony Wasserka.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/font.c | 64 ++++++++++++++++++++++++++++++++++++-- dlls/d3dx9_36/tests/core.c | 23 +++++++------- 2 files changed, 73 insertions(+), 14 deletions(-)
diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c index fe645a51c0..e204ca3012 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -166,12 +166,70 @@ static HDC WINAPI ID3DXFontImpl_GetDC(ID3DXFont *iface) return This->hdc; }
+/************************************************************ + * ID3DXFont_GetGlyphData + * + * Returns the internally stored texture and some info about + * the position of the requested glyph on that texture + * + * PARAMS + * glyph [I] glyph + * texture [O] length of the string + * blackbox [O] smallest rectangle that completely encloses the glyph on the texture + * cellinc [O] offset from the baseline to the bottom of the glyph + * + * RETURNS + * Success: D3D_OK + * Failure: D3DERR_INVALIDCALL + * D3DXERR_INVALIDDATA + * + * NOTES + * Glyphs which are passed to this function get preloaded, too + * + */ static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph, IDirect3DTexture9 **texture, RECT *blackbox, POINT *cellinc) { - FIXME("iface %p, glyph %#x, texture %p, blackbox %p, cellinc %p stub!\n", - iface, glyph, texture, blackbox, cellinc); - return E_NOTIMPL; + struct d3dx_font *This = impl_from_ID3DXFont(iface); + HRESULT hr; + int i; + TRACE("iface %p, glyph %#x, texture %p, blackbox %p, cellinc %p\n", + iface, glyph, texture, blackbox, cellinc); + + for (i = 0; i < This->glyph_count; i++) + if (This->glyphs[i].id == glyph) + { + if (cellinc) + *cellinc = This->glyphs[i].cellinc; + if (blackbox) + *blackbox = This->glyphs[i].blackbox; + if (texture) + *texture = This->glyphs[i].texture; + if (texture && *texture) + IDirect3DTexture9_AddRef(This->glyphs[i].texture); + return D3D_OK; + } + + hr = ID3DXFont_PreloadGlyphs(iface, glyph, glyph); + if (FAILED(hr)) + return hr; + + /* Try again */ + for (i = 0; i < This->glyph_count; i++) + if (This->glyphs[i].id == glyph) + { + if (cellinc) + *cellinc = This->glyphs[i].cellinc; + if (blackbox) + *blackbox = This->glyphs[i].blackbox; + if (texture) + *texture = This->glyphs[i].texture; + if (texture && *texture) + IDirect3DTexture9_AddRef(This->glyphs[i].texture); + return D3D_OK; + } + + return D3DXERR_INVALIDDATA; }
static HRESULT WINAPI ID3DXFontImpl_PreloadCharacters(ID3DXFont *iface, UINT first, UINT last) diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index dc4a9873e9..fe709669ed 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -529,7 +529,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
hdc = ID3DXFont_GetDC(font);
- todo_wine { hr = ID3DXFont_GetGlyphData(font, 0, NULL, &blackbox, &cellinc); ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXFont_GetGlyphData(font, 0, &texture, NULL, &cellinc); @@ -538,7 +537,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) hr = ID3DXFont_GetGlyphData(font, 0, &texture, &blackbox, NULL); if(SUCCEEDED(hr)) check_release((IUnknown*)texture, 1); ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); - } hr = ID3DXFont_PreloadCharacters(font, 'b', 'a'); ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXFont_PreloadGlyphs(font, 1, 0); @@ -552,7 +550,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ok(ret != GDI_ERROR, "GetGlyphIndicesA failed\n");
hr = ID3DXFont_GetGlyphData(font, glyph, &texture, &blackbox, &cellinc); - todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); + ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); if(SUCCEEDED(hr)) { DWORD ret, levels; TEXTMETRICW tm; @@ -600,7 +598,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) for (glyph = 1; glyph < 4; glyph++) { hr = ID3DXFont_GetGlyphData(font, glyph, &texture, &blackbox, &cellinc); - todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); + ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); ok(!texture, "Got unexpected texture\n"); }
@@ -629,22 +627,25 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ok(ret != GDI_ERROR, "GetGlyphIndicesA failed\n");
hr = ID3DXFont_GetGlyphData(font, glyph, &texture, NULL, NULL); - todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); + ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK); if(SUCCEEDED(hr)) { DWORD levels; D3DSURFACE_DESC desc;
levels = IDirect3DTexture9_GetLevelCount(texture); - ok(levels == tests[i].expected_levels, "Got levels %u, expected %u\n", - levels, tests[i].expected_levels); + todo_wine_if(tests[i].expected_levels < 9 || tests[i].font_height == 257) + ok(levels == tests[i].expected_levels, "Got levels %u, expected %u\n", + levels, tests[i].expected_levels); hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc); ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc failed\n"); ok(desc.Format == D3DFMT_A8R8G8B8, "Got format %#x, expected %#x\n", desc.Format, D3DFMT_A8R8G8B8); ok(desc.Usage == 0, "Got usage %#x, expected %#x\n", desc.Usage, 0); - ok(desc.Width == tests[i].expected_size, "Got width %u, expected %u\n", - desc.Width, tests[i].expected_size); - ok(desc.Height == tests[i].expected_size, "Got height %u, expected %u\n", - desc.Height, tests[i].expected_size); + todo_wine_if(tests[i].font_height == 4 || tests[i].font_height == 257) + ok(desc.Width == tests[i].expected_size, "Got width %u, expected %u\n", + desc.Width, tests[i].expected_size); + todo_wine_if(tests[i].font_height == 4 || tests[i].font_height == 257) + ok(desc.Height == tests[i].expected_size, "Got height %u, expected %u\n", + desc.Height, tests[i].expected_size); ok(desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected %u\n", desc.Pool, D3DPOOL_MANAGED);
IDirect3DTexture9_Release(texture);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62859
Your paranoid android.
=== debian10 (32 bit report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit French report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit Japanese:Japan report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit Chinese:China report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit WoW report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (64 bit WoW report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
Based on a patch by Tony Wasserka.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/font.c | 52 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c index e204ca3012..e7e4f33d2c 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -232,10 +232,58 @@ static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph, return D3DXERR_INVALIDDATA; }
+/************************************************************ + * ID3DXFont_PreloadCharacters + * + * Preloads the specified character series into the internal texture + * + * PARAMS + * first [I] first character to be preloaded + * last [I] last character to be preloaded + * + * RETURNS + * Success: D3D_OK + * Failure: D3DERR_INVALIDCALL + * + * NOTES + * We just split each character into its glyphs and call PreloadGlyphs here. + * + */ static HRESULT WINAPI ID3DXFontImpl_PreloadCharacters(ID3DXFont *iface, UINT first, UINT last) { - FIXME("iface %p, first %u, last %u stub!\n", iface, first, last); - return S_OK; + struct d3dx_font *This = impl_from_ID3DXFont(iface); + UINT i, count; + WCHAR *chars; + WORD *indices; + + TRACE("iface %p, first %u, last %u\n", iface, first, last); + + if (last < first) return D3D_OK; + + count = last - first + 1; + indices = heap_alloc(count * sizeof(WORD)); + if (!indices) + return E_OUTOFMEMORY; + + chars = heap_alloc(count * sizeof(WCHAR)); + if (!chars) + { + heap_free(indices); + return E_OUTOFMEMORY; + } + + for (i = 0; i < count; i++) + chars[i] = (WCHAR)(first + i); + + GetGlyphIndicesW(This->hdc, chars, count, indices, 0); + + for (i = 0; i < count; i++) + ID3DXFont_PreloadGlyphs(iface, indices[i], indices[i]); + + heap_free(chars); + heap_free(indices); + + return D3D_OK; }
/************************************************************
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62860
Your paranoid android.
=== debian10 (32 bit report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit Chinese:China report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit WoW report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (64 bit WoW report) ===
d3dx9_36: core.c:637: Test succeeded inside todo block: Got levels 9, expected 9 core.c:644: Test succeeded inside todo block: Got width 256, expected 256 core.c:647: Test succeeded inside todo block: Got height 256, expected 256
Based on a patch by Tony Wasserka.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/font.c | 63 +++++++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/core.c | 2 -- 2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c index e7e4f33d2c..1037f49cd5 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -446,16 +446,71 @@ static HRESULT WINAPI ID3DXFontImpl_PreloadGlyphs(ID3DXFont *iface, UINT first, return D3D_OK; }
+/************************************************************ + * ID3DXFont_PreloadText + * + * Preloads a string into the internal texture + * + * PARAMS + * string [I] string to be preloaded + * count [I] length of the string + * + * RETURNS + * Success: D3D_OK, if we successfully preload the text or + * if string and count are NULL + * Failure: D3DERR_INVALIDCALL, if string is NULL and count is not 0 + * + */ static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, const char *string, INT count) { - FIXME("iface %p, string %s, count %d stub!\n", iface, debugstr_a(string), count); - return E_NOTIMPL; + + WCHAR *wstr; + HRESULT hr; + TRACE("iface %p, string %s, count %d\n", iface, debugstr_a(string), count); + + if (!string && count == 0) return D3D_OK; + if (!string) return D3DERR_INVALIDCALL; + + if (count < 0) + count = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0); + + wstr = heap_alloc_zero(count * sizeof(WCHAR)); + if (!wstr) + return E_OUTOFMEMORY; + + MultiByteToWideChar(CP_ACP, 0, string, -1, wstr, count); + + hr = ID3DXFont_PreloadTextW(iface, wstr, count); + + heap_free(wstr); + + return hr; }
static HRESULT WINAPI ID3DXFontImpl_PreloadTextW(ID3DXFont *iface, const WCHAR *string, INT count) { - FIXME("iface %p, string %s, count %d stub!\n", iface, debugstr_w(string), count); - return E_NOTIMPL; + struct d3dx_font *This = impl_from_ID3DXFont(iface); + UINT i; + WORD *indices; + + TRACE("iface %p, string %s, count %d\n", iface, debugstr_w(string), count); + + if (!string && count == 0) return D3D_OK; + if (!string) return D3DERR_INVALIDCALL; + if (count < 0) count = lstrlenW(string); + + indices = heap_alloc(count * sizeof(WORD)); + if (!indices) + return E_OUTOFMEMORY; + + GetGlyphIndicesW(This->hdc, string, count, indices, 0); + + for (i = 0; i < count; i++) + ID3DXFont_PreloadGlyphs(iface, indices[i], indices[i]); + + heap_free(indices); + + return D3D_OK; }
static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index fe709669ed..8a0f164259 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -483,7 +483,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) /* ID3DXFont_PreloadText */ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font); if(SUCCEEDED(hr)) { - todo_wine { hr = ID3DXFont_PreloadTextA(font, NULL, -1); ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXFont_PreloadTextA(font, NULL, 0); @@ -509,7 +508,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXFont_PreloadTextW(font, emptyW, -1); ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK); - }
check_release((IUnknown*)font, 0); } else skip("Failed to create a ID3DXFont object\n");
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62861
Your paranoid android.
=== debian10 (32 bit report) ===
d3dx9_36: core.c:635: Test succeeded inside todo block: Got levels 9, expected 9 core.c:642: Test succeeded inside todo block: Got width 256, expected 256 core.c:645: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit French report) ===
d3dx9_36: core.c:635: Test succeeded inside todo block: Got levels 9, expected 9 core.c:642: Test succeeded inside todo block: Got width 256, expected 256 core.c:645: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit Japanese:Japan report) ===
d3dx9_36: core.c:635: Test succeeded inside todo block: Got levels 9, expected 9 core.c:642: Test succeeded inside todo block: Got width 256, expected 256 core.c:645: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit Chinese:China report) ===
d3dx9_36: core.c:635: Test succeeded inside todo block: Got levels 9, expected 9 core.c:642: Test succeeded inside todo block: Got width 256, expected 256 core.c:645: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (32 bit WoW report) ===
d3dx9_36: core.c:635: Test succeeded inside todo block: Got levels 9, expected 9 core.c:642: Test succeeded inside todo block: Got width 256, expected 256 core.c:645: Test succeeded inside todo block: Got height 256, expected 256
=== debian10 (64 bit WoW report) ===
d3dx9_36: core.c:635: Test succeeded inside todo block: Got levels 9, expected 9 core.c:642: Test succeeded inside todo block: Got width 256, expected 256 core.c:645: Test succeeded inside todo block: Got height 256, expected 256
On 1/4/20 2:59 PM, Sven Baars wrote:
static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, const char *string, INT count) {
- FIXME("iface %p, string %s, count %d stub!\n", iface, debugstr_a(string), count);
- return E_NOTIMPL;
- WCHAR *wstr;
- HRESULT hr;
- TRACE("iface %p, string %s, count %d\n", iface, debugstr_a(string), count);
- if (!string && count == 0) return D3D_OK;
- if (!string) return D3DERR_INVALIDCALL;
- if (count < 0)
count = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);
- wstr = heap_alloc_zero(count * sizeof(WCHAR));
- if (!wstr)
return E_OUTOFMEMORY;
- MultiByteToWideChar(CP_ACP, 0, string, -1, wstr, count);
- hr = ID3DXFont_PreloadTextW(iface, wstr, count);
- heap_free(wstr);
- return hr;
There is some confusion with conversion here. Method argument indicates length on input A string, and if negative means it's terminated. So to convert to W:
- countW = mbtowc(string, count < 0 ? -1 : count, NULL, 0) - wstr = heap_alloc(countW) - mbtowc(string, count < 0 ? -1 : count, wstr, countW)
Based on a patch by Tony Wasserka.
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=24754 Signed-off-by: Sven Baars sbaars@codeweavers.com --- 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 | 392 ++++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/core.c | 45 ++--- 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, 427 insertions(+), 50 deletions(-)
diff --git a/dlls/d3dx9_24/Makefile.in b/dlls/d3dx9_24/Makefile.in index faad4c49ac..f80541a9aa 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 292b33db2b..e3144f0d45 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 22bb54a498..1b432afb21 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 4ed104a170..65d8cad9d6 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 94e059ae9d..ff7ba564c1 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 94b39aee37..7e53415c43 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 6beadbc47e..9bc955753f 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 b73f32872c..58b72c527c 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 50bc9d0e26..88cc083bbe 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 7be34e1d4b..f6de942ed8 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 248735a531..5d0bc9b3a4 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 01c809dab2..5eb00327c1 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 825e5ddfbc..6a08c41159 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 1037f49cd5..b91f21b671 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -20,6 +20,10 @@
#include "d3dx9_private.h"
+#include <assert.h> + +#include "usp10.h" + WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
typedef struct _GLYPH @@ -513,20 +517,396 @@ static HRESULT WINAPI ID3DXFontImpl_PreloadTextW(ID3DXFont *iface, const WCHAR * return D3D_OK; }
+/************************************************************ + * ID3DXFont_DrawText + * + * Renders the specified string to the screen + * + * PARAMS + * sprite [I] sprite object used to draw the text + * string [I] string to be drawn + * count [I] length of the string + * rect [I,O] rect which tells us where to draw the string, + * which can be computed by passing DT_CALCRECT + * format [I] format of the string + * color [I] text color + * + * RETURNS + * The height of the drawn text + * + */ static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, const char *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) { - FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x stub!\n", - iface, sprite, debugstr_a(string), count, wine_dbgstr_rect(rect), format, color); - return 1; + WCHAR *wstr; + INT ret; + + TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x\n", + iface, sprite, debugstr_a(string), count, wine_dbgstr_rect(rect), format, color); + + if (!string) + return 0; + + if (count < 0) + count = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0) - 1; + + if (count == 0) + return 0; + + wstr = heap_alloc_zero(count * sizeof(WCHAR)); + if (!wstr) + return 0; + + MultiByteToWideChar(CP_ACP, 0, string, -1, wstr, count); + + ret = ID3DXFont_DrawTextW(iface, sprite, wstr, count, rect, format, color); + + heap_free(wstr); + + return ret; +} + +/* DrawText helpers copied from user32 */ +#define TAB 9 +#define LF 10 +#define CR 13 +#define SPACE 32 +static void TEXT_WordBreak(HDC hdc, WCHAR *str, unsigned int max_str, + unsigned int *len_str, + int width, int format, unsigned int chars_fit, + unsigned int *chars_used, SIZE *size) +{ + WCHAR *p; + BOOL word_fits; + SCRIPT_LOGATTR *sla; + SCRIPT_ANALYSIS sa; + int i; + + assert(format & DT_WORDBREAK); + assert(chars_fit < *len_str); + + sla = heap_alloc(sizeof(SCRIPT_LOGATTR) * *len_str); + + memset(&sa, 0, sizeof(SCRIPT_ANALYSIS)); + sa.eScript = SCRIPT_UNDEFINED; + + ScriptBreak(str, *len_str, &sa, sla); + + /* Work back from the last character that did fit to either a space or the + * last character of a word, whichever is met first. + */ + p = str + chars_fit; /* The character that doesn't fit */ + i = chars_fit; + word_fits = TRUE; + if (!chars_fit) + word_fits = FALSE; + else if (sla[i].fSoftBreak) /* chars_fit < *len_str so this is valid */ + { + /* the word just fitted */ + p--; + } + else + { + while (i > 0 && !sla[(--i)+1].fSoftBreak) p--; + p--; + word_fits = (i != 0 || sla[i+1].fSoftBreak); + } + + /* If there was one. */ + if (word_fits) + { + BOOL next_is_space; + /* break the line before/after that character */ + if (!(format & (DT_RIGHT | DT_CENTER)) || *p != SPACE) + p++; + next_is_space = (p - str) < *len_str && *p == SPACE; + *len_str = p - str; + /* and if the next character is a space then discard it. */ + *chars_used = *len_str; + if (next_is_space) + (*chars_used)++; + } + /* Suppose there was none. */ + else + { + /* discard any trailing space. */ + const WCHAR *e = str + *len_str; + p = str + chars_fit; + while (p < e && *p != SPACE) + p++; + *chars_used = p - str; + if (p < e) /* i.e. loop failed because *p == SPACE */ + (*chars_used)++; + *len_str = p - str; + } + /* Remeasure the string */ + GetTextExtentExPointW(hdc, str, *len_str, 0, NULL, NULL, size); + heap_free(sla); +} + +static const WCHAR *TEXT_NextLineW(HDC hdc, const WCHAR *str, int *count, + WCHAR *dest, int *len, int width, DWORD format, + SIZE *retsize, int last_line, int tabwidth) +{ + int i = 0, j = 0; + int plen = 0; + SIZE size; + int maxl = *len; + int seg_i, seg_count, seg_j; + int max_seg_width; + int num_fit; + BOOL word_broken, line_fits; + unsigned int j_in_seg; + + /* For each text segment in the line */ + + retsize->cy = 0; + while (*count) + { + + /* Skip any leading tabs */ + + if (str[i] == TAB && (format & DT_EXPANDTABS)) + { + plen = ((plen/tabwidth)+1)*tabwidth; + (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++; + while (*count && str[i] == TAB) + { + plen += tabwidth; + (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++; + } + } + + + /* Now copy as far as the next tab or cr/lf or eos */ + + seg_i = i; + seg_count = *count; + seg_j = j; + + while (*count && (str[i] != TAB || !(format & DT_EXPANDTABS)) && ((str[i] != CR && str[i] != LF) || (format & DT_SINGLELINE))) + { + (*count)--; + if (j < maxl) dest[j++] = str[i]; + i++; + } + + /* Measure the whole text segment and possibly WordBreak */ + + j_in_seg = j - seg_j; + max_seg_width = width - plen; + GetTextExtentExPointW(hdc, dest + seg_j, j_in_seg, max_seg_width, &num_fit, NULL, &size); + + /* The Microsoft handling of various combinations of formats is weird. + * The following may very easily be incorrect if several formats are + * combined, and may differ between versions (to say nothing of the + * several bugs in the Microsoft versions). + */ + word_broken = FALSE; + line_fits = (num_fit >= j_in_seg); + if (!line_fits && (format & DT_WORDBREAK)) + { + const WCHAR *s; + unsigned int chars_used; + TEXT_WordBreak(hdc, dest+seg_j, maxl-seg_j, &j_in_seg, + max_seg_width, format, num_fit, &chars_used, &size); + line_fits = (size.cx <= max_seg_width); + /* and correct the counts */ + *count = seg_count - chars_used; + s = str + seg_i + chars_used; + i = s - str; + word_broken = TRUE; + } + + j = seg_j + j_in_seg; + + plen += size.cx; + if (size.cy > retsize->cy) + retsize->cy = size.cy; + + if (word_broken) + break; + else if (!*count) + break; + else if (str[i] == CR || str[i] == LF) + { + (*count)--, i++; + if (*count && (str[i] == CR || str[i] == LF) && str[i] != str[i-1]) + { + (*count)--, i++; + } + break; + } + /* else it was a Tab and we go around again */ + } + + retsize->cx = plen; + *len = j; + if (*count) + return (&str[i]); + else + return NULL; }
+#define MAX_BUFFER 1024 static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) { - FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x stub!\n", - iface, sprite, debugstr_w(string), count, wine_dbgstr_rect(rect), format, color); - return 1; + struct d3dx_font *This = impl_from_ID3DXFont(iface); + ID3DXSprite *target = sprite; + + const WCHAR *strPtr; + WCHAR line[MAX_BUFFER]; + int lh; + TEXTMETRICW tm; + int x, y; + int width; + int max_width = 0; + int last_line; + int tabwidth = 0; + RECT textrect = {0}; + + TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x\n", + iface, sprite, debugstr_w(string), count, wine_dbgstr_rect(rect), format, color); + + if (!string) + return 0; + + if (count < 0) + count = lstrlenW(string); + + if (count == 0) + return 0; + + if (format & DT_SINGLELINE) + format &= ~DT_WORDBREAK; + if (format & DT_CALCRECT) + format |= DT_NOCLIP; + + if (!rect) + { + y = ID3DXFont_DrawTextW(iface, NULL, string, count, &textrect, format | DT_CALCRECT, 0); + + if (format & DT_CALCRECT) + return y; + } + else + textrect = *rect; + + x = textrect.left; + y = textrect.top; + width = textrect.right - textrect.left; + strPtr = string; + + ID3DXFont_GetTextMetricsW(iface, &tm); + lh = tm.tmHeight; + + if (format & DT_EXPANDTABS) + tabwidth = tm.tmAveCharWidth * 8; + + if (!(format & DT_CALCRECT) && !sprite) + { + D3DXCreateSprite(This->device, &target); + ID3DXSprite_Begin(target, 0); + } + + do { + SIZE size; + int len = ARRAY_SIZE(line); + + last_line = !(format & DT_NOCLIP) && (y + lh > textrect.bottom); + strPtr = TEXT_NextLineW(This->hdc, strPtr, &count, line, &len, width, format, &size, last_line, tabwidth); + + if (format & DT_CENTER) + x = (textrect.left + textrect.right - size.cx) / 2; + else if (format & DT_RIGHT) + x = textrect.right - size.cx; + + if (format & DT_SINGLELINE) + { + if (format & DT_VCENTER) + y = textrect.top + (textrect.bottom - textrect.top) / 2 - size.cy / 2; + else if (format & DT_BOTTOM) + y = textrect.bottom - size.cy; + } + + if (!(format & DT_CALCRECT)) + { + int xseg = x; + const WCHAR *str = line; + + while (len) + { + int len_seg; + GCP_RESULTSW results; + D3DXVECTOR3 pos; + UINT i; + + if ((format & DT_EXPANDTABS)) + { + const WCHAR *p; + p = str; while (p < str+len && *p != TAB) p++; + len_seg = p - str; + if (len_seg != len && !GetTextExtentPointW(This->hdc, str, len_seg, &size)) + return 0; + } + else + len_seg = len; + + ZeroMemory(&results, sizeof(GCP_RESULTSW)); + results.lpCaretPos = heap_alloc(len_seg * sizeof(INT)); + results.lpGlyphs = heap_alloc(len_seg * sizeof(WORD)); + results.nGlyphs = len_seg; + + GetCharacterPlacementW(This->hdc, str, len_seg, 0, &results, 0); + + for (i = 0; i < results.nGlyphs; i++) + { + LPDIRECT3DTEXTURE9 tex; + RECT bbox; + POINT cinc; + + ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &tex, &bbox, &cinc); + + if (!tex) + continue; + + pos.x = results.lpCaretPos[i] + cinc.x + xseg; + pos.y = cinc.y + y; + + ID3DXSprite_Draw(target, tex, &bbox, NULL, &pos, color); + IDirect3DTexture9_Release(tex); + } + + len -= len_seg; + str += len_seg; + if (len) + { + assert((format & DT_EXPANDTABS) && *str == TAB); + len--; str++; + xseg += ((size.cx/tabwidth)+1)*tabwidth; + } + } + } + else if (size.cx > max_width) + max_width = size.cx; + + y += lh; + } while (strPtr && !last_line); + + textrect.right = textrect.left + max_width; + textrect.bottom = y; + + if ((format & DT_CALCRECT) && rect) + *rect = textrect; + + if (target != sprite) + { + ID3DXSprite_End(target); + ID3DXSprite_Release(target); + } + + return y - textrect.top; }
static HRESULT WINAPI ID3DXFontImpl_OnLostDevice(ID3DXFont *iface) diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index 8a0f164259..c2c83952fb 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -320,20 +320,21 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) unsigned int expected_height; unsigned int expected_size; unsigned int expected_levels; + BOOL todo; } tests[] = { - { 2, 2, 32, 2 }, - { 4, 4, 64, 3 }, - { 6, 6, 128, 4 }, - { 8, 8, 128, 4 }, - { 10, 10, 256, 5 }, - { 12, 12, 256, 5 }, - { 72, 72, 256, 8 }, - { 256, 255, 256, 9 }, - { 257, 255, 256, 9 }, - { 258, 258, 512, 10 }, - { 512, 512, 512, 10 }, + { 2, 2, 32, 2, FALSE}, + { 4, 4, 64, 3, TRUE}, + { 6, 6, 128, 4, FALSE}, + { 8, 8, 128, 4, TRUE}, + { 10, 10, 256, 5, FALSE}, + { 12, 12, 256, 5, FALSE}, + { 72, 72, 256, 8, FALSE}, + { 256, 255, 256, 9, TRUE}, + { 257, 255, 256, 9, TRUE}, + { 258, 258, 512, 10, FALSE}, + { 512, 512, 512, 10, FALSE}, }; const unsigned int size = ARRAY_SIZE(testW); D3DXFONT_DESCA desc; @@ -659,26 +660,24 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) hr = ID3DXSprite_Begin(sprite, D3DXSPRITE_ALPHABLEND); ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- todo_wine { height = ID3DXFont_DrawTextW(font, sprite, testW, -1, &rect, DT_TOP, 0xffffffff); - ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); + todo_wine_if(tests[i].todo) ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_TOP, 0xffffffff); - ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); + todo_wine_if(tests[i].todo) ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_RIGHT, 0xffffffff); - ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); + todo_wine_if(tests[i].todo) ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_NOCLIP, 0xffffffff); - ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); - } + todo_wine_if(tests[i].todo) ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height);
SetRectEmpty(&rect); height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_CALCRECT, 0xffffffff); - todo_wine ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); + todo_wine_if(tests[i].todo) ok(height == tests[i].expected_height, "Got unexpected height %u.\n", height); ok(!rect.left, "Got unexpected rect left %d.\n", rect.left); ok(!rect.top, "Got unexpected rect top %d.\n", rect.top); - todo_wine ok(rect.right, "Got unexpected rect right %d.\n", rect.right); - todo_wine ok(rect.bottom == tests[i].expected_height, "Got unexpected rect bottom %d.\n", rect.bottom); + ok(rect.right, "Got unexpected rect right %d.\n", rect.right); + todo_wine_if(tests[i].todo) ok(rect.bottom == tests[i].expected_height, "Got unexpected rect bottom %d.\n", rect.bottom);
hr = ID3DXSprite_End(sprite); ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr); @@ -694,7 +693,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) RECT rect; int height;
- todo_wine { SetRect(&rect, 10, 10, 200, 200);
height = ID3DXFont_DrawTextA(font, NULL, "test", -2, &rect, 0, 0xFF00FF); @@ -730,7 +728,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) SetRect(&rect, 10, 10, 50, 50);
height = ID3DXFont_DrawTextA(font, NULL, longText, -1, &rect, DT_WORDBREAK, 0xFF00FF); - ok(height == 60, "DrawTextA returned %d, expected 60.\n", height); + todo_wine ok(height == 60, "DrawTextA returned %d, expected 60.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, longText, -1, &rect, DT_WORDBREAK | DT_NOCLIP, 0xFF00FF); ok(height == 96, "DrawTextA returned %d, expected 96.\n", height); @@ -772,11 +770,10 @@ if (0) { /* Causes a lockup on Windows 7+ */ SetRect(&rect, 10, 10, 50, 50);
height = ID3DXFont_DrawTextW(font, NULL, longTextW, -1, &rect, DT_WORDBREAK, 0xFF00FF); - ok(height == 60, "DrawTextW returned %d, expected 60.\n", height); + todo_wine ok(height == 60, "DrawTextW returned %d, expected 60.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, longTextW, -1, &rect, DT_WORDBREAK | DT_NOCLIP, 0xFF00FF); ok(height == 96, "DrawTextW returned %d, expected 96.\n", height); - }
ID3DXFont_Release(font); } diff --git a/dlls/d3dx9_37/Makefile.in b/dlls/d3dx9_37/Makefile.in index a0896df82e..b9dda315f2 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 24bbc3f0cf..adeb4f245a 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 a3f7626f33..0e210488f6 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 fbbcb0c04e..05349e4b40 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 9b44213117..587e94b7d1 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 f725e87471..bb837c4e39 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 dbebc51ad0..0701cde7b7 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
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62862
Your paranoid android.
=== debian10 (32 bit report) ===
d3dx9_36: core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255. core.c:636: Test succeeded inside todo block: Got levels 9, expected 9 core.c:643: Test succeeded inside todo block: Got width 256, expected 256 core.c:646: Test succeeded inside todo block: Got height 256, expected 256 core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255.
=== debian10 (32 bit French report) ===
d3dx9_36: core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255. core.c:636: Test succeeded inside todo block: Got levels 9, expected 9 core.c:643: Test succeeded inside todo block: Got width 256, expected 256 core.c:646: Test succeeded inside todo block: Got height 256, expected 256 core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255.
=== debian10 (32 bit Japanese:Japan report) ===
d3dx9_36: core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255. core.c:636: Test succeeded inside todo block: Got levels 9, expected 9 core.c:643: Test succeeded inside todo block: Got width 256, expected 256 core.c:646: Test succeeded inside todo block: Got height 256, expected 256 core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255.
=== debian10 (32 bit Chinese:China report) ===
d3dx9_36: core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255. core.c:636: Test succeeded inside todo block: Got levels 9, expected 9 core.c:643: Test succeeded inside todo block: Got width 256, expected 256 core.c:646: Test succeeded inside todo block: Got height 256, expected 256 core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255.
=== debian10 (32 bit WoW report) ===
d3dx9_36: core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255. core.c:636: Test succeeded inside todo block: Got levels 9, expected 9 core.c:643: Test succeeded inside todo block: Got width 256, expected 256 core.c:646: Test succeeded inside todo block: Got height 256, expected 256 core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255.
=== debian10 (64 bit WoW report) ===
d3dx9_36: core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255. core.c:636: Test succeeded inside todo block: Got levels 9, expected 9 core.c:643: Test succeeded inside todo block: Got width 256, expected 256 core.c:646: Test succeeded inside todo block: Got height 256, expected 256 core.c:664: Test succeeded inside todo block: Got unexpected height 255. core.c:666: Test succeeded inside todo block: Got unexpected height 255. core.c:668: Test succeeded inside todo block: Got unexpected height 255. core.c:671: Test succeeded inside todo block: Got unexpected height 255. core.c:676: Test succeeded inside todo block: Got unexpected height 255. core.c:680: Test succeeded inside todo block: Got unexpected rect bottom 255.
On 1/4/20 7:59 PM, Sven Baars wrote:
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Sven Baars sbaars@codeweavers.com
I'm sending this series mostly so it can be reviewed, but I sent the tests first so they may still be committed during code freeze, if they are acceptable.
dlls/d3dx9_36/tests/core.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index fa874a5ef5..8b90f0ef5f 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -637,6 +637,69 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
ID3DXFont_Release(font); }
- /* ID3DXFont_DrawTextA, ID3DXFont_DrawTextW */
- hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
Arial may be unavailable. Please use Tahoma instead.
- if (SUCCEEDED(hr)) {
RECT rect;
int height;
todo_wine {
SetRect(&rect, 10, 10, 200, 200);
height = ID3DXFont_DrawTextA(font, NULL, "test", -2, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, "test", -1, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, "test", 0, &rect, 0, 0xFF00FF);
ok(height == 0, "DrawTextA returned %d, expected 0.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, "test", 1, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, "test", 2, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, "test", -1, NULL, 0, 0xFF00FF);
ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, "test", -1, NULL, DT_CALCRECT, 0xFF00FF);
ok(height == 12, "DrawTextA returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextA(font, NULL, NULL, -1, NULL, 0, 0xFF00FF);
ok(height == 0, "DrawTextA returned %d, expected 0.\n", height);
+if (0) { /* Causes a lockup on windows 7. */
height = ID3DXFont_DrawTextW(font, NULL, testW, -2, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
+}
height = ID3DXFont_DrawTextW(font, NULL, testW, -1, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, testW, 0, &rect, 0, 0xFF00FF);
ok(height == 0, "DrawTextW returned %d, expected 0.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, testW, 1, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, testW, 2, &rect, 0, 0xFF00FF);
ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, testW, -1, NULL, 0, 0xFF00FF);
ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, testW, -1, NULL, DT_CALCRECT, 0xFF00FF);
ok(height == 12, "DrawTextW returned %d, expected 12.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, NULL, -1, NULL, 0, 0xFF00FF);
ok(height == 0, "DrawTextW returned %d, expected 0.\n", height);
}
ID3DXFont_Release(font);
} }
static void test_D3DXCreateRenderToSurface(IDirect3DDevice9 *device)
On 05-01-2020 02:14, Zhiyi Zhang wrote:
On 1/4/20 7:59 PM, Sven Baars wrote:
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Sven Baars sbaars@codeweavers.com
I'm sending this series mostly so it can be reviewed, but I sent the tests first so they may still be committed during code freeze, if they are acceptable.
dlls/d3dx9_36/tests/core.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index fa874a5ef5..8b90f0ef5f 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -637,6 +637,69 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ID3DXFont_Release(font); }
+ /* ID3DXFont_DrawTextA, ID3DXFont_DrawTextW */ + hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
Arial may be unavailable. Please use Tahoma instead.
All tests in that file use Arial though, as well as the DrawText tests in user32. And if I grep all tests in wine, I get about the same amount of matches for Arial as for Tahoma. Should all other tests be changed as well?
On 1/6/20 6:15 PM, Sven Baars wrote:
On 05-01-2020 02:14, Zhiyi Zhang wrote:
On 1/4/20 7:59 PM, Sven Baars wrote:
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Sven Baars sbaars@codeweavers.com
I'm sending this series mostly so it can be reviewed, but I sent the tests first so they may still be committed during code freeze, if they are acceptable.
dlls/d3dx9_36/tests/core.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index fa874a5ef5..8b90f0ef5f 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -637,6 +637,69 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) ID3DXFont_Release(font); }
+ /* ID3DXFont_DrawTextA, ID3DXFont_DrawTextW */ + hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
Arial may be unavailable. Please use Tahoma instead.
All tests in that file use Arial though, as well as the DrawText tests in user32. And if I grep all tests in wine, I get about the same amount of matches for Arial as for Tahoma. Should all other tests be changed as well?
If font geometry is not important, you can use Arial because even if it is not installed, Wine should find a fallback for it. So you should use an existent font in case a font is unavailable and you end up testing the fallback. As for other tests, if they merely require a font name to be specified, I guess that is okay.
On Mon, Jan 6, 2020 at 1:16 PM Sven Baars sbaars@codeweavers.com wrote:
On 05-01-2020 02:14, Zhiyi Zhang wrote:
On 1/4/20 7:59 PM, Sven Baars wrote:
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
Signed-off-by: Sven Baars sbaars@codeweavers.com
I'm sending this series mostly so it can be reviewed, but I sent the tests first so they may still be committed during code freeze, if they are acceptable.
dlls/d3dx9_36/tests/core.c | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index fa874a5ef5..8b90f0ef5f 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -637,6 +637,69 @@ static void test_ID3DXFont(IDirect3DDevice9
*device)
ID3DXFont_Release(font); }
- /* ID3DXFont_DrawTextA, ID3DXFont_DrawTextW */
- hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
Arial may be unavailable. Please use Tahoma instead.
All tests in that file use Arial though, as well as the DrawText tests in user32. And if I grep all tests in wine, I get about the same amount of matches for Arial as for Tahoma. Should all other tests be changed as well?
For purposes of d3dx9 tests I think it's enough to test that sizes match
what gdi (or user32:DrawText) calls return, and to make it more predictable, using Tahoma, since wine provides it.