SetTextJustification() patch (resend)

Keith Dunwoody kstephen at interchange.ubc.ca
Wed Jun 1 22:57:13 CDT 2005


Hi,

I think yahoo mangled this patch the first time, here's try two:

SetTextJustification() didn't match the Windows function, because it
failed to distribute all the extra space requested between the breaks.
Originally the same amount of extra space was added to each break
character when using SetTextJustification().  With this patch, the
amount of extra space changes slightly, so that the amount of extra
space more closely matches the amount requested by SetTextJustification
(). 

2005-05-25  Keith Dunwoody <keithdunwoody at yahoo.com>
    * Fixed text justification. (Fixes bug: #50)


Index: dlls/gdi/dc.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/dc.c,v
retrieving revision 1.10
diff -u -p -r1.10 dc.c
--- dlls/gdi/dc.c       25 Apr 2005 16:02:27 -0000      1.10
+++ dlls/gdi/dc.c       30 May 2005 02:28:45 -0000
@@ -105,8 +105,8 @@ DC *DC_AllocDC( const DC_FUNCTIONS *func
     dc->brushOrgY           = 0;
     dc->textAlign           = TA_LEFT | TA_TOP | TA_NOUPDATECP;
     dc->charExtra           = 0;
-    dc->breakExtra          = 0;
-    dc->breakRem            = 0;
+    dc->breakTotalExtra     = 0;
+    dc->breakCount          = 0;
     dc->MapMode             = MM_TEXT;
     dc->GraphicsMode        = GM_COMPATIBLE;
     dc->pAbortProc          = NULL;
@@ -317,8 +317,8 @@ HDC WINAPI GetDCState( HDC hdc )
     newdc->brushOrgY        = dc->brushOrgY;
     newdc->textAlign        = dc->textAlign;
     newdc->charExtra        = dc->charExtra;
-    newdc->breakExtra       = dc->breakExtra;
-    newdc->breakRem         = dc->breakRem;
+    newdc->breakTotalExtra  = dc->breakTotalExtra;
+    newdc->breakCount         = dc->breakCount;
     newdc->MapMode          = dc->MapMode;
     newdc->GraphicsMode     = dc->GraphicsMode;
     newdc->CursPosX         = dc->CursPosX;
@@ -415,8 +415,8 @@ void WINAPI SetDCState( HDC hdc, HDC hdc
     dc->brushOrgY        = dcs->brushOrgY;
     dc->textAlign        = dcs->textAlign;
     dc->charExtra        = dcs->charExtra;
-    dc->breakExtra       = dcs->breakExtra;
-    dc->breakRem         = dcs->breakRem;
+    dc->breakTotalExtra  = dcs->breakTotalExtra;
+    dc->breakCount       = dcs->breakCount;
     dc->MapMode          = dcs->MapMode;
     dc->GraphicsMode     = dcs->GraphicsMode;
     dc->CursPosX         = dcs->CursPosX;
Index: dlls/gdi/font.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/font.c,v
retrieving revision 1.10
diff -u -p -r1.10 font.c
--- dlls/gdi/font.c     18 Apr 2005 10:30:56 -0000      1.10
+++ dlls/gdi/font.c     30 May 2005 02:28:46 -0000
@@ -973,17 +973,9 @@ BOOL WINAPI SetTextJustification( HDC hd
     else
     {
         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
-        if (!extra) breaks = 0;
-        if (breaks)
-        {
-            dc->breakExtra = extra / breaks;
-            dc->breakRem   = extra - (breaks * dc->breakExtra);
-        }
-        else
-        {
-            dc->breakExtra = 0;
-            dc->breakRem   = 0;
-        }
+        if (!extra) { breaks = 0; dc->breakTotalExtra = 0; }
+       dc->breakTotalExtra += extra;
+       dc->breakCount   = breaks;
     }
     GDI_ReleaseObj( hdc );
     return ret;
@@ -1090,7 +1082,7 @@ BOOL WINAPI GetTextExtentPoint32W(
     {
        size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
        size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
-        size->cx += count * dc->charExtra + dc->breakRem;
+        size->cx += dc->breakTotalExtra;
     }

     GDI_ReleaseObj( hdc );
@@ -1740,11 +1732,11 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x,
                               lpReorderedString, count, NULL );

                 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
-                                             lprect,lpReorderedString,count,lpDx,dc->breakExtra);
+                                             lprect,lpReorderedString,count,lpDx, &dc->breakTotalExtra, &dc->breakCount);
                 HeapFree(GetProcessHeap(), 0, lpReorderedString);
             } else
                 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,
-                                             lpDx,dc->breakExtra);
+                                             lpDx, &dc->breakTotalExtra, &dc->breakCount);
         }
         GDI_ReleaseObj( hdc );
     }
