Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/d3dx9_36/font.c | 109 ++++++++++++++++++++++++++----------- dlls/d3dx9_36/tests/core.c | 14 ++--- 2 files changed, 83 insertions(+), 40 deletions(-)
diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c index 8ca35b8c21..23e6e5c401 100644 --- a/dlls/d3dx9_36/font.c +++ b/dlls/d3dx9_36/font.c @@ -509,14 +509,49 @@ static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, return ret; }
+#define LF 10 +#define CR 13 +static const WCHAR *TEXT_NextLineW(HDC hdc, const WCHAR *str, int *count, + WCHAR *dest, int *len, int width, SIZE *retsize) +{ + int max_len = *len; + int i = 0, j = 0; + + while (*count && str[i] != LF) + { + --(*count); + if (j < max_len && str[i] != CR) + dest[j++] = str[i]; + ++i; + } + + GetTextExtentExPointW(hdc, dest, j, width, NULL, NULL, retsize); + + if (*count && str[i] == LF) + { + --(*count); + ++i; + } + + *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) { struct d3dx_font *font = impl_from_ID3DXFont(iface); ID3DXSprite *target = sprite; + const WCHAR *strPtr = string; + WCHAR line[MAX_BUFFER]; RECT textrect = {0}; - int lh, x, y; + int lh, x, y, width; int ret = 0; + SIZE size;
TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x.\n", iface, sprite, debugstr_wn(string, count), count, wine_dbgstr_rect(rect), format, color); @@ -544,6 +579,7 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
x = textrect.left; y = textrect.top; + width = textrect.right - textrect.left;
lh = font->metrics.tmHeight;
@@ -553,50 +589,57 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, ID3DXSprite_Begin(target, 0); }
- if (!(format & DT_CALCRECT)) + while (strPtr) { - GCP_RESULTSW results; - D3DXVECTOR3 pos; - int i; - - memset(&results, 0, sizeof(results)); - results.nGlyphs = count; + int len = ARRAY_SIZE(line);
- results.lpCaretPos = heap_alloc(count * sizeof(*results.lpCaretPos)); - if (!results.lpCaretPos) - goto cleanup; + strPtr = TEXT_NextLineW(font->hdc, strPtr, &count, line, &len, width, &size);
- results.lpGlyphs = heap_alloc(count * sizeof(*results.lpGlyphs)); - if (!results.lpGlyphs) + if (!(format & DT_CALCRECT)) { - heap_free(results.lpCaretPos); - goto cleanup; - } + GCP_RESULTSW results; + D3DXVECTOR3 pos; + int i;
- GetCharacterPlacementW(font->hdc, string, count, 0, &results, 0); + memset(&results, 0, sizeof(results)); + results.nGlyphs = len;
- for (i = 0; i < results.nGlyphs; ++i) - { - IDirect3DTexture9 *texture; - POINT cell_inc; - RECT black_box; + results.lpCaretPos = heap_alloc(len * sizeof(*results.lpCaretPos)); + if (!results.lpCaretPos) + goto cleanup;
- ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture, &black_box, &cell_inc); + results.lpGlyphs = heap_alloc(len * sizeof(*results.lpGlyphs)); + if (!results.lpGlyphs) + { + heap_free(results.lpCaretPos); + goto cleanup; + }
- if (!texture) - continue; + GetCharacterPlacementW(font->hdc, line, len, 0, &results, 0);
- pos.x = cell_inc.x + x + results.lpCaretPos[i]; - pos.y = cell_inc.y + y; + for (i = 0; i < results.nGlyphs; ++i) + { + IDirect3DTexture9 *texture; + POINT cell_inc; + RECT black_box;
- ID3DXSprite_Draw(target, texture, &black_box, NULL, &pos, color); - IDirect3DTexture9_Release(texture); - } + ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture, &black_box, &cell_inc);
- heap_free(results.lpCaretPos); - heap_free(results.lpGlyphs); + if (!texture) + continue; + + pos.x = cell_inc.x + x + results.lpCaretPos[i]; + pos.y = cell_inc.y + y; + + ID3DXSprite_Draw(target, texture, &black_box, NULL, &pos, color); + IDirect3DTexture9_Release(texture); + } + + heap_free(results.lpCaretPos); + heap_free(results.lpGlyphs); + } + y += lh; } - y += lh;
ret = y - textrect.top;
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c index c1e0eac0c8..c6f5beff43 100644 --- a/dlls/d3dx9_36/tests/core.c +++ b/dlls/d3dx9_36/tests/core.c @@ -762,19 +762,19 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 96, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, 0, 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"a\r\na", -1, &rect, 0, 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"a\ra", -1, &rect, 0, 0xff00ff); ok(height == 12, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"a\na", -1, &rect, DT_SINGLELINE, 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"a\naaaaa aaaa", -1, &rect, 0, 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"a\naaaaa aaaa", -1, &rect, DT_WORDBREAK, 0xff00ff); todo_wine ok(height == 36, "Got unexpected height %d.\n", height); @@ -783,7 +783,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 48, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"1\n2\n3\n4\n5\n6", -1, &rect, DT_NOCLIP, 0xff00ff); - todo_wine ok(height == 72, "Got unexpected height %d.\n", height); + ok(height == 72, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"\t\t\t\t\t\t\t\t\t\t", -1, &rect, DT_WORDBREAK, 0xff00ff); todo_wine ok(height == 0, "Got unexpected height %d.\n", height); @@ -834,10 +834,10 @@ static void test_ID3DXFont(IDirect3DDevice9 *device) todo_wine ok(height == 32, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_RIGHT, 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"aaaa\naaaa", -1, &rect, DT_CENTER, 0xff00ff); - todo_wine ok(height == 24, "Got unexpected height %d.\n", height); + ok(height == 24, "Got unexpected height %d.\n", height);
ID3DXFont_Release(font); }