Commit caac9837 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

d2d1: Implement retrieving dash pattern data for stroke styles.

parent 4b8bcdf8
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment