[2/3] gdiplus: Fix internal font metrics handling.

Dmitry Timoshkov dmitry at baikal.ru
Fri May 4 05:33:24 CDT 2012


This patch makes values returned by GdipGetCellAscent(), GdipGetCellDescent(),
GdipGetEmHeight(), GdipGetLineSpacing(), GdipGetFontHeight(), GdipGetFontSize()
match what the tests expect, and should fix the regression reported in
the bug 30559.
---
 dlls/gdiplus/font.c            |  318 +++++++++++++++++++---------------------
 dlls/gdiplus/gdiplus_private.h |   10 +-
 dlls/gdiplus/graphics.c        |   10 +-
 dlls/gdiplus/graphicspath.c    |    4 +-
 4 files changed, 166 insertions(+), 176 deletions(-)

diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c
index 7cc5910..11f4efa 100644
--- a/dlls/gdiplus/font.c
+++ b/dlls/gdiplus/font.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007 Google (Evan Stade)
+ * Copyright (C) 2012 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,37 +39,34 @@ static const REAL inch_per_point = 1.0/72.0;
 
 static GpFontCollection installedFontCollection = {0};
 
-static inline REAL get_dpi (void)
+static LONG em_size_to_pixel(REAL em_size, Unit unit, LONG dpi)
 {
-    REAL dpi;
-    GpGraphics *graphics;
-    HDC hdc = GetDC(0);
-    GdipCreateFromHDC (hdc, &graphics);
-    GdipGetDpiX(graphics, &dpi);
-    GdipDeleteGraphics(graphics);
-    ReleaseDC (0, hdc);
-
-    return dpi;
-}
-
-static inline REAL point_to_pixel (REAL point)
-{
-    return point * get_dpi() * inch_per_point;
-}
-
-static inline REAL inch_to_pixel (REAL inch)
-{
-    return inch * get_dpi();
-}
-
-static inline REAL document_to_pixel (REAL doc)
-{
-    return doc * (get_dpi() / 300.0); /* Per MSDN */
-}
+    switch (unit)
+    {
+        default:
+            FIXME("Unhandled unit type: %d\n", unit);
+            return 0;
 
-static inline REAL mm_to_pixel (REAL mm)
-{
-    return mm * (get_dpi() / mm_per_inch);
+        case UnitPixel:
+        case UnitWorld:
+            /* FIXME: Figure out when World != Pixel */
+            return em_size;
+        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 */
+            return 0;
+        case UnitPoint:
+            return em_size * dpi * inch_per_point;
+        case UnitInch:
+            return em_size * dpi;
+        case UnitDocument:
+            return em_size * dpi / 300.0; /* Per MSDN */
+        case UnitMillimeter:
+            return em_size * dpi / mm_per_inch;
+    }
 }
 
 /*******************************************************************************
@@ -95,70 +93,53 @@ static inline REAL mm_to_pixel (REAL mm)
 GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
                         REAL emSize, INT style, Unit unit, GpFont **font)
 {
-    WCHAR facename[LF_FACESIZE];
-    LOGFONTW* lfw;
-    const OUTLINETEXTMETRICW *otm;
+    HFONT hfont;
+    OUTLINETEXTMETRICW otm;
+    LOGFONTW lfw;
+    HDC hdc;
     GpStatus stat;
+    int ret;
 
-    if (!fontFamily || !font)
+    if (!fontFamily || !font || emSize < 0.0)
         return InvalidParameter;
 
     TRACE("%p (%s), %f, %d, %d, %p\n", fontFamily,
             debugstr_w(fontFamily->FamilyName), emSize, style, unit, font);
 
-    stat = GdipGetFamilyName (fontFamily, facename, 0);
-    if (stat != Ok) return stat;
-    *font = GdipAlloc(sizeof(GpFont));
-
-    otm = &fontFamily->otm;
-    lfw = &((*font)->lfw);
-    ZeroMemory(&(*lfw), sizeof(*lfw));
+    memset(&lfw, 0, sizeof(lfw));
 
-    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);
+    stat = GdipGetFamilyName(fontFamily, lfw.lfFaceName, LANG_NEUTRAL);
+    if (stat != Ok) return stat;
 
-    switch (unit)
-    {
-        case UnitWorld:
-            /* FIXME: Figure out when World != Pixel */
-            (*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 */
-            (*font)->pixel_size = 0; break;
-        case UnitPixel:
-            (*font)->pixel_size = emSize; break;
-        case UnitPoint:
-            (*font)->pixel_size = point_to_pixel(emSize); break;
-        case UnitInch:
-            (*font)->pixel_size = inch_to_pixel(emSize); break;
-        case UnitDocument:
-            (*font)->pixel_size = document_to_pixel(emSize); break;
-        case UnitMillimeter:
-            (*font)->pixel_size = mm_to_pixel(emSize); break;
-    }
+    lfw.lfHeight = -em_size_to_pixel(emSize, unit, fontFamily->ntm.tmDigitizedAspectY);
+    lfw.lfWeight = style & FontStyleBold ? FW_BOLD : FW_REGULAR;
+    lfw.lfItalic = style & FontStyleItalic;
+    lfw.lfUnderline = style & FontStyleUnderline;
+    lfw.lfStrikeOut = style & FontStyleStrikeout;
+
+    hfont = CreateFontIndirectW(&lfw);
+    hdc = CreateCompatibleDC(0);
+    SelectObject(hdc, hfont);
+    otm.otmSize = sizeof(otm);
+    ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
+    DeleteDC(hdc);
+    DeleteObject(hfont);
 
