Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v2: d2d1: Add property data for the Color Matrix effect. d2d1: Add property data for the Crop effect. d2d1: Do not use property getter for standalone properties. d2d1: Add property data for the Composite effect. d2d1: Add property data for the 3D Perspective Transform effect.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 51 +++++++++++++++++++++++++- dlls/d2d1/tests/d2d1.c | 83 ++++++++++++++++++++++++++++++++++++++++++ include/d2d1_1.idl | 4 ++ 3 files changed, 136 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index d6159055cbc..f0577a0b681 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1159,11 +1159,58 @@ L"<?xml version='1.0'?> <Inputs> \ <Input name='Source'/> \ </Inputs> \ + <Property name='InterpolationMode' type='enum' /> \ + <Property name='BorderMode' type='enum' /> \ + <Property name='Depth' type='float' /> \ + <Property name='PerspectiveOrigin' type='vector2' /> \ + <Property name='LocalOffset' type='vector3' /> \ + <Property name='GlobalOffset' type='vector3' /> \ + <Property name='RotationOrigin' type='vector3' /> \ + <Property name='Rotation' type='vector3' /> \ </Effect>";
+struct _3d_perspective_transform_properties +{ + D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE interpolation_mode; + D2D1_BORDER_MODE border_mode; + float depth; + D2D1_VECTOR_2F perspective_origin; + D2D1_VECTOR_3F local_offset; + D2D1_VECTOR_3F global_offset; + D2D1_VECTOR_3F rotation_origin; + D2D1_VECTOR_3F rotation; +}; + +EFFECT_PROPERTY_RW(_3d_perspective_transform, interpolation_mode, ENUM) +EFFECT_PROPERTY_RW(_3d_perspective_transform, border_mode, ENUM) +EFFECT_PROPERTY_RW(_3d_perspective_transform, depth, FLOAT) +EFFECT_PROPERTY_RW(_3d_perspective_transform, perspective_origin, VECTOR2) +EFFECT_PROPERTY_RW(_3d_perspective_transform, local_offset, VECTOR3) +EFFECT_PROPERTY_RW(_3d_perspective_transform, global_offset, VECTOR3) +EFFECT_PROPERTY_RW(_3d_perspective_transform, rotation_origin, VECTOR3) +EFFECT_PROPERTY_RW(_3d_perspective_transform, rotation, VECTOR3) + +static const D2D1_PROPERTY_BINDING _3d_perspective_transform_bindings[] = +{ + { L"InterpolationMode", BINDING_RW(_3d_perspective_transform, interpolation_mode) }, + { L"BorderMode", BINDING_RW(_3d_perspective_transform, border_mode) }, + { L"Depth", BINDING_RW(_3d_perspective_transform, depth) }, + { L"PerspectiveOrigin", BINDING_RW(_3d_perspective_transform, perspective_origin) }, + { L"LocalOffset", BINDING_RW(_3d_perspective_transform, local_offset) }, + { L"GlobalOffset", BINDING_RW(_3d_perspective_transform, global_offset) }, + { L"RotationOrigin", BINDING_RW(_3d_perspective_transform, rotation_origin) }, + { L"Rotation", BINDING_RW(_3d_perspective_transform, rotation) }, +}; + static HRESULT __stdcall _3d_perspective_transform_factory(IUnknown **effect) { - return d2d_effect_create_impl(effect, NULL, 0); + static const struct _3d_perspective_transform_properties properties = + { + .interpolation_mode = D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_LINEAR, + .border_mode = D2D1_BORDER_MODE_SOFT, + .depth = 1000.0f, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
static const WCHAR composite_description[] = @@ -1474,7 +1521,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) #define X(name) name##_description, name##_factory #define X2(name) name##_description, name##_factory, name##_bindings, ARRAY_SIZE(name##_bindings) { &CLSID_D2D12DAffineTransform, X2(_2d_affine_transform) }, - { &CLSID_D2D13DPerspectiveTransform, X(_3d_perspective_transform) }, + { &CLSID_D2D13DPerspectiveTransform, X2(_3d_perspective_transform) }, { &CLSID_D2D1Composite, X(composite) }, { &CLSID_D2D1Crop, X(crop) }, { &CLSID_D2D1Shadow, X2(shadow) }, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index d5aa8783060..61a83b1c40c 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13638,6 +13638,88 @@ static void test_effect_shadow(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_3d_perspective_transform(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"InterpolationMode", D2D1_3DPERSPECTIVETRANSFORM_PROP_INTERPOLATION_MODE, D2D1_PROPERTY_TYPE_ENUM }, + { L"BorderMode", D2D1_3DPERSPECTIVETRANSFORM_PROP_BORDER_MODE, D2D1_PROPERTY_TYPE_ENUM }, + { L"Depth", D2D1_3DPERSPECTIVETRANSFORM_PROP_DEPTH, D2D1_PROPERTY_TYPE_FLOAT }, + { L"PerspectiveOrigin", D2D1_3DPERSPECTIVETRANSFORM_PROP_PERSPECTIVE_ORIGIN, D2D1_PROPERTY_TYPE_VECTOR2 }, + { L"LocalOffset", D2D1_3DPERSPECTIVETRANSFORM_PROP_LOCAL_OFFSET, D2D1_PROPERTY_TYPE_VECTOR3 }, + { L"GlobalOffset", D2D1_3DPERSPECTIVETRANSFORM_PROP_GLOBAL_OFFSET, D2D1_PROPERTY_TYPE_VECTOR3 }, + { L"RotationOrigin", D2D1_3DPERSPECTIVETRANSFORM_PROP_ROTATION_ORIGIN, D2D1_PROPERTY_TYPE_VECTOR3 }, + { L"Rotation", D2D1_3DPERSPECTIVETRANSFORM_PROP_ROTATION, D2D1_PROPERTY_TYPE_VECTOR3 }, + }; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + D2D1_VECTOR_3F vec3; + D2D1_VECTOR_2F vec2; + WCHAR name[64]; + HRESULT hr; + UINT32 v; + float f; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D13DPerspectiveTransform, &effect); + if (FAILED(hr)) + { + win_skip("3D Perspective Transform is not available.\n"); + release_test_context(&ctx); + return; + } + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 8, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + v = effect_get_enum_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_INTERPOLATION_MODE); + ok(v == D2D1_3DPERSPECTIVETRANSFORM_INTERPOLATION_MODE_LINEAR, "Unexpected value %#x.\n", v); + + v = effect_get_enum_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_BORDER_MODE); + ok(v == D2D1_BORDER_MODE_SOFT, "Unexpected value %#x.\n", v); + + f = effect_get_float_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_DEPTH); + ok(f == 1000.0f, "Unexpected value %.8e.\n", f); + + vec2 = effect_get_vec2_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_PERSPECTIVE_ORIGIN); + ok(vec2.x == 0.0f && vec2.y == 0.0f, "Unexpected value {%.8e,%.8e}.\n", vec2.x, vec2.y); + + vec3 = effect_get_vec3_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_LOCAL_OFFSET); + ok(vec3.x == 0.0f && vec3.y == 0.0f && vec3.z == 0.0f, + "Unexpected value {%.8e,%.8e,%.8e}.\n", vec3.x, vec3.y, vec3.z); + + vec3 = effect_get_vec3_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_GLOBAL_OFFSET); + ok(vec3.x == 0.0f && vec3.y == 0.0f && vec3.z == 0.0f, + "Unexpected value {%.8e,%.8e,%.8e}.\n", vec3.x, vec3.y, vec3.z); + + vec3 = effect_get_vec3_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_ROTATION_ORIGIN); + ok(vec3.x == 0.0f && vec3.y == 0.0f && vec3.z == 0.0f, + "Unexpected value {%.8e,%.8e,%.8e}.\n", vec3.x, vec3.y, vec3.z); + + vec3 = effect_get_vec3_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_ROTATION); + ok(vec3.x == 0.0f && vec3.y == 0.0f && vec3.z == 0.0f, + "Unexpected value {%.8e,%.8e,%.8e}.\n", vec3.x, vec3.y, vec3.z); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_effect_flood(BOOL d3d11) { static const struct effect_property properties[] = @@ -17093,6 +17175,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_point_specular); queue_d3d10_test(test_effect_arithmetic_composite); queue_d3d10_test(test_effect_shadow); + queue_d3d10_test(test_effect_3d_perspective_transform); queue_test(test_effect_flood); queue_test(test_transform_graph); queue_test(test_offset_transform); diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl index ea46fa956eb..b81cead66ba 100644 --- a/include/d2d1_1.idl +++ b/include/d2d1_1.idl @@ -29,6 +29,10 @@ interface ID2D1ColorContext; interface ID2D1Effect; interface ID2D1BitmapBrush1;
+typedef D2D_VECTOR_2F D2D1_VECTOR_2F; +typedef D2D_VECTOR_3F D2D1_VECTOR_3F; +typedef D2D_VECTOR_4F D2D1_VECTOR_4F; + cpp_quote("#ifndef __dwrite_h__") /* already defined in dwrite.h but needed for WIDL */ typedef struct DWRITE_GLYPH_RUN_DESCRIPTION DWRITE_GLYPH_RUN_DESCRIPTION;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 21 +++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index f0577a0b681..c2b89ca94e6 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1224,11 +1224,28 @@ L"<?xml version='1.0'?> \ <Input name='Source1'/> \ <Input name='Source2'/> \ </Inputs> \ + <Property name='Mode' type='enum' /> \ </Effect>";
+struct composite_properties +{ + D2D1_COMPOSITE_MODE mode; +}; + +EFFECT_PROPERTY_RW(composite, mode, ENUM) + +static const D2D1_PROPERTY_BINDING composite_bindings[] = +{ + { L"Mode", BINDING_RW(composite, mode) }, +}; + static HRESULT __stdcall composite_factory(IUnknown **effect) { - return d2d_effect_create_impl(effect, NULL, 0); + static const struct composite_properties properties = + { + .mode = D2D1_COMPOSITE_MODE_SOURCE_OVER, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
static const WCHAR crop_description[] = @@ -1522,7 +1539,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) #define X2(name) name##_description, name##_factory, name##_bindings, ARRAY_SIZE(name##_bindings) { &CLSID_D2D12DAffineTransform, X2(_2d_affine_transform) }, { &CLSID_D2D13DPerspectiveTransform, X2(_3d_perspective_transform) }, - { &CLSID_D2D1Composite, X(composite) }, + { &CLSID_D2D1Composite, X2(composite) }, { &CLSID_D2D1Crop, X(crop) }, { &CLSID_D2D1Shadow, X2(shadow) }, { &CLSID_D2D1Grayscale, X(grayscale) }, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 61a83b1c40c..7eb7ca94519 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13798,6 +13798,47 @@ static void test_effect_flood(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_composite(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"Mode", D2D1_COMPOSITE_PROP_MODE, D2D1_PROPERTY_TYPE_ENUM }, + }; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + WCHAR name[64]; + HRESULT hr; + UINT32 v; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Composite, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 1, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + v = effect_get_enum_prop(effect, D2D1_COMPOSITE_PROP_MODE); + ok(v == D2D1_COMPOSITE_MODE_SOURCE_OVER, "Unexpected value %#x.\n", v); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17176,6 +17217,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_arithmetic_composite); queue_d3d10_test(test_effect_shadow); queue_d3d10_test(test_effect_3d_perspective_transform); + queue_d3d10_test(test_effect_composite); queue_test(test_effect_flood); queue_test(test_transform_graph); queue_test(test_offset_transform);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index c2b89ca94e6..a47da0f2e09 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1859,6 +1859,7 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties const struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 size) { struct d2d_effect *effect = properties->effect; + PD2D1_PROPERTY_GET_FUNCTION get_function = effect ? prop->get_function : NULL; UINT32 actual_size;
memset(value, 0, size); @@ -1872,8 +1873,8 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties return E_INVALIDARG; }
- if (prop->get_function) - return prop->get_function((IUnknown *)effect->impl, value, size, &actual_size); + if (get_function) + return get_function((IUnknown *)effect->impl, value, size, &actual_size);
switch (prop->type) {
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 25 +++++++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 32 +++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index a47da0f2e09..4776cdcdb6d 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1259,11 +1259,32 @@ L"<?xml version='1.0'?> \ <Input name='Source'/> \ </Inputs> \ <Property name='Rect' type='vector4' /> \ + <Property name='BorderMode' type='enum' /> \ </Effect>";
+struct crop_properties +{ + D2D1_VECTOR_4F rect; + D2D1_BORDER_MODE border_mode; +}; + +EFFECT_PROPERTY_RW(crop, rect, VECTOR4) +EFFECT_PROPERTY_RW(crop, border_mode, ENUM) + +static const D2D1_PROPERTY_BINDING crop_bindings[] = +{ + { L"Rect", BINDING_RW(crop, rect) }, + { L"BorderMode", BINDING_RW(crop, border_mode) }, +}; + static HRESULT __stdcall crop_factory(IUnknown **effect) { - return d2d_effect_create_impl(effect, NULL, 0); + static const struct crop_properties properties = + { + .rect = { -INFINITY, -INFINITY, INFINITY, INFINITY }, + .border_mode = D2D1_BORDER_MODE_SOFT, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
static const WCHAR shadow_description[] = @@ -1540,7 +1561,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D12DAffineTransform, X2(_2d_affine_transform) }, { &CLSID_D2D13DPerspectiveTransform, X2(_3d_perspective_transform) }, { &CLSID_D2D1Composite, X2(composite) }, - { &CLSID_D2D1Crop, X(crop) }, + { &CLSID_D2D1Crop, X2(crop) }, { &CLSID_D2D1Shadow, X2(shadow) }, { &CLSID_D2D1Grayscale, X(grayscale) }, { &CLSID_D2D1ColorMatrix, X(color_matrix) }, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 7eb7ca94519..660f4a39838 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13228,6 +13228,11 @@ static void test_effect_2d_affine(BOOL d3d11)
static void test_effect_crop(BOOL d3d11) { + static const struct effect_property properties[] = + { + { L"Rect", D2D1_CROP_PROP_RECT, D2D1_PROPERTY_TYPE_VECTOR4 }, + { L"BorderMode", D2D1_CROP_PROP_BORDER_MODE, D2D1_PROPERTY_TYPE_ENUM }, + }; D2D1_BITMAP_PROPERTIES1 bitmap_desc; struct d2d1_test_context ctx; ID2D1DeviceContext *context; @@ -13238,8 +13243,11 @@ static void test_effect_crop(BOOL d3d11) ID2D1Bitmap1 *bitmap; DWORD image[16 * 16]; ID2D1Effect *effect; + D2D1_VECTOR_4F vec4; ID2D1Image *output; + WCHAR name[64]; HRESULT hr; + UINT32 v;
const struct crop_effect_test { @@ -13277,7 +13285,21 @@ static void test_effect_crop(BOOL d3d11) check_system_properties(effect);
count = ID2D1Effect_GetPropertyCount(effect); - todo_wine ok(count == 2, "Got unexpected property count %u.\n", count); + ok(count == 2, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + vec4 = effect_get_vec4_prop(effect, D2D1_CROP_PROP_RECT); + ok(vec4.x == -INFINITY && vec4.y == -INFINITY && vec4.z == INFINITY && vec4.w == INFINITY, + "Unexpected value {%.8e,%.8e,%.8e,%.8e}.\n", vec4.x, vec4.y, vec4.z, vec4.w); + + v = effect_get_enum_prop(effect, D2D1_CROP_PROP_BORDER_MODE); + ok(v == D2D1_BORDER_MODE_SOFT, "Unexpected value %#x.\n", v);
for (i = 0; i < ARRAY_SIZE(crop_effect_tests); ++i) { @@ -13298,14 +13320,7 @@ static void test_effect_crop(BOOL d3d11) ID2D1Effect_SetInput(effect, 0, (ID2D1Image *)bitmap, FALSE); hr = ID2D1Effect_SetValue(effect, D2D1_CROP_PROP_RECT, D2D1_PROPERTY_TYPE_VECTOR4, (const BYTE *)&test->crop_rect, sizeof(test->crop_rect)); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - if (hr == D2DERR_INVALID_PROPERTY) - { - ID2D1Bitmap1_Release(bitmap); - winetest_pop_context(); - continue; - } ID2D1Effect_GetOutput(effect, &output);
set_rect(&output_bounds, -1.0f, -1.0f, -1.0f, -1.0f); @@ -15982,7 +15997,6 @@ static void test_get_effect_properties(BOOL d3d11) ID2D1Properties_Release(properties2);
count = ID2D1Properties_GetPropertyCount(properties); - todo_wine ok(count == 2, "Unexpected property count %u.\n", count);
hr = ID2D1Properties_GetPropertyName(properties, 0, buffW, ARRAY_SIZE(buffW));
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/effect.c | 30 ++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 62 +++++++++++++++++++++++++++++++++++++++++ include/d2d1_1.idl | 5 +++- include/d2d1effects.idl | 15 ++++++++++ 4 files changed, 109 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 4776cdcdb6d..003fdb02e5d 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1358,11 +1358,37 @@ L"<?xml version='1.0'?> \ <Inputs > \ <Input name='Source'/> \ </Inputs> \ + <Property name='ColorMatrix' type='matrix5x4' /> \ + <Property name='AlphaMode' type='enum' /> \ + <Property name='ClampOutput' type='bool' /> \ </Effect>";
+struct color_matrix_properties +{ + D2D1_MATRIX_5X4_F color_matrix; + D2D1_COLORMATRIX_ALPHA_MODE alpha_mode; + BOOL clamp_output; +}; + +EFFECT_PROPERTY_RW(color_matrix, color_matrix, MATRIX_5X4) +EFFECT_PROPERTY_RW(color_matrix, alpha_mode, ENUM) +EFFECT_PROPERTY_RW(color_matrix, clamp_output, BOOL) + +static const D2D1_PROPERTY_BINDING color_matrix_bindings[] = +{ + { L"ColorMatrix", BINDING_RW(color_matrix, color_matrix) }, + { L"AlphaMode", BINDING_RW(color_matrix, alpha_mode) }, + { L"ClampOutput", BINDING_RW(color_matrix, clamp_output) }, +}; + static HRESULT __stdcall color_matrix_factory(IUnknown **effect) { - return d2d_effect_create_impl(effect, NULL, 0); + static const struct color_matrix_properties properties = + { + .color_matrix = { ._11 = 1.0f, ._22 = 1.0f, ._33 = 1.0f, ._44 = 1.0f }, + .alpha_mode = D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
static const WCHAR flood_description[] = @@ -1564,7 +1590,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D1Crop, X2(crop) }, { &CLSID_D2D1Shadow, X2(shadow) }, { &CLSID_D2D1Grayscale, X(grayscale) }, - { &CLSID_D2D1ColorMatrix, X(color_matrix) }, + { &CLSID_D2D1ColorMatrix, X2(color_matrix) }, { &CLSID_D2D1Flood, X2(flood) }, { &CLSID_D2D1GaussianBlur, X2(gaussian_blur) }, { &CLSID_D2D1PointSpecular, X2(point_specular) }, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 660f4a39838..f01f51661d9 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -132,6 +132,15 @@ static UINT32 _effect_get_bool_prop(ID2D1Effect *effect, UINT32 prop, int line) return v; }
+#define effect_get_mat5x4_prop(a,b,c) _effect_get_mat5x4_prop(a,b,c,__LINE__) +static void _effect_get_mat5x4_prop(ID2D1Effect *effect, UINT32 prop, D2D1_MATRIX_5X4_F *m, int line) +{ + HRESULT hr; + + hr = ID2D1Effect_GetValue(effect, prop, D2D1_PROPERTY_TYPE_MATRIX_5X4, (BYTE *)m, sizeof(*m)); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + static const WCHAR *effect_xml_a = L"<?xml version='1.0'?> \ <Effect> \ @@ -13854,6 +13863,58 @@ static void test_effect_composite(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_color_matrix(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"ColorMatrix", D2D1_COLORMATRIX_PROP_COLOR_MATRIX, D2D1_PROPERTY_TYPE_MATRIX_5X4 }, + { L"AlphaMode", D2D1_COLORMATRIX_PROP_ALPHA_MODE, D2D1_PROPERTY_TYPE_ENUM }, + { L"ClampOutput", D2D1_COLORMATRIX_PROP_CLAMP_OUTPUT, D2D1_PROPERTY_TYPE_BOOL }, + }; + D2D1_MATRIX_5X4_F m, identity; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + WCHAR name[64]; + HRESULT hr; + UINT32 v; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1ColorMatrix, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 3, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + memset(&identity, 0, sizeof(identity)); + identity._11 = identity._22 = identity._33 = identity._44 = 1.0f; + effect_get_mat5x4_prop(effect, D2D1_COLORMATRIX_PROP_COLOR_MATRIX, &m); + ok(!memcmp(&m, &identity, sizeof(m)), "Unexpected value.\n"); + + v = effect_get_enum_prop(effect, D2D1_COLORMATRIX_PROP_ALPHA_MODE); + ok(v == D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED, "Unexpected value %#x.\n", v); + + v = effect_get_bool_prop(effect, D2D1_COLORMATRIX_PROP_CLAMP_OUTPUT); + ok(!v, "Unexpected value %#x.\n", v); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17232,6 +17293,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_shadow); queue_d3d10_test(test_effect_3d_perspective_transform); queue_d3d10_test(test_effect_composite); + queue_d3d10_test(test_effect_color_matrix); queue_test(test_effect_flood); queue_test(test_transform_graph); queue_test(test_offset_transform); diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl index b81cead66ba..b9eb13e272a 100644 --- a/include/d2d1_1.idl +++ b/include/d2d1_1.idl @@ -33,6 +33,10 @@ typedef D2D_VECTOR_2F D2D1_VECTOR_2F; typedef D2D_VECTOR_3F D2D1_VECTOR_3F; typedef D2D_VECTOR_4F D2D1_VECTOR_4F;
+typedef D2D_MATRIX_4X3_F D2D1_MATRIX_4X3_F; +typedef D2D_MATRIX_4X4_F D2D1_MATRIX_4X4_F; +typedef D2D_MATRIX_5X4_F D2D1_MATRIX_5X4_F; + cpp_quote("#ifndef __dwrite_h__") /* already defined in dwrite.h but needed for WIDL */ typedef struct DWRITE_GLYPH_RUN_DESCRIPTION DWRITE_GLYPH_RUN_DESCRIPTION; @@ -162,7 +166,6 @@ typedef enum D2D1_LAYER_OPTIONS1 } D2D1_LAYER_OPTIONS1;
struct D2D1_PROPERTY_BINDING; -typedef D2D_MATRIX_4X4_F D2D1_MATRIX_4X4_F;
typedef enum D2D1_PROPERTY_TYPE { diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl index efaeba5c92d..5534314468e 100644 --- a/include/d2d1effects.idl +++ b/include/d2d1effects.idl @@ -219,3 +219,18 @@ typedef enum D2D1_FLOOD_PROP D2D1_FLOOD_PROP_COLOR = 0, D2D1_FLOOD_PROP_FORCE_DWORD = 0xffffffff } D2D1_FLOOD_PROP; + +typedef enum D2D1_COLORMATRIX_PROP +{ + D2D1_COLORMATRIX_PROP_COLOR_MATRIX = 0, + D2D1_COLORMATRIX_PROP_ALPHA_MODE = 1, + D2D1_COLORMATRIX_PROP_CLAMP_OUTPUT = 2, + D2D1_COLORMATRIX_PROP_FORCE_DWORD = 0xffffffff +} D2D1_COLORMATRIX_PROP; + +typedef enum D2D1_COLORMATRIX_ALPHA_MODE +{ + D2D1_COLORMATRIX_ALPHA_MODE_PREMULTIPLIED = 1, + D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT = 2, + D2D1_COLORMATRIX_ALPHA_MODE_FORCE_DWORD = 0xffffffff +} D2D1_COLORMATRIX_ALPHA_MODE;