Module: wine Branch: master Commit: a8ad62aa51f8da1e86dd05a41186322467079210 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a8ad62aa51f8da1e86dd05a411...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Nov 7 13:17:38 2014 +0300
dwrite: Implement ConvertFontToLOGFONT().
---
dlls/dwrite/dwrite_private.h | 3 ++- dlls/dwrite/font.c | 22 ++++++++++++++---- dlls/dwrite/gdiinterop.c | 50 ++++++++++++++++++++++++++++++++++++++-- dlls/dwrite/main.c | 2 +- dlls/dwrite/tests/font.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 8 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index b606d23..57983ed 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -106,7 +106,8 @@ extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN; extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN; extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN; extern HRESULT create_fontface(DWRITE_FONT_FACE_TYPE,UINT32,IDWriteFontFile* const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace2**) DECLSPEC_HIDDEN; -extern HRESULT create_font_collection(IDWriteFactory*,IDWriteFontFileEnumerator*,IDWriteFontCollection**) DECLSPEC_HIDDEN; +extern HRESULT create_font_collection(IDWriteFactory*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection**) DECLSPEC_HIDDEN; +extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN;
/* Opentype font table functions */ extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 36d333f..8bb39fa 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -31,6 +31,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p') #define MS_NAME_TAG DWRITE_MAKE_OPENTYPE_TAG('n','a','m','e')
+static const IID IID_issystemcollection = {0x14d88047,0x331f,0x4cd3,{0xbc,0xa8,0x3e,0x67,0x99,0xaf,0x34,0x75}}; + struct dwrite_font_data { LONG ref;
@@ -66,6 +68,7 @@ struct dwrite_fontcollection { struct dwrite_fontfamily_data **family_data; UINT32 family_count; UINT32 family_alloc; + BOOL is_system; };
struct dwrite_fontfamily { @@ -1190,6 +1193,12 @@ static HRESULT create_fontfamily(struct dwrite_fontfamily_data *data, IDWriteFon return S_OK; }
+BOOL is_system_collection(IDWriteFontCollection *collection) +{ + void *obj; + return IDWriteFontCollection_QueryInterface(collection, &IID_issystemcollection, (void**)&obj) == S_OK; +} + static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection *iface, REFIID riid, void **obj) { struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); @@ -1204,6 +1213,10 @@ static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection }
*obj = NULL; + + if (This->is_system && IsEqualIID(riid, &IID_issystemcollection)) + return S_OK; + return E_NOINTERFACE; }
@@ -1413,12 +1426,13 @@ static HRESULT fontcollection_add_family(struct dwrite_fontcollection *collectio return S_OK; }
-static HRESULT init_font_collection(struct dwrite_fontcollection *collection) +static HRESULT init_font_collection(struct dwrite_fontcollection *collection, BOOL is_system) { collection->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl; collection->ref = 1; collection->family_count = 0; collection->family_alloc = 2; + collection->is_system = is_system;
collection->family_data = heap_alloc(sizeof(*collection->family_data)*2); if (!collection->family_data) @@ -1506,7 +1520,7 @@ static HRESULT init_fontfamily_data(IDWriteLocalizedStrings *familyname, struct return S_OK; }
-HRESULT create_font_collection(IDWriteFactory* factory, IDWriteFontFileEnumerator *enumerator, IDWriteFontCollection **ret) +HRESULT create_font_collection(IDWriteFactory* factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, IDWriteFontCollection **ret) { struct dwrite_fontcollection *collection; BOOL current = FALSE; @@ -1517,7 +1531,7 @@ HRESULT create_font_collection(IDWriteFactory* factory, IDWriteFontFileEnumerato collection = heap_alloc(sizeof(struct dwrite_fontcollection)); if (!collection) return E_OUTOFMEMORY;
- hr = init_font_collection(collection); + hr = init_font_collection(collection, is_system); if (FAILED(hr)) { heap_free(collection); return hr; @@ -1765,7 +1779,7 @@ HRESULT get_system_fontcollection(IDWriteFactory *factory, IDWriteFontCollection return hr;
TRACE("building system font collection for factory %p\n", factory); - hr = create_font_collection(factory, enumerator, collection); + hr = create_font_collection(factory, enumerator, TRUE, collection); IDWriteFontFileEnumerator_Release(enumerator); return hr; } diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c index b099e52..3715bf0 100644 --- a/dlls/dwrite/gdiinterop.c +++ b/dlls/dwrite/gdiinterop.c @@ -326,8 +326,54 @@ static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop *iface, IDWriteFont *font, LOGFONTW *logfont, BOOL *is_systemfont) { struct gdiinterop *This = impl_from_IDWriteGdiInterop(iface); - FIXME("(%p)->(%p %p %p): stub\n", This, font, logfont, is_systemfont); - return E_NOTIMPL; + 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; + + TRACE("(%p)->(%p %p %p)\n", This, font, logfont, is_systemfont); + + *is_systemfont = FALSE; + + if (!font) + return E_INVALIDARG; + + hr = IDWriteFont_GetFontFamily(font, &family); + if (FAILED(hr)) + return hr; + + hr = IDWriteFontFamily_GetFontCollection(family, &collection); + IDWriteFontFamily_Release(family); + if (FAILED(hr)) + return hr; + + *is_systemfont = is_system_collection(collection); + IDWriteFontCollection_Release(collection); + + simulations = IDWriteFont_GetSimulations(font); + style = IDWriteFont_GetStyle(font); + + 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; + + exists = FALSE; + hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &name, &exists); + if (FAILED(hr) || !exists) + return hr; + + IDWriteLocalizedStrings_FindLocaleName(name, enusW, &index, &exists); + IDWriteLocalizedStrings_GetString(name, index, logfont->lfFaceName, sizeof(logfont->lfFaceName)/sizeof(WCHAR)); + IDWriteLocalizedStrings_Release(name); + + return S_OK; }
static HRESULT WINAPI gdiinterop_ConvertFontFaceToLOGFONT(IDWriteGdiInterop *iface, diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 023ae4f..2868c3b 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -631,7 +631,7 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *i if (FAILED(hr)) return hr;
- hr = create_font_collection(iface, enumerator, collection); + hr = create_font_collection(iface, enumerator, FALSE, collection); IDWriteFontFileEnumerator_Release(enumerator); return hr; } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index d7e61e5..60d0d44 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -2266,6 +2266,60 @@ todo_wine DeleteFileW(test_fontfile); }
+static void test_ConvertFontToLOGFONT(void) +{ + IDWriteFactory *factory, *factory2; + IDWriteFontCollection *collection; + IDWriteGdiInterop *interop; + IDWriteFontFamily *family; + IDWriteFont *font; + LOGFONTW logfont; + BOOL system; + HRESULT hr; + + factory = create_factory(); + factory2 = create_factory(); + + interop = NULL; + hr = IDWriteFactory_GetGdiInterop(factory, &interop); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_GetSystemFontCollection(factory2, &collection, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontCollection_GetFontFamily(collection, 0, &family); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + +if (0) { /* crashes on native */ + IDWriteGdiInterop_ConvertFontToLOGFONT(interop, NULL, NULL, NULL); + IDWriteGdiInterop_ConvertFontToLOGFONT(interop, NULL, &logfont, NULL); + IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, NULL, &system); +} + system = TRUE; + hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, NULL, &logfont, &system); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(!system, "got %d\n", system); + + system = FALSE; + memset(&logfont, 0, sizeof(logfont)); + hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(system, "got %d\n", system); + ok(logfont.lfFaceName[0] != 0, "got face name %s\n", wine_dbgstr_w(logfont.lfFaceName)); + + IDWriteFactory_Release(factory2); + + IDWriteFontCollection_Release(collection); + IDWriteFontFamily_Release(family); + IDWriteFont_Release(font); + IDWriteGdiInterop_Release(interop); + IDWriteFactory_Release(factory); +} + START_TEST(font) { IDWriteFactory *factory; @@ -2296,6 +2350,7 @@ START_TEST(font) test_GetSimulations(); test_GetFaceNames(); test_TryGetFontTable(); + test_ConvertFontToLOGFONT();
IDWriteFactory_Release(factory); }