-    lfw->lfHeight = (*font)->pixel_size * -1;
+    if (!ret) return NotTrueTypeFont;
 
-    lfw->lfWeight = style & FontStyleBold ? FW_BOLD : FW_REGULAR;
-    lfw->lfItalic = style & FontStyleItalic;
-    lfw->lfUnderline = style & FontStyleUnderline;
-    lfw->lfStrikeOut = style & FontStyleStrikeout;
+    *font = GdipAlloc(sizeof(GpFont));
+    if (!*font) return OutOfMemory;
 
-    (*font)->unit = unit;
     (*font)->emSize = emSize;
-    (*font)->height = otm->otmEMSquare;
-    (*font)->line_spacing = otm->otmTextMetrics.tmAscent + otm->otmTextMetrics.tmDescent + otm->otmTextMetrics.tmExternalLeading;
+    (*font)->unit = unit;
+    (*font)->otm = otm;
 
-    TRACE("<-- %p\n", *font);
+    stat = GdipCloneFontFamily((GpFontFamily *)fontFamily, &(*font)->family);
+    if (stat != Ok)
+    {
+        GdipFree(*font);
+        return stat;
+    }
 
     return Ok;
 }
@@ -170,41 +151,37 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     GDIPCONST LOGFONTW *logfont, GpFont **font)
 {
     HFONT hfont, oldfont;
-    TEXTMETRICW textmet;
+    OUTLINETEXTMETRICW otm;
+    GpStatus stat;
+    int ret;
 
     TRACE("(%p, %p, %p)\n", hdc, logfont, font);
 
-    if(!logfont || !font)
+    if (!hdc || !logfont || !font)
         return InvalidParameter;
 
-    if (logfont->lfFaceName[0] == 0)
-        return NotTrueTypeFont;
-
-    *font = GdipAlloc(sizeof(GpFont));
-    if(!*font)  return OutOfMemory;
-
-    memcpy((*font)->lfw.lfFaceName, logfont->lfFaceName, LF_FACESIZE *
-           sizeof(WCHAR));
-    (*font)->lfw.lfHeight = logfont->lfHeight;
-    (*font)->lfw.lfItalic = logfont->lfItalic;
-    (*font)->lfw.lfUnderline = logfont->lfUnderline;
-    (*font)->lfw.lfStrikeOut = logfont->lfStrikeOut;
-
-    hfont = CreateFontIndirectW(&(*font)->lfw);
+    hfont = CreateFontIndirectW(logfont);
     oldfont = SelectObject(hdc, hfont);
-    GetTextMetricsW(hdc, &textmet);
+    otm.otmSize = sizeof(otm);
+    ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
+    SelectObject(hdc, oldfont);
+    DeleteObject(hfont);
+
+    if (!ret) return NotTrueTypeFont;
 
-    (*font)->lfw.lfHeight = -(textmet.tmHeight-textmet.tmInternalLeading);
-    (*font)->lfw.lfWeight = textmet.tmWeight;
-    (*font)->lfw.lfCharSet = textmet.tmCharSet;
+    *font = GdipAlloc(sizeof(GpFont));
+    if (!*font) return OutOfMemory;
 
-    (*font)->pixel_size = (*font)->emSize = textmet.tmHeight;
-    (*font)->unit = UnitPixel;
-    (*font)->height = 1; /* FIXME: need NEWTEXTMETRIC.ntmSizeEM here */
-    (*font)->line_spacing = textmet.tmAscent + textmet.tmDescent + textmet.tmExternalLeading;
+    (*font)->emSize = otm.otmTextMetrics.tmAscent;
+    (*font)->unit = UnitWorld;
+    (*font)->otm = otm;
 
-    SelectObject(hdc, oldfont);
-    DeleteObject(hfont);
+    stat = GdipCreateFontFamilyFromName(logfont->lfFaceName, NULL, &(*font)->family);
+    if (stat != Ok)
+    {
+        GdipFree(*font);
+        return NotTrueTypeFont;
+    }
 
     TRACE("<-- %p\n", *font);
 
@@ -242,6 +219,7 @@ GpStatus WINGDIPAPI GdipDeleteFont(GpFont* font)
     if(!font)
         return InvalidParameter;
 
+    GdipDeleteFontFamily(font->family);
     GdipFree(font);
 
     return Ok;
@@ -287,10 +265,10 @@ GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
 {
     TRACE("%p %p\n", font, family);
 
-    if (!(font && family))
+    if (!font || !family)
         return InvalidParameter;
 
-    return GdipCreateFontFamilyFromName(font->lfw.lfFaceName, NULL, family);
+    return GdipCloneFontFamily(font->family, family);
 }
 
 /******************************************************************************
@@ -313,10 +291,10 @@ GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
 {
     TRACE("(%p, %p)\n", font, size);
 
-    if (!(font && size)) return InvalidParameter;
+    if (!font || !size) return InvalidParameter;
 
     *size = font->emSize;
-    TRACE("%s,%d => %f\n", debugstr_w(font->lfw.lfFaceName), font->lfw.lfHeight, *size);
+    TRACE("%s,%d => %f\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *size);
 
     return Ok;
 }
@@ -341,15 +319,15 @@ GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
     if (!(font && style))
         return InvalidParameter;
 
-    if (font->lfw.lfWeight > FW_REGULAR)
+    if (font->otm.otmTextMetrics.tmWeight > FW_REGULAR)
         *style = FontStyleBold;
     else
         *style = FontStyleRegular;
-    if (font->lfw.lfItalic)
+    if (font->otm.otmTextMetrics.tmItalic)
         *style |= FontStyleItalic;
-    if (font->lfw.lfUnderline)
+    if (font->otm.otmTextMetrics.tmUnderlined)
         *style |= FontStyleUnderline;
-    if (font->lfw.lfStrikeOut)
+    if (font->otm.otmTextMetrics.tmStruckOut)
         *style |= FontStyleStrikeout;
 
     return Ok;
@@ -373,7 +351,7 @@ GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
     if (!(font && unit)) return InvalidParameter;
 
     *unit = font->unit;
-    TRACE("%s,%d => %d\n", debugstr_w(font->lfw.lfFaceName), font->lfw.lfHeight, *unit);
+    TRACE("%s,%d => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *unit);
 
     return Ok;
 }
@@ -409,12 +387,24 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
 {
     TRACE("(%p, %p, %p)\n", font, graphics, lfw);
 
-    /* FIXME: use graphics */
-    if(!font || !graphics || !lfw)
-        return InvalidParameter;
-
-    *lfw = font->lfw;
-    TRACE("=> %s,%d\n", debugstr_w(font->lfw.lfFaceName), font->lfw.lfHeight);
+    if (!font || !graphics || !lfw) return InvalidParameter;
+
+    lfw->lfHeight = -font->otm.otmTextMetrics.tmAscent;
+    lfw->lfWidth = 0;
+    lfw->lfEscapement = 0;
+    lfw->lfOrientation = 0;
+    lfw->lfWeight = font->otm.otmTextMetrics.tmWeight;
+    lfw->lfItalic = font->otm.otmTextMetrics.tmItalic ? 1 : 0;
+    lfw->lfUnderline = font->otm.otmTextMetrics.tmUnderlined ? 1 : 0;
+    lfw->lfStrikeOut = font->otm.otmTextMetrics.tmStruckOut ? 1 : 0;
+    lfw->lfCharSet = font->otm.otmTextMetrics.tmCharSet;
+    lfw->lfOutPrecision = OUT_DEFAULT_PRECIS;
+    lfw->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+    lfw->lfQuality = DEFAULT_QUALITY;
+    lfw->lfPitchAndFamily = 0;
+    strcpyW(lfw->lfFaceName, font->family->FamilyName);
+
+    TRACE("=> %s,%d\n", debugstr_w(lfw->lfFaceName), lfw->lfHeight);
 
     return Ok;
 }
