From e43fce0da93058eabd83a5a1e4f774ddb0f7ff30 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Tue, 24 Apr 2012 17:02:59 +0900 Subject: [PATCH] gdiplus: Do not rely on an enumerated font size being equal to otmEMSquare. --- dlls/gdiplus/font.c | 61 +++++++++++++++++++++------------- dlls/gdiplus/gdiplus_private.h | 2 +- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index df3d407936c..eab82849aaf 100644 --- a/dlls/gdiplus/font.c +++ b/dlls/gdiplus/font.c @@ -97,7 +97,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, { WCHAR facename[LF_FACESIZE]; LOGFONTW* lfw; - const NEWTEXTMETRICW* tmw; + const OUTLINETEXTMETRICW *otm; GpStatus stat; if (!fontFamily || !font) @@ -110,16 +110,16 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, if (stat != Ok) return stat; *font = GdipAlloc(sizeof(GpFont)); - tmw = &fontFamily->tmw; + otm = &fontFamily->otm; lfw = &((*font)->lfw); ZeroMemory(&(*lfw), sizeof(*lfw)); - lfw->lfWeight = tmw->tmWeight; - lfw->lfItalic = tmw->tmItalic; - lfw->lfUnderline = tmw->tmUnderlined; - lfw->lfStrikeOut = tmw->tmStruckOut; - lfw->lfCharSet = tmw->tmCharSet; - lfw->lfPitchAndFamily = tmw->tmPitchAndFamily; + lfw->lfWeight = otm->otmTextMetrics.tmWeight; + lfw->lfItalic = otm->otmTextMetrics.tmItalic; + lfw->lfUnderline = otm->otmTextMetrics.tmUnderlined; + lfw->lfStrikeOut = otm->otmTextMetrics.tmStruckOut; + lfw->lfCharSet = otm->otmTextMetrics.tmCharSet; + lfw->lfPitchAndFamily = otm->otmTextMetrics.tmPitchAndFamily; lstrcpynW(lfw->lfFaceName, facename, LF_FACESIZE); switch (unit) @@ -155,8 +155,8 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, (*font)->unit = unit; (*font)->emSize = emSize; - (*font)->height = tmw->ntmSizeEM; - (*font)->line_spacing = tmw->tmAscent + tmw->tmDescent + tmw->tmExternalLeading; + (*font)->height = otm->otmEMSquare; + (*font)->line_spacing = otm->otmTextMetrics.tmAscent + otm->otmTextMetrics.tmDescent + otm->otmTextMetrics.tmExternalLeading; TRACE("<-- %p\n", *font); @@ -529,20 +529,33 @@ static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf, return 1; } - *(NEWTEXTMETRICW*)lParam = *(const NEWTEXTMETRICW*)ntm; + *(LOGFONTW *)lParam = *elf; return 0; } -static BOOL find_installed_font(const WCHAR *name, NEWTEXTMETRICW *ntm) +static BOOL find_installed_font(const WCHAR *name, OUTLINETEXTMETRICW *otm) { - HDC hdc = GetDC(0); + LOGFONTW lf; + HDC hdc = CreateCompatibleDC(0); BOOL ret = FALSE; - if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)ntm)) - ret = TRUE; + if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)&lf)) + { + HFONT hfont; - ReleaseDC(0, hdc); + lf.lfHeight = -2048; + hfont = CreateFontIndirectW(&lf); + hfont = SelectObject(hdc, hfont); + + otm->otmSize = sizeof(*otm); + if (GetOutlineTextMetricsW(hdc, otm->otmSize, otm)) + ret = TRUE; + + DeleteObject(SelectObject(hdc, hfont)); + } + + DeleteDC(hdc); return ret; } @@ -571,7 +584,7 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name, GpFontFamily **FontFamily) { GpFontFamily* ffamily; - NEWTEXTMETRICW ntm; + OUTLINETEXTMETRICW otm; TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily); @@ -580,13 +593,13 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name, if (fontCollection) FIXME("No support for FontCollections yet!\n"); - if (!find_installed_font(name, &ntm)) + if (!find_installed_font(name, &otm)) return FontFamilyNotFound; ffamily = GdipAlloc(sizeof (GpFontFamily)); if (!ffamily) return OutOfMemory; - ffamily->tmw = ntm; + ffamily->otm = otm; lstrcpynW(ffamily->FamilyName, name, LF_FACESIZE); *FontFamily = ffamily; @@ -618,7 +631,7 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily** *clonedFontFamily = GdipAlloc(sizeof(GpFontFamily)); if (!*clonedFontFamily) return OutOfMemory; - (*clonedFontFamily)->tmw = FontFamily->tmw; + (*clonedFontFamily)->otm = FontFamily->otm; lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName); TRACE("<-- %p\n", *clonedFontFamily); @@ -691,7 +704,7 @@ GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily *family, { if (!(family && CellAscent)) return InvalidParameter; - *CellAscent = family->tmw.tmAscent; + *CellAscent = family->otm.otmTextMetrics.tmAscent; return Ok; } @@ -703,7 +716,7 @@ GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily *family, if (!(family && CellDescent)) return InvalidParameter; - *CellDescent = family->tmw.tmDescent; + *CellDescent = family->otm.otmTextMetrics.tmDescent; return Ok; } @@ -728,7 +741,7 @@ GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, U TRACE("%p (%s), %d, %p\n", family, debugstr_w(family->FamilyName), style, EmHeight); - *EmHeight = family->tmw.ntmSizeEM; + *EmHeight = family->otm.otmEMSquare; return Ok; } @@ -758,7 +771,7 @@ GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family, if (style) FIXME("ignoring style\n"); - *LineSpacing = family->tmw.tmAscent + family->tmw.tmDescent + family->tmw.tmExternalLeading; + *LineSpacing = family->otm.otmTextMetrics.tmAscent + family->otm.otmTextMetrics.tmDescent + family->otm.otmTextMetrics.tmExternalLeading; return Ok; } diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 06dee299781..72de9cb43c7 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -377,7 +377,7 @@ struct GpFontCollection{ }; struct GpFontFamily{ - NEWTEXTMETRICW tmw; + OUTLINETEXTMETRICW otm; WCHAR FamilyName[LF_FACESIZE]; };