Index: dlls/gdi/gdi_private.h
===================================================================
RCS file: /home/wine/wine/dlls/gdi/gdi_private.h,v
retrieving revision 1.25
diff -u -p -r1.25 gdi_private.h
--- dlls/gdi/gdi_private.h      13 Apr 2005 16:11:18 -0000      1.25
+++ dlls/gdi/gdi_private.h      30 May 2005 02:28:46 -0000
@@ -82,7 +82,7 @@ typedef struct tagDC_FUNCS
     INT      (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
     BOOL     (*pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
     INT      (*pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
-    BOOL     (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*,INT);
+    BOOL     (*pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*,INT*, INT*);
     BOOL     (*pFillPath)(PHYSDEV);
     BOOL     (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
     BOOL     (*pFlattenPath)(PHYSDEV);
@@ -257,8 +257,8 @@ typedef struct tagDC

     WORD          textAlign;         /* Text alignment from SetTextAlign() */
     INT           charExtra;         /* Spacing from SetTextCharacterExtra() */
-    INT           breakExtra;        /* breakTotalExtra / breakCount */
-    INT           breakRem;          /* breakTotalExtra % breakCount */
+    INT           breakTotalExtra;     /* Total amount of extra pixels */
+    INT           breakCount;          /* Number of breaks to divide it into */
     INT           MapMode;
     INT           GraphicsMode;      /* Graphics mode */
     ABORTPROC     pAbortProc;        /* AbortProc for Printing */
Index: dlls/gdi/enhmfdrv/enhmetafiledrv.h
===================================================================
RCS file: /home/wine/wine/dlls/gdi/enhmfdrv/enhmetafiledrv.h,v
retrieving revision 1.18
diff -u -p -r1.18 enhmetafiledrv.h
--- dlls/gdi/enhmfdrv/enhmetafiledrv.h  4 Mar 2004 20:41:13 -0000       1.18
+++ dlls/gdi/enhmfdrv/enhmetafiledrv.h  30 May 2005 02:28:46 -0000
@@ -78,7 +78,7 @@ extern BOOL     EMFDRV_ExtFloodFill( PHY
 extern INT      EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode );
 extern BOOL     EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
                                    UINT flags, const RECT *lprect, LPCWSTR str,
-                                   UINT count, const INT *lpDx, INT breakExtra );
+                                   UINT count, const INT *lpDx, INT *breakTotalExtra, INT *breakCount );
 extern BOOL     EMFDRV_FillPath( PHYSDEV dev );
 extern BOOL     EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
 extern BOOL     EMFDRV_FlattenPath( PHYSDEV dev );
Index: dlls/gdi/enhmfdrv/graphics.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/enhmfdrv/graphics.c,v
retrieving revision 1.16
diff -u -p -r1.16 graphics.c
--- dlls/gdi/enhmfdrv/graphics.c        21 Dec 2004 14:49:19 -0000      1.16
+++ dlls/gdi/enhmfdrv/graphics.c        30 May 2005 02:28:47 -0000
@@ -710,7 +710,7 @@ EMFDRV_SetTextColor( PHYSDEV dev, COLORR
  */
 BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
                        const RECT *lprect, LPCWSTR str, UINT count,
-                       const INT *lpDx, INT breakExtra )
+                       const INT *lpDx, INT *breakTotalExtra, INT *breakCount )
 {
     EMREXTTEXTOUTW *pemr;
     DWORD nSize;
Index: dlls/gdi/mfdrv/metafiledrv.h
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/metafiledrv.h,v
retrieving revision 1.14
diff -u -p -r1.14 metafiledrv.h
--- dlls/gdi/mfdrv/metafiledrv.h        4 Mar 2004 20:41:13 -0000       1.14
+++ dlls/gdi/mfdrv/metafiledrv.h        30 May 2005 02:28:47 -0000
@@ -84,7 +84,7 @@ extern BOOL MFDRV_ExtFloodFill( PHYSDEV
 extern INT  MFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode );
 extern BOOL MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y,
                               UINT flags, const RECT *lprect, LPCWSTR str,
-                              UINT count, const INT *lpDx, INT breakExtra );
+                              UINT count, const INT *lpDx, INT *breakTotalExtra, INT *breakCount);
 extern BOOL MFDRV_FillPath( PHYSDEV dev );
 extern BOOL MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush );
 extern BOOL MFDRV_FlattenPath( PHYSDEV dev );