@@ -424,6 +414,8 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
  */
 GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
 {
+    GpStatus stat;
+
     TRACE("(%p, %p)\n", font, cloneFont);
 
     if(!font || !cloneFont)
@@ -432,9 +424,13 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
     *cloneFont = GdipAlloc(sizeof(GpFont));
     if(!*cloneFont)    return OutOfMemory;
 
-    **cloneFont = *font;
+    (*cloneFont)->emSize = font->emSize;
+    (*cloneFont)->unit = font->unit;
+    (*cloneFont)->otm = font->otm;
+    stat = GdipCloneFontFamily(font->family, &(*cloneFont)->family);
+    if (stat != Ok) GdipFree(*cloneFont);
 
-    return Ok;
+    return stat;
 }
 
 /*******************************************************************************
@@ -458,12 +454,15 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
 
     TRACE("%p %p %p\n", font, graphics, height);
 
-    stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
-
-    if (stat == Ok)
-        stat = GdipGetFontHeightGivenDPI(font, dpi, height);
+    if (graphics)
+    {
+        stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
+        if (stat != Ok) return stat;
+    }
+    else
+        dpi = font->otm.otmTextMetrics.tmDigitizedAspectY;
 
-    return stat;
+    return GdipGetFontHeightGivenDPI(font, dpi, height);
 }
 
 /*******************************************************************************
@@ -483,14 +482,18 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
  */
 GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height)
 {
-    REAL font_height;
+    GpStatus stat;
+    REAL font_height, font_size;
+
+    if (!font || !height) return InvalidParameter;
 
     TRACE("%p (%s), %f, %p\n", font,
-            debugstr_w(font->lfw.lfFaceName), dpi, height);
+            debugstr_w(font->family->FamilyName), dpi, height);
 
