[1/3] gdiplus: Do not rely on an enumerated font size being equal to otmEMSquare. Resend.

Dmitry Timoshkov dmitry at baikal.ru
Tue Apr 24 03:02:59 CDT 2012


---
 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 df3d407..eab8284 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;
+
+        lf.lfHeight = -2048;
+        hfont = CreateFontIndirectW(&lf);
+        hfont = SelectObject(hdc, hfont);
 
-    ReleaseDC(0, hdc);
+        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 5d5a92c..e7f7049 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -376,7 +376,7 @@ struct GpFontCollection{
 };
 
 struct GpFontFamily{
-    NEWTEXTMETRICW tmw;
+    OUTLINETEXTMETRICW otm;
     WCHAR FamilyName[LF_FACESIZE];
 };
 
-- 
1.7.9.4




More information about the wine-patches mailing list