From 6fd4f963f69f50c3a062e305b89635ff872238b9 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 15 Jun 2015 01:13:00 +0300 Subject: [PATCH] dwrite: Initial implementation of Draw() for trimming sign. --- dlls/dwrite/dwrite_private.h | 2 +- dlls/dwrite/layout.c | 33 +++++++++++++++++++++++++-------- dlls/dwrite/main.c | 2 +- dlls/dwrite/tests/layout.c | 15 +++++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index a692e38e2de..34f67f012df 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -103,7 +103,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_gdicompat_textlayout(const WCHAR*,UINT32,IDWriteTextFormat*,FLOAT,FLOAT,FLOAT,const DWRITE_MATRIX*,BOOL,IDWriteTextLayout**) DECLSPEC_HIDDEN; -extern HRESULT create_trimmingsign(IDWriteTextFormat*,IDWriteInlineObject**) DECLSPEC_HIDDEN; +extern HRESULT create_trimmingsign(IDWriteFactory2*,IDWriteTextFormat*,IDWriteInlineObject**) DECLSPEC_HIDDEN; extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN; extern HRESULT create_gdiinterop(IDWriteFactory2*,IDWriteGdiInterop**) DECLSPEC_HIDDEN; extern void release_gdiinterop(IDWriteGdiInterop*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index bd50e8b5af1..74cdc46be00 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -243,6 +243,8 @@ struct dwrite_textformat { struct dwrite_trimmingsign { IDWriteInlineObject IDWriteInlineObject_iface; LONG ref; + + IDWriteTextLayout *layout; }; struct dwrite_typography { @@ -3371,7 +3373,6 @@ static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *ifa *obj = NULL; return E_NOINTERFACE; - } static ULONG WINAPI dwritetrimmingsign_AddRef(IDWriteInlineObject *iface) @@ -3389,18 +3390,24 @@ static ULONG WINAPI dwritetrimmingsign_Release(IDWriteInlineObject *iface) TRACE("(%p)->(%d)\n", This, ref); - if (!ref) + if (!ref) { + IDWriteTextLayout_Release(This->layout); heap_free(This); + } return ref; } static HRESULT WINAPI dwritetrimmingsign_Draw(IDWriteInlineObject *iface, void *context, IDWriteTextRenderer *renderer, - FLOAT originX, FLOAT originY, BOOL is_sideways, BOOL is_rtl, IUnknown *drawing_effect) + FLOAT originX, FLOAT originY, BOOL is_sideways, BOOL is_rtl, IUnknown *effect) { struct dwrite_trimmingsign *This = impl_from_IDWriteInlineObject(iface); - FIXME("(%p)->(%p %p %f %f %d %d %p): stub\n", This, context, renderer, originX, originY, is_sideways, is_rtl, drawing_effect); - return E_NOTIMPL; + DWRITE_TEXT_RANGE range = { 0, ~0u }; + + TRACE("(%p)->(%p %p %.2f %.2f %d %d %p)\n", This, context, renderer, originX, originY, is_sideways, is_rtl, effect); + + IDWriteTextLayout_SetDrawingEffect(This->layout, effect, range); + return IDWriteTextLayout_Draw(This->layout, context, renderer, originX, originY); } static HRESULT WINAPI dwritetrimmingsign_GetMetrics(IDWriteInlineObject *iface, DWRITE_INLINE_OBJECT_METRICS *metrics) @@ -3463,11 +3470,13 @@ static inline BOOL is_flow_direction_vert(DWRITE_FLOW_DIRECTION direction) (direction == DWRITE_FLOW_DIRECTION_BOTTOM_TO_TOP); } -HRESULT create_trimmingsign(IDWriteTextFormat *format, IDWriteInlineObject **sign) +HRESULT create_trimmingsign(IDWriteFactory2 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign) { + static const WCHAR ellipsisW = 0x2026; struct dwrite_trimmingsign *This; DWRITE_READING_DIRECTION reading; DWRITE_FLOW_DIRECTION flow; + HRESULT hr; *sign = NULL; @@ -3480,12 +3489,20 @@ HRESULT create_trimmingsign(IDWriteTextFormat *format, IDWriteInlineObject **sig (is_reading_direction_vert(reading) && is_flow_direction_vert(flow))) return DWRITE_E_FLOWDIRECTIONCONFLICTS; - This = heap_alloc(sizeof(struct dwrite_trimmingsign)); - if (!This) return E_OUTOFMEMORY; + This = heap_alloc(sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; This->IDWriteInlineObject_iface.lpVtbl = &dwritetrimmingsignvtbl; This->ref = 1; + hr = IDWriteFactory2_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0, 0.0, &This->layout); + if (FAILED(hr)) { + heap_free(This); + return hr; + } + + IDWriteTextLayout_SetWordWrapping(This->layout, DWRITE_WORD_WRAPPING_NO_WRAP); *sign = &This->IDWriteInlineObject_iface; return S_OK; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 10597f82d66..96b49251451 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1052,7 +1052,7 @@ static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory2 * { struct dwritefactory *This = impl_from_IDWriteFactory2(iface); TRACE("(%p)->(%p %p)\n", This, format, trimming_sign); - return create_trimmingsign(format, trimming_sign); + return create_trimmingsign(iface, format, trimming_sign); } static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory2 *iface, IDWriteTextAnalyzer **analyzer) diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index f041979950a..d03d14a84e8 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -856,12 +856,18 @@ static void test_GetLocaleName(void) IDWriteFactory_Release(factory); } +static const struct drawcall_entry drawellipsis_seq[] = { + { DRAW_GLYPHRUN, {0x2026, 0} }, + { DRAW_LAST_KIND } +}; + static void test_CreateEllipsisTrimmingSign(void) { DWRITE_BREAK_CONDITION before, after; IDWriteTextFormat *format; IDWriteInlineObject *sign; IDWriteFactory *factory; + IUnknown *unk; HRESULT hr; factory = create_factory(); @@ -875,6 +881,9 @@ static void test_CreateEllipsisTrimmingSign(void) ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(format, 1); + hr = IDWriteInlineObject_QueryInterface(sign, &IID_IDWriteTextLayout, (void**)&unk); + ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); + if (0) /* crashes on native */ hr = IDWriteInlineObject_GetBreakConditions(sign, NULL, NULL); @@ -883,6 +892,12 @@ if (0) /* crashes on native */ ok(hr == S_OK, "got 0x%08x\n", hr); ok(before == DWRITE_BREAK_CONDITION_NEUTRAL, "got %d\n", before); ok(after == DWRITE_BREAK_CONDITION_NEUTRAL, "got %d\n", after); + + /* Draw tests */ + flush_sequence(sequences, RENDERER_ID); + hr = IDWriteInlineObject_Draw(sign, NULL, &testrenderer, 0.0, 0.0, FALSE, FALSE, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok_sequence(sequences, RENDERER_ID, drawellipsis_seq, "ellipsis sign draw test", FALSE); IDWriteInlineObject_Release(sign); /* non-orthogonal flow/reading combination */