[PATCH v4 4/5] d3dx9: Handle tabs in ID3DXFont_DrawText.

Matteo Bruni matteo.mystral at gmail.com
Wed Apr 1 13:32:17 CDT 2020


On Fri, Mar 27, 2020 at 5:49 PM Sven Baars <sbaars at codeweavers.com> wrote:
>
> Signed-off-by: Sven Baars <sbaars at codeweavers.com>
> ---
>  dlls/d3dx9_36/font.c       | 213 ++++++++++++++++++++++++++-----------
>  dlls/d3dx9_36/tests/core.c |   8 +-
>  2 files changed, 155 insertions(+), 66 deletions(-)

This seems more complicated than necessary. See the attached patch for
a possible alternative (which I didn't test a lot, it's mostly a proof
of concept).

The tabs and no-tabs code paths could also be merged, although we
probably want to keep avoiding extra extent computations in the
no-tabs case.
-------------- next part --------------
diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c
index 54aef71913c..6914fd1bb7c 100644
--- a/dlls/d3dx9_36/font.c
+++ b/dlls/d3dx9_36/font.c
@@ -518,6 +518,9 @@ static void word_break(HDC hdc, const WCHAR *str, unsigned int *str_len,
     SCRIPT_ANALYSIS sa;
     unsigned int i;
 
+    TRACE("hdc %p, str %s, str_len %u, chars_fit %u, chars_used %p, format %#x, size %p.\n",
+            hdc, debugstr_w(str), *str_len, chars_fit, chars_used, format, size);
+
     *chars_used = 0;
 
     sla = heap_alloc(*str_len * sizeof(*sla));
@@ -555,21 +558,42 @@ static void word_break(HDC hdc, const WCHAR *str, unsigned int *str_len,
 static const WCHAR *read_line(HDC hdc, const WCHAR *str, int *count,
         WCHAR *dest, unsigned int *dest_len, int width, DWORD format, SIZE *size)
 {
-    unsigned int i = 0;
     int orig_count = *count;
-    int num_fit;
+    BOOL found_tabs = FALSE;
+    unsigned int i = 0;
+    int num_fit = 0;
+    DWORD dim;
+
+    TRACE("hdc %p, str %s, count %u, dest %p, dest_len %p, width %u, format %#x, size %p.\n",
+            hdc, debugstr_w(str), *count, dest, dest_len, width, format, size);
 
+    if (width < 0)
+        width = INT_MAX;
     *dest_len = 0;
     while (*count && (str[i] != '\n' || (format & DT_SINGLELINE)))
     {
+        if ((format & DT_EXPANDTABS) && str[i] == '\t')
+            found_tabs = TRUE;
+
         --(*count);
-        if (str[i] != '\r' && str[i] != '\n')
+        if (str[i] != '\r' && str[i] != '\n' && (str[i] != '\t' || format & DT_EXPANDTABS))
             dest[(*dest_len)++] = str[i];
         ++i;
+
+        if (found_tabs)
+        {
+            dim = GetTabbedTextExtentW(hdc, dest, *dest_len, 0, NULL);
+            TRACE("dest_len %u.\n", *dest_len);
+            if (!(format & (DT_SINGLELINE | DT_CALCRECT)) && LOWORD(dim) >= width)
+                break;
+            else
+                num_fit = *dest_len;
+        }
     }
 
-    num_fit = 0;
-    GetTextExtentExPointW(hdc, dest, *dest_len, width, &num_fit, NULL, size);
+    if (!found_tabs)
+        GetTextExtentExPointW(hdc, dest, *dest_len, width, &num_fit, NULL, size);
+    TRACE("dest_len %u, num_fit %u.\n", *dest_len, num_fit);
 
     if (num_fit < *dest_len)
     {
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c
index 020f18e622c..9b942e15353 100644
--- a/dlls/d3dx9_36/tests/core.c
+++ b/dlls/d3dx9_36/tests/core.c
@@ -807,10 +807,10 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
     todo_wine ok(height == 0, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"\t\t\t\t\t\t\t\t\t\ta", -1, &rect, DT_WORDBREAK, 0xff00ff);
-    todo_wine ok(height == 12, "Got unexpected height %d.\n", height);
+    ok(height == 12, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"\taaaaaaaaaa", -1, &rect, DT_WORDBREAK, 0xff00ff);
-    todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
+    ok(height == 24, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"\taaaaaaaaaa", -1, &rect, DT_EXPANDTABS | DT_WORDBREAK, 0xff00ff);
     ok(height == 36, "Got unexpected height %d.\n", height);
@@ -819,7 +819,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
     ok(height == 24, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"\taaa\taaa\taaa", -1, &rect, DT_EXPANDTABS | DT_WORDBREAK, 0xff00ff);
-    todo_wine ok(height == 48, "Got unexpected height %d.\n", height);
+    ok(height == 48, "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_EXPANDTABS | DT_WORDBREAK, 0xff00ff);
     todo_wine ok(height == 60, "Got unexpected height %d.\n", height);
@@ -828,7 +828,7 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
     ok(height == 12, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"a\ta\ta", -1, &rect, DT_EXPANDTABS | DT_WORDBREAK, 0xff00ff);
-    todo_wine ok(height == 24, "Got unexpected height %d.\n", height);
+    ok(height == 24, "Got unexpected height %d.\n", height);
 
     height = ID3DXFont_DrawTextW(font, NULL, L"aaaaaaaaaaaaaaaaaaaa", -1, &rect, DT_WORDBREAK, 0xff00ff);
     ok(height == 36, "Got unexpected height %d.\n", height);


More information about the wine-devel mailing list