dwrite: Fix lfItalic flag as returned by ConvertFontToLOGFONT().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Nikolay Sivov 2016-12-04 19:22:13 +03:00 committed by Alexandre Julliard
parent 3316f90418
commit a7fd13c244
5 changed files with 155 additions and 40 deletions

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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);