-    if (!(font && height)) return InvalidParameter;
+    stat = GdipGetFontSize((GpFont *)font, &font_size);
+    if (stat != Ok) return stat;
 
-    font_height = font->line_spacing * (font->emSize / font->height);
+    font_height = (REAL)font->family->ntm.ntmCellHeight * font_size / (REAL)font->family->ntm.ntmSizeEM;
 
     switch (font->unit)
     {
@@ -516,7 +519,7 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
     }
 
     TRACE("%s,%d(unit %d) => %f\n",
-          debugstr_w(font->lfw.lfFaceName), font->lfw.lfHeight, font->unit, *height);
+          debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, font->unit, *height);
 
     return Ok;
 }
@@ -535,34 +538,19 @@ static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
         return 1;
     }
 
-    *(LOGFONTW *)lParam = *elf;
+    *(NEWTEXTMETRICW *)lParam = *(const NEWTEXTMETRICW *)ntm;
 
     return 0;
 }
 
-static BOOL find_installed_font(const WCHAR *name, OUTLINETEXTMETRICW *otm)
+static BOOL find_installed_font(const WCHAR *name, NEWTEXTMETRICW *ntm)
 {
-    LOGFONTW lf;
     HDC hdc = CreateCompatibleDC(0);
-    BOOL ret = FALSE;
-
-    if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)&lf))
-    {
-        HFONT hfont;
-
-        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));
-    }
+    BOOL ret;
 
+    ret = EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)ntm);
     DeleteDC(hdc);
-    return ret;
+    return !ret;
 }
 
 /*******************************************************************************
@@ -590,7 +578,7 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
                                         GpFontFamily **FontFamily)
 {
     GpFontFamily* ffamily;
-    OUTLINETEXTMETRICW otm;
+    NEWTEXTMETRICW ntm;
 
     TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily);
 
@@ -599,13 +587,13 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
     if (fontCollection)
         FIXME("No support for FontCollections yet!\n");
 
-    if (!find_installed_font(name, &otm))
+    if (!find_installed_font(name, &ntm))
         return FontFamilyNotFound;
 
     ffamily = GdipAlloc(sizeof (GpFontFamily));
     if (!ffamily) return OutOfMemory;
 
-    ffamily->otm = otm;
+    ffamily->ntm = ntm;
     lstrcpynW(ffamily->FamilyName, name, LF_FACESIZE);
 
     *FontFamily = ffamily;
@@ -637,7 +625,7 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily**
     *clonedFontFamily = GdipAlloc(sizeof(GpFontFamily));
     if (!*clonedFontFamily) return OutOfMemory;
 
-    (*clonedFontFamily)->otm = FontFamily->otm;
+    (*clonedFontFamily)->ntm = FontFamily->ntm;
     lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName);
 
     TRACE("<-- %p\n", *clonedFontFamily);
@@ -710,8 +698,9 @@ GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily *family,
 {
     if (!(family && CellAscent)) return InvalidParameter;
 
-    *CellAscent = family->otm.otmTextMetrics.tmAscent;
-    TRACE("%d => %u\n", family->otm.otmTextMetrics.tmHeight, *CellAscent);
+    /* FIXME: should be set from pOS2->usWinAscent */
+    *CellAscent = family->ntm.ntmSizeEM;
+    TRACE("%d => %u\n", family->ntm.tmHeight, *CellAscent);
 
     return Ok;
 }
