Adam Petaccia : gdiplus: Implement GdipCreateFont.

Alexandre Julliard julliard at winehq.org
Wed Jun 25 16:44:26 CDT 2008


Module: wine
Branch: master
Commit: b0b1588ab6520ad018ea8694d3373969a7c43c84
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b0b1588ab6520ad018ea8694d3373969a7c43c84

Author: Adam Petaccia <adam at tpetaccia.com>
Date:   Sat Jun 21 13:02:53 2008 -0400

gdiplus: Implement GdipCreateFont.

---

 dlls/gdiplus/font.c            |  126 ++++++++++++++++++++++++++++++++++++++++
 dlls/gdiplus/gdiplus.spec      |    2 +-
 dlls/gdiplus/gdiplus_private.h |    2 +
 include/gdiplusenums.h         |   11 ++++
 include/gdiplusflat.h          |    2 +
 5 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c
index fe514a3..9762356 100644
--- a/dlls/gdiplus/font.c
+++ b/dlls/gdiplus/font.c
@@ -22,6 +22,7 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winnls.h"
+#include "winreg.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
 
@@ -32,6 +33,128 @@ WINE_DEFAULT_DEBUG_CHANNEL (gdiplus);
 #include "gdiplus.h"
 #include "gdiplus_private.h"
 
+static const REAL mm_per_pixel = 25.4;
+
+static inline REAL get_dpi (void)
+{
+    REAL dpi;
+    GpGraphics *graphics;
+    HDC hdc = GetDC(0);
+    GdipCreateFromHDC (hdc, &graphics);
+    GdipGetDpiX(graphics, &dpi);
+    ReleaseDC (0, hdc);
+
+    return dpi;
+}
+
+static inline REAL point_to_pixel (REAL point)
+{
+    return point * 1.5;
+}
+
+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 */
+}
+
+static inline REAL mm_to_pixel (REAL mm)
+{
+    return mm * (get_dpi() / mm_per_pixel);
+}
+
+/*******************************************************************************
+ * GdipCreateFont [GDIPLUS.@]
+ *
+ * Create a new font based off of a FontFamily
+ *
+ * PARAMS
+ *  *fontFamily     [I] Family to base the font off of
+ *  emSize          [I] Size of the font
+ *  style           [I] Bitwise OR of FontStyle enumeration
+ *  unit            [I] Unit emSize is measured in
+ *  **font          [I] the resulting Font object
+ *
+ * RETURNS
+ *  SUCCESS: Ok
+ *  FAILURE: InvalidParameter if fontfamily or font is NULL.
+ *  FAILURE: FontFamilyNotFound if an invalid FontFamily is given
+ *
+ * NOTES
+ *  UnitDisplay is unsupported.
+ *  emSize is stored separately from lfHeight, to hold the fraction.
+ */
+GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
+                        REAL emSize, INT style, Unit unit, GpFont **font)
+{
+    WCHAR facename[LF_FACESIZE];
+    LOGFONTW* lfw;
+    TEXTMETRICW* tmw;
+    GpStatus stat;
+
+    if ((!fontFamily && fontFamily->FamilyName && font))
+        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));
+
+    tmw = fontFamily->tmw;
+    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;
+    lstrcpynW((lfw->lfFaceName), facename, sizeof(WCHAR) * LF_FACESIZE);
+
+    switch (unit)
+    {
+        case UnitWorld:
+            /* FIXME: Figure out when World != Pixel */
+            lfw->lfHeight = 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;
+        case UnitPixel:
+            lfw->lfHeight = emSize; break;
+        case UnitPoint:
+            lfw->lfHeight = point_to_pixel(emSize); break;
+        case UnitInch:
+            lfw->lfHeight = inch_to_pixel(emSize); break;
+        case UnitDocument:
+            lfw->lfHeight = document_to_pixel(emSize); break;
+        case UnitMillimeter:
+            lfw->lfHeight = mm_to_pixel(emSize); break;
+    }
+
+    lfw->lfHeight *= -1;
+
+    lfw->lfWeight = style & FontStyleBold ? 700 : 400;
+    lfw->lfItalic = style & FontStyleItalic;
+    lfw->lfUnderline = style & FontStyleUnderline;
+    lfw->lfStrikeOut = style & FontStyleStrikeout;
+
+    (*font)->unit = unit;
+    (*font)->emSize = emSize;
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     GDIPCONST LOGFONTW *logfont, GpFont **font)
 {
@@ -51,6 +174,9 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
     (*font)->lfw.lfUnderline = logfont->lfUnderline;
     (*font)->lfw.lfStrikeOut = logfont->lfStrikeOut;
 
+    (*font)->emSize = logfont->lfHeight;
+    (*font)->unit = UnitPixel;
+
     hfont = CreateFontIndirectW(&(*font)->lfw);
     oldfont = SelectObject(hdc, hfont);
     GetTextMetricsW(hdc, &textmet);
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 7b71fc8..f43a63e 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -84,7 +84,7 @@
 @ stub GdipCreateCachedBitmap
 @ stdcall GdipCreateCustomLineCap(ptr ptr long long ptr)
 @ stub GdipCreateEffect
-@ stub GdipCreateFont
+@ stdcall GdipCreateFont(ptr long long long ptr)
 @ stdcall GdipCreateFontFamilyFromName(wstr ptr ptr)
 @ stdcall GdipCreateFontFromDC(long ptr)
 @ stdcall GdipCreateFontFromLogfontA(long ptr ptr)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index acda374..6042835 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -174,6 +174,8 @@ struct GpImageAttributes{
 
 struct GpFont{
     LOGFONTW lfw;
+    REAL emSize;
+    Unit unit;
 };
 
 struct GpStringFormat{
diff --git a/include/gdiplusenums.h b/include/gdiplusenums.h
index a27ed5e..8e1148d 100644
--- a/include/gdiplusenums.h
+++ b/include/gdiplusenums.h
@@ -250,6 +250,16 @@ enum StringTrimming
     StringTrimmingEllipsisPath         = 5
 };
 
+enum FontStyle
+{
+    FontStyleRegular    = 0,
+    FontStyleBold       = 1,
+    FontStyleItalic     = 2,
+    FontStyleBoldItalic = 3,
+    FontStyleUnderline  = 4,
+    FontStyleStrikeout  = 8
+};
+
 enum HotkeyPrefix
 {
     HotkeyPrefixNone   = 0,
@@ -330,6 +340,7 @@ typedef enum CompositingMode CompositingMode;
 typedef enum TextRenderingHint TextRenderingHint;
 typedef enum StringAlignment StringAlignment;
 typedef enum StringTrimming StringTrimming;
+typedef enum FontStyle FontStyle;
 typedef enum StringFormatFlags StringFormatFlags;
 typedef enum HotkeyPrefix HotkeyPrefix;
 typedef enum PenAlignment GpPenAlignment;
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index b4cde21..a8caf9b 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -341,6 +341,8 @@ GpStatus WINGDIPAPI GdipSetImageAttributesColorMatrix(GpImageAttributes*,
 GpStatus WINGDIPAPI GdipSetImageAttributesWrapMode(GpImageAttributes*,WrapMode,
     ARGB,BOOL);
 
+GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily*, REAL, INT, Unit,
+    GpFont**);
 GpStatus WINGDIPAPI GdipCreateFontFromDC(HDC,GpFont**);
 GpStatus WINGDIPAPI GdipCreateFontFromLogfontA(HDC,GDIPCONST LOGFONTA*,GpFont**);
 GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC,GDIPCONST LOGFONTW*,GpFont**);




More information about the wine-cvs mailing list