diff --git a/dlls/d2d1/d2d1.spec b/dlls/d2d1/d2d1.spec index 26d17c687dc..3443b295053 100644 --- a/dlls/d2d1/d2d1.spec +++ b/dlls/d2d1/d2d1.spec @@ -1,8 +1,8 @@ @ stdcall D2D1CreateFactory(long ptr ptr ptr) @ stdcall D2D1MakeRotateMatrix(float float float ptr) @ stub D2D1MakeSkewMatrix -@ stub D2D1IsMatrixInvertible -@ stub D2D1InvertMatrix +@ stdcall D2D1IsMatrixInvertible(ptr) +@ stdcall D2D1InvertMatrix(ptr) @ stub D2D1ConvertColorSpace @ stub D2D1CreateDevice @ stub D2D1CreateDeviceContext diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 7810e957d4d..d2e53879e69 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -554,6 +554,22 @@ void WINAPI D2D1MakeRotateMatrix(float angle, D2D1_POINT_2F center, D2D1_MATRIX_ matrix->_32 = center.y - center.x * sin_theta - center.y * cos_theta; } +BOOL WINAPI D2D1IsMatrixInvertible(const D2D1_MATRIX_3X2_F *matrix) +{ + TRACE("matrix %p.\n", matrix); + + return (matrix->_11 * matrix->_22 - matrix->_21 * matrix->_12) != 0.0f; +} + +BOOL WINAPI D2D1InvertMatrix(D2D1_MATRIX_3X2_F *matrix) +{ + D2D1_MATRIX_3X2_F m = *matrix; + + TRACE("matrix %p.\n", matrix); + + return d2d_matrix_invert(matrix, &m); +} + static BOOL get_config_key_dword(HKEY default_key, HKEY application_key, const char *name, DWORD *value) { DWORD type, data, size; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 8e58eef6583..eeae75f8413 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -6968,6 +6968,89 @@ if (SUCCEEDED(hr)) ID3D10Device1_Release(d3d_device); } +static void test_invert_matrix(void) +{ + static const struct + { + D2D1_MATRIX_3X2_F matrix; + D2D1_MATRIX_3X2_F inverse; + BOOL invertible; + } + invert_tests[] = + { + { { 0 }, { 0 }, FALSE }, + { + { + 1.0f, 2.0f, + 1.0f, 2.0f, + 4.0f, 8.0f + }, + { + 1.0f, 2.0f, + 1.0f, 2.0f, + 4.0f, 8.0f + }, + FALSE + }, + { + { + 2.0f, 0.0f, + 0.0f, 2.0f, + 4.0f, 8.0f + }, + { + 0.5f, -0.0f, + -0.0f, 0.5f, + -2.0f, -4.0f + }, + TRUE + }, + { + { + 2.0f, 1.0f, + 2.0f, 2.0f, + 4.0f, 8.0f + }, + { + 1.0f, -0.5f, + -1.0f, 1.0f, + 4.0f, -6.0f + }, + TRUE + }, + { + { + 2.0f, 1.0f, + 3.0f, 1.0f, + 4.0f, 8.0f + }, + { + -1.0f, 1.0f, + 3.0f, -2.0f, + -20.0f, 12.0f + }, + TRUE + }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(invert_tests); ++i) + { + D2D1_MATRIX_3X2_F m; + BOOL ret; + + m = invert_tests[i].matrix; + ret = D2D1InvertMatrix(&m); + ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret); + ok(!memcmp(&m, &invert_tests[i].inverse, sizeof(m)), + "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i, + m._11, m._12, m._21, m._22, m._31, m._32); + + ret = D2D1IsMatrixInvertible(&invert_tests[i].matrix); + ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret); + } +} + START_TEST(d2d1) { unsigned int argc, i; @@ -7009,6 +7092,7 @@ START_TEST(d2d1) queue_test(test_create_device); queue_test(test_bitmap_surface); queue_test(test_device_context); + queue_test(test_invert_matrix); run_queued_tests(); } diff --git a/include/d2d1.idl b/include/d2d1.idl index fbfb40d93d6..ff2dc03cfd7 100644 --- a/include/d2d1.idl +++ b/include/d2d1.idl @@ -1254,4 +1254,6 @@ interface ID2D1Factory : IUnknown [local] HRESULT __stdcall D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid, const D2D1_FACTORY_OPTIONS *factory_options, void **factory); +[local] BOOL __stdcall D2D1InvertMatrix(D2D1_MATRIX_3X2_F *matrix); +[local] BOOL __stdcall D2D1IsMatrixInvertible(const D2D1_MATRIX_3X2_F *matrix); [local] void __stdcall D2D1MakeRotateMatrix(float angle, D2D1_POINT_2F center, D2D1_MATRIX_3X2_F *matrix);