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