1 #include <boost/test/unit_test.hpp>
2 #include <boost/test/test_tools.hpp>
3 #include <boost/test/floating_point_comparison.hpp>
4 using namespace boost::unit_test;
5 
6 #include <cairomm/matrix.h>
7 
8 // this is necessary for BOOST_CHECK_EQUAL, but there's no equivalent in the C
9 // API, so I'm reluctant to include it in cairomm right now
operator ==(const Cairo::Matrix & A,const Cairo::Matrix & B)10 bool operator==(const Cairo::Matrix& A, const Cairo::Matrix& B)
11 {
12   return
13     A.xx == B.xx &&
14     A.yx == B.yx &&
15     A.xy == B.xy &&
16     A.yy == B.yy &&
17     A.x0 == B.x0 &&
18     A.y0 == B.y0;
19 }
20 
21 // this is necessary for BOOST_CHECK_EQUAL to work but doesn't seem useful
22 // enough to put in the actual implementation
operator <<(std::ostream & out,const Cairo::Matrix & matrix)23 std::ostream& operator<<(std::ostream& out, const Cairo::Matrix& matrix)
24 {
25   return out << "[ "
26     << matrix.xx << ", "
27     << matrix.yx << ", "
28     << matrix.xy << ", "
29     << matrix.yy << ", "
30     << matrix.x0 << ", "
31     << matrix.y0 << " ]";
32 }
33 
test_constructors()34 void test_constructors()
35 {
36   cairo_matrix_t c_identity;
37   cairo_matrix_init_identity(&c_identity);
38   BOOST_CHECK_EQUAL(c_identity.xx, Cairo::identity_matrix().xx);
39   BOOST_CHECK_EQUAL(c_identity.xy, Cairo::identity_matrix().xy);
40   BOOST_CHECK_EQUAL(c_identity.yx, Cairo::identity_matrix().yx);
41   BOOST_CHECK_EQUAL(c_identity.yy, Cairo::identity_matrix().yy);
42   BOOST_CHECK_EQUAL(c_identity.x0, Cairo::identity_matrix().x0);
43   BOOST_CHECK_EQUAL(c_identity.y0, Cairo::identity_matrix().y0);
44 
45   // nonsense values, just for testing
46   const double xx=1, yx=2, xy=3, yy=5, x0=6, y0=7;
47   cairo_matrix_t c_matrix;
48   cairo_matrix_init(&c_matrix, xx, yx, xy, yy, x0, y0);
49   Cairo::Matrix cpp_matrix(xx, yx, xy, yy, x0, y0);
50 
51   BOOST_CHECK_EQUAL(c_matrix.xx, cpp_matrix.xx);
52   BOOST_CHECK_EQUAL(c_matrix.xy, cpp_matrix.xy);
53   BOOST_CHECK_EQUAL(c_matrix.yx, cpp_matrix.yx);
54   BOOST_CHECK_EQUAL(c_matrix.yy, cpp_matrix.yy);
55   BOOST_CHECK_EQUAL(c_matrix.x0, cpp_matrix.x0);
56   BOOST_CHECK_EQUAL(c_matrix.y0, cpp_matrix.y0);
57 }
58 
test_invert()59 void test_invert()
60 {
61   // test a valid matrix
62   BOOST_CHECK_NO_THROW(Cairo::identity_matrix().invert());
63   // check a degenerate matrix
64   Cairo::Matrix degenerate(0,0,0,0,0,0);
65   BOOST_CHECK_THROW(degenerate.invert(), std::logic_error);
66 }
67 
68 cairo_matrix_t* test_matrix = nullptr;
foo(cairo_matrix_t * matrix)69 static void foo(cairo_matrix_t* matrix)
70 {
71   test_matrix = matrix;
72 }
73 
test_cast()74 void test_cast()
75 {
76   // make sure that we can cast between C++ and C types without ill effect
77   auto matrix = Cairo::identity_matrix();
78   auto casted = (cairo_matrix_t) Cairo::identity_matrix();
79   // check that it's equal to the identity matrix
80   cairo_matrix_t identity;
81   cairo_matrix_init_identity(&identity);
82 
83   BOOST_CHECK_EQUAL(casted.xx, identity.xx);
84   BOOST_CHECK_EQUAL(casted.xy, identity.xy);
85   BOOST_CHECK_EQUAL(casted.yx, identity.yx);
86   BOOST_CHECK_EQUAL(casted.yy, identity.yy);
87   BOOST_CHECK_EQUAL(casted.x0, identity.x0);
88   BOOST_CHECK_EQUAL(casted.y0, identity.y0);
89 
90   // pass C++ type as an argument to C
91   foo(&matrix);
92   BOOST_CHECK_EQUAL(matrix.xx, test_matrix->xx);
93   BOOST_CHECK_EQUAL(matrix.xy, test_matrix->xy);
94   BOOST_CHECK_EQUAL(matrix.yx, test_matrix->yx);
95   BOOST_CHECK_EQUAL(matrix.yy, test_matrix->yy);
96   BOOST_CHECK_EQUAL(matrix.x0, test_matrix->x0);
97   BOOST_CHECK_EQUAL(matrix.y0, test_matrix->y0);
98 }
99 
test_multiply()100 void test_multiply()
101 {
102   auto A = Cairo::scaling_matrix(2, 4);
103   auto B = Cairo::translation_matrix(5.3, 1.2);
104   auto C = A * B;
105   Cairo::Matrix D;
106   D.multiply(A, B);
107   BOOST_CHECK_EQUAL(C, D);
108 }
109 
110 test_suite*
init_unit_test_suite(int,char **)111 init_unit_test_suite(int /*argc*/, char** /*argv*/)
112 {
113   test_suite* test= BOOST_TEST_SUITE( "Cairo::Matrix Tests" );
114 
115   test->add (BOOST_TEST_CASE (&test_constructors));
116   test->add (BOOST_TEST_CASE (&test_invert));
117   test->add (BOOST_TEST_CASE (&test_cast));
118   test->add (BOOST_TEST_CASE (&test_multiply));
119 
120   return test;
121 }
122