d2d1: Implement retrieving dash pattern data for stroke styles.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4b8bcdf8f6
commit
caac983742
|
@ -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);
|
||||
|
||||
return 0;
|
||||
TRACE("iface %p.\n", iface);
|
||||
|
||||
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,8 +3390,77 @@ 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));
|
||||
|
|
Loading…
Reference in New Issue