diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 24fb5806381..32c248b5564 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -57,6 +57,7 @@ struct dwrite_textformat_data { IDWriteInlineObject *trimmingsign; IDWriteFontCollection *collection; + IDWriteFontFallback *fallback; }; enum layout_range_attr_kind { @@ -173,6 +174,7 @@ static const IDWriteTextFormat1Vtbl dwritetextformatvtbl; static void release_format_data(struct dwrite_textformat_data *data) { if (data->collection) IDWriteFontCollection_Release(data->collection); + if (data->fallback) IDWriteFontFallback_Release(data->fallback); if (data->trimmingsign) IDWriteInlineObject_Release(data->trimmingsign); heap_free(data->family_name); heap_free(data->locale); @@ -219,6 +221,14 @@ static inline const char *debugstr_run(const struct layout_run *run) run->descr.stringLength); } +static HRESULT get_fontfallback_from_format(const struct dwrite_textformat_data *format, IDWriteFontFallback **fallback) +{ + *fallback = format->fallback; + if (*fallback) + IDWriteFontFallback_AddRef(*fallback); + return S_OK; +} + static struct layout_run *alloc_layout_run(void) { struct layout_run *ret; @@ -1877,8 +1887,8 @@ static HRESULT WINAPI dwritetextlayout2_SetFontFallback(IDWriteTextLayout2 *ifac static HRESULT WINAPI dwritetextlayout2_GetFontFallback(IDWriteTextLayout2 *iface, IDWriteFontFallback **fallback) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); - FIXME("(%p)->(%p): stub\n", This, fallback); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, fallback); + return get_fontfallback_from_format(&This->format, fallback); } static const IDWriteTextLayout2Vtbl dwritetextlayoutvtbl = { @@ -2194,6 +2204,7 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format); layout->format.readingdir = IDWriteTextFormat_GetReadingDirection(format); layout->format.flow = IDWriteTextFormat_GetFlowDirection(format); + layout->format.fallback = NULL; hr = IDWriteTextFormat_GetLineSpacing(format, &layout->format.spacingmethod, &layout->format.spacing, &layout->format.baseline); if (FAILED(hr)) @@ -2228,6 +2239,7 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I hr = IDWriteTextFormat_QueryInterface(format, &IID_IDWriteTextFormat1, (void**)&format1); if (hr == S_OK) { layout->format.vertical_orientation = IDWriteTextFormat1_GetVerticalGlyphOrientation(format1); + IDWriteTextFormat1_GetFontFallback(format1, &layout->format.fallback); IDWriteTextFormat1_Release(format1); } else @@ -2745,8 +2757,8 @@ static HRESULT WINAPI dwritetextformat1_SetFontFallback(IDWriteTextFormat1 *ifac static HRESULT WINAPI dwritetextformat1_GetFontFallback(IDWriteTextFormat1 *iface, IDWriteFontFallback **fallback) { struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface); - FIXME("(%p)->(%p): stub\n", This, fallback); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, fallback); + return get_fontfallback_from_format(&This->format, fallback); } static const IDWriteTextFormat1Vtbl dwritetextformatvtbl = { @@ -2822,6 +2834,7 @@ HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *colle This->format.trimming.delimiterCount = 0; This->format.trimmingsign = NULL; This->format.collection = collection; + This->format.fallback = NULL; IDWriteFontCollection_AddRef(collection); *format = (IDWriteTextFormat*)&This->IDWriteTextFormat1_iface; diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index a0de75eafb2..663605e2d73 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -1122,6 +1122,42 @@ static void test_SetVerticalGlyphOrientation(void) IDWriteTextLayout2_Release(layout2); } +static void test_fallback(void) +{ + static const WCHAR strW[] = {'a','b','c','d',0}; + IDWriteFontFallback *fallback; + IDWriteTextLayout2 *layout2; + IDWriteTextFormat *format; + IDWriteTextLayout *layout; + HRESULT hr; + + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDWriteTextFormat_Release(format); + + hr = IDWriteTextLayout_QueryInterface(layout, &IID_IDWriteTextLayout2, (void**)&layout2); + IDWriteTextLayout_Release(layout); + + if (hr != S_OK) { + win_skip("GetFontFallback() is not supported.\n"); + return; + } + +if (0) /* crashes on native */ + hr = IDWriteTextLayout2_GetFontFallback(layout2, NULL); + + fallback = (void*)0xdeadbeef; + hr = IDWriteTextLayout2_GetFontFallback(layout2, &fallback); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(fallback == NULL, "got %p\n", fallback); + + IDWriteTextLayout2_Release(layout2); +} + START_TEST(layout) { HRESULT hr; @@ -1150,6 +1186,7 @@ START_TEST(layout) test_SetLocaleName(); test_SetPairKerning(); test_SetVerticalGlyphOrientation(); + test_fallback(); IDWriteFactory_Release(factory); }