[v2 PATCH] d2d1: Implement retrieving dash pattern data for stroke styles
Nikolay Sivov
nsivov at codeweavers.com
Thu Nov 24 05:29:37 CST 2016
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
v2: fixed GetDashes() when requested dash count exceeds actual dash count
dlls/d2d1/d2d1_private.h | 4 ++-
dlls/d2d1/factory.c | 8 ++++-
dlls/d2d1/stroke.c | 59 +++++++++++++++++++++++++++++----
dlls/d2d1/tests/d2d1.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 148 insertions(+), 8 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index bfe60ee..29823cc 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -224,9 +224,11 @@ struct d2d_stroke_style
ID2D1Factory *factory;
D2D1_STROKE_STYLE_PROPERTIES desc;
+ float *dashes;
+ UINT32 dash_count;
};
-void d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *factory,
+HRESULT d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *factory,
const D2D1_STROKE_STYLE_PROPERTIES *desc, const float *dashes, UINT32 dash_count) DECLSPEC_HIDDEN;
struct d2d_mesh
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c
index 6de0271..3bb240f 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -213,6 +213,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory *ifa
ID2D1StrokeStyle **stroke_style)
{
struct d2d_stroke_style *object;
+ HRESULT hr;
TRACE("iface %p, desc %p, dashes %p, dash_count %u, stroke_style %p.\n",
iface, desc, dashes, dash_count, stroke_style);
@@ -220,7 +221,12 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory *ifa
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
- d2d_stroke_style_init(object, iface, desc, dashes, dash_count);
+ if (FAILED(hr = d2d_stroke_style_init(object, iface, desc, dashes, dash_count)))
+ {
+ WARN("Failed to initialize stroke style, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
TRACE("Created stroke style %p.\n", object);
*stroke_style = &object->ID2D1StrokeStyle_iface;
diff --git a/dlls/d2d1/stroke.c b/dlls/d2d1/stroke.c
index 3b5dbfd..c5a1d50 100644
--- a/dlls/d2d1/stroke.c
+++ b/dlls/d2d1/stroke.c
@@ -67,6 +67,8 @@ static ULONG STDMETHODCALLTYPE d2d_stroke_style_Release(ID2D1StrokeStyle *iface)
if (!refcount)
{
ID2D1Factory_Release(style->factory);
+ if (style->desc.dashStyle == D2D1_DASH_STYLE_CUSTOM)
+ HeapFree(GetProcessHeap(), 0, style->dashes);
HeapFree(GetProcessHeap(), 0, style);
}
@@ -147,14 +149,22 @@ static D2D1_DASH_STYLE STDMETHODCALLTYPE d2d_stroke_style_GetDashStyle(ID2D1Stro
static UINT32 STDMETHODCALLTYPE d2d_stroke_style_GetDashesCount(ID2D1StrokeStyle *iface)
{
- FIXME("iface %p stub!\n", iface);
+ struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface);
+
+ TRACE("iface %p.\n", iface);
- return 0;
+ return style->dash_count;
}
-static void STDMETHODCALLTYPE d2d_stroke_style_GetDashes(ID2D1StrokeStyle *iface, float *dashes, UINT32 count)
+static void STDMETHODCALLTYPE d2d_stroke_style_GetDashes(ID2D1StrokeStyle *iface, float *dashes, UINT32 dash_count)
{
- FIXME("iface %p, dashes %p, count %u stub!\n", iface, dashes, count);
+ struct d2d_stroke_style *style = impl_from_ID2D1StrokeStyle(iface);
+
+ TRACE("iface %p, dashes %p, count %u.\n", iface, dashes, dash_count);
+
+ memcpy(dashes, style->dashes, min(style->dash_count, dash_count) * sizeof(*dashes));
+ if (dash_count > style->dash_count)
+ memset(dashes + style->dash_count, 0, (dash_count - style->dash_count) * sizeof(*dashes));
}
static const struct ID2D1StrokeStyleVtbl d2d_stroke_style_vtbl =
@@ -174,13 +184,50 @@ static const struct ID2D1StrokeStyleVtbl d2d_stroke_style_vtbl =
d2d_stroke_style_GetDashes,
};
-void d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *factory,
+HRESULT d2d_stroke_style_init(struct d2d_stroke_style *style, ID2D1Factory *factory,
const D2D1_STROKE_STYLE_PROPERTIES *desc, const float *dashes, UINT32 dash_count)
{
- FIXME("Ignoring stroke style properties.\n");
+ static const struct
+ {
+ UINT32 dash_count;
+ float dashes[6];
+ }
+ builtin_dash_styles[] =
+ {
+ /* D2D1_DASH_STYLE_SOLID */ { 0 },
+ /* D2D1_DASH_STYLE_DASH */ { 2, {2.0f, 2.0f}},
+ /* D2D1_DASH_STYLE_DOT */ { 2, {0.0f, 2.0f}},
+ /* D2D1_DASH_STYLE_DASH_DOT */ { 4, {2.0f, 2.0f, 0.0f, 2.0f}},
+ /* D2D1_DASH_STYLE_DASH_DOT_DOT */ { 6, {2.0f, 2.0f, 0.0f, 2.0f, 0.0f, 2.0f}},
+ };
+
+ if (desc->dashStyle > D2D1_DASH_STYLE_CUSTOM)
+ return E_INVALIDARG;
style->ID2D1StrokeStyle_iface.lpVtbl = &d2d_stroke_style_vtbl;
style->refcount = 1;
+
+ if (desc->dashStyle == D2D1_DASH_STYLE_CUSTOM)
+ {
+ if (!dashes || !dash_count)
+ return E_INVALIDARG;
+
+ if (!(style->dashes = HeapAlloc(GetProcessHeap(), 0, dash_count * sizeof(*style->dashes))))
+ return E_OUTOFMEMORY;
+ memcpy(style->dashes, dashes, dash_count * sizeof(*style->dashes));
+ style->dash_count = dash_count;
+ }
+ else
+ {
+ if (dashes)
+ return E_INVALIDARG;
+
+ style->dashes = (float *)builtin_dash_styles[desc->dashStyle].dashes;
+ style->dash_count = builtin_dash_styles[desc->dashStyle].dash_count;
+ }
+
ID2D1Factory_AddRef(style->factory = factory);
style->desc = *desc;
+
+ return S_OK;
}
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 857cba2..7fcda64 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -3335,6 +3335,20 @@ static void test_desktop_dpi(void)
static void test_stroke_style(void)
{
+ static const struct
+ {
+ D2D1_DASH_STYLE dash_style;
+ UINT32 dash_count;
+ float dashes[6];
+ }
+ dash_style_tests[] =
+ {
+ {D2D1_DASH_STYLE_SOLID, 0},
+ {D2D1_DASH_STYLE_DASH, 2, {2.0f, 2.0f}},
+ {D2D1_DASH_STYLE_DOT, 2, {0.0f, 2.0f}},
+ {D2D1_DASH_STYLE_DASH_DOT, 4, {2.0f, 2.0f, 0.0f, 2.0f}},
+ {D2D1_DASH_STYLE_DASH_DOT_DOT, 6, {2.0f, 2.0f, 0.0f, 2.0f, 0.0f, 2.0f}},
+ };
D2D1_STROKE_STYLE_PROPERTIES desc;
ID2D1StrokeStyle *style;
ID2D1Factory *factory;
@@ -3344,6 +3358,8 @@ static void test_stroke_style(void)
D2D1_LINE_JOIN line_join;
float miter_limit, dash_offset;
D2D1_DASH_STYLE dash_style;
+ unsigned int i;
+ float dashes[2];
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
@@ -3374,9 +3390,78 @@ static void test_stroke_style(void)
dash_offset = ID2D1StrokeStyle_GetDashOffset(style);
ok(dash_offset == -1.0f, "Unexpected dash offset %f.\n", dash_offset);
+ /* Custom dash pattern, no dashes data specified. */
+ desc.startCap = D2D1_CAP_STYLE_SQUARE;
+ desc.endCap = D2D1_CAP_STYLE_ROUND;
+ desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
+ desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ desc.miterLimit = 1.5f;
+ desc.dashStyle = D2D1_DASH_STYLE_CUSTOM;
+ desc.dashOffset = 0.0f;
+
+ hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
+ ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
+
+ hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 0, &style);
+ ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
+ hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
+ ok(hr == S_OK, "Unexpected return value, %#x.\n", hr);
ID2D1StrokeStyle_Release(style);
+ /* Builtin style, dashes are specified. */
+ desc.dashStyle = D2D1_DASH_STYLE_DOT;
+ hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
+ ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
+
+ /* Invalid style. */
+ desc.dashStyle = 100;
+ hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
+ ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
+
+ /* Test returned dash pattern for builtin styles. */
+ desc.startCap = D2D1_CAP_STYLE_SQUARE;
+ desc.endCap = D2D1_CAP_STYLE_ROUND;
+ desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
+ desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ desc.miterLimit = 1.5f;
+ desc.dashOffset = 0.0f;
+
+ for (i = 0; i < sizeof(dash_style_tests)/sizeof(dash_style_tests[0]); i++)
+ {
+ float dashes[10];
+ UINT dash_count;
+
+ desc.dashStyle = dash_style_tests[i].dash_style;
+
+ hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
+ ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
+
+ dash_count = ID2D1StrokeStyle_GetDashesCount(style);
+ ok(dash_count == dash_style_tests[i].dash_count, "%u: unexpected dash count %u, expected %u.\n",
+ i, dash_count, dash_style_tests[i].dash_count);
+ ok(dash_count < sizeof(dashes)/sizeof(dashes[0]), "%u: unexpectedly large dash count %u.\n", i, dash_count);
+ if (dash_count == dash_style_tests[i].dash_count)
+ {
+ unsigned int j;
+
+ ID2D1StrokeStyle_GetDashes(style, dashes, dash_count);
+ ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
+ "%u: unexpected dash array.\n", i);
+
+ /* Ask for more dashes than style actually has. */
+ memset(dashes, 0xcc, sizeof(dashes));
+ ID2D1StrokeStyle_GetDashes(style, dashes, sizeof(dashes)/sizeof(dashes[0]));
+ ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
+ "%u: unexpected dash array.\n", i);
+
+ for (j = dash_count; j < sizeof(dashes)/sizeof(dashes[0]); j++)
+ ok(dashes[j] == 0.0f, "%u: unexpected dash value at %u.\n", i, j);
+ }
+
+ ID2D1StrokeStyle_Release(style);
+ }
+
/* NULL dashes array, non-zero length. */
memset(&desc, 0, sizeof(desc));
hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 1, &style);
--
2.10.2
More information about the wine-patches
mailing list