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