add new sigc++2 directory
[ardour.git] / libs / cairomm / tests / test-context.cc
1 // vim: ts=2 sw=2 et
2 /*
3  * These tests are of limited usefulness.  In fact, you might even say that
4  * they're not really tests at all.  But I felt that it would be useful to have
5  * some basic usage of most functions just to verify that things compile and
6  * work generally
7  */
8
9 #include <cfloat>
10 #include <boost/test/unit_test.hpp>
11 #include <boost/test/test_tools.hpp>
12 #include <boost/test/floating_point_comparison.hpp>
13 using namespace boost::unit_test;
14 #include <cairomm/context.h>
15
16 #define CREATE_CONTEXT(varname) \
17   Cairo::RefPtr<Cairo::Surface> surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 10, 10); \
18   Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surf);
19
20 void
21 test_dashes ()
22 {
23   CREATE_CONTEXT(cr);
24   std::valarray<double> dash_array(4);
25   dash_array[0] = 0.1;
26   dash_array[1] = 0.2;
27   dash_array[2] = 0.04;
28   dash_array[3] = 0.31;
29   cr->set_dash(dash_array, 0.54);
30
31   std::vector<double> get_array;
32   double get_offset;
33   cr->get_dash (get_array, get_offset);
34   BOOST_CHECK_EQUAL (dash_array[0], get_array[0]);
35   BOOST_CHECK_EQUAL (dash_array[1], get_array[1]);
36   BOOST_CHECK_EQUAL (dash_array[2], get_array[2]);
37   BOOST_CHECK_EQUAL (dash_array[3], get_array[3]);
38   BOOST_CHECK_EQUAL (0.54, get_offset);
39
40   std::vector<double> dash_vect(4);
41   dash_vect[0] = 0.5;
42   dash_vect[1] = 0.25;
43   dash_vect[2] = 0.93;
44   dash_vect[3] = 1.31;
45   cr->set_dash(dash_vect, 0.4);
46
47   cr->get_dash (get_array, get_offset);
48   BOOST_CHECK_EQUAL (dash_vect[0], get_array[0]);
49   BOOST_CHECK_EQUAL (dash_vect[1], get_array[1]);
50   BOOST_CHECK_EQUAL (dash_vect[2], get_array[2]);
51   BOOST_CHECK_EQUAL (dash_vect[3], get_array[3]);
52   BOOST_CHECK_EQUAL (0.4, get_offset);
53
54   cr->unset_dash ();
55   cr->get_dash (get_array, get_offset);
56   BOOST_CHECK (get_array.empty ());
57 }
58
59 void
60 test_save_restore ()
61 {
62   CREATE_CONTEXT(cr);
63   cr->set_line_width (2.3);
64   cr->save ();
65   cr->set_line_width (4.0);
66   BOOST_CHECK_EQUAL (4.0, cr->get_line_width ());
67   cr->restore ();
68   BOOST_CHECK_EQUAL (2.3, cr->get_line_width ());
69 }
70
71 void
72 test_operator ()
73 {
74   CREATE_CONTEXT(cr);
75   cr->set_operator (Cairo::OPERATOR_ATOP);
76   BOOST_CHECK_EQUAL (Cairo::OPERATOR_ATOP, cr->get_operator ());
77   cr->set_operator (Cairo::OPERATOR_CLEAR);
78   BOOST_CHECK_EQUAL (Cairo::OPERATOR_CLEAR, cr->get_operator ());
79 }
80
81 void
82 test_source ()
83 {
84   CREATE_CONTEXT(cr);
85   Cairo::RefPtr<Cairo::Pattern> solid_pattern =
86     Cairo::SolidPattern::create_rgb (1.0, 0.5, 0.25);
87   Cairo::RefPtr<Cairo::Pattern> gradient_pattern =
88     Cairo::LinearGradient::create (0.0, 0.0, 1.0, 1.0);
89
90   cr->set_source (solid_pattern);
91   {
92     Cairo::RefPtr<Cairo::SolidPattern> retrieved_solid =
93       Cairo::RefPtr<Cairo::SolidPattern>::cast_dynamic(cr->get_source ());
94     BOOST_REQUIRE (retrieved_solid);
95     double r, g, b, a;
96     retrieved_solid->get_rgba (r, g, b, a);
97     BOOST_CHECK_EQUAL (1.0, r);
98     BOOST_CHECK_EQUAL (0.5, g);
99     BOOST_CHECK_EQUAL (0.25, b);
100
101     // now try for const objects..
102     Cairo::RefPtr<const Cairo::Context> cr2 = cr;
103     Cairo::RefPtr<const Cairo::SolidPattern> retrieved_solid2 =
104       Cairo::RefPtr<const Cairo::SolidPattern>::cast_dynamic(cr2->get_source ());
105     BOOST_REQUIRE (retrieved_solid2);
106   }
107
108   cr->set_source (gradient_pattern);
109   {
110     Cairo::RefPtr<Cairo::LinearGradient> retrieved_linear =
111       Cairo::RefPtr<Cairo::LinearGradient>::cast_dynamic(cr->get_source ());
112     BOOST_REQUIRE (retrieved_linear);
113     double x0, x1, y0, y1;
114     retrieved_linear->get_linear_points (x0, y0, x1, y1);
115     BOOST_CHECK_EQUAL (0.0, x0);
116     BOOST_CHECK_EQUAL (0.0, y0);
117     BOOST_CHECK_EQUAL (1.0, x1);
118     BOOST_CHECK_EQUAL (1.0, y1);
119   }
120
121   cr->set_source_rgb (1.0, 0.5, 0.25);
122   {
123     Cairo::RefPtr<Cairo::SolidPattern> solid =
124       Cairo::RefPtr<Cairo::SolidPattern>::cast_dynamic(cr->get_source ());
125     BOOST_REQUIRE (solid);
126     double rx, gx, bx, ax;
127     solid->get_rgba (rx, gx, bx, ax);
128     BOOST_CHECK_EQUAL (1.0, rx);
129     BOOST_CHECK_EQUAL (0.5, gx);
130     BOOST_CHECK_EQUAL (0.25, bx);
131   }
132   cr->set_source_rgba (0.1, 0.3, 0.5, 0.7);
133   {
134     Cairo::RefPtr<Cairo::SolidPattern> solid =
135       Cairo::RefPtr<Cairo::SolidPattern>::cast_dynamic(cr->get_source ());
136     BOOST_REQUIRE (solid);
137     double rx, gx, bx, ax;
138     solid->get_rgba (rx, gx, bx, ax);
139     BOOST_CHECK_EQUAL (0.1, rx);
140     BOOST_CHECK_EQUAL (0.3, gx);
141     BOOST_CHECK_EQUAL (0.5, bx);
142     BOOST_CHECK_EQUAL (0.7, ax);
143   }
144 }
145
146 void
147 test_tolerance ()
148 {
149   CREATE_CONTEXT(cr);
150   cr->set_tolerance (3.0);
151   BOOST_CHECK_EQUAL (3.0, cr->get_tolerance ());
152 }
153
154 void
155 test_antialias ()
156 {
157   CREATE_CONTEXT(cr);
158   cr->set_antialias (Cairo::ANTIALIAS_GRAY);
159   BOOST_CHECK_EQUAL (Cairo::ANTIALIAS_GRAY, cr->get_antialias ());
160
161   cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
162   BOOST_CHECK_EQUAL (Cairo::ANTIALIAS_SUBPIXEL, cr->get_antialias ());
163 }
164
165 void
166 test_fill_rule ()
167 {
168   CREATE_CONTEXT(cr);
169   cr->set_fill_rule (Cairo::FILL_RULE_EVEN_ODD);
170   BOOST_CHECK_EQUAL (Cairo::FILL_RULE_EVEN_ODD, cr->get_fill_rule ());
171   cr->set_fill_rule (Cairo::FILL_RULE_WINDING);
172   BOOST_CHECK_EQUAL (Cairo::FILL_RULE_WINDING, cr->get_fill_rule ());
173 }
174
175 void
176 test_line_width ()
177 {
178   CREATE_CONTEXT(cr);
179   cr->set_line_width (1.0);
180   BOOST_CHECK_EQUAL (1.0, cr->get_line_width ());
181   cr->set_line_width (4.0);
182   BOOST_CHECK_EQUAL (4.0, cr->get_line_width ());
183 }
184
185 void
186 test_line_cap ()
187 {
188   CREATE_CONTEXT(cr);
189   cr->set_line_cap (Cairo::LINE_CAP_BUTT);
190   BOOST_CHECK_EQUAL (Cairo::LINE_CAP_BUTT, cr->get_line_cap ());
191   cr->set_line_cap (Cairo::LINE_CAP_ROUND);
192   BOOST_CHECK_EQUAL (Cairo::LINE_CAP_ROUND, cr->get_line_cap ());
193 }
194
195 void
196 test_line_join ()
197 {
198   CREATE_CONTEXT(cr);
199   cr->set_line_join (Cairo::LINE_JOIN_BEVEL);
200   BOOST_CHECK_EQUAL (Cairo::LINE_JOIN_BEVEL, cr->get_line_join ());
201   cr->set_line_join (Cairo::LINE_JOIN_MITER);
202   BOOST_CHECK_EQUAL (Cairo::LINE_JOIN_MITER, cr->get_line_join ());
203 }
204
205 void
206 test_miter_limit ()
207 {
208   CREATE_CONTEXT (cr);
209   cr->set_miter_limit (1.3);
210   BOOST_CHECK_EQUAL (1.3, cr->get_miter_limit ());
211   cr->set_miter_limit (4.12);
212   BOOST_CHECK_EQUAL (4.12, cr->get_miter_limit ());
213 }
214
215 void
216 test_matrix ()
217 {
218   // just excercise the functionality
219   CREATE_CONTEXT (cr);
220   Cairo::Matrix matrix;
221   cairo_matrix_init (&matrix, 1.0, 0.1, 0.1, 1.0, 1.5, 1.5);
222   cr->transform(matrix);
223   cairo_matrix_init (&matrix, 1.0, -0.1, -0.1, 1.0, 1.5, 1.5);
224   cr->set_matrix(matrix);
225   cr->set_identity_matrix ();
226   cr->get_matrix (matrix);
227 }
228
229 void
230 test_user_device ()
231 {
232   // scale / transform a context, and then verify that user-to-device and
233   // device-to-user things work.
234   CREATE_CONTEXT (cr);
235   cr->scale (2.3, 2.3);
236   double x = 1.8, y = 1.8;
237   cr->user_to_device (x, y);
238   // x = (0.0 + x) * 2.3 => 1.8 * 2.3 = 5.29
239   BOOST_CHECK_EQUAL (4.14, x);
240   BOOST_CHECK_EQUAL (4.14, y);
241   cr->device_to_user (x, y);
242   BOOST_CHECK_EQUAL (1.8, x);
243   BOOST_CHECK_EQUAL (1.8, y);
244   cr->translate (0.5, 0.5);
245   cr->user_to_device (x, y);
246   // x = (0.5 + x) * 2.3 => 2.3 * 2.3 = 5.29
247   BOOST_CHECK_CLOSE (5.29, x, FLT_EPSILON);
248   BOOST_CHECK_CLOSE (5.29, y, FLT_EPSILON);
249 }
250
251 void
252 test_draw ()
253 {
254   CREATE_CONTEXT (cr);
255   // just call a bunch of drawing functions to excercise them a bit.  There's no
256   // rhyme or reason to this, don't expect it to draw anything interesting.
257   cr->begin_new_path ();
258   cr->move_to (1.0, 1.0);
259   cr->line_to (2.0, 2.0);
260   cr->curve_to (0.5, 0.5, 0.5, 0.5, 1.0, 1.0);
261   cr->arc (1.5, 0.5, 0.5, 0, 2 * M_PI);
262   cr->stroke ();
263   cr->arc_negative (1.5, 0.5, 0.5, 0, 2 * M_PI);
264   cr->rel_move_to (0.1, 0.1);
265   cr->rel_line_to (0.5, -0.5);
266   cr->rel_curve_to (0.5, 0.5, 0.5, 0.5, 1.0, 1.0);
267   cr->rectangle (0.0, 0.0, 1.0, 1.0);
268   cr->close_path ();
269   cr->paint ();
270 }
271
272 void
273 test_clip ()
274 {
275   CREATE_CONTEXT (cr);
276   cr->rectangle (0.0, 0.0, 1.0, 1.0);
277   cr->clip ();
278   double x1, y1, x2, y2;
279   cr->get_clip_extents (x1, y1, x2, y2);
280   BOOST_CHECK (x1 == 0.0);
281   BOOST_CHECK (y1 == 0.0);
282   BOOST_CHECK (x2 == 1.0);
283   BOOST_CHECK (y2 == 1.0);
284 }
285
286 void
287 test_current_point ()
288 {
289   CREATE_CONTEXT (cr);
290   cr->move_to (2.0, 3.0);
291   double x, y;
292   cr->get_current_point (x, y);
293   BOOST_CHECK (x == 2.0);
294   BOOST_CHECK (y == 3.0);
295 }
296
297 void
298 test_target ()
299 {
300   Cairo::RefPtr<Cairo::Surface> surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 10, 10); \
301   Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surf);
302
303   Cairo::RefPtr<Cairo::ImageSurface> target_surface =
304     Cairo::RefPtr<Cairo::ImageSurface>::cast_dynamic(cr->get_target ());
305   Cairo::RefPtr<Cairo::PdfSurface> bad_surface =
306     Cairo::RefPtr<Cairo::PdfSurface>::cast_dynamic(cr->get_target ());
307   BOOST_CHECK (target_surface);
308   BOOST_CHECK (!bad_surface);
309
310   // now check for const objects...
311   Cairo::RefPtr<const Cairo::Context> cr2 = Cairo::Context::create(surf);
312
313   Cairo::RefPtr<const Cairo::ImageSurface> target_surface2 =
314     Cairo::RefPtr<const Cairo::ImageSurface>::cast_dynamic(cr2->get_target ());
315   Cairo::RefPtr<const Cairo::PdfSurface> bad_surface2 =
316     Cairo::RefPtr<const Cairo::PdfSurface>::cast_dynamic(cr2->get_target ());
317   BOOST_CHECK (target_surface2);
318   BOOST_CHECK (!bad_surface2);
319
320 }
321
322 test_suite*
323 init_unit_test_suite(int argc, char* argv[])
324 {
325   // compile even with -Werror
326   if (argc && argv) {}
327
328   test_suite* test= BOOST_TEST_SUITE( "Cairo::Context Tests" );
329
330   test->add (BOOST_TEST_CASE (&test_dashes));
331   test->add (BOOST_TEST_CASE (&test_save_restore));
332   test->add (BOOST_TEST_CASE (&test_operator));
333   test->add (BOOST_TEST_CASE (&test_source));
334   test->add (BOOST_TEST_CASE (&test_tolerance));
335   test->add (BOOST_TEST_CASE (&test_antialias));
336   test->add (BOOST_TEST_CASE (&test_fill_rule));
337   test->add (BOOST_TEST_CASE (&test_line_width));
338   test->add (BOOST_TEST_CASE (&test_line_cap));
339   test->add (BOOST_TEST_CASE (&test_line_join));
340   test->add (BOOST_TEST_CASE (&test_miter_limit));
341   test->add (BOOST_TEST_CASE (&test_matrix));
342   test->add (BOOST_TEST_CASE (&test_user_device));
343   test->add (BOOST_TEST_CASE (&test_draw));
344   test->add (BOOST_TEST_CASE (&test_clip));
345   test->add (BOOST_TEST_CASE (&test_current_point));
346   test->add (BOOST_TEST_CASE (&test_target));
347
348   return test;
349 }