From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 39 +++++++++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 17 +++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 5daf16fd838..7cfed6577c4 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -229,6 +229,35 @@ static const struct d2d_effect_info builtin_effects[] = {&CLSID_D2D1Grayscale, 1, 1, 1}, };
+/* Same syntax is used for value and default values. */ +static HRESULT d2d_effect_parse_vector_value(D2D1_PROPERTY_TYPE type, const WCHAR *value, + float *vec) +{ + unsigned int i, num_components; + WCHAR *end_ptr; + + assert(type == D2D1_PROPERTY_TYPE_VECTOR2 || type == D2D1_PROPERTY_TYPE_VECTOR3 + || type == D2D1_PROPERTY_TYPE_VECTOR4); + + if (*(value++) != '(') return E_INVALIDARG; + + /* Type values are sequential. */ + num_components = (type - D2D1_PROPERTY_TYPE_VECTOR2) + 2; + + for (i = 0; i < num_components; ++i) + { + vec[i] = wcstof(value, &end_ptr); + if (value == end_ptr) return E_INVALIDARG; + value = end_ptr; + + /* Trailing characters after last component are ignored. */ + if (i == num_components - 1) continue; + if (*(value++) != ',') return E_INVALIDARG; + } + + return S_OK; +} + static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties *props, const WCHAR *name, UINT32 index, BOOL subprop, D2D1_PROPERTY_TYPE type, const WCHAR *value) { @@ -255,6 +284,7 @@ static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties * sizeof(void *), /* D2D1_PROPERTY_TYPE_COLOR_CONTEXT */ }; struct d2d_effect_property *p; + HRESULT hr;
assert(type >= D2D1_PROPERTY_TYPE_STRING && type <= D2D1_PROPERTY_TYPE_COLOR_CONTEXT);
@@ -302,6 +332,7 @@ static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties * { void *src = NULL; UINT32 _uint32; + float _vec[4]; CLSID _clsid; BOOL _bool;
@@ -328,6 +359,14 @@ static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties * CLSIDFromString(value, &_clsid); src = &_clsid; break; + case D2D1_PROPERTY_TYPE_VECTOR2: + if (FAILED(hr = d2d_effect_parse_vector_value(p->type, value, _vec))) + { + WARN("Failed to parse vector value %s.\n", wine_dbgstr_w(value)); + return hr; + } + src = _vec; + break; case D2D1_PROPERTY_TYPE_IUNKNOWN: case D2D1_PROPERTY_TYPE_COLOR_CONTEXT: break; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 9dfe1e760ba..b7eab5003d7 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -54,6 +54,10 @@ L"<?xml version='1.0'?> \ <Property name='DisplayName' type='string' value='Bool property'/> \ <Property name='Default' type='bool' value='false'/> \ </Property> \ + <Property name='Vec2Prop' type='vector2' value='( 3.0, 4.0)'> \ + <Property name='DisplayName' type='string' value='Vec2 prop'/> \ + <Property name='Default' type='vector2' value='(1.0, 2.0)'/> \ + </Property> \ </Effect> \ ";
@@ -11029,6 +11033,7 @@ static void test_effect_properties(BOOL d3d11) ID2D1Effect *effect; UINT32 count, data; WCHAR buffer[128]; + float vec2[2]; CLSID clsid; BOOL cached; HRESULT hr; @@ -11119,6 +11124,18 @@ static void test_effect_properties(BOOL d3d11) ok(!wcscmp(buffer, L"IsReadOnly"), "Unexpected name %s.\n", wine_dbgstr_w(buffer));
ID2D1Properties_Release(subproperties); + + /* Vector2 property */ + index = ID2D1Effect_GetPropertyIndex(effect, L"Vec2Prop"); + hr = ID2D1Effect_GetPropertyName(effect, index, buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"Vec2Prop"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + prop_type = ID2D1Effect_GetType(effect, index); + ok(prop_type == D2D1_PROPERTY_TYPE_VECTOR2, "Unexpected type %u.\n", prop_type); + hr = ID2D1Effect_GetValue(effect, index, D2D1_PROPERTY_TYPE_VECTOR2, (BYTE *)vec2, sizeof(vec2)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(vec2[0] == 3.0f && vec2[1] == 4.0f, "Unexpected vector (%.8e,%.8e).\n", vec2[0], vec2[1]); + ID2D1Effect_Release(effect);
hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);