Nikolay Sivov : dwrite: Check format directions in CreateEllipsisTrimmingSign().

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jun 15 08:49:08 CDT 2015


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Jun 15 00:39:32 2015 +0300

dwrite: Check format directions in CreateEllipsisTrimmingSign().

---

 dlls/dwrite/dwrite_private.h |  2 +-
 dlls/dwrite/layout.c         | 47 +++++++++++++++++++++++++++++++-
 dlls/dwrite/main.c           |  4 +--
 dlls/dwrite/tests/layout.c   | 64 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 112 insertions(+), 5 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index cd6d08c..a692e38 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(IDWriteInlineObject**) DECLSPEC_HIDDEN;
+extern HRESULT create_trimmingsign(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 bdd8ad6..bd50e8b 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -3439,12 +3439,47 @@ static const IDWriteInlineObjectVtbl dwritetrimmingsignvtbl = {
     dwritetrimmingsign_GetBreakConditions
 };
 
-HRESULT create_trimmingsign(IDWriteInlineObject **sign)
+static inline BOOL is_reading_direction_horz(DWRITE_READING_DIRECTION direction)
+{
+    return (direction == DWRITE_READING_DIRECTION_LEFT_TO_RIGHT) ||
+           (direction == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
+}
+
+static inline BOOL is_reading_direction_vert(DWRITE_READING_DIRECTION direction)
+{
+    return (direction == DWRITE_READING_DIRECTION_TOP_TO_BOTTOM) ||
+           (direction == DWRITE_READING_DIRECTION_BOTTOM_TO_TOP);
+}
+
+static inline BOOL is_flow_direction_horz(DWRITE_FLOW_DIRECTION direction)
+{
+    return (direction == DWRITE_FLOW_DIRECTION_LEFT_TO_RIGHT) ||
+           (direction == DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT);
+}
+
+static inline BOOL is_flow_direction_vert(DWRITE_FLOW_DIRECTION direction)
+{
+    return (direction == DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM) ||
+           (direction == DWRITE_FLOW_DIRECTION_BOTTOM_TO_TOP);
+}
+
+HRESULT create_trimmingsign(IDWriteTextFormat *format, IDWriteInlineObject **sign)
 {
     struct dwrite_trimmingsign *This;
+    DWRITE_READING_DIRECTION reading;
+    DWRITE_FLOW_DIRECTION flow;
 
     *sign = NULL;
 
+    /* Validate reading/flow direction here, layout creation won't complain about
+       invalid combinations. */
+    reading = IDWriteTextFormat_GetReadingDirection(format);
+    flow = IDWriteTextFormat_GetFlowDirection(format);
+
+    if ((is_reading_direction_horz(reading) && is_flow_direction_horz(flow)) ||
+        (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;
 
@@ -3527,7 +3562,12 @@ static HRESULT WINAPI dwritetextformat_SetWordWrapping(IDWriteTextFormat1 *iface
 static HRESULT WINAPI dwritetextformat_SetReadingDirection(IDWriteTextFormat1 *iface, DWRITE_READING_DIRECTION direction)
 {
     struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
+
     TRACE("(%p)->(%d)\n", This, direction);
+
+    if ((UINT32)direction > DWRITE_READING_DIRECTION_BOTTOM_TO_TOP)
+        return E_INVALIDARG;
+
     This->format.readingdir = direction;
     return S_OK;
 }
@@ -3535,7 +3575,12 @@ static HRESULT WINAPI dwritetextformat_SetReadingDirection(IDWriteTextFormat1 *i
 static HRESULT WINAPI dwritetextformat_SetFlowDirection(IDWriteTextFormat1 *iface, DWRITE_FLOW_DIRECTION direction)
 {
     struct dwrite_textformat *This = impl_from_IDWriteTextFormat1(iface);
+
     TRACE("(%p)->(%d)\n", This, direction);
+
+    if ((UINT32)direction > DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT)
+        return E_INVALIDARG;
+
     This->format.flow = direction;
     return S_OK;
 }
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 20f9d36..10597f8 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1051,8 +1051,8 @@ static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory2 *
     IDWriteInlineObject **trimming_sign)
 {
     struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
-    FIXME("(%p)->(%p %p): semi-stub\n", This, format, trimming_sign);
-    return create_trimmingsign(trimming_sign);
+    TRACE("(%p)->(%p %p)\n", This, format, trimming_sign);
+    return create_trimmingsign(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 2b19961..f041979 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -883,8 +883,19 @@ 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);
-
     IDWriteInlineObject_Release(sign);
+
+    /* non-orthogonal flow/reading combination */
+    hr = IDWriteTextFormat_SetReadingDirection(format, DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteTextFormat_SetFlowDirection(format, DWRITE_FLOW_DIRECTION_LEFT_TO_RIGHT);
+    ok(hr == S_OK || broken(hr == E_INVALIDARG) /* vista, win7 */, "got 0x%08x\n", hr);
+    if (hr == S_OK) {
+        hr = IDWriteFactory_CreateEllipsisTrimmingSign(factory, format, &sign);
+        ok(hr == DWRITE_E_FLOWDIRECTIONCONFLICTS, "got 0x%08x\n", hr);
+    }
+
     IDWriteTextFormat_Release(format);
     IDWriteFactory_Release(factory);
 }
@@ -2362,6 +2373,56 @@ todo_wine {
     IDWriteFactory_Release(factory);
 }
 
+static void test_SetFlowDirection(void)
+{
+    static const WCHAR strW[] = {'a','b','c','d',0};
+    DWRITE_READING_DIRECTION reading;
+    DWRITE_FLOW_DIRECTION flow;
+    IDWriteTextFormat *format;
+    IDWriteTextLayout *layout;
+    IDWriteFactory *factory;
+    HRESULT hr;
+
+    factory = create_factory();
+
+    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);
+
+    flow = IDWriteTextFormat_GetFlowDirection(format);
+    ok(flow == DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM, "got %d\n", flow);
+
+    reading = IDWriteTextFormat_GetReadingDirection(format);
+    ok(reading == DWRITE_READING_DIRECTION_LEFT_TO_RIGHT, "got %d\n", reading);
+
+    hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IDWriteTextLayout_Release(layout);
+
+    hr = IDWriteTextFormat_SetFlowDirection(format, DWRITE_FLOW_DIRECTION_LEFT_TO_RIGHT);
+    ok(hr == S_OK || broken(hr == E_INVALIDARG) /* vista,win7 */, "got 0x%08x\n", hr);
+    if (hr == S_OK) {
+        hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        IDWriteTextLayout_Release(layout);
+
+        hr = IDWriteTextFormat_SetReadingDirection(format, DWRITE_READING_DIRECTION_TOP_TO_BOTTOM);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IDWriteTextFormat_SetFlowDirection(format, DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        IDWriteTextLayout_Release(layout);
+    }
+    else
+        win_skip("DWRITE_FLOW_DIRECTION_LEFT_TO_RIGHT is not supported\n");
+
+    IDWriteTextFormat_Release(format);
+    IDWriteFactory_Release(factory);
+}
+
 START_TEST(layout)
 {
     static const WCHAR ctrlstrW[] = {0x202a,0};
@@ -2399,6 +2460,7 @@ START_TEST(layout)
     test_SetFontStretch();
     test_SetStrikethrough();
     test_GetMetrics();
+    test_SetFlowDirection();
 
     IDWriteFactory_Release(factory);
 }




More information about the wine-cvs mailing list