Index: dlls/gdi/mfdrv/text.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/text.c,v
retrieving revision 1.12
diff -u -p -r1.12 text.c
--- dlls/gdi/mfdrv/text.c       23 Dec 2004 18:41:05 -0000      1.12
+++ dlls/gdi/mfdrv/text.c       30 May 2005 02:28:47 -0000
@@ -74,7 +74,7 @@ static BOOL MFDRV_MetaExtTextOut( PHYSDE
 BOOL
 MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
                   const RECT *lprect, LPCWSTR str, UINT count,
-                  const INT *lpDx, INT breakExtra )
+                  const INT *lpDx, INT *breakTotalExtra, INT *breakCount )
 {
     RECT16     rect16;
     LPINT16    lpdx16 = NULL;
Index: dlls/ttydrv/graphics.c
===================================================================
RCS file: /home/wine/wine/dlls/ttydrv/graphics.c,v
retrieving revision 1.16
diff -u -p -r1.16 graphics.c
--- dlls/ttydrv/graphics.c      4 Mar 2004 01:42:57 -0000       1.16
+++ dlls/ttydrv/graphics.c      30 May 2005 02:28:48 -0000
@@ -338,7 +338,7 @@ BOOL TTYDRV_DC_StretchBlt(TTYDRV_PDEVICE
  */
 BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                          const RECT *lpRect, LPCWSTR str, UINT count,
-                         const INT *lpDx, INT breakExtra )
+                         const INT *lpDx, INT *breakTotalExtra, INT *breakCount )
 {
 #ifdef WINE_CURSES
   INT row, col;
Index: dlls/ttydrv/ttydrv.h
===================================================================
RCS file: /home/wine/wine/dlls/ttydrv/ttydrv.h,v
retrieving revision 1.27
diff -u -p -r1.27 ttydrv.h
--- dlls/ttydrv/ttydrv.h        9 Dec 2004 11:45:16 -0000       1.27
+++ dlls/ttydrv/ttydrv.h        30 May 2005 02:28:48 -0000
@@ -76,7 +76,7 @@ extern BOOL TTYDRV_DC_BitBlt(TTYDRV_PDEV
 extern BOOL TTYDRV_DC_Chord(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
 extern BOOL TTYDRV_DC_Ellipse(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom);
 extern BOOL TTYDRV_DC_ExtFloodFill(TTYDRV_PDEVICE *physDev, INT x, INT y, COLORREF color, UINT fillType);
-extern BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lpRect, LPCWSTR str, UINT count, const INT *lpDx, INT breakExtra);
+extern BOOL TTYDRV_DC_ExtTextOut(TTYDRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lpRect, LPCWSTR str, UINT count, const INT *lpDx, INT *breakTotalExtra, INT *breakCount);
 extern BOOL TTYDRV_DC_GetCharWidth(TTYDRV_PDEVICE *physDev, UINT firstChar, UINT lastChar, LPINT buffer);
 extern COLORREF TTYDRV_DC_GetPixel(TTYDRV_PDEVICE *physDev, INT x, INT y);

Index: dlls/wineps/psdrv.h
===================================================================
RCS file: /home/wine/wine/dlls/wineps/psdrv.h,v
retrieving revision 1.56
diff -u -p -r1.56 psdrv.h
--- dlls/wineps/psdrv.h 6 May 2005 20:02:36 -0000       1.56
+++ dlls/wineps/psdrv.h 30 May 2005 02:28:49 -0000
@@ -469,7 +469,7 @@ extern INT PSDRV_EndDoc( PSDRV_PDEVICE *
 extern INT PSDRV_EndPage( PSDRV_PDEVICE *physDev );
 extern BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                                const RECT *lprect, LPCWSTR str, UINT count,
-                               const INT *lpDx, INT breakExtra );
+                               const INT *lpDx, INT *breakTotalExtra, INT *breakCount );
 extern BOOL PSDRV_GetCharWidth( PSDRV_PDEVICE *physDev, UINT firstChar, UINT lastChar,
                                  LPINT buffer );
 extern BOOL PSDRV_GetTextExtentPoint( PSDRV_PDEVICE *physDev, LPCWSTR str, INT count,
Index: dlls/wineps/text.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/text.c,v
retrieving revision 1.24
diff -u -p -r1.24 text.c
--- dlls/wineps/text.c  22 Sep 2004 02:46:39 -0000      1.24
+++ dlls/wineps/text.c  30 May 2005 02:28:49 -0000
@@ -40,7 +40,7 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *ph
  */
 BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                       const RECT *lprect, LPCWSTR str, UINT count,
-                      const INT *lpDx, INT breakExtra )
+                      const INT *lpDx, INT *breakTotalExtra, INT *breakCount )
 {
     BOOL bResult = TRUE;
     BOOL bClipped = FALSE;
Index: dlls/x11drv/text.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/text.c,v
retrieving revision 1.15
diff -u -p -r1.15 text.c
--- dlls/x11drv/text.c  23 Dec 2004 20:31:56 -0000      1.15
+++ dlls/x11drv/text.c  30 May 2005 02:28:49 -0000
@@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(text);
 BOOL
 X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                    const RECT *lprect, LPCWSTR wstr, UINT count,
-                   const INT *lpDx, INT breakExtra )
+                   const INT *lpDx, INT *breakTotalExtra, INT *breakCount )
 {
     unsigned int i;
     fontObject*                pfo;
@@ -60,7 +60,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physD
     INT                 charExtra;

     if(physDev->has_gdi_font)
-        return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx, breakExtra);
+        return X11DRV_XRender_ExtTextOut(physDev, x, y, flags, lprect, wstr, count, lpDx, breakTotalExtra, breakCount);

     if (!X11DRV_SetupGCForText( physDev )) return TRUE;

@@ -269,7 +269,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physD
     wine_tsx11_unlock();
     if(!rotated)
     {
-      if (!charExtra && !breakExtra && !lpDx)
+      if (!charExtra && !*breakCount && !lpDx)
       {
         X11DRV_cptable[pfo->fi->cptable].pDrawString(
                pfo, gdi_display, physDev->drawable, physDev->gc,
@@ -322,7 +322,7 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physD
                err = LOWORD(fSum);
           }
        }
-       else /* charExtra or breakExtra */
+       else /* charExtra or breakTotalExtra */
        {
             while (i < count)
             {
@@ -335,8 +335,10 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physD
                do
                 {
                     delta += charExtra;
-                    if (str2b[i].byte2 == (char)dfBreakChar)
-                     delta += breakExtra;
+                    if (str2b[i].byte2 == (char)dfBreakChar && *breakCount) {
+                     delta += *breakTotalExtra / *breakCount;
+                     *breakTotalExtra -= *breakTotalExtra / (*breakCount)--;
+                   }
                    pitem->nchars++;
                 } while ((++i < count) && !delta);
                pitem++;
@@ -378,8 +380,10 @@ X11DRV_ExtTextOut( X11DRV_PDEVICE *physD
                              font->min_bounds.attributes)
                          * pfo->lpX11Trans->pixelsize / 1000.0;
          offset += charExtra;
-         if (str2b[i].byte2 == (char)dfBreakChar)
-           offset += breakExtra;
+         if (str2b[i].byte2 == (char)dfBreakChar && *breakCount) {
+           offset += *breakTotalExtra / *breakCount;
+           *breakTotalExtra -= *breakTotalExtra / (*breakCount)--;
+         }
        }
       }
     }
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.72
diff -u -p -r1.72 x11drv.h
--- dlls/x11drv/x11drv.h        21 Apr 2005 17:31:50 -0000      1.72
+++ dlls/x11drv/x11drv.h        30 May 2005 02:28:50 -0000
@@ -212,7 +212,8 @@ extern BOOL X11DRV_ExtFloodFill( X11DRV_
                                   COLORREF color, UINT fillType );
 extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y,
                                 UINT flags, const RECT *lprect,
-                                LPCWSTR str, UINT count, const INT *lpDx, INT breakExtra );
+                                LPCWSTR str, UINT count, const INT *lpDx,
+                              INT *breakTotalExtra, INT *breakCount );
 extern LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count );
 extern void X11DRV_SetDeviceClipping( X11DRV_PDEVICE *physDev, HRGN vis_rgn, HRGN clip_rgn );
 extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest,
@@ -272,7 +273,8 @@ extern BOOL X11DRV_XRender_SelectFont(X1
 extern void X11DRV_XRender_DeleteDC(X11DRV_PDEVICE*);
 extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                                      const RECT *lprect, LPCWSTR wstr,
-                                     UINT count, const INT *lpDx, INT breakExtra);
+                                     UINT count, const INT *lpDx,
+                                     INT *breakTotalExtra, INT *breakCount);
 extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);

 extern void X11DRV_OpenGL_Init(Display *display);
Index: dlls/x11drv/xrender.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/xrender.c,v
retrieving revision 1.63
diff -u -p -r1.63 xrender.c
--- dlls/x11drv/xrender.c       20 Apr 2005 15:18:42 -0000      1.63
+++ dlls/x11drv/xrender.c       30 May 2005 02:28:50 -0000
@@ -1004,7 +1004,8 @@ static int XRenderErrorHandler(Display *
  */
 BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                                const RECT *lprect, LPCWSTR wstr, UINT count,
-                               const INT *lpDx, INT breakExtra )
+                               const INT *lpDx, INT *breakTotalExtra,
+                               INT *breakCount )
 {
     XRenderColor col;
     unsigned int idx;
@@ -1141,7 +1142,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_P
     TRACE("real x,y %d,%d\n", x, y);

     char_extra = GetTextCharacterExtra(hdc);
-    if(char_extra || breakExtra) {
+    if(char_extra || *breakCount) {
         UINT i;
        SIZE tmpsz;
         deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
@@ -1153,8 +1154,9 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_P
                deltas[i] = tmpsz.cx;
            }

-            if (breakExtra && wstr[i] == tm.tmBreakChar) {
-                deltas[i] = deltas[i] + breakExtra;
+            if (*breakCount && wstr[i] == tm.tmBreakChar) {
+                deltas[i] += *breakTotalExtra / *breakCount;
+               *breakTotalExtra -= *breakTotalExtra / (*breakCount)--;
             }
        }
     } else if(lpDx)
@@ -1776,7 +1778,8 @@ void X11DRV_XRender_DeleteDC(X11DRV_PDEV

 BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags,
                                const RECT *lprect, LPCWSTR wstr, UINT count,
-                               const INT *lpDx, INT breakExtra )
+                               const INT *lpDx, INT *breakTotalExtra,
+                               INT *breakCount )
 {
   assert(0);
   return FALSE;






More information about the wine-patches mailing list