Vincent Povirk : gdiplus: GdipDrawString: Handle either a width or height of 0 sanely.

Alexandre Julliard julliard at winehq.org
Thu Apr 2 10:42:41 CDT 2009


Module: wine
Branch: master
Commit: 0879b767aef1d295083dcb448fcc63ef2c00364b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0879b767aef1d295083dcb448fcc63ef2c00364b

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Wed Apr  1 14:08:12 2009 -0500

gdiplus: GdipDrawString: Handle either a width or height of 0 sanely.

Based on Aric's recent patch.

---

 dlls/gdiplus/graphics.c       |   27 ++++++++++++++++----
 dlls/gdiplus/tests/graphics.c |   52 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 5d1cbd6..2a98ee5 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -2011,20 +2011,35 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
     rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
     transform_and_round_points(graphics, corners, rectcpy, 4);
 
-    if(roundr(rect->Width) == 0 && roundr(rect->Height) == 0){
-        rel_width = rel_height = 1.0;
-        nwidth = nheight = INT_MAX;
+    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)
+    {
+        rel_height = 1.0;
+        nheight = INT_MAX;
+    }
+    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;
-
-        nwidth = roundr(rel_width * rect->Width);
         nheight = roundr(rel_height * rect->Height);
+    }
+
+    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);
     }
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 8091a9a..7199151 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -935,6 +935,57 @@ static void test_textcontrast(void)
     ReleaseDC(0, hdc);
 }
 
+static void test_GdipDrawString(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpFont *fnt = NULL;
+    RectF  rect;
+    GpStringFormat *format;
+    GpBrush *brush;
+    LOGFONTA logfont;
+    HDC hdc = GetDC(0);
+    static const WCHAR string[] = {'T','e','s','t',0};
+
+    memset(&logfont,0,sizeof(logfont));
+    strcpy(logfont.lfFaceName,"Arial");
+    logfont.lfHeight = 12;
+    logfont.lfCharSet = DEFAULT_CHARSET;
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+
+    status = GdipCreateFontFromLogfontA(hdc, &logfont, &fnt);
+    if (status == FileNotFound)
+    {
+        skip("Arial not installed.\n");
+        return;
+    }
+    expect(Ok, status);
+
+    status = GdipCreateSolidFill((ARGB)0xdeadbeef, (GpSolidFill**)&brush);
+    expect(Ok, status);
+
+    status = GdipCreateStringFormat(0,0,&format);
+    expect(Ok, status);
+
+    rect.X = 0;
+    rect.Y = 0;
+    rect.Width = 0;
+    rect.Height = 12;
+
+    status = GdipDrawString(graphics, string, 4, fnt, &rect, format, brush);
+    expect(Ok, status);
+
+    GdipDeleteGraphics(graphics);
+    GdipDeleteBrush(brush);
+    GdipDeleteFont(fnt);
+    GdipDeleteStringFormat(format);
+
+    ReleaseDC(0, hdc);
+}
+
+
 START_TEST(graphics)
 {
     struct GdiplusStartupInput gdiplusStartupInput;
@@ -954,6 +1005,7 @@ START_TEST(graphics)
     test_GdipDrawArcI();
     test_GdipDrawLineI();
     test_GdipDrawLinesI();
+    test_GdipDrawString();
     test_Get_Release_DC();
     test_transformpoints();
     test_get_set_clip();




More information about the wine-cvs mailing list