diff --git a/dlls/d2d1/d2d1.spec b/dlls/d2d1/d2d1.spec index 3443b295053..fff6f1c9c81 100644 --- a/dlls/d2d1/d2d1.spec +++ b/dlls/d2d1/d2d1.spec @@ -1,6 +1,6 @@ @ stdcall D2D1CreateFactory(long ptr ptr ptr) @ stdcall D2D1MakeRotateMatrix(float float float ptr) -@ stub D2D1MakeSkewMatrix +@ stdcall D2D1MakeSkewMatrix(float float float float ptr) @ stdcall D2D1IsMatrixInvertible(ptr) @ stdcall D2D1InvertMatrix(ptr) @ stub D2D1ConvertColorSpace diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 2459b58c03d..8d9d8c324b7 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -592,6 +592,24 @@ void WINAPI D2D1MakeRotateMatrix(float angle, D2D1_POINT_2F center, D2D1_MATRIX_ matrix->_32 = center.y - center.x * sin_theta - center.y * cos_theta; } +void WINAPI D2D1MakeSkewMatrix(float angle_x, float angle_y, D2D1_POINT_2F center, D2D1_MATRIX_3X2_F *matrix) +{ + float tan_x, tan_y; + + TRACE("angle_x %.8e, angle_y %.8e, center %s, matrix %p.\n", angle_x, angle_y, debug_d2d_point_2f(¢er), matrix); + + tan_x = tan(angle_x * (M_PI / 180.0f)); + tan_y = tan(angle_y * (M_PI / 180.0f)); + + /* translate(-center) * skew() * translate(center) */ + matrix->_11 = 1.0f; + matrix->_12 = tan_y; + matrix->_21 = tan_x; + matrix->_22 = 1.0f; + matrix->_31 = -tan_x * center.y; + matrix->_32 = -tan_y * center.x; +} + BOOL WINAPI D2D1IsMatrixInvertible(const D2D1_MATRIX_3X2_F *matrix) { TRACE("matrix %p.\n", matrix); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index d00fba1b413..0bea1c80a8b 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -7601,6 +7601,44 @@ static void test_invert_matrix(void) } } +static void test_skew_matrix(void) +{ + static const struct + { + float angle_x; + float angle_y; + D2D1_POINT_2F center; + D2D1_MATRIX_3X2_F matrix; + } + skew_tests[] = + { + { 0.0f, 0.0f, { 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } }, + { 45.0f, 0.0f, { 0.0f, 0.0f }, { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f } }, + { 0.0f, 0.0f, { 10.0f, -3.0f }, { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } }, + { -45.0f, 45.0f, { 0.1f, 0.5f }, { 1.0f, 1.0f, -1.0f, 1.0f, 0.5f, -0.1f } }, + { -45.0f, 45.0f, { 1.0f, 2.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 2.0f, -1.0f } }, + { 45.0f, -45.0f, { 1.0f, 2.0f }, { 1.0f, -1.0f, 1.0f, 1.0f, -2.0f, 1.0f } }, + { 30.0f, -60.0f, { 12.0f, -5.0f }, { 1.0f, -1.7320509f, 0.577350259f, 1.0f, 2.88675117f, 20.7846107f } }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(skew_tests); ++i) + { + const D2D1_MATRIX_3X2_F *expected = &skew_tests[i].matrix; + D2D1_MATRIX_3X2_F m; + BOOL ret; + + D2D1MakeSkewMatrix(skew_tests[i].angle_x, skew_tests[i].angle_y, skew_tests[i].center, &m); + ret = compare_float(m._11, expected->_11, 3) && compare_float(m._12, expected->_12, 3) + && compare_float(m._21, expected->_21, 3) && compare_float(m._22, expected->_22, 3) + && compare_float(m._31, expected->_31, 3) && compare_float(m._32, expected->_32, 3); + + ok(ret, "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, expected " + "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i, m._11, m._12, m._21, m._22, m._31, m._32, + expected->_11, expected->_12, expected->_21, expected->_22, expected->_31, expected->_32); + } +} + START_TEST(d2d1) { unsigned int argc, i; @@ -7643,6 +7681,7 @@ START_TEST(d2d1) queue_test(test_bitmap_surface); queue_test(test_device_context); queue_test(test_invert_matrix); + queue_test(test_skew_matrix); run_queued_tests(); } diff --git a/include/d2d1.idl b/include/d2d1.idl index ff2dc03cfd7..c9fb8f0b6bc 100644 --- a/include/d2d1.idl +++ b/include/d2d1.idl @@ -1257,3 +1257,4 @@ interface ID2D1Factory : IUnknown [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); +[local] void __stdcall D2D1MakeSkewMatrix(float angle_x, float angle_y, D2D1_POINT_2F center, D2D1_MATRIX_3X2_F *matrix);