Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v3: d2d1/tests: Test value size checking for custom properties. d2d1/tests: Add tests for GetPropertyCount(). d2d1/tests: Add tests for system properties attributes. d2d1/effect: Initial implementation of subproperties.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/d2d1_private.h | 8 + dlls/d2d1/effect.c | 359 +++++++++++++++++++++++++++++++-------- dlls/d2d1/factory.c | 51 +++++- dlls/d2d1/tests/d2d1.c | 57 ++++++- 4 files changed, 405 insertions(+), 70 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 7e74f5dd959..db6787c2f86 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -617,10 +617,14 @@ struct d2d_effect_property UINT32 size; PD2D1_PROPERTY_SET_FUNCTION set_function; PD2D1_PROPERTY_GET_FUNCTION get_function; + struct d2d_effect_properties *subproperties; };
struct d2d_effect_properties { + ID2D1Properties ID2D1Properties_iface; + struct d2d_effect *effect; + struct d2d_effect_property *properties; size_t offset; size_t size; @@ -673,6 +677,10 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec ID2D1Effect **effect) DECLSPEC_HIDDEN; HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name, UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) DECLSPEC_HIDDEN; +HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) DECLSPEC_HIDDEN; +struct d2d_effect_property * d2d_effect_properties_get_property_by_name( + const struct d2d_effect_properties *properties, const WCHAR *name) DECLSPEC_HIDDEN; void d2d_effect_properties_cleanup(struct d2d_effect_properties *props) DECLSPEC_HIDDEN;
static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 7abee71e6d9..5daf16fd838 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -229,8 +229,8 @@ static const struct d2d_effect_info builtin_effects[] = {&CLSID_D2D1Grayscale, 1, 1, 1}, };
-HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name, - UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) +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) { static const UINT32 sizes[] = { @@ -246,7 +246,7 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH 0, /* FIXME: D2D1_PROPERTY_TYPE_BLOB */ sizeof(void *), /* D2D1_PROPERTY_TYPE_IUNKNOWN */ sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ENUM */ - 0, /* FIXME: D2D1_PROPERTY_TYPE_ARRAY */ + sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ARRAY */ sizeof(CLSID), /* D2D1_PROPERTY_TYPE_CLSID */ 6 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_3X2 */ 12 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_4X3 */ @@ -258,7 +258,7 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH
assert(type >= D2D1_PROPERTY_TYPE_STRING && type <= D2D1_PROPERTY_TYPE_COLOR_CONTEXT);
- if (type == D2D1_PROPERTY_TYPE_BLOB || type == D2D1_PROPERTY_TYPE_ARRAY) + if (type == D2D1_PROPERTY_TYPE_BLOB) { FIXME("Ignoring property %s of type %u.\n", wine_dbgstr_w(name), type); return S_OK; @@ -279,21 +279,24 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH props->data.count += sizes[type];
p = &props->properties[props->count++]; + memset(p, 0, sizeof(*p)); p->index = index; if (p->index < 0x80000000) { props->custom_count++; - /* FIXME: this should probably be controller by subproperty */ + /* FIXME: this should probably be controlled by subproperty */ p->readonly = FALSE; } + else if (subprop) + p->readonly = TRUE; else p->readonly = index != D2D1_PROPERTY_CACHED && index != D2D1_PROPERTY_PRECISION; p->name = wcsdup(name); p->type = type; - if (p->type == D2D1_PROPERTY_TYPE_STRING) + if (p->type == D2D1_PROPERTY_TYPE_STRING && value) { - p->data.ptr = value ? wcsdup(value) : NULL; - p->size = value ? (wcslen(value) + 1) * sizeof(WCHAR) : 0; + p->data.ptr = wcsdup(value); + p->size = (wcslen(value) + 1) * sizeof(WCHAR); } else { @@ -337,15 +340,26 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH else if (p->size) memset(props->data.ptr + p->data.offset, 0, p->size); } - p->set_function = NULL; - p->get_function = NULL;
return S_OK; }
+HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) +{ + return d2d_effect_properties_internal_add(props, name, index, FALSE, type, value); +} + +HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const WCHAR *name, + UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) +{ + return d2d_effect_properties_internal_add(props, name, index, TRUE, type, value); +} + static HRESULT d2d_effect_duplicate_properties(struct d2d_effect_properties *dst, const struct d2d_effect_properties *src) { + HRESULT hr; size_t i;
memset(dst, 0, sizeof(*dst)); @@ -372,6 +386,14 @@ static HRESULT d2d_effect_duplicate_properties(struct d2d_effect_properties *dst d->name = wcsdup(s->name); if (d->type == D2D1_PROPERTY_TYPE_STRING) d->data.ptr = wcsdup((WCHAR *)s->data.ptr); + + if (s->subproperties) + { + if (!(d->subproperties = calloc(1, sizeof(*d->subproperties)))) + return E_OUTOFMEMORY; + if (FAILED(hr = d2d_effect_duplicate_properties(d->subproperties, s->subproperties))) + return hr; + } }
return S_OK; @@ -391,7 +413,7 @@ static struct d2d_effect_property * d2d_effect_properties_get_property_by_index( return NULL; }
-static struct d2d_effect_property * d2d_effect_properties_get_property_by_name( +struct d2d_effect_property * d2d_effect_properties_get_property_by_name( const struct d2d_effect_properties *properties, const WCHAR *name) { unsigned int i; @@ -405,9 +427,10 @@ static struct d2d_effect_property * d2d_effect_properties_get_property_by_name( return NULL; }
-static UINT32 d2d_effect_properties_get_value_size(const struct d2d_effect *effect, - const struct d2d_effect_properties *properties, UINT32 index) +static UINT32 d2d_effect_properties_get_value_size(const struct d2d_effect_properties *properties, + UINT32 index) { + struct d2d_effect *effect = properties->effect; struct d2d_effect_property *prop; UINT32 size;
@@ -432,10 +455,10 @@ static HRESULT d2d_effect_return_string(const WCHAR *str, WCHAR *buffer, UINT32 return S_OK; }
-static HRESULT d2d_effect_property_get_value(const struct d2d_effect *effect, - const struct d2d_effect_properties *properties, const struct d2d_effect_property *prop, - D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 size) +static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties *properties, + const struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 size) { + struct d2d_effect *effect = properties->effect; UINT32 actual_size;
if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG; @@ -446,7 +469,6 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect *effect,
switch (prop->type) { - case D2D1_PROPERTY_TYPE_ARRAY: case D2D1_PROPERTY_TYPE_BLOB: FIXME("Unimplemented for type %u.\n", prop->type); return E_NOTIMPL; @@ -460,10 +482,10 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect *effect, return S_OK; }
-static HRESULT d2d_effect_property_set_value(const struct d2d_effect *effect, - struct d2d_effect_properties *properties, struct d2d_effect_property *prop, - D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 size) +static HRESULT d2d_effect_property_set_value(struct d2d_effect_properties *properties, + struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 size) { + struct d2d_effect *effect = properties->effect; if (prop->readonly) return E_INVALIDARG; if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG; if (prop->get_function && !prop->set_function) return E_INVALIDARG; @@ -499,6 +521,11 @@ void d2d_effect_properties_cleanup(struct d2d_effect_properties *props) free(p->name); if (p->type == D2D1_PROPERTY_TYPE_STRING) free(p->data.ptr); + if (p->subproperties) + { + d2d_effect_properties_cleanup(p->subproperties); + free(p->subproperties); + } } free(props->properties); free(props->data.ptr); @@ -967,118 +994,91 @@ static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyCount(ID2D1Effect *iface)
TRACE("iface %p.\n", iface);
- return effect->properties.custom_count; + return ID2D1Properties_GetPropertyCount(&effect->properties.ID2D1Properties_iface); }
static HRESULT STDMETHODCALLTYPE d2d_effect_GetPropertyName(ID2D1Effect *iface, UINT32 index, WCHAR *name, UINT32 name_count) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, index %u, name %p, name_count %u.\n", iface, index, name, name_count);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index))) - return D2DERR_INVALID_PROPERTY; - - return d2d_effect_return_string(prop->name, name, name_count); + return ID2D1Properties_GetPropertyName(&effect->properties.ID2D1Properties_iface, + index, name, name_count); }
static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyNameLength(ID2D1Effect *iface, UINT32 index) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, index %u.\n", iface, index);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index))) - return D2DERR_INVALID_PROPERTY; - - return wcslen(prop->name) + 1; + return ID2D1Properties_GetPropertyNameLength(&effect->properties.ID2D1Properties_iface, index); }
static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_GetType(ID2D1Effect *iface, UINT32 index) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, index %#x.\n", iface, index);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index))) - return D2D1_PROPERTY_TYPE_UNKNOWN; - - return prop->type; + return ID2D1Properties_GetType(&effect->properties.ID2D1Properties_iface, index); }
static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyIndex(ID2D1Effect *iface, const WCHAR *name) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, name %s.\n", iface, debugstr_w(name));
- if (!(prop = d2d_effect_properties_get_property_by_name(&effect->properties, name))) - return D2D1_INVALID_PROPERTY_INDEX; - - return prop->index; + return ID2D1Properties_GetPropertyIndex(&effect->properties.ID2D1Properties_iface, name); }
static HRESULT STDMETHODCALLTYPE d2d_effect_SetValueByName(ID2D1Effect *iface, const WCHAR *name, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, name %s, type %u, value %p, value_size %u.\n", iface, debugstr_w(name), type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_name(&effect->properties, name))) - return D2DERR_INVALID_PROPERTY; - - return d2d_effect_property_set_value(effect, &effect->properties, prop, type, value, value_size); + return ID2D1Properties_SetValueByName(&effect->properties.ID2D1Properties_iface, name, + type, value, value_size); }
static HRESULT STDMETHODCALLTYPE d2d_effect_SetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index))) - return D2DERR_INVALID_PROPERTY; - - return d2d_effect_property_set_value(effect, &effect->properties, prop, type, value, value_size); + return ID2D1Properties_SetValue(&effect->properties.ID2D1Properties_iface, index, type, + value, value_size); }
static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, const WCHAR *name, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, name %s, type %#x, value %p, value_size %u.\n", iface, debugstr_w(name), type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_name(&effect->properties, name))) - return D2DERR_INVALID_PROPERTY; - - return d2d_effect_property_get_value(effect, &effect->properties, prop, type, value, value_size); + return ID2D1Properties_GetValueByName(&effect->properties.ID2D1Properties_iface, name, type, + value, value_size); }
static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) { struct d2d_effect *effect = impl_from_ID2D1Effect(iface); - struct d2d_effect_property *prop;
TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index))) - return D2DERR_INVALID_PROPERTY; - - return d2d_effect_property_get_value(effect, &effect->properties, prop, type, value, value_size); + return ID2D1Properties_GetValue(&effect->properties.ID2D1Properties_iface, index, type, + value, value_size); }
static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index) @@ -1087,14 +1087,17 @@ static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT
TRACE("iface %p, index %#x.\n", iface, index);
- return d2d_effect_properties_get_value_size(effect, &effect->properties, index); + return ID2D1Properties_GetValueSize(&effect->properties.ID2D1Properties_iface, index); }
-static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, ID2D1Properties **props) +static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, + ID2D1Properties **props) { - FIXME("iface %p, index %u, props %p stub!\n", iface, index, props); + struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- return E_NOTIMPL; + TRACE("iface %p, index %u, props %p.\n", iface, index, props); + + return ID2D1Properties_GetSubProperties(&effect->properties.ID2D1Properties_iface, index, props); }
static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image *input, BOOL invalidate) @@ -1255,17 +1258,234 @@ static const ID2D1ImageVtbl d2d_effect_image_vtbl = d2d_effect_image_GetFactory, };
+static inline struct d2d_effect_properties *impl_from_ID2D1Properties(ID2D1Properties *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_effect_properties, ID2D1Properties_iface); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_QueryInterface(ID2D1Properties *iface, + REFIID riid, void **obj) +{ + if (IsEqualGUID(riid, &IID_ID2D1Properties) || + IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + ID2D1Properties_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d2d_effect_properties_AddRef(ID2D1Properties *iface) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + return ID2D1Effect_AddRef(&properties->effect->ID2D1Effect_iface); +} + +static ULONG STDMETHODCALLTYPE d2d_effect_properties_Release(ID2D1Properties *iface) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + return ID2D1Effect_Release(&properties->effect->ID2D1Effect_iface); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyCount(ID2D1Properties *iface) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + + TRACE("iface %p.\n", iface); + + return properties->custom_count; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetPropertyName(ID2D1Properties *iface, + UINT32 index, WCHAR *name, UINT32 name_count) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %u, name %p, name_count %u.\n", iface, index, name, name_count); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_return_string(prop->name, name, name_count); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyNameLength(ID2D1Properties *iface, + UINT32 index) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %u.\n", iface, index); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return wcslen(prop->name) + 1; +} + +static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_properties_GetType(ID2D1Properties *iface, + UINT32 index) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %#x.\n", iface, index); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2D1_PROPERTY_TYPE_UNKNOWN; + + return prop->type; +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyIndex(ID2D1Properties *iface, + const WCHAR *name) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name)); + + if (!(prop = d2d_effect_properties_get_property_by_name(properties, name))) + return D2D1_INVALID_PROPERTY_INDEX; + + return prop->index; +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_SetValueByName(ID2D1Properties *iface, + const WCHAR *name, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, name %s, type %u, value %p, value_size %u.\n", iface, debugstr_w(name), + type, value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_name(properties, name))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_set_value(properties, prop, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_SetValue(ID2D1Properties *iface, + UINT32 index, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_set_value(properties, prop, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetValueByName(ID2D1Properties *iface, + const WCHAR *name, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, name %s, type %#x, value %p, value_size %u.\n", iface, debugstr_w(name), type, + value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_name(properties, name))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_get_value(properties, prop, type, value, value_size); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetValue(ID2D1Properties *iface, + UINT32 index, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + return d2d_effect_property_get_value(properties, prop, type, value, value_size); +} + +static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetValueSize(ID2D1Properties *iface, + UINT32 index) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + + TRACE("iface %p, index %#x.\n", iface, index); + + return d2d_effect_properties_get_value_size(properties, index); +} + +static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetSubProperties(ID2D1Properties *iface, + UINT32 index, ID2D1Properties **props) +{ + struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface); + struct d2d_effect_property *prop; + + TRACE("iface %p, index %u, props %p.\n", iface, index, props); + + if (!(prop = d2d_effect_properties_get_property_by_index(properties, index))) + return D2DERR_INVALID_PROPERTY; + + if (!prop->subproperties) return D2DERR_NO_SUBPROPERTIES; + + *props = &prop->subproperties->ID2D1Properties_iface; + ID2D1Properties_AddRef(*props); + return S_OK; +} + +static const ID2D1PropertiesVtbl d2d_effect_properties_vtbl = +{ + d2d_effect_properties_QueryInterface, + d2d_effect_properties_AddRef, + d2d_effect_properties_Release, + d2d_effect_properties_GetPropertyCount, + d2d_effect_properties_GetPropertyName, + d2d_effect_properties_GetPropertyNameLength, + d2d_effect_properties_GetType, + d2d_effect_properties_GetPropertyIndex, + d2d_effect_properties_SetValueByName, + d2d_effect_properties_SetValue, + d2d_effect_properties_GetValueByName, + d2d_effect_properties_GetValue, + d2d_effect_properties_GetValueSize, + d2d_effect_properties_GetSubProperties, +}; + +static void d2d_effect_init_properties_vtbls(struct d2d_effect *effect) +{ + unsigned int i; + + effect->properties.ID2D1Properties_iface.lpVtbl = &d2d_effect_properties_vtbl; + effect->properties.effect = effect; + + for (i = 0; i < effect->properties.count; ++i) + { + struct d2d_effect_property *prop = &effect->properties.properties[i]; + if (!prop->subproperties) continue; + prop->subproperties->ID2D1Properties_iface.lpVtbl = &d2d_effect_properties_vtbl; + prop->subproperties->effect = effect; + } +} + HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id, ID2D1Effect **effect) { const struct d2d_effect_info *builtin = NULL; struct d2d_effect_context *effect_context; const struct d2d_effect_registration *reg; + unsigned int i, default_input_count; struct d2d_transform_graph *graph; PD2D1_EFFECT_FACTORY factory; struct d2d_effect *object; WCHAR clsidW[39]; - unsigned int i; HRESULT hr;
if (!(reg = d2d_factory_get_registered_effect(context->factory, effect_id))) @@ -1323,7 +1543,7 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, max_inputs);
- d2d_effect_SetInputCount(&object->ID2D1Effect_iface, builtin->default_input_count); + default_input_count = builtin->default_input_count;
factory = builtin_factory_stub; } @@ -1335,7 +1555,7 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS, D2D1_PROPERTY_TYPE_UINT32, L"1" /* FIXME */);
- d2d_effect_SetInputCount(&object->ID2D1Effect_iface, 1); + default_input_count = 1;
factory = reg->factory; } @@ -1343,6 +1563,9 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec d2d_effect_properties_add(&object->properties, L"CLSID", D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, clsidW); d2d_effect_properties_add(&object->properties, L"Cached", D2D1_PROPERTY_CACHED, D2D1_PROPERTY_TYPE_BOOL, L"false"); d2d_effect_properties_add(&object->properties, L"Precision", D2D1_PROPERTY_PRECISION, D2D1_PROPERTY_TYPE_ENUM, L"0"); + d2d_effect_init_properties_vtbls(object); + + d2d_effect_SetInputCount(&object->ID2D1Effect_iface, default_input_count);
if (FAILED(hr = factory((IUnknown **)&object->impl))) { diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 911d809b58b..699b8c05669 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -782,6 +782,55 @@ static HRESULT parse_effect_property(IXmlReader *reader, struct d2d_effect_regis return hr; }
+static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registration *effect) +{ + struct d2d_effect_properties *subproperties; + unsigned int depth, input_count = 0; + struct d2d_effect_property *inputs; + XmlNodeType node_type; + WCHAR nameW[16]; + WCHAR *name; + HRESULT hr; + + if (FAILED(hr = d2d_effect_properties_add(&effect->properties, L"Inputs", + D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, NULL))) + return hr; + + if (!(inputs = d2d_effect_properties_get_property_by_name(&effect->properties, L"Inputs"))) + return E_FAIL; + if (!(inputs->subproperties = calloc(1, sizeof(*inputs->subproperties)))) + return E_OUTOFMEMORY; + subproperties = inputs->subproperties; + + d2d_effect_subproperties_add(subproperties, L"IsReadOnly", D2D1_SUBPROPERTY_ISREADONLY, + D2D1_PROPERTY_TYPE_BOOL, L"true"); + d2d_effect_subproperties_add(subproperties, L"DisplayName", D2D1_SUBPROPERTY_DISPLAYNAME, + D2D1_PROPERTY_TYPE_STRING, L"Inputs"); + + if (IXmlReader_IsEmptyElement(reader)) return S_OK; + + while (parse_effect_get_next_xml_node(reader, XmlNodeType_None, L"Input", &depth) == S_OK) + { + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; + if (node_type == XmlNodeType_EndElement) continue; + if (node_type != XmlNodeType_Element) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + if (FAILED(hr = parse_effect_get_attribute(reader, L"name", &name))) return hr; + + swprintf(nameW, ARRAY_SIZE(nameW), L"%lu", input_count); + d2d_effect_subproperties_add(subproperties, nameW, input_count, D2D1_PROPERTY_TYPE_STRING, name); + input_count++; + + free(name); + } + *(UINT32 *)(effect->properties.data.ptr + inputs->data.offset) = input_count; + + if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr; + if (node_type != XmlNodeType_EndElement) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + + return S_OK; +} + static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registration *effect) { const WCHAR *node_name; @@ -808,7 +857,7 @@ static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registrati if (!wcscmp(node_name, L"Property")) hr = parse_effect_property(reader, effect); else if (!wcscmp(node_name, L"Inputs")) - hr = parse_effect_skip_element(reader, depth); + hr = parse_effect_inputs(reader, effect); else { WARN("Unexpected element %s.\n", debugstr_w(node_name)); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 960d4480747..332fd02a07f 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10934,12 +10934,15 @@ static void test_effect_context(BOOL d3d11)
static void test_effect_properties(BOOL d3d11) { - UINT32 i, min_inputs, max_inputs, integer, index; + UINT32 i, min_inputs, max_inputs, integer, index, size; ID2D1EffectContext *effect_context; D2D1_BUFFER_PRECISION precision; + ID2D1Properties *subproperties; + D2D1_PROPERTY_TYPE prop_type; struct d2d1_test_context ctx; ID2D1Factory1 *factory; ID2D1Effect *effect; + UINT32 count, data; WCHAR buffer[128]; CLSID clsid; BOOL cached; @@ -10984,6 +10987,58 @@ static void test_effect_properties(BOOL d3d11) return; }
+ /* Inputs array */ + hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, effect_xml_a, + NULL, 0, effect_impl_create); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + size = ID2D1Effect_GetValueSize(effect, D2D1_PROPERTY_INPUTS); + ok(size == 4, "Unexpected size %u.\n", size); + prop_type = ID2D1Effect_GetType(effect, D2D1_PROPERTY_INPUTS); + ok(prop_type == D2D1_PROPERTY_TYPE_ARRAY, "Unexpected type %u.\n", prop_type); + hr = ID2D1Effect_GetPropertyName(effect, D2D1_PROPERTY_INPUTS, buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"Inputs"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + + /* Value is the number of elements. */ + data = 123; + hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, + (BYTE *)&data, sizeof(data)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(data == 1, "Unexpected data %u.\n", data); + + hr = ID2D1Effect_GetSubProperties(effect, D2D1_PROPERTY_INPUTS, &subproperties); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + count = ID2D1Properties_GetPropertyCount(subproperties); + ok(count == 1, "Unexpected count %u.\n", count); + + hr = ID2D1Properties_GetPropertyName(subproperties, 0, buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"0"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + hr = ID2D1Properties_GetValue(subproperties, 0, D2D1_PROPERTY_TYPE_STRING, + (BYTE *)buffer, sizeof(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"Source"), "Unexpected value %s.\n", wine_dbgstr_w(buffer)); + + hr = ID2D1Properties_GetValue(subproperties, D2D1_SUBPROPERTY_ISREADONLY, D2D1_PROPERTY_TYPE_BOOL, + (BYTE *)&data, sizeof(data)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(data == TRUE, "Unexpected value %u.\n", data); + hr = ID2D1Properties_GetPropertyName(subproperties, D2D1_SUBPROPERTY_ISREADONLY, + buffer, ARRAY_SIZE(buffer)); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(buffer, L"IsReadOnly"), "Unexpected name %s.\n", wine_dbgstr_w(buffer)); + + ID2D1Properties_Release(subproperties); + ID2D1Effect_Release(effect); + + hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + /* Test system properties */
for (i = 0; i < ARRAY_SIZE(system_property_tests); ++i)
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 97 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 332fd02a07f..a43843bb8ca 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10322,7 +10322,85 @@ static void test_mt_factory(BOOL d3d11) ID2D1Factory_Release(factory); }
-static void test_effect(BOOL d3d11) +#define check_system_properties(effect, is_builtin) check_system_properties_(__LINE__, effect, is_builtin) +static void check_system_properties_(unsigned int line, ID2D1Effect *effect, BOOL is_builtin) +{ + UINT i, value_size, str_size; + WCHAR name[32], buffer[256]; + D2D1_PROPERTY_TYPE type; + HRESULT hr; + + static const struct system_property_test + { + UINT32 index; + const WCHAR *name; + D2D1_PROPERTY_TYPE type; + UINT32 value_size; + } + system_property_tests[] = + { + {D2D1_PROPERTY_CLSID, L"CLSID", D2D1_PROPERTY_TYPE_CLSID, sizeof(CLSID)}, + {D2D1_PROPERTY_DISPLAYNAME, L"DisplayName", D2D1_PROPERTY_TYPE_STRING }, + {D2D1_PROPERTY_AUTHOR, L"Author", D2D1_PROPERTY_TYPE_STRING }, + {D2D1_PROPERTY_CATEGORY, L"Category", D2D1_PROPERTY_TYPE_STRING }, + {D2D1_PROPERTY_DESCRIPTION, L"Description", D2D1_PROPERTY_TYPE_STRING }, + {D2D1_PROPERTY_INPUTS, L"Inputs", D2D1_PROPERTY_TYPE_ARRAY, sizeof(UINT32)}, + {D2D1_PROPERTY_CACHED, L"Cached", D2D1_PROPERTY_TYPE_BOOL, sizeof(BOOL)}, + {D2D1_PROPERTY_PRECISION, L"Precision", D2D1_PROPERTY_TYPE_ENUM, sizeof(UINT32)}, + {D2D1_PROPERTY_MIN_INPUTS, L"MinInputs", D2D1_PROPERTY_TYPE_UINT32, sizeof(UINT32)}, + {D2D1_PROPERTY_MAX_INPUTS, L"MaxInputs", D2D1_PROPERTY_TYPE_UINT32, sizeof(UINT32)}, + }; + + hr = ID2D1Effect_GetPropertyName(effect, 0xdeadbeef, name, sizeof(name)); + ok_(__FILE__, line)(hr == D2DERR_INVALID_PROPERTY, "GetPropertyName() got unexpected hr %#lx for 0xdeadbeef.\n", hr); + type = ID2D1Effect_GetType(effect, 0xdeadbeef); + ok_(__FILE__, line)(type == D2D1_PROPERTY_TYPE_UNKNOWN, "Got unexpected property type %#x for 0xdeadbeef.\n", type); + value_size = ID2D1Effect_GetValueSize(effect, 0xdeadbeef); + ok_(__FILE__, line)(value_size == 0, "Got unexpected value size %u for 0xdeadbeef.\n", value_size); + + for (i = 0; i < ARRAY_SIZE(system_property_tests); ++i) + { + const struct system_property_test *test = &system_property_tests[i]; + winetest_push_context("Property %u", i); + + name[0] = 0; + hr = ID2D1Effect_GetPropertyName(effect, test->index, name, sizeof(name)); + todo_wine_if((is_builtin && (test->type == D2D1_PROPERTY_TYPE_ARRAY || test->type == D2D1_PROPERTY_TYPE_STRING))) + { + ok_(__FILE__, line)(hr == S_OK, "Failed to get property name, hr %#lx\n", hr); + ok_(__FILE__, line)(!wcscmp(name, test->name), "Got unexpected property name %s, expected %s.\n", + debugstr_w(name), debugstr_w(test->name)); + } + + type = D2D1_PROPERTY_TYPE_UNKNOWN; + type = ID2D1Effect_GetType(effect, test->index); + todo_wine_if((is_builtin && (test->type == D2D1_PROPERTY_TYPE_ARRAY || test->type == D2D1_PROPERTY_TYPE_STRING))) + ok_(__FILE__, line)(type == test->type, "Got unexpected property type %#x, expected %#x.\n", + type, test->type); + + value_size = 0; + value_size = ID2D1Effect_GetValueSize(effect, test->index); + if (test->value_size != 0) + { + todo_wine_if(is_builtin && test->type == D2D1_PROPERTY_TYPE_ARRAY) + ok_(__FILE__, line)(value_size == test->value_size, "Got unexpected value size %u, expected %u.\n", + value_size, test->value_size); + } + else if (test->type == D2D1_PROPERTY_TYPE_STRING) + { + hr = ID2D1Effect_GetValue(effect, test->index, D2D1_PROPERTY_TYPE_STRING, (BYTE *)buffer, sizeof(buffer)); + todo_wine_if(is_builtin) + ok_(__FILE__, line)(hr == S_OK, "Failed to get value, hr %#lx.\n", hr); + str_size = (wcslen((WCHAR *)buffer) + 1) * sizeof(WCHAR); + todo_wine_if(is_builtin || buffer[0] == 0) + ok_(__FILE__, line)(value_size == str_size, "Got unexpected value size %u, expected %u.\n", + value_size, str_size); + } + winetest_pop_context(); + } +} + +static void test_builtin_effect(BOOL d3d11) { unsigned int i, j, min_inputs, max_inputs, str_size, input_count; D2D1_BITMAP_PROPERTIES bitmap_desc; @@ -10384,6 +10462,7 @@ static void test_effect(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, test->clsid, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Test output image pointer */ hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ID2D1Effect_GetOutput(effect, &image_b); @@ -10391,6 +10470,7 @@ static void test_effect(BOOL d3d11) ID2D1Image_Release(image_b); ID2D1Image_Release(image_a);
+ /* Test GetValue() */ hr = ID2D1Effect_GetValue(effect, 0xdeadbeef, D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid)); ok(hr == D2DERR_INVALID_PROPERTY, "Got unexpected hr %#lx.\n", hr);
@@ -10447,10 +10527,12 @@ static void test_effect(BOOL d3d11) ok(max_inputs == test->max_inputs, "Got unexpected max inputs %u, expected %u.\n", max_inputs, test->max_inputs);
+ /* Test default input count */ input_count = ID2D1Effect_GetInputCount(effect); ok(input_count == test->default_input_count, "Got unexpected input count %u, expected %u.\n", input_count, test->default_input_count);
+ /* Test SetInputCount() */ input_count = (test->max_inputs < 16 ? test->max_inputs : 16); for (j = 0; j < input_count + 4; ++j) { @@ -10463,6 +10545,7 @@ static void test_effect(BOOL d3d11) winetest_pop_context(); }
+ /* Test GetInput() before any input is set */ input_count = ID2D1Effect_GetInputCount(effect); for (j = 0; j < input_count + 4; ++j) { @@ -10472,6 +10555,7 @@ static void test_effect(BOOL d3d11) winetest_pop_context(); }
+ /* Test GetInput() after an input is set */ set_size_u(&size, 1, 1); bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; @@ -10498,6 +10582,7 @@ static void test_effect(BOOL d3d11) winetest_pop_context(); }
+ /* Test setting inputs with out-of-bounds index */ for (j = input_count; j < input_count + 4; ++j) { winetest_push_context("Input %u", j); @@ -11053,6 +11138,8 @@ static void test_effect_properties(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, FALSE); + hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -11315,6 +11402,8 @@ static void test_effect_2d_affine(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D12DAffineTransform, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, TRUE); + for (i = 0; i < ARRAY_SIZE(effect_2d_affine_tests); ++i) { const struct effect_2d_affine_test *test = &effect_2d_affine_tests[i]; @@ -11425,6 +11514,8 @@ static void test_effect_crop(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Crop, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, TRUE); + for (i = 0; i < ARRAY_SIZE(crop_effect_tests); ++i) { const struct crop_effect_test *test = &crop_effect_tests[i]; @@ -11498,6 +11589,8 @@ static void test_effect_grayscale(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Grayscale, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, TRUE); + for (i = 0; i < ARRAY_SIZE(test_pixels); ++i) { DWORD pixel = test_pixels[i]; @@ -12351,7 +12444,7 @@ START_TEST(d2d1) queue_test(test_effect_register); queue_test(test_effect_context); queue_test(test_effect_properties); - queue_test(test_effect); + queue_test(test_builtin_effect); queue_test(test_effect_2d_affine); queue_test(test_effect_crop); queue_test(test_effect_grayscale);
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index a43843bb8ca..3d517983e69 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -11238,6 +11238,9 @@ static void test_effect_properties(BOOL d3d11) hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 2, "Got unexpected property count %u.\n", count); + index = ID2D1Effect_GetPropertyIndex(effect, L"Context"); ok(index == 0, "Got unexpected index %u.\n", index); index = ID2D1Effect_GetPropertyIndex(effect, L"Integer"); @@ -11322,10 +11325,10 @@ static void test_effect_2d_affine(BOOL d3d11) { D2D1_MATRIX_3X2_F rotate, scale, skew; D2D1_BITMAP_PROPERTIES1 bitmap_desc; + unsigned int i, x, y, w, h, count; D2D_RECT_F output_bounds = {0}; struct d2d1_test_context ctx; ID2D1DeviceContext *context; - unsigned int i, x, y, w, h; D2D1_SIZE_U input_size; ID2D1Factory1 *factory; D2D1_POINT_2F offset; @@ -11404,6 +11407,9 @@ static void test_effect_2d_affine(BOOL d3d11)
check_system_properties(effect, TRUE);
+ count = ID2D1Effect_GetPropertyCount(effect); + todo_wine ok(count == 4, "Got unexpected property count %u.\n", count); + for (i = 0; i < ARRAY_SIZE(effect_2d_affine_tests); ++i) { const struct effect_2d_affine_test *test = &effect_2d_affine_tests[i]; @@ -11474,11 +11480,11 @@ static void test_effect_crop(BOOL d3d11) D2D_RECT_F output_bounds; D2D1_SIZE_U input_size; ID2D1Factory1 *factory; + unsigned int count, i; ID2D1Bitmap1 *bitmap; DWORD image[16 * 16]; ID2D1Effect *effect; ID2D1Image *output; - unsigned int i; HRESULT hr;
const struct crop_effect_test @@ -11516,6 +11522,9 @@ static void test_effect_crop(BOOL d3d11)
check_system_properties(effect, TRUE);
+ count = ID2D1Effect_GetPropertyCount(effect); + todo_wine ok(count == 2, "Got unexpected property count %u.\n", count); + for (i = 0; i < ARRAY_SIZE(crop_effect_tests); ++i) { const struct crop_effect_test *test = &crop_effect_tests[i]; @@ -11565,10 +11574,10 @@ static void test_effect_grayscale(BOOL d3d11) ID2D1DeviceContext *context; D2D1_SIZE_U input_size; ID2D1Factory3 *factory; + unsigned int count, i; ID2D1Bitmap1 *bitmap; ID2D1Effect *effect; ID2D1Image *output; - unsigned int i; HRESULT hr;
const DWORD test_pixels[] = {0xffffffff, 0x12345678, 0x89abcdef, 0x77777777, 0xdeadbeef}; @@ -11591,6 +11600,9 @@ static void test_effect_grayscale(BOOL d3d11)
check_system_properties(effect, TRUE);
+ count = ID2D1Effect_GetPropertyCount(effect); + ok(!count, "Got unexpected property count %u.\n", count); + for (i = 0; i < ARRAY_SIZE(test_pixels); ++i) { DWORD pixel = test_pixels[i];
This merge request was approved by Alexandre Julliard.
From: Ziqing Hui zhui@codeweavers.com
Signed-off-by: Ziqing Hui zhui@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/tests/d2d1.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 3d517983e69..78f255c1f99 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10690,7 +10690,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_set_integer(IUnknown *iface, const { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
- if (!data || data_size != sizeof(effect_impl->integer)) + if (!data) return E_INVALIDARG;
effect_impl->integer = *((UINT *)data); @@ -10703,7 +10703,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_get_integer(const IUnknown *iface, { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
- if (!data || data_size != sizeof(effect_impl->integer)) + if (!data) return E_INVALIDARG;
*((UINT *)data) = effect_impl->integer; @@ -10718,7 +10718,7 @@ static HRESULT STDMETHODCALLTYPE effect_impl_get_context(const IUnknown *iface, { struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl((ID2D1EffectImpl *)iface);
- if (!data || data_size != sizeof(effect_impl->effect_context)) + if (!data) return E_INVALIDARG;
*((ID2D1EffectContext **)data) = effect_impl->effect_context; @@ -11247,6 +11247,12 @@ static void test_effect_properties(BOOL d3d11) ok(index == 1, "Got unexpected index %u.\n", index);
effect_context = (ID2D1EffectContext *)0xdeadbeef; + hr = ID2D1Effect_GetValueByName(effect, + L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValueByName(effect, + L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValueByName(effect, L"Context", D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); @@ -11254,6 +11260,10 @@ static void test_effect_properties(BOOL d3d11) "Got unexpected effect context %p.\n", effect_context);
effect_context = (ID2D1EffectContext *)0xdeadbeef; + hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValue(effect, 0, D2D1_PROPERTY_TYPE_IUNKNOWN, (BYTE *)&effect_context, sizeof(effect_context)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(effect_context != NULL && effect_context != (ID2D1EffectContext *)0xdeadbeef, @@ -11263,16 +11273,28 @@ static void test_effect_properties(BOOL d3d11) ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
integer = 0xdeadbeef; + hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValueByName(effect, L"Integer", D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 10, "Got unexpected integer %u.", integer);
integer = 0xdeadbeef; + hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_GetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); ok(integer == 10, "Got unexpected integer %u.", integer);
integer = 20; + hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) - 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer) + 1); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = ID2D1Effect_SetValue(effect, 1, D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&integer, sizeof(integer)); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); integer = 0xdeadbeef;