Vincent Povirk : gdiplus: Don' t settle on a font size until absolutely necessary.

Alexandre Julliard julliard at winehq.org
Tue Apr 5 11:23:30 CDT 2011


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Mon Apr  4 17:18:23 2011 -0500

gdiplus: Don't settle on a font size until absolutely necessary.

When we create a new font, we should store its height in a REAL field so
we don't have to round it. Further, when we calculate the width, we should
base the calculation on the metrics of a font at the height we will use, to
prevent rounding errors when the graphics transform will enlarge the font.

---

 dlls/gdiplus/font.c            |   18 +++++++++---------
 dlls/gdiplus/gdiplus_private.h |    1 +
 dlls/gdiplus/graphics.c        |    8 +++++---
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c
index 54accd7..3624391 100644
--- a/dlls/gdiplus/font.c
+++ b/dlls/gdiplus/font.c
@@ -126,27 +126,27 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
     {
         case UnitWorld:
             /* FIXME: Figure out when World != Pixel */
-            lfw->lfHeight = emSize; break;
+            (*font)->pixel_size = emSize; break;
         case UnitDisplay:
             FIXME("Unknown behavior for UnitDisplay! Please report!\n");
             /* FIXME: Figure out how this works...
              * MSDN says that if "DISPLAY" is a monitor, then pixel should be
              * used. That's not what I got. Tests on Windows revealed no output,
              * and the tests in tests/font crash windows */
-            lfw->lfHeight = 0; break;
+            (*font)->pixel_size = 0; break;
         case UnitPixel:
-            lfw->lfHeight = emSize; break;
+            (*font)->pixel_size = emSize; break;
         case UnitPoint:
-            lfw->lfHeight = point_to_pixel(emSize); break;
+            (*font)->pixel_size = point_to_pixel(emSize); break;
         case UnitInch:
-            lfw->lfHeight = inch_to_pixel(emSize); break;
+            (*font)->pixel_size = inch_to_pixel(emSize); break;
         case UnitDocument:
-            lfw->lfHeight = document_to_pixel(emSize); break;
+            (*font)->pixel_size = document_to_pixel(emSize); break;
         case UnitMillimeter:
-            lfw->lfHeight = mm_to_pixel(emSize); break;
+            (*font)->pixel_size = mm_to_pixel(emSize); break;
     }
 
-    lfw->lfHeight *= -1;
+    lfw->lfHeight = (*font)->pixel_size * -1;
 
     lfw->lfWeight = style & FontStyleBold ? 700 : 400;
     lfw->lfItalic = style & FontStyleItalic;
@@ -190,7 +190,7 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     (*font)->lfw.lfUnderline = logfont->lfUnderline;
     (*font)->lfw.lfStrikeOut = logfont->lfStrikeOut;
 
-    (*font)->emSize = logfont->lfHeight;
+    (*font)->pixel_size = (*font)->emSize = logfont->lfHeight;
     (*font)->unit = UnitPixel;
 
     hfont = CreateFontIndirectW(&(*font)->lfw);
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 380c22d..1629ae6 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -323,6 +323,7 @@ struct GpImageAttributes{
 struct GpFont{
     LOGFONTW lfw;
     REAL emSize;
+    REAL pixel_size;
     UINT height;
     LONG line_spacing;
     Unit unit;
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index d7cc644..5ba3a4f 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -1677,14 +1677,16 @@ void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font, HFONT *hfont)
     rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
                       (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
 
-    unscaled_font = CreateFontIndirectW(&font->lfw);
+    lfw = font->lfw;
+    lfw.lfHeight = roundr(-font->pixel_size * rel_height);
+    unscaled_font = CreateFontIndirectW(&lfw);
 
     SelectObject(hdc, unscaled_font);
     GetTextMetricsW(hdc, &textmet);
 
     lfw = font->lfw;
-    lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height);
-    lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width);
+    lfw.lfHeight = roundr(-font->pixel_size * rel_height);
+    lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width / rel_height);
     lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0);
 
     *hfont = CreateFontIndirectW(&lfw);




More information about the wine-cvs mailing list