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