[PATCH 2/5] dwrite: Fix lfItalic flag as returned by ConvertFontToLOGFONT()
Nikolay Sivov
nsivov at codeweavers.com
Sun Dec 4 10:22:13 CST 2016
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 2 +
dlls/dwrite/font.c | 20 ++++++
dlls/dwrite/gdiinterop.c | 7 +-
dlls/dwrite/opentype.c | 9 ++-
dlls/dwrite/tests/font.c | 157 ++++++++++++++++++++++++++++++++++---------
5 files changed, 155 insertions(+), 40 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index dad0f47..77b6c4a 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -200,6 +200,7 @@ extern HRESULT create_fontfacereference(IDWriteFactory4*,IDWriteFontFile*,UINT32
extern HRESULT factory_get_cached_fontface(IDWriteFactory4*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace**,
struct list**) DECLSPEC_HIDDEN;
extern void factory_cache_fontface(struct list*,IDWriteFontFace4*) DECLSPEC_HIDDEN;
+extern void get_logfont_from_font(IDWriteFont*,LOGFONTW*) DECLSPEC_HIDDEN;
/* Opentype font table functions */
struct dwrite_font_props {
@@ -207,6 +208,7 @@ struct dwrite_font_props {
DWRITE_FONT_STRETCH stretch;
DWRITE_FONT_WEIGHT weight;
DWRITE_PANOSE panose;
+ LOGFONTW lf;
};
struct file_stream_desc {
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 76a90bd..356000c 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -19,6 +19,8 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+
+#include <assert.h>
#include <math.h>
#define COBJMACROS
@@ -90,6 +92,8 @@ struct dwrite_font_data {
USHORT simulations;
+ LOGFONTW lf;
+
/* used to mark font as tested when scanning for simulation candidate */
BOOL bold_sim_tested : 1;
BOOL oblique_sim_tested : 1;
@@ -1673,6 +1677,20 @@ static const IDWriteFont3Vtbl dwritefontvtbl = {
dwritefont3_GetLocality
};
+static struct dwrite_font *unsafe_impl_from_IDWriteFont(IDWriteFont *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == (IDWriteFontVtbl*)&dwritefontvtbl);
+ return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont3_iface);
+}
+
+void get_logfont_from_font(IDWriteFont *iface, LOGFONTW *lf)
+{
+ struct dwrite_font *font = unsafe_impl_from_IDWriteFont(iface);
+ *lf = font->data->lf;
+}
+
static HRESULT create_font(struct dwrite_font_data *data, IDWriteFontFamily1 *family, IDWriteFont3 **font)
{
struct dwrite_font *This;
@@ -3244,6 +3262,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized
data->stretch = props.stretch;
data->weight = props.weight;
data->panose = props.panose;
+ data->lf = props.lf;
fontstrings_get_en_string(*family_name, familyW, sizeof(familyW)/sizeof(WCHAR));
fontstrings_get_en_string(data->names, faceW, sizeof(faceW)/sizeof(WCHAR));
@@ -3446,6 +3465,7 @@ static void fontfamily_add_oblique_simulated_face(struct dwrite_fontfamily_data
if (init_font_data_from_font(family->fonts[regular], DWRITE_FONT_SIMULATIONS_OBLIQUE, facenameW, &obliqueface) == S_OK) {
obliqueface->oblique_sim_tested = 1;
+ obliqueface->lf.lfItalic = 1;
fontfamily_add_font(family, obliqueface);
}
}
diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c
index 886bebb..e4ef835 100644
--- a/dlls/dwrite/gdiinterop.c
+++ b/dlls/dwrite/gdiinterop.c
@@ -624,11 +624,9 @@ static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop1 *iface,
{
struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
static const WCHAR enusW[] = {'e','n','-','u','s',0};
- DWRITE_FONT_SIMULATIONS simulations;
IDWriteFontCollection *collection;
IDWriteLocalizedStrings *name;
IDWriteFontFamily *family;
- DWRITE_FONT_STYLE style;
UINT32 index;
BOOL exists;
HRESULT hr;
@@ -654,12 +652,9 @@ static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop1 *iface,
*is_systemfont = is_system_collection(collection);
IDWriteFontCollection_Release(collection);
- simulations = IDWriteFont_GetSimulations(font);
- style = IDWriteFont_GetStyle(font);
-
+ get_logfont_from_font(font, logfont);
logfont->lfCharSet = DEFAULT_CHARSET;
logfont->lfWeight = IDWriteFont_GetWeight(font);
- logfont->lfItalic = style == DWRITE_FONT_STYLE_ITALIC || (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE);
logfont->lfOutPrecision = OUT_OUTLINE_PRECIS;
logfont->lfFaceName[0] = 0;
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 3fe4690..e16bf76 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -1285,6 +1285,7 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
props->weight = DWRITE_FONT_WEIGHT_NORMAL;
props->style = DWRITE_FONT_STYLE_NORMAL;
memset(&props->panose, 0, sizeof(props->panose));
+ memset(&props->lf, 0, sizeof(props->lf));
/* DWRITE_FONT_STRETCH enumeration values directly match font data values */
if (tt_os2) {
@@ -1306,8 +1307,10 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
if (version >= 4 && (fsSelection & OS2_FSSELECTION_OBLIQUE))
props->style = DWRITE_FONT_STYLE_OBLIQUE;
- else if (fsSelection & OS2_FSSELECTION_ITALIC)
+ else if (fsSelection & OS2_FSSELECTION_ITALIC) {
props->style = DWRITE_FONT_STYLE_ITALIC;
+ props->lf.lfItalic = 1;
+ }
memcpy(&props->panose, &tt_os2->panose, sizeof(props->panose));
}
else if (tt_head) {
@@ -1321,8 +1324,10 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
if (macStyle & TT_HEAD_MACSTYLE_BOLD)
props->weight = DWRITE_FONT_WEIGHT_BOLD;
- if (macStyle & TT_HEAD_MACSTYLE_ITALIC)
+ if (macStyle & TT_HEAD_MACSTYLE_ITALIC) {
props->style = DWRITE_FONT_STYLE_ITALIC;
+ props->lf.lfItalic = 1;
+ }
}
TRACE("stretch=%d, weight=%d, style %d\n", props->stretch, props->weight, props->style);
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 8df6f44..d3c9d42 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -132,6 +132,17 @@ typedef struct
SHORT glyphdata_format;
} TT_HEAD;
+enum TT_HEAD_MACSTYLE
+{
+ TT_HEAD_MACSTYLE_BOLD = 1 << 0,
+ TT_HEAD_MACSTYLE_ITALIC = 1 << 1,
+ TT_HEAD_MACSTYLE_UNDERLINE = 1 << 2,
+ TT_HEAD_MACSTYLE_OUTLINE = 1 << 3,
+ TT_HEAD_MACSTYLE_SHADOW = 1 << 4,
+ TT_HEAD_MACSTYLE_CONDENSED = 1 << 5,
+ TT_HEAD_MACSTYLE_EXTENDED = 1 << 6,
+};
+
typedef struct
{
USHORT version;
@@ -3445,6 +3456,61 @@ static void test_TryGetFontTable(void)
DELETE_FONTFILE(path);
}
+static void get_logfont_from_font(IDWriteFont *font, LOGFONTW *logfont)
+{
+ DWRITE_FONT_STYLE style;
+
+ /* These are rendering time properties. */
+ logfont->lfHeight = 0;
+ logfont->lfWidth = 0;
+ logfont->lfEscapement = 0;
+ logfont->lfOrientation = 0;
+ logfont->lfUnderline = 0;
+ logfont->lfStrikeOut = 0;
+
+ logfont->lfItalic = 0;
+
+ if (IDWriteFont_GetSimulations(font) & DWRITE_FONT_SIMULATIONS_OBLIQUE)
+ logfont->lfItalic = 1;
+
+ style = IDWriteFont_GetStyle(font);
+ if (!logfont->lfItalic && ((style == DWRITE_FONT_STYLE_ITALIC) || (style == DWRITE_FONT_STYLE_OBLIQUE))) {
+ void *os2_context, *head_context;
+ IDWriteFontFace *fontface;
+ const TT_OS2_V2 *tt_os2;
+ const TT_HEAD *tt_head;
+ UINT32 size;
+ BOOL exists;
+ HRESULT hr;
+
+ hr = IDWriteFont_CreateFontFace(font, &fontface);
+ ok(hr == S_OK, "Failed to create font face, %#x\n", hr);
+
+ hr = IDWriteFontFace_TryGetFontTable(fontface, MS_0S2_TAG, (const void **)&tt_os2, &size,
+ &os2_context, &exists);
+ ok(hr == S_OK, "Failed to get OS/2 table, %#x\n", hr);
+
+ hr = IDWriteFontFace_TryGetFontTable(fontface, MS_HEAD_TAG, (const void **)&tt_head, &size,
+ &head_context, &exists);
+ ok(hr == S_OK, "Failed to get head table, %#x\n", hr);
+
+ if (tt_os2) {
+ USHORT fsSelection = GET_BE_WORD(tt_os2->fsSelection);
+ logfont->lfItalic = !!(fsSelection & OS2_FSSELECTION_ITALIC);
+ }
+ else if (tt_head) {
+ USHORT macStyle = GET_BE_WORD(tt_head->macStyle);
+ logfont->lfItalic = !!(macStyle & TT_HEAD_MACSTYLE_ITALIC);
+ }
+
+ if (tt_os2)
+ IDWriteFontFace_ReleaseFontTable(fontface, os2_context);
+ if (tt_head)
+ IDWriteFontFace_ReleaseFontTable(fontface, head_context);
+ IDWriteFontFace_Release(fontface);
+ }
+}
+
static void test_ConvertFontToLOGFONT(void)
{
IDWriteFactory *factory, *factory2;
@@ -3453,6 +3519,7 @@ static void test_ConvertFontToLOGFONT(void)
IDWriteFontFamily *family;
IDWriteFont *font;
LOGFONTW logfont;
+ UINT32 i, count;
BOOL system;
HRESULT hr;
@@ -3486,41 +3553,67 @@ if (0) { /* crashes on native */
ok(!system, "got %d\n", system);
ok(logfont.lfFaceName[0] == 0, "got face name %s\n", wine_dbgstr_w(logfont.lfFaceName));
- system = FALSE;
+ count = IDWriteFontCollection_GetFontFamilyCount(collection);
+ for (i = 0; i < count; i++) {
+ WCHAR nameW[128], familynameW[64], facenameW[64];
+ IDWriteLocalizedStrings *names;
+ DWRITE_FONT_SIMULATIONS sim;
+ IDWriteFontFamily *family;
+ UINT32 font_count, j;
+ IDWriteFont *font;
+ LOGFONTW lf;
- logfont.lfHeight = 10;
- logfont.lfWidth = 11;
- logfont.lfEscapement = 10;
- logfont.lfOrientation = 10;
- logfont.lfWeight = 0;
- logfont.lfItalic = 1;
- logfont.lfUnderline = 1;
- logfont.lfStrikeOut = 1;
- logfont.lfCharSet = 0;
- logfont.lfOutPrecision = 0;
- logfont.lfClipPrecision = 0;
- logfont.lfQuality = 0;
- logfont.lfPitchAndFamily = 0;
- logfont.lfFaceName[0] = 0;
+ hr = IDWriteFontCollection_GetFontFamily(collection, i, &family);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(system, "got %d\n", system);
+ hr = IDWriteFontFamily_GetFamilyNames(family, &names);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(logfont.lfHeight == 0, "got %d\n", logfont.lfHeight);
- ok(logfont.lfWidth == 0, "got %d\n", logfont.lfWidth);
- ok(logfont.lfEscapement == 0, "got %d\n", logfont.lfEscapement);
- ok(logfont.lfOrientation == 0, "got %d\n", logfont.lfOrientation);
- ok(logfont.lfWeight > 0, "got %d\n", logfont.lfWeight);
- ok(logfont.lfItalic == 0, "got %d\n", logfont.lfItalic);
- ok(logfont.lfUnderline == 0, "got %d\n", logfont.lfUnderline);
- ok(logfont.lfStrikeOut == 0, "got %d\n", logfont.lfStrikeOut);
- ok(logfont.lfCharSet == DEFAULT_CHARSET, "got %d\n", logfont.lfCharSet);
- ok(logfont.lfOutPrecision == OUT_OUTLINE_PRECIS, "got %d\n", logfont.lfOutPrecision);
- ok(logfont.lfClipPrecision == 0, "got %d\n", logfont.lfClipPrecision);
- ok(logfont.lfQuality == 0, "got %d\n", logfont.lfQuality);
- ok(logfont.lfPitchAndFamily == 0, "got %d\n", logfont.lfPitchAndFamily);
- ok(logfont.lfFaceName[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont.lfFaceName));
+ get_enus_string(names, familynameW, sizeof(familynameW)/sizeof(familynameW[0]));
+ IDWriteLocalizedStrings_Release(names);
+
+ font_count = IDWriteFontFamily_GetFontCount(family);
+
+ for (j = 0; j < font_count; j++) {
+ static const WCHAR spaceW[] = {' ', 0};
+
+ hr = IDWriteFontFamily_GetFont(family, j, &font);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IDWriteFont_GetFaceNames(font, &names);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ get_enus_string(names, facenameW, sizeof(facenameW)/sizeof(facenameW[0]));
+ IDWriteLocalizedStrings_Release(names);
+
+ lstrcpyW(nameW, familynameW);
+ lstrcatW(nameW, spaceW);
+ lstrcatW(nameW, facenameW);
+
+ system = FALSE;
+ memset(&logfont, 0xcc, sizeof(logfont));
+ hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(system, "got %d\n", system);
+
+ sim = IDWriteFont_GetSimulations(font);
+
+ get_logfont_from_font(font, &lf);
+ ok(logfont.lfItalic == lf.lfItalic, "%s: unexpected italic flag %d, oblique simulation %s\n",
+ wine_dbgstr_w(nameW), logfont.lfItalic, sim & DWRITE_FONT_SIMULATIONS_OBLIQUE ? "yes" : "no");
+
+ ok(logfont.lfWeight > 0, "got %d\n", logfont.lfWeight);
+ ok(logfont.lfOutPrecision == OUT_OUTLINE_PRECIS, "got %d\n", logfont.lfOutPrecision);
+ ok(logfont.lfClipPrecision == 0, "got %d\n", logfont.lfClipPrecision);
+ ok(logfont.lfQuality == 0, "got %d\n", logfont.lfQuality);
+ ok(logfont.lfPitchAndFamily == 0, "got %d\n", logfont.lfPitchAndFamily);
+ ok(logfont.lfFaceName[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont.lfFaceName));
+
+ IDWriteFont_Release(font);
+ }
+
+ IDWriteFontFamily_Release(family);
+ }
IDWriteFactory_Release(factory2);
--
2.10.2
More information about the wine-patches
mailing list