From 80770f323aa30eebfd09606e53074e9969f48de0 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 4 Apr 2011 17:18:23 -0500 Subject: [PATCH 3/4] 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 | 16 ++++++++-------- dlls/gdiplus/gdiplus_private.h | 1 + dlls/gdiplus/graphics.c | 8 +++++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index 54accd7..58a2252 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; 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); -- 1.7.1