From: Nikolay Sivov Subject: [PATCH] dwrite: Added IDWriteTypography implementation Message-Id: <541BAA2C.70400@codeweavers.com> Date: Fri, 19 Sep 2014 07:59:40 +0400 --- From 8cda53175baba023844cb15759f5584d32f4364e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 19 Sep 2014 07:54:00 +0400 Subject: [PATCH] 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..3e83537 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; +} \ No newline at end of file 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); } -- 2.1.0