@@ -723,8 +712,9 @@ GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily *family,
 
     if (!(family && CellDescent)) return InvalidParameter;
 
-    *CellDescent = family->otm.otmTextMetrics.tmDescent;
-    TRACE("%d => %u\n", family->otm.otmTextMetrics.tmHeight, *CellDescent);
+    /* FIXME: should be set from pOS2->usWinDescent */
+    *CellDescent = family->ntm.ntmCellHeight - family->ntm.ntmSizeEM;
+    TRACE("%d => %u\n", family->ntm.tmHeight, *CellDescent);
 
     return Ok;
 }
@@ -749,8 +739,8 @@ GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, U
 
     TRACE("%p (%s), %d, %p\n", family, debugstr_w(family->FamilyName), style, EmHeight);
 
-    *EmHeight = family->otm.otmEMSquare;
-    TRACE("%d => %u\n", family->otm.otmTextMetrics.tmHeight, *EmHeight);
+    *EmHeight = family->ntm.ntmSizeEM;
+    TRACE("%d => %u\n", family->ntm.tmHeight, *EmHeight);
 
     return Ok;
 }
@@ -780,8 +770,8 @@ GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family,
 
     if (style) FIXME("ignoring style\n");
 
-    *LineSpacing = family->otm.otmTextMetrics.tmAscent + family->otm.otmTextMetrics.tmDescent + family->otm.otmTextMetrics.tmExternalLeading;
-    TRACE("%d => %u\n", family->otm.otmTextMetrics.tmHeight, *LineSpacing);
+    *LineSpacing = family->ntm.ntmCellHeight;
+    TRACE("%d => %u\n", family->ntm.tmHeight, *LineSpacing);
 
     return Ok;
 }
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 72de9cb..1595ac0 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -346,12 +346,10 @@ struct GpImageAttributes{
 };
 
 struct GpFont{
-    LOGFONTW lfw;
-    REAL emSize;
-    REAL pixel_size;
-    UINT height;
-    LONG line_spacing;
+    GpFontFamily *family;
+    REAL emSize; /* in font units */
     Unit unit;
+    OUTLINETEXTMETRICW otm;
 };
 
 struct GpStringFormat{
@@ -377,7 +375,7 @@ struct GpFontCollection{
 };
 
 struct GpFontFamily{
-    OUTLINETEXTMETRICW otm;
+    NEWTEXTMETRICW ntm;
     WCHAR FamilyName[LF_FACESIZE];
 };
 
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index a5e3eb2..780e56f 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -2136,15 +2136,13 @@ 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));
 
-    lfw = font->lfw;
-    lfw.lfHeight = roundr(-font->pixel_size * rel_height);
+    GdipGetLogFontW((GpFont *)font, graphics, &lfw);
+    lfw.lfHeight = roundr(lfw.lfHeight * rel_height);
     unscaled_font = CreateFontIndirectW(&lfw);
 
     SelectObject(hdc, unscaled_font);
     GetTextMetricsW(hdc, &textmet);
 
-    lfw = font->lfw;
-    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);
 
@@ -4919,6 +4917,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
 {
     GpStatus stat;
     int i;
+    LOGFONTW lfw;
     HFONT oldfont;
     struct measure_ranges_args args;
     HDC hdc, temp_hdc=NULL;
@@ -4943,7 +4942,8 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
     if (stringFormat->attr)
         TRACE("may be ignoring some format flags: attr %x\n", stringFormat->attr);
 
-    oldfont = SelectObject(hdc, CreateFontIndirectW(&font->lfw));
+    GdipGetLogFontW((GpFont *)font, graphics, &lfw);
+    oldfont = SelectObject(hdc, CreateFontIndirectW(&lfw));
 
     for (i=0; i<stringFormat->range_count; i++)
     {
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index d37512e..c1673e6 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -942,6 +942,7 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
 {
     GpFont *font;
     GpStatus status;
+    LOGFONTW lfw;
     HANDLE hfont;
     HDC dc;
     GpPath *backup;
@@ -956,7 +957,8 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
     if (status != Ok)
         return status;
 
-    hfont = CreateFontIndirectW(&font->lfw);
+    GdipGetLogFontW((GpFont *)font, NULL, &lfw);
+    hfont = CreateFontIndirectW(&lfw);
     if (!hfont)
     {
         WARN("Failed to create font\n");
-- 
1.7.9.4




More information about the wine-patches mailing list