Nikolay Sivov : dwrite: Added IDWriteTypography implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Sep 19 13:18:31 CDT 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Sep 19 07:54:00 2014 +0400

dwrite: Added IDWriteTypography implementation.

---

 dlls/dwrite/dwrite_private.h |   1 +
 dlls/dwrite/layout.c         | 127 +++++++++++++++++++++++++++++++++++++++++++
 dlls/dwrite/main.c           |   4 +-
 dlls/dwrite/tests/layout.c   |  46 ++++++++++++++++
 4 files changed, 176 insertions(+), 2 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 77834cd..626230e 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -88,6 +88,7 @@ extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT
                                  FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN;
 extern HRESULT create_textlayout(const WCHAR*,UINT32,IDWriteTextFormat*,FLOAT,FLOAT,IDWriteTextLayout**) DECLSPEC_HIDDEN;
 extern HRESULT create_trimmingsign(IDWriteInlineObject**) DECLSPEC_HIDDEN;
+extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN;
 extern HRESULT get_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN;
 extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
 extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 82525d8..0b33b92 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -122,6 +122,15 @@ struct dwrite_trimmingsign {
     LONG ref;
 };
 
+struct dwrite_typography {
+    IDWriteTypography IDWriteTypography_iface;
+    LONG ref;
+
+    DWRITE_FONT_FEATURE *features;
+    UINT32 allocated;
+    UINT32 count;
+};
+
 static const IDWriteTextFormatVtbl dwritetextformatvtbl;
 
 static void release_format_data(struct dwrite_textformat_data *data)
@@ -152,6 +161,11 @@ static inline struct dwrite_trimmingsign *impl_from_IDWriteInlineObject(IDWriteI
     return CONTAINING_RECORD(iface, struct dwrite_trimmingsign, IDWriteInlineObject_iface);
 }
 
+static inline struct dwrite_typography *impl_from_IDWriteTypography(IDWriteTypography *iface)
+{
+    return CONTAINING_RECORD(iface, struct dwrite_typography, IDWriteTypography_iface);
+}
+
 /* To be used in IDWriteTextLayout methods to validate and fix passed range */
 static inline BOOL validate_text_range(struct dwrite_textlayout *layout, DWRITE_TEXT_RANGE *r)
 {
@@ -1787,3 +1801,116 @@ HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *colle
 
     return S_OK;
 }
+
+static HRESULT WINAPI dwritetypography_QueryInterface(IDWriteTypography *iface, REFIID riid, void **obj)
+{
+    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
+
+    TRACE("(%p)->(%s %p)\n", typography, debugstr_guid(riid), obj);
+
+    if (IsEqualIID(riid, &IID_IDWriteTypography) || IsEqualIID(riid, &IID_IUnknown)) {
+        *obj = iface;
+        IDWriteTypography_AddRef(iface);
+        return S_OK;
+    }
+
+    *obj = NULL;
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dwritetypography_AddRef(IDWriteTypography *iface)
+{
+    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
+    ULONG ref = InterlockedIncrement(&typography->ref);
+    TRACE("(%p)->(%d)\n", typography, ref);
+    return ref;
+}
+
+static ULONG WINAPI dwritetypography_Release(IDWriteTypography *iface)
+{
+    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
+    ULONG ref = InterlockedDecrement(&typography->ref);
+
+    TRACE("(%p)->(%d)\n", typography, ref);
+
+    if (!ref) {
+        heap_free(typography->features);
+        heap_free(typography);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI dwritetypography_AddFontFeature(IDWriteTypography *iface, DWRITE_FONT_FEATURE feature)
+{
+    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
+
+    TRACE("(%p)->(%x %u)\n", typography, feature.nameTag, feature.parameter);
+
+    if (typography->count == typography->allocated) {
+        DWRITE_FONT_FEATURE *ptr = heap_realloc(typography->features, 2*typography->allocated*sizeof(DWRITE_FONT_FEATURE));
+        if (!ptr)
+            return E_OUTOFMEMORY;
+
+        typography->features = ptr;
+        typography->allocated *= 2;
+    }
+
+    typography->features[typography->count++] = feature;
+    return S_OK;
+}
+
+static UINT32 WINAPI dwritetypography_GetFontFeatureCount(IDWriteTypography *iface)
+{
+    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
+    TRACE("(%p)\n", typography);
+    return typography->count;
+}
+
+static HRESULT WINAPI dwritetypography_GetFontFeature(IDWriteTypography *iface, UINT32 index, DWRITE_FONT_FEATURE *feature)
+{
+    struct dwrite_typography *typography = impl_from_IDWriteTypography(iface);
+
+    TRACE("(%p)->(%u %p)\n", typography, index, feature);
+
+    if (index >= typography->count)
+        return E_INVALIDARG;
+
+    *feature = typography->features[index];
+    return S_OK;
+}
+
+static const IDWriteTypographyVtbl dwritetypographyvtbl = {
+    dwritetypography_QueryInterface,
+    dwritetypography_AddRef,
+    dwritetypography_Release,
+    dwritetypography_AddFontFeature,
+    dwritetypography_GetFontFeatureCount,
+    dwritetypography_GetFontFeature
+};
+
+HRESULT create_typography(IDWriteTypography **ret)
+{
+    struct dwrite_typography *typography;
+
+    *ret = NULL;
+
+    typography = heap_alloc(sizeof(*typography));
+    if (!typography)
+        return E_OUTOFMEMORY;
+
+    typography->IDWriteTypography_iface.lpVtbl = &dwritetypographyvtbl;
+    typography->ref = 1;
+    typography->allocated = 2;
+    typography->count = 0;
+
+    typography->features = heap_alloc(typography->allocated*sizeof(DWRITE_FONT_FEATURE));
+    if (!typography->features) {
+        heap_free(typography);
+        return E_OUTOFMEMORY;
+    }
+
+    *ret = &typography->IDWriteTypography_iface;
+    return S_OK;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index bcddbba..c626201 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -696,8 +696,8 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory *iface, WCHA
 static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory *iface, IDWriteTypography **typography)
 {
     struct dwritefactory *This = impl_from_IDWriteFactory(iface);
-    FIXME("(%p)->(%p): stub\n", This, typography);
-    return E_NOTIMPL;
+    TRACE("(%p)->(%p)\n", This, typography);
+    return create_typography(typography);
 }
 
 static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory *iface, IDWriteGdiInterop **gdi_interop)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index b778a80..2e4618a 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -750,6 +750,51 @@ todo_wine
     IDWriteTextLayout_Release(layout);
 }
 
+static void test_typography(void)
+{
+    DWRITE_FONT_FEATURE feature;
+    IDWriteTypography *typography;
+    UINT32 count;
+    HRESULT hr;
+
+    hr = IDWriteFactory_CreateTypography(factory, &typography);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    feature.nameTag = DWRITE_FONT_FEATURE_TAG_KERNING;
+    feature.parameter = 1;
+    hr = IDWriteTypography_AddFontFeature(typography, feature);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    count = IDWriteTypography_GetFontFeatureCount(typography);
+    ok(count == 1, "got %u\n", count);
+
+    /* duplicated features work just fine */
+    feature.nameTag = DWRITE_FONT_FEATURE_TAG_KERNING;
+    feature.parameter = 0;
+    hr = IDWriteTypography_AddFontFeature(typography, feature);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    count = IDWriteTypography_GetFontFeatureCount(typography);
+    ok(count == 2, "got %u\n", count);
+
+    memset(&feature, 0, sizeof(feature));
+    hr = IDWriteTypography_GetFontFeature(typography, 0, &feature);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(feature.nameTag == DWRITE_FONT_FEATURE_TAG_KERNING, "got tag %x\n", feature.nameTag);
+    ok(feature.parameter == 1, "got %u\n", feature.parameter);
+
+    memset(&feature, 0, sizeof(feature));
+    hr = IDWriteTypography_GetFontFeature(typography, 1, &feature);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(feature.nameTag == DWRITE_FONT_FEATURE_TAG_KERNING, "got tag %x\n", feature.nameTag);
+    ok(feature.parameter == 0, "got %u\n", feature.parameter);
+
+    hr = IDWriteTypography_GetFontFeature(typography, 2, &feature);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+
+    IDWriteTypography_Release(typography);
+}
+
 START_TEST(layout)
 {
     HRESULT hr;
@@ -773,6 +818,7 @@ START_TEST(layout)
     test_fontweight();
     test_SetInlineObject();
     test_draw_sequence();
+    test_typography();
 
     IDWriteFactory_Release(factory);
 }




More information about the wine-cvs mailing list