Nikolay Sivov : dwrite: Implement ConvertFontToLOGFONT().

Alexandre Julliard julliard at wine.codeweavers.com
Fri Nov 7 06:44:37 CST 2014


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

Author: Nikolay Sivov <nsivov at 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);
 }




More information about the wine-cvs mailing list