Add missing cairomm lib from previous commit.
[ardour.git] / libs / cairomm / cairomm / context.cc
1 /* Copyright (C) 2005 The cairomm Development Team
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Library General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Library General Public License for more details.
12  *
13  * You should have received a copy of the GNU Library General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16  * 02110-1301, USA.
17  */
18
19 #include <cairomm/context.h>
20 #include <cairomm/private.h>
21
22 /* M_PI is defined in math.h in the case of Microsoft Visual C++ */
23 #if defined(_MSC_VER)
24 #define _USE_MATH_DEFINES
25 #include <math.h>
26 #endif 
27
28 namespace Cairo
29 {
30
31 Context::Context(const RefPtr<Surface>& target)
32 : m_cobject(0)
33 {
34   m_cobject = cairo_create(target->cobj());
35   check_object_status_and_throw_exception(*this);
36 }
37
38 RefPtr<Context> Context::create(const RefPtr<Surface>& target)
39 {
40   return RefPtr<Context>(new Context(target));
41 }
42
43 Context::Context(cairo_t* cobject, bool has_reference)
44 : m_cobject(0)
45 {
46   if(has_reference)
47     m_cobject = cobject;
48   else
49     m_cobject = cairo_reference(cobject);
50 }
51
52 Context::~Context()
53 {
54   if(m_cobject)
55     cairo_destroy(m_cobject);
56 }
57
58
59 void Context::reference() const
60 {
61  cairo_reference(m_cobject);
62 }
63
64 void Context::unreference() const
65 {
66   cairo_destroy(m_cobject);
67 }
68
69 void Context::save()
70 {
71   cairo_save(m_cobject);
72   check_object_status_and_throw_exception(*this);
73 }
74
75 void Context::restore()
76 {
77   cairo_restore(m_cobject);
78   check_object_status_and_throw_exception(*this);
79 }
80
81 void Context::set_operator(Operator op)
82 {
83   cairo_set_operator(m_cobject, static_cast<cairo_operator_t>(op));
84   check_object_status_and_throw_exception(*this);
85 }
86
87 void Context::set_source(const RefPtr<const Pattern>& source)
88 {
89   cairo_set_source(m_cobject, const_cast<cairo_pattern_t*>(source->cobj()));
90   check_object_status_and_throw_exception(*this);
91 }
92
93 void Context::set_source_rgb(double red, double green, double blue)
94 {
95   cairo_set_source_rgb(m_cobject, red, green, blue);
96   check_object_status_and_throw_exception(*this);
97 }
98
99 void Context::set_source_rgba(double red, double green, double blue,
100 double alpha)
101 {
102   cairo_set_source_rgba(m_cobject, red, green, blue, alpha);
103   check_object_status_and_throw_exception(*this);
104 }
105
106 void Context::set_source(const RefPtr<Surface>& surface, double x, double y)
107 {
108   cairo_set_source_surface(m_cobject, surface->cobj(), x, y);
109   check_object_status_and_throw_exception(*this);
110 }
111
112 void Context::set_tolerance(double tolerance)
113 {
114   cairo_set_tolerance(m_cobject, tolerance);
115   check_object_status_and_throw_exception(*this);
116 }
117
118 void Context::set_antialias(Antialias antialias)
119 {
120   cairo_set_antialias(m_cobject, static_cast<cairo_antialias_t>(antialias));
121   check_object_status_and_throw_exception(*this);
122 }
123
124 void Context::set_fill_rule(FillRule fill_rule)
125 {
126   cairo_set_fill_rule(m_cobject, static_cast<cairo_fill_rule_t>(fill_rule));
127   check_object_status_and_throw_exception(*this);
128 }
129
130 void Context::set_line_width(double width)
131 {
132   cairo_set_line_width(m_cobject, width);
133   check_object_status_and_throw_exception(*this);
134 }
135
136 void Context::set_line_cap(LineCap line_cap)
137 {
138   cairo_set_line_cap(m_cobject, static_cast<cairo_line_cap_t>(line_cap));
139   check_object_status_and_throw_exception(*this);
140 }
141
142 void Context::set_line_join(LineJoin line_join)
143 {
144   cairo_set_line_join(m_cobject, static_cast<cairo_line_join_t>(line_join));
145   check_object_status_and_throw_exception(*this);
146 }
147
148 void Context::set_dash(std::valarray<double>& dashes, double offset)
149 {
150   cairo_set_dash(m_cobject, &dashes[0], dashes.size(), offset);
151   check_object_status_and_throw_exception(*this);
152 }
153
154 void Context::unset_dash()
155 {
156   cairo_set_dash(m_cobject, NULL, 0, 0.0);
157   check_object_status_and_throw_exception(*this);
158 }
159
160 void Context::set_miter_limit(double limit)
161 {
162   cairo_set_miter_limit(m_cobject, limit);
163   check_object_status_and_throw_exception(*this);
164 }
165
166 void Context::translate(double tx, double ty)
167 {
168   cairo_translate(m_cobject, tx, ty);
169   check_object_status_and_throw_exception(*this);
170 }
171
172 void Context::scale(double sx, double sy)
173 {
174   cairo_scale(m_cobject, sx, sy);
175   check_object_status_and_throw_exception(*this);
176 }
177
178 void Context::rotate(double angle_radians)
179 {
180   cairo_rotate(m_cobject, angle_radians);
181   check_object_status_and_throw_exception(*this);
182 }
183
184 void Context::rotate_degrees(double angle_degrees)
185 {
186   cairo_rotate(m_cobject, angle_degrees * M_PI/180.0);
187   check_object_status_and_throw_exception(*this);
188 }
189
190 void Context::transform(const Matrix& matrix)
191 {
192   cairo_transform(m_cobject, &matrix);
193   check_object_status_and_throw_exception(*this);
194 }
195
196 void Context::set_matrix(const Matrix& matrix)
197 {
198   cairo_set_matrix(m_cobject, &matrix);
199   check_object_status_and_throw_exception(*this);
200 }
201
202 void Context::set_identity_matrix()
203 {
204   cairo_identity_matrix(m_cobject);
205   check_object_status_and_throw_exception(*this);
206 }
207
208 void Context::user_to_device(double& x, double& y)
209 {
210   cairo_user_to_device(m_cobject, &x, &y);
211   check_object_status_and_throw_exception(*this);
212 }
213
214 void Context::user_to_device_distance(double& dx, double& dy)
215 {
216   cairo_user_to_device_distance(m_cobject, &dx, &dy);
217   check_object_status_and_throw_exception(*this);
218 }
219
220 void Context::device_to_user(double& x, double& y)
221 {
222   cairo_device_to_user(m_cobject, &x, &y);
223   check_object_status_and_throw_exception(*this);
224 }
225
226 void Context::device_to_user_distance(double& dx, double& dy)
227 {
228   cairo_device_to_user_distance(m_cobject, &dx, &dy);
229   check_object_status_and_throw_exception(*this);
230 }
231
232 void Context::begin_new_path()
233 {
234   cairo_new_path(m_cobject);
235   check_object_status_and_throw_exception(*this);
236 }
237
238 void Context::begin_new_sub_path()
239 {
240   cairo_new_sub_path(m_cobject);
241   check_object_status_and_throw_exception(*this);
242 }
243
244 void Context::move_to(double x, double y)
245 {
246   cairo_move_to(m_cobject, x, y);
247   check_object_status_and_throw_exception(*this);
248 }
249
250 void Context::line_to(double x, double y)
251 {
252   cairo_line_to(m_cobject, x, y);
253   check_object_status_and_throw_exception(*this);
254 }
255
256 void Context::curve_to(double x1, double y1, double x2, double y2, double x3, double y3)
257 {
258   cairo_curve_to(m_cobject, x1, y1, x2, y2, x3, y3);
259   check_object_status_and_throw_exception(*this);
260 }
261
262 void Context::arc(double xc, double yc, double radius, double angle1, double angle2)
263 {
264   cairo_arc(m_cobject, xc, yc, radius, angle1, angle2);
265   check_object_status_and_throw_exception(*this);
266 }
267
268 void Context::arc_negative(double xc, double yc, double radius, double angle1, double angle2)
269 {
270   cairo_arc_negative(m_cobject, xc, yc, radius, angle1, angle2);
271   check_object_status_and_throw_exception(*this);
272 }
273
274 void Context::rel_move_to(double dx, double dy)
275 {
276   cairo_rel_move_to(m_cobject, dx, dy);
277   check_object_status_and_throw_exception(*this);
278 }
279
280 void Context::rel_line_to(double dx, double dy)
281 {
282   cairo_rel_line_to(m_cobject, dx, dy);
283   check_object_status_and_throw_exception(*this);
284 }
285
286 void Context::rel_curve_to(double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
287 {
288   cairo_rel_curve_to(m_cobject, dx1, dy1, dx2, dy2, dx3, dy3);
289   check_object_status_and_throw_exception(*this);
290 }
291
292 void Context::rectangle(double x, double y, double width, double height)
293 {
294   cairo_rectangle(m_cobject, x, y, width, height);
295   check_object_status_and_throw_exception(*this);
296 }
297
298 void Context::close_path()
299 {
300   cairo_close_path(m_cobject);
301   check_object_status_and_throw_exception(*this);
302 }
303
304 void Context::paint()
305 {
306   cairo_paint(m_cobject);
307   check_object_status_and_throw_exception(*this);
308 }
309
310 void Context::paint_with_alpha(double alpha)
311 {
312   cairo_paint_with_alpha(m_cobject, alpha);
313   check_object_status_and_throw_exception(*this);
314 }
315
316 void Context::mask(const RefPtr<const Pattern>& pattern)
317 {
318   cairo_mask(m_cobject, const_cast<cairo_pattern_t*>(pattern->cobj()));
319   check_object_status_and_throw_exception(*this);
320 }
321
322 void Context::mask(const RefPtr<const Surface>& surface, double surface_x, double surface_y)
323 {
324   cairo_mask_surface(m_cobject, const_cast<cairo_surface_t*>(surface->cobj()), surface_x, surface_y);
325   check_object_status_and_throw_exception(*this);
326 }
327
328 void Context::stroke()
329 {
330   cairo_stroke(m_cobject);
331   check_object_status_and_throw_exception(*this);
332 }
333
334 void Context::stroke_preserve()
335 {
336   cairo_stroke_preserve(m_cobject);
337   check_object_status_and_throw_exception(*this);
338 }
339
340 void Context::fill()
341 {
342   cairo_fill(m_cobject);
343   check_object_status_and_throw_exception(*this);
344 }
345
346 void Context::fill_preserve()
347 {
348   cairo_fill_preserve(m_cobject);
349   check_object_status_and_throw_exception(*this);
350 }
351
352 void Context::copy_page()
353 {
354   cairo_copy_page(m_cobject);
355   check_object_status_and_throw_exception(*this);
356 }
357
358 void Context::show_page()
359 {
360   cairo_show_page(m_cobject);
361   check_object_status_and_throw_exception(*this);
362 }
363
364 bool Context::in_stroke(double x, double y) const
365 {
366   const bool result = cairo_in_stroke(m_cobject, x, y);
367   check_object_status_and_throw_exception(*this);
368   return result;
369 }
370
371 bool Context::in_fill(double x, double y) const
372 {
373   const bool result = cairo_in_fill(m_cobject, x, y);
374   check_object_status_and_throw_exception(*this);
375   return result;
376 }
377
378 void Context::get_stroke_extents(double& x1, double& y1, double& x2, double& y2) const
379 {
380   cairo_stroke_extents(m_cobject, &x1, &y1, &x2, &y2);
381   check_object_status_and_throw_exception(*this);
382 }
383
384 void Context::get_fill_extents(double& x1, double& y1, double& x2, double& y2) const
385 {
386   cairo_fill_extents(m_cobject, &x1, &y1, &x2, &y2);
387   check_object_status_and_throw_exception(*this);
388 }
389
390 void Context::reset_clip()
391 {
392   cairo_reset_clip(m_cobject);
393   check_object_status_and_throw_exception(*this);
394 }
395
396 void Context::clip()
397 {
398   cairo_clip(m_cobject);
399   check_object_status_and_throw_exception(*this);
400 }
401
402 void Context::clip_preserve()
403 {
404   cairo_clip_preserve(m_cobject);
405   check_object_status_and_throw_exception(*this);
406 }
407
408 void Context::select_font_face(const std::string& family, FontSlant slant, FontWeight weight)
409 {
410   cairo_select_font_face (m_cobject, family.c_str(),
411           static_cast<cairo_font_slant_t>(slant),
412           static_cast<cairo_font_weight_t>(weight));
413   check_object_status_and_throw_exception(*this);
414 }
415
416 void Context::set_font_size(double size)
417 {
418   cairo_set_font_size(m_cobject, size);
419   check_object_status_and_throw_exception(*this);
420 }
421
422 void Context::set_font_matrix(const Matrix& matrix)
423 {
424   cairo_set_font_matrix(m_cobject, &matrix);
425   check_object_status_and_throw_exception(*this);
426 }
427
428 void Context::get_font_matrix(Matrix& matrix) const
429 {
430   cairo_get_font_matrix(m_cobject, &matrix);
431   check_object_status_and_throw_exception(*this);
432 }
433
434 void Context::set_font_options(const FontOptions& options)
435 {
436   cairo_set_font_options(m_cobject, options.cobj());
437   check_object_status_and_throw_exception(*this);
438 }
439
440 void Context::show_text(const std::string& utf8)
441 {
442   cairo_show_text(m_cobject, utf8.c_str());
443   check_object_status_and_throw_exception(*this);
444 }
445
446 void Context::show_glyphs(const std::vector<Glyph>& glyphs)
447 {
448   cairo_show_glyphs(m_cobject, const_cast<cairo_glyph_t*>(&glyphs[0]), glyphs.size());
449   check_object_status_and_throw_exception(*this);
450 }
451
452 RefPtr<FontFace> Context::get_font_face()
453 {
454   cairo_font_face_t* cfontface = cairo_get_font_face(m_cobject);
455   check_object_status_and_throw_exception(*this);
456   return RefPtr<FontFace>(new FontFace(cfontface, false /* does not have reference */));
457 }
458
459 RefPtr<const FontFace> Context::get_font_face() const
460 {
461   cairo_font_face_t* cfontface = cairo_get_font_face(m_cobject);
462   check_object_status_and_throw_exception(*this);
463   return RefPtr<const FontFace>(new FontFace(cfontface, false /* does not have reference */));
464 }
465
466 void Context::get_font_extents(FontExtents& extents) const
467 {
468   cairo_font_extents(m_cobject, &extents);
469   check_object_status_and_throw_exception(*this);
470 }
471
472 void Context::set_font_face(const RefPtr<const FontFace>& font_face)
473 {
474   cairo_set_font_face(m_cobject, const_cast<cairo_font_face_t*>(font_face->cobj()));
475   check_object_status_and_throw_exception(*this);
476 }
477
478 void Context::get_text_extents(const std::string& utf8, TextExtents& extents) const
479 {
480   cairo_text_extents(m_cobject, utf8.c_str(), &extents);
481   check_object_status_and_throw_exception(*this);
482 }
483
484 void Context::get_glyph_extents(const std::vector<Glyph>& glyphs, TextExtents& extents) const
485 {
486   cairo_glyph_extents(m_cobject, const_cast<cairo_glyph_t*>(&glyphs[0]), glyphs.size(), &extents);
487   check_object_status_and_throw_exception(*this);
488 }
489
490 void Context::text_path(const std::string& utf8)
491 {
492   cairo_text_path(m_cobject, utf8.c_str());
493   check_object_status_and_throw_exception(*this);
494 }
495
496 void Context::glyph_path(const std::vector<Glyph>& glyphs)
497 {
498   cairo_glyph_path(m_cobject, const_cast<cairo_glyph_t*>(&glyphs[0]), glyphs.size());
499   check_object_status_and_throw_exception(*this);
500 }
501
502 Operator Context::get_operator() const
503 {
504   const Operator result = static_cast<Operator>(cairo_get_operator(m_cobject));
505   check_object_status_and_throw_exception(*this);
506   return result;
507 }
508
509 RefPtr<Pattern> Context::get_source()
510 {
511   cairo_pattern_t* pattern = cairo_get_source(m_cobject);
512   check_object_status_and_throw_exception(*this);
513   return RefPtr<Pattern>(new Pattern(pattern, false /* does not have reference */));
514 }
515
516 RefPtr<const Pattern> Context::get_source() const
517 {
518   cairo_pattern_t* pattern = cairo_get_source(m_cobject);
519   check_object_status_and_throw_exception(*this);
520   return RefPtr<const Pattern>(new Pattern(pattern, false /* does not have reference */));
521 }
522
523 double Context::get_tolerance() const
524 {
525   const double result = cairo_get_tolerance(m_cobject);
526   check_object_status_and_throw_exception(*this);
527   return result;
528 }
529
530 Antialias Context::get_antialias() const
531 {
532   const Antialias result = static_cast<Antialias>(cairo_get_antialias(m_cobject));
533   check_object_status_and_throw_exception(*this);
534   return result;
535 }
536
537 void Context::get_current_point(double& x, double& y) const
538 {
539   cairo_get_current_point(m_cobject, &x, &y);
540   check_object_status_and_throw_exception(*this);
541 }
542
543 FillRule Context::get_fill_rule() const
544 {
545   const FillRule result = static_cast<FillRule>(cairo_get_fill_rule(m_cobject));
546   check_object_status_and_throw_exception(*this);
547   return result;
548 }
549
550 double Context::get_line_width() const
551 {
552   const double result = cairo_get_line_width(m_cobject);
553   check_object_status_and_throw_exception(*this);
554   return result;
555 }
556
557 LineCap Context::get_line_cap() const
558 {
559   const LineCap result = static_cast<LineCap>(cairo_get_line_cap(m_cobject));
560   check_object_status_and_throw_exception(*this);
561   return result;
562 }
563
564 LineJoin Context::get_line_join() const
565 {
566   const LineJoin result = static_cast<LineJoin>(cairo_get_line_join(m_cobject));
567   check_object_status_and_throw_exception(*this);
568   return result;
569 }
570
571 double Context::get_miter_limit() const
572 {
573   const double result = cairo_get_miter_limit(m_cobject);
574   check_object_status_and_throw_exception(*this);
575   return result;
576 }
577
578 void Context::get_matrix(Matrix& matrix)
579 {
580   cairo_get_matrix(m_cobject, &matrix);
581   check_object_status_and_throw_exception(*this);
582 }
583
584 RefPtr<Surface> Context::get_target()
585 {
586   cairo_surface_t* surface = cairo_get_target(const_cast<cairo_t*>(m_cobject));
587   check_object_status_and_throw_exception(*this);
588   return RefPtr<Surface>(new Surface(surface, false /* does not have reference */));
589 }
590
591 RefPtr<const Surface> Context::get_target() const
592 {
593   cairo_surface_t* surface = cairo_get_target(const_cast<cairo_t*>(m_cobject));
594   check_object_status_and_throw_exception(*this);
595   return RefPtr<const Surface>(new Surface(surface, false /* does not have reference */));
596 }
597
598 Path* Context::copy_path() const
599 {
600   cairo_path_t* cresult = cairo_copy_path(const_cast<cairo_t*>(m_cobject));
601   check_object_status_and_throw_exception(*this);
602   return new Path(cresult, true /* take ownership */); //The caller must delete it.
603 }
604
605 Path* Context::copy_path_flat() const
606 {
607   cairo_path_t* cresult = cairo_copy_path_flat(const_cast<cairo_t*>(m_cobject));
608   check_object_status_and_throw_exception(*this);
609   return new Path(cresult, true /* take ownership */); //The caller must delete it.
610 }
611
612 void Context::append_path(const Path& path)
613 {
614   cairo_append_path(m_cobject, const_cast<cairo_path_t*>(path.cobj()));
615   check_object_status_and_throw_exception(*this);
616 }
617
618 void Context::push_group()
619 {
620   cairo_push_group(m_cobject);
621   check_object_status_and_throw_exception(*this);
622 }
623
624 void Context::push_group_with_content(Content content)
625 {
626   cairo_push_group_with_content(m_cobject, static_cast<cairo_content_t>(content));
627   check_object_status_and_throw_exception(*this);
628 }
629
630 RefPtr<Pattern> Context::pop_group()
631 {
632   cairo_pattern_t* pattern = cairo_pop_group(m_cobject);
633   check_object_status_and_throw_exception(*this);
634   return RefPtr<Pattern>(new Pattern(pattern));
635 }
636
637 void Context::pop_group_to_source()
638 {
639   cairo_pop_group_to_source(m_cobject);
640   check_object_status_and_throw_exception(*this);
641 }
642
643 RefPtr<Surface> Context::get_group_target()
644 {
645   cairo_surface_t* surface = cairo_get_group_target(m_cobject);
646   // surface can be NULL if you're not between push/pop group calls
647   if (surface == NULL)
648   {
649     // FIXME: is this really the right way to handle this?
650     throw_exception(CAIRO_STATUS_NULL_POINTER);
651   }
652   return RefPtr<Surface>(new Surface(surface, false));
653 }
654
655 RefPtr<const Surface> Context::get_group_target() const
656 {
657   cairo_surface_t* surface = cairo_get_group_target(m_cobject);
658   // surface can be NULL if you're not between push/pop group calls
659   if (surface == NULL)
660   {
661     // FIXME: is this really the right way to handle this?
662     throw_exception(CAIRO_STATUS_NULL_POINTER);
663   }
664   return RefPtr<const Surface>(new Surface(surface, false));
665 }
666
667 } //namespace Cairo
668
669 // vim: ts=2 sw=2 et