Dmitry Timoshkov : gdiplus: get_font_hfont helper should transform returned font height using font and device unit /resolution/scale.

Alexandre Julliard julliard at winehq.org
Tue Aug 14 12:59:53 CDT 2012


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

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Thu Aug  9 12:55:19 2012 +0900

gdiplus: get_font_hfont helper should transform returned font height using font and device unit/resolution/scale.

---

 dlls/gdiplus/gdiplus.c         |    6 ++++++
 dlls/gdiplus/gdiplus_private.h |    1 +
 dlls/gdiplus/graphics.c        |   20 ++++++++++++++++++--
 dlls/gdiplus/tests/graphics.c  |   29 +++++++++++++++++++++--------
 4 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c
index ed2dcae..0146a0f 100644
--- a/dlls/gdiplus/gdiplus.c
+++ b/dlls/gdiplus/gdiplus.c
@@ -389,6 +389,12 @@ REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi)
     }
 }
 
+REAL units_scale(GpUnit from, GpUnit to, REAL dpi)
+{
+    REAL pixels = units_to_pixels(1.0, from, dpi);
+    return pixels_to_units(pixels, to, dpi);
+}
+
 /* Calculates Bezier points from cardinal spline points. */
 void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
     REAL *y1, REAL *x2, REAL *y2)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 0c7e055..ac070fe 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -51,6 +51,7 @@ extern GpStatus hresult_to_status(HRESULT res) DECLSPEC_HIDDEN;
 extern REAL convert_unit(REAL logpixels, GpUnit unit) DECLSPEC_HIDDEN;
 extern REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi) DECLSPEC_HIDDEN;
 extern REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi) DECLSPEC_HIDDEN;
+extern REAL units_scale(GpUnit from, GpUnit to, REAL dpi) DECLSPEC_HIDDEN;
 
 extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
 
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 101b73a..41034e5 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -2115,11 +2115,27 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *
 {
     HDC hdc = CreateCompatibleDC(0);
     GpPointF pt[3];
-    REAL angle, rel_width, rel_height;
+    REAL angle, rel_width, rel_height, font_height, font_to_pixel_scale;
     LOGFONTW lfw;
     HFONT unscaled_font;
     TEXTMETRICW textmet;
 
+    font_to_pixel_scale = units_scale(UnitPoint, UnitPixel, font->family->dpi);
+
+    if (font->unit == UnitPixel)
+        font_height = font->emSize * font_to_pixel_scale;
+    else
+    {
+        REAL unit_scale, res;
+
+        res = (graphics->unit == UnitDisplay || graphics->unit == UnitPixel) ? graphics->xres : graphics->yres;
+        unit_scale = units_scale(font->unit, graphics->unit, res);
+
+        font_height = font->emSize * font_to_pixel_scale * unit_scale;
+        if (graphics->unit != UnitDisplay)
+            font_height /= graphics->scale;
+    }
+
     pt[0].X = 0.0;
     pt[0].Y = 0.0;
     pt[1].X = 1.0;
@@ -2135,7 +2151,7 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *
                       (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
 
     get_log_fontW(font, graphics, &lfw);
-    lfw.lfHeight = roundr(lfw.lfHeight * rel_height);
+    lfw.lfHeight = roundr(font_height * rel_height);
     unscaled_font = CreateFontIndirectW(&lfw);
 
     SelectObject(hdc, unscaled_font);
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 5f1213c..fb0c1cd 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -3495,14 +3495,6 @@ static void test_GdipMeasureString(void)
             base_cy = bounds.Height;
         }
 
-        /* FIXME: remove once Wine is fixed */
-        if (fabs(height - bounds.Height) > height / 100.0)
-        {
-            /* further testing is useless */
-            GdipDeleteGraphics(graphics);
-            continue;
-        }
-
         expectf(0.0, bounds.X);
         expectf(0.0, bounds.Y);
         expectf_(height, bounds.Height, height / 100.0);
@@ -3521,6 +3513,13 @@ static void test_GdipMeasureString(void)
         expect(Ok, status);
         expectf(50.0, bounds.X);
         expectf(50.0, bounds.Y);
+        /* FIXME: remove once Wine is fixed */
+        if (fabs(height - bounds.Height) > height / 100.0)
+        {
+            /* further testing is useless */
+            GdipDeleteGraphics(graphics);
+            continue;
+        }
         expectf_(height, bounds.Height, height / 100.0);
         expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
         expect(7, chars);
@@ -3595,6 +3594,13 @@ static void test_GdipMeasureString(void)
 
             expectf(0.0, bounds.X);
             expectf(0.0, bounds.Y);
+            /* FIXME: remove once Wine is fixed */
+            if (fabs(height - bounds.Height) > height / 85.0)
+            {
+                /* further testing is useless */
+                GdipDeleteGraphics(graphics);
+                continue;
+            }
             expectf_(height, bounds.Height, height / 85.0);
             expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
             expect(7, chars);
@@ -3611,6 +3617,13 @@ static void test_GdipMeasureString(void)
             expect(Ok, status);
             expectf(50.0, bounds.X);
             expectf(50.0, bounds.Y);
+            /* FIXME: remove once Wine is fixed */
+            if (fabs(height - bounds.Height) > height / 85.0)
+            {
+                /* further testing is useless */
+                GdipDeleteGraphics(graphics);
+                continue;
+            }
             expectf_(height, bounds.Height, height / 85.0);
             expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
             expect(7, chars);




More information about the wine-cvs mailing list