Added support for string alignment in GdipDrawString

Stephan Rose kermos at somrek.net
Tue Jun 2 06:54:04 CDT 2009


---
 dlls/gdiplus/graphics.c |   48 +++++++++++++++++++++++++++++++---------------
 1 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index adeea3c..b4718a7 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -2045,7 +2045,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
     POINT corners[4];
     WCHAR* stringdup;
     REAL angle, ang_cos, ang_sin, rel_width, rel_height;
-    INT sum = 0, height = 0, fit, fitcpy, save_state, i, j, lret, nwidth,
+    INT sum = 0, height = 0, alignflags = 0, offsety = 0, fit, fitcpy, save_state, i, j, lret, nwidth,
         nheight;
     SIZE size;
     RECT drawcoord;
@@ -2061,9 +2061,27 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
         return NotImplemented;
     }
 
-    if(format)
+    if(format){
         TRACE("may be ignoring some format flags: attr %x\n", format->attr);
 
+        /* Should be no need to explicitly test for StringAlignmentNear as
+         * that is default behavior if no alignment is passed. */
+        if(format->align == StringAlignmentCenter)
+            alignflags = DT_CENTER;
+        else if(format->align == StringAlignmentFar)
+            alignflags = DT_RIGHT;
+
+        if(format->vertalign != StringAlignmentNear){
+            RectF bounds;
+            GdipMeasureString(graphics, string, length, font, rect, format, &bounds, 0, 0);
+
+            if(format->vertalign == StringAlignmentCenter)
+                offsety = (rect->Height - bounds.Height) / 2;
+            else if(format->vertalign == StringAlignmentFar)
+                offsety = (rect->Height - bounds.Height);
+        }
+    }
+
     if(length == -1) length = lstrlenW(string);
 
     stringdup = GdipAlloc(length * sizeof(WCHAR));
@@ -2074,39 +2092,34 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
     SetTextColor(graphics->hdc, brush->lb.lbColor);
 
     rectcpy[3].X = rectcpy[0].X = rect->X;
-    rectcpy[1].Y = rectcpy[0].Y = rect->Y;
+    rectcpy[1].Y = rectcpy[0].Y = rect->Y + offsety;
     rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
-    rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
+    rectcpy[3].Y = rectcpy[2].Y = rect->Y + offsety + rect->Height;
     transform_and_round_points(graphics, corners, rectcpy, 4);
 
-    if (roundr(rect->Width) == 0)
-    {
+    if (roundr(rect->Width) == 0){
         rel_width = 1.0;
         nwidth = INT_MAX;
     }
-    else
-    {
+    else{
         rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) +
                          (corners[1].y - corners[0].y) * (corners[1].y - corners[0].y))
                          / rect->Width;
         nwidth = roundr(rel_width * rect->Width);
     }
 
-    if (roundr(rect->Height) == 0)
-    {
+    if (roundr(rect->Height) == 0){
         rel_height = 1.0;
         nheight = INT_MAX;
     }
-    else
-    {
+    else{
         rel_height = sqrt((corners[2].x - corners[1].x) * (corners[2].x - corners[1].x) +
                           (corners[2].y - corners[1].y) * (corners[2].y - corners[1].y))
                           / rect->Height;
         nheight = roundr(rel_height * rect->Height);
     }
 
-    if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0)
-    {
+    if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0){
         /* FIXME: If only the width or only the height is 0, we should probably still clip */
         rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
         SelectClipRgn(graphics->hdc, rgn);
@@ -2148,13 +2161,16 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
         drawcoord.left = corners[0].x + roundr(ang_sin * (REAL) height);
         drawcoord.top = corners[0].y + roundr(ang_cos * (REAL) height);
 
+        /* Don't forget about right hand and side for horizontal alignment */
+        drawcoord.right = corners[1].x + roundr(ang_sin * (REAL) height);
+
         GetTextExtentExPointW(graphics->hdc, stringdup + sum, length - sum,
                               nwidth, &fit, NULL, &size);
         fitcpy = fit;
 
         if(fit == 0){
             DrawTextW(graphics->hdc, stringdup + sum, 1, &drawcoord, DT_NOCLIP |
-                      DT_EXPANDTABS);
+                      DT_EXPANDTABS | alignflags);
             break;
         }
 
@@ -2183,7 +2199,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
                 }
         }
         DrawTextW(graphics->hdc, stringdup + sum, min(length - sum, fit),
-                  &drawcoord, DT_NOCLIP | DT_EXPANDTABS);
+                  &drawcoord, DT_NOCLIP | DT_EXPANDTABS | alignflags);
 
         sum += fit + (lret < fitcpy ? 1 : 0);
         height += size.cy;
-- 
1.6.0.4


--=-quUZqu8SyMekY+lQGqZH--




More information about the wine-patches mailing list