[PATCH] Patch for bug 50

Pedro Araujo Chaves Jr. inckie at gmail.com
Fri Feb 2 08:38:36 CST 2007


Attached is my proposed patch for Bug #50; the test case was attached
in my previous message.
--
Patch description:

This patch fixes Wine's Bug #50: "PrgWin95: Text justification needs
beefing up".

What it does: first, it takes in consideration that not always the
number of extra pixels will be a multiple of the number of break
characters in a given extent of a given string that should be
justified, and so the integer division of extra by breaks in
SetTextJustification() is likely to leave a remainder (which the
latter function addresses, of course, but ExtTextOutW() seems to
overlook — that's the reason for the changes at lines 1788 (breakRem),
and 1901 and 1922 (dc->breakExtra || breakRem), which prevent some
lines from being ignored in the justification).

That fixed, if there remained any pixels indeed, their number
shouldn't be greater than dc->breakCount; then the first breakRem
break characters in that given extent are widened by one pixel (lines
1925-1929 added).

GetTextExtentExPointW() is also fixed so that it now returns the
expected width of the text when it is to be justified. This has the
good side effect that TabbedTextOut() now also returns the proper
width when called after SetTextJustification(). What the patch does
here is that GetTextExtentExPointW() now calculates the extra width
only when (breakExtra || breakRem) resolves TRUE , and corrects the
extra space additions by applying them only to break characters. What
was broken before is that it always added extra space, regardless of
whether it was measuring a single character or a full string, or
whether it was a break character or not. (Lines added: 1191, 1199,
1227, 1229, 1236-1245, 1254-1268).

This patch is copyrighted by Banco do Brasil under the LGPL.

--
Regards,
Pedro Araújo.
-------------- next part --------------
From 5df5c0f75242ba08174d99bdffb684f809903c2e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Pedro_Ara=C3=BAjo_Chaves_J=C3=BAnior?= <pedrojr at pulchra.(none)>
Date: Fri, 2 Feb 2007 12:19:02 -0200
Subject: [PATCH] Patch for bug 50.
---
 dlls/gdi32/font.c       |   51 ++++++++++++++++++++++++++++++++++++++++-------
 dlls/gdi32/tests/font.c |    3 ---
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 527a0d9..5f0f91e 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1188,12 +1188,15 @@ BOOL WINAPI GetTextExtentExPointW( HDC h
     LPINT dxs = NULL;
     DC *dc;
     BOOL ret = FALSE;
+    TEXTMETRICW tm;
 
     TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
 
     dc = DC_GetDCPtr(hdc);
     if (! dc)
         return FALSE;
+    
+    GetTextMetricsW(hdc, &tm);
 
     /* If we need to calculate nFit, then we need the partial extents even if
        the user hasn't provided us with an array.  */
@@ -1220,22 +1223,49 @@ BOOL WINAPI GetTextExtentExPointW( HDC h
     /* Perform device size to world size transformations.  */
     if (ret)
     {
-	INT extra = dc->charExtra, breakRem = dc->breakRem;
+	INT extra      = dc->charExtra,
+            breakExtra = dc->breakExtra,
+            breakRem   = dc->breakRem,
+            i;
 
 	if (dxs)
 	{
-	    INT i;
 	    for (i = 0; i < count; ++i)
 	    {
 		dxs[i] = abs(INTERNAL_XDSTOWS(dc, dxs[i]));
-		dxs[i] += (i+1) * extra + breakRem;
+		dxs[i] += (i+1) * extra;
+                if (count > 1 && (breakExtra || breakRem) && str[i] == tm.tmBreakChar)
+                {
+                    dxs[i] += breakExtra;
+                    if (breakRem > 0)
+                    {
+                        breakRem--;
+                        dxs[i]++;
+                    }
+                }
 		if (dxs[i] <= maxExt)
 		    ++nFit;
 	    }
+            breakRem = dc->breakRem;
 	}
 	size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
 	size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
-	size->cx += count * extra + breakRem;
+
+        if (!dxs && count > 1 && (breakExtra || breakRem))
+        {
+            for (i = 0; i < count; i++)
+            {
+                if (str[i] == tm.tmBreakChar)
+                {
+                    size->cx += breakExtra;
+                    if (breakRem > 0)
+                    {
+                        breakRem--;
+                        (size->cx)++;
+                    }
+                }
+            }
+        }
     }
 
     if (lpnFit)
@@ -1752,9 +1782,10 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
     SIZE sz;
     RECT rc;
     BOOL done_extents = FALSE;
-    INT width, xwidth = 0, ywidth = 0;
+    INT width = 0, xwidth = 0, ywidth = 0;
     DWORD type;
     DC * dc = DC_GetDCUpdate( hdc );
+    INT breakRem = dc->breakRem;
 
     if (!dc) return FALSE;
 
@@ -1867,8 +1898,7 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
     y = pt.y;
 
     char_extra = GetTextCharacterExtra(hdc);
-    width = 0;
-    if(char_extra || dc->breakExtra || lpDx)
+    if(char_extra || dc->breakExtra || breakRem || lpDx)
     {
         UINT i;
         SIZE tmpsz;
@@ -1889,9 +1919,14 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
                 deltas[i] = tmpsz.cx;
             }
             
-            if (!(flags & ETO_GLYPH_INDEX) && dc->breakExtra && reordered_str[i] == tm.tmBreakChar)
+            if (!(flags & ETO_GLYPH_INDEX) && (dc->breakExtra || breakRem) && reordered_str[i] == tm.tmBreakChar)
             {
                 deltas[i] = deltas[i] + dc->breakExtra;
+                if (breakRem > 0)
+                {
+                    deltas[i]++;
+                    breakRem--;
+                }
             }
             deltas[i] = INTERNAL_XWSTODS(dc, deltas[i]);
             width += deltas[i];
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 5ac30a2..b78fa77 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -806,12 +806,9 @@ void testJustification(HDC hdc, PSTR str
 
     for (e = 0; e < nErrors; e++)
     {
-todo_wine
-{
         ok(error[e].width == areaWidth,
             "The output text (\"%s\") width should be %d, not %d.\n",
             error[e].extent, areaWidth, error[e].width);
-}
     }
 }
 
-- 
1.4.1


More information about the wine-patches mailing list