[PATCH 4/5] user32: Fix using DrawTextEx() to calculate rect with flag DT_BOTTOM.

Zhiyi Zhang zzhang at codeweavers.com
Thu May 3 22:13:04 CDT 2018


Fix using DrawTextEx() to calculate text rect with DT_BOTTOM flag set
returns zero for text height.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/user32/tests/text.c | 12 ++++++++++++
 dlls/user32/text.c       | 20 +++++++++++---------
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/dlls/user32/tests/text.c b/dlls/user32/tests/text.c
index 3cc9571521..23868128d7 100644
--- a/dlls/user32/tests/text.c
+++ b/dlls/user32/tests/text.c
@@ -28,6 +28,8 @@
 #include "winerror.h"
 #include "winnls.h"
 
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
 #define MODIFIED(rect) (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)
 #define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top)
 
@@ -46,11 +48,13 @@ static void test_DrawTextCalcRect(void)
     static CHAR wordbreak_text[] = "line1 line2";
     static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0};
     static char tabstring[] = "one\ttwo";
+    static const DWORD alignments[] = {DT_TOP, DT_LEFT, DT_CENTER, DT_RIGHT, DT_VCENTER, DT_BOTTOM};
     INT textlen, textheight, heightcheck;
     RECT rect = { 0, 0, 100, 0 }, rect2;
     BOOL ret;
     DRAWTEXTPARAMS dtp;
     BOOL conform_xp = TRUE;
+    INT i;
 
     /* Initialization */
     hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
@@ -586,6 +590,14 @@ static void test_DrawTextCalcRect(void)
     ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top);
     ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom);
 
+    for (i = 0; i < ARRAY_SIZE(alignments); i++)
+    {
+        SetRectEmpty(&rect);
+        textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_NOCLIP | DT_CALCRECT | DT_SINGLELINE | alignments[i]);
+        ok(textheight > 0, "Alignment 0x%08x got unexpected textheight %d\n", alignments[i], textheight);
+        ok(rect.right - rect.left > 0, "Alignment 0x%08x got unexpected rect width %d\n", alignments[i],
+           rect.right - rect.left);
+    }
 
     SelectObject(hdc, hOldFont);
     ret = DeleteObject(hFont);
diff --git a/dlls/user32/text.c b/dlls/user32/text.c
index dbde596a1c..34e035607b 100644
--- a/dlls/user32/text.c
+++ b/dlls/user32/text.c
@@ -892,7 +892,7 @@ INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
     int lmargin = 0, rmargin = 0;
     int x = rect->left, y = rect->top, xseg;
     int width = rect->right - rect->left;
-    int max_width = 0;
+    int max_width = 0, max_height = 0;
     int last_line;
     int tabwidth /* to keep gcc happy */ = 0;
     int prefix_offset;
@@ -1029,6 +1029,8 @@ INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
 
         if (size.cx > max_width) max_width = size.cx;
 
+        max_height += lh;
+
         if (invert_y)
             y -= lh;
         else
@@ -1040,13 +1042,13 @@ INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
 
     if (!(flags & DT_CALCRECT))
     {
-        y = rect->top;
-        if (flags & DT_SINGLELINE)
-	{
-	    if (flags & DT_VCENTER) y = rect->top +
-	    	(rect->bottom - rect->top) / 2 - size.cy / 2;
-	    else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
-        }
+        if (flags & DT_VCENTER)
+            y = invert_y ? rect->top - (rect->bottom - rect->top) / 2 + max_height / 2
+                         : rect->top + (rect->bottom - rect->top) / 2 - max_height / 2;
+        else if (flags & DT_BOTTOM)
+            y = invert_y ? rect->bottom + max_height : rect->bottom - max_height;
+        else
+            y = rect->top;
 
         for (line_num = 0; line_num < used_lines; line_num++)
         {
@@ -1118,7 +1120,7 @@ INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
 
     if (retstr) memcpy(str, retstr, size_retstr);
 
-    ret = y - rect->top;
+    ret = invert_y ? -max_height : max_height;
 done:
     heap_free(retstr);
     if (lines_ptr != lines_buffer) heap_free(lines_ptr);
-- 
2.17.0





More information about the wine-devel mailing list