[4/4] gdiplus: GdipMeasureString operates internally in pixels but in/out rectangles are in device units.

Dmitry Timoshkov dmitry at baikal.ru
Wed Jul 4 00:49:15 CDT 2012


Before this patch values returned by GdipMeasureString are order of magnitude
off of the expected ones, they are pretty close now, but don't exactly match
values returned under Windows for various not related to this patch reasons,
that's why I decided to remove todo_wine and use 10% bias for comparisons.

---
 dlls/gdiplus/graphics.c       | 35 ++++++++++++++++++++++++++++++++---
 dlls/gdiplus/tests/graphics.c | 18 ++++++------------
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 2e3d0b5..1402a5c 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -4910,6 +4910,30 @@ static GpStatus measure_ranges_callback(HDC hdc,
     return stat;
 }
 
+static void rect_to_pixels(const RectF *in, const GpGraphics *graphics, RectF *out)
+{
+    REAL dpi;
+
+    GdipGetDpiX((GpGraphics *)graphics, &dpi);
+    out->X = units_to_pixels(in->X, graphics->unit, dpi);
+    out->Width = units_to_pixels(in->Width, graphics->unit, dpi);
+    GdipGetDpiY((GpGraphics *)graphics, &dpi);
+    out->Y = units_to_pixels(in->Y, graphics->unit, dpi);
+    out->Height = units_to_pixels(in->Height, graphics->unit, dpi);
+}
+
+static void rect_to_units(const RectF *in, const GpGraphics *graphics, RectF *out)
+{
+    REAL dpi;
+
+    GdipGetDpiX((GpGraphics *)graphics, &dpi);
+    out->X = pixels_to_units(in->X, graphics->unit, dpi);
+    out->Width = pixels_to_units(in->Width, graphics->unit, dpi);
+    GdipGetDpiY((GpGraphics *)graphics, &dpi);
+    out->Y = pixels_to_units(in->Y, graphics->unit, dpi);
+    out->Height = pixels_to_units(in->Height, graphics->unit, dpi);
+}
+
 GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
         GDIPCONST WCHAR* string, INT length, GDIPCONST GpFont* font,
         GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat,
@@ -5013,6 +5037,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
     struct measure_string_args args;
     HDC temp_hdc=NULL, hdc;
     GpPointF pt[3];
+    RectF rect_pixels;
 
     TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics,
         debugstr_wn(string, length), length, font, debugstr_rectf(rect), format,
@@ -5050,8 +5075,10 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
     get_font_hfont(graphics, font, &gdifont);
     oldfont = SelectObject(hdc, gdifont);
 
-    bounds->X = rect->X;
-    bounds->Y = rect->Y;
+    rect_to_pixels(rect, graphics, &rect_pixels);
+
+    bounds->X = rect_pixels.X;
+    bounds->Y = rect_pixels.Y;
     bounds->Width = 0.0;
     bounds->Height = 0.0;
 
@@ -5059,9 +5086,11 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
     args.codepointsfitted = codepointsfitted;
     args.linesfilled = linesfilled;
 
-    gdip_format_string(hdc, string, length, font, rect, format,
+    gdip_format_string(hdc, string, length, font, &rect_pixels, format,
         measure_string_callback, &args);
 
+    rect_to_units(bounds, graphics, bounds);
+
     SelectObject(hdc, oldfont);
     DeleteObject(gdifont);
 
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 8986708..7c53ced 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -3350,10 +3350,8 @@ static void test_GdipMeasureString(void)
         expect(Ok, status);
         expectf(0.0, bounds.X);
         expectf(0.0, bounds.Y);
-todo_wine
-        expectf(102.499985, bounds.Width);
-todo_wine
-        expectf(31.968744, bounds.Height);
+        expectf_(102.499985, bounds.Width, 11.5);
+        expectf_(31.968744, bounds.Height, 3.1);
     }
     else
         skip("screen resolution %f dpi, test runs at 96 dpi\n", dpi);
@@ -3372,10 +3370,8 @@ todo_wine
     expect(Ok, status);
     expectf(0.0, bounds.X);
     expectf(0.0, bounds.Y);
-todo_wine
-    expectf(76.875000, bounds.Width);
-todo_wine
-    expectf(23.976563, bounds.Height);
+    expectf_(76.875000, bounds.Width, 10.0);
+    expectf_(23.976563, bounds.Height, 2.1);
 
     status = GdipSetPageUnit(graphics, UnitMillimeter);
     expect(Ok, status);
@@ -3391,10 +3387,8 @@ todo_wine
     expect(Ok, status);
     expectf(0.0, bounds.X);
     expectf(0.0, bounds.Y);
-todo_wine
-    expectf(27.119789, bounds.Width);
-todo_wine
-    expectf(8.458398, bounds.Height);
+    expectf_(27.119789, bounds.Width, 2.7);
+    expectf_(8.458398, bounds.Height, 0.8);
 
     GdipDeleteStringFormat(format);
     GdipDeleteFont(font);
-- 
1.7.11.1




More information about the wine-patches mailing list