* added files in patch for ardour-3.0 to compile on OS X thanks to Sakari Bergen
[ardour.git] / libs / cairomm / cairomm / surface.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/surface.h>
20 #include <cairomm/private.h>
21
22 namespace Cairo
23 {
24
25 Surface::Surface(cairo_surface_t* cobject, bool has_reference)
26 : m_cobject(0)
27 {
28   if(has_reference)
29     m_cobject = cobject;
30   else
31     m_cobject = cairo_surface_reference(cobject);
32 }
33
34 Surface::~Surface()
35 {
36   if(m_cobject)
37     cairo_surface_destroy(m_cobject);
38 }
39
40 void Surface::finish()
41 {
42   cairo_surface_finish(m_cobject);
43   check_object_status_and_throw_exception(*this);
44 }
45
46 void Surface::get_font_options(FontOptions& options) const
47 {
48   cairo_font_options_t* cfontoptions = cairo_font_options_create();
49   cairo_surface_get_font_options(m_cobject, cfontoptions);
50   options = FontOptions(cfontoptions);
51   cairo_font_options_destroy(cfontoptions);
52   check_object_status_and_throw_exception(*this);
53 }
54
55 void Surface::flush()
56 {
57   cairo_surface_flush(m_cobject);
58   check_object_status_and_throw_exception(*this);
59 }
60
61 void Surface::mark_dirty()
62 {
63   cairo_surface_mark_dirty(m_cobject);
64   check_object_status_and_throw_exception(*this);
65 }
66
67 void Surface::mark_dirty(int x, int y, int width, int height)
68 {
69   cairo_surface_mark_dirty_rectangle(m_cobject, x, y, width, height);
70   check_object_status_and_throw_exception(*this);
71 }
72
73 void Surface::set_device_offset(double x_offset, double y_offset)
74 {
75   cairo_surface_set_device_offset(m_cobject, x_offset, y_offset);
76   check_object_status_and_throw_exception(*this);
77 }
78
79 void Surface::get_device_offset(double& x_offset, double& y_offset) const
80 {
81   cairo_surface_get_device_offset(const_cast<cobject*>(m_cobject), &x_offset, &y_offset);
82 }
83
84 void Surface::set_fallback_resolution(double x_pixels_per_inch, double y_pixels_per_inch)
85 {
86   cairo_surface_set_fallback_resolution(m_cobject, x_pixels_per_inch, y_pixels_per_inch);
87   check_object_status_and_throw_exception(*this);
88 }
89
90 SurfaceType Surface::get_type() const
91 {
92   cairo_surface_type_t surface_type = cairo_surface_get_type(m_cobject);
93   check_object_status_and_throw_exception(*this);
94   return static_cast<SurfaceType>(surface_type);
95 }
96
97 #ifdef CAIRO_HAS_PNG_FUNCTIONS
98 void Surface::write_to_png(const std::string& filename)
99 {
100   ErrorStatus status = cairo_surface_write_to_png(m_cobject, filename.c_str());
101   check_status_and_throw_exception(status);
102 }
103
104 void Surface::write_to_png(cairo_write_func_t write_func, void *closure)
105 {
106   ErrorStatus status = cairo_surface_write_to_png_stream(m_cobject, write_func, closure);
107   check_status_and_throw_exception(status);
108 }
109 #endif
110
111 void Surface::reference() const
112 {
113   cairo_surface_reference(m_cobject);
114 }
115
116 void Surface::unreference() const
117 {
118   cairo_surface_destroy(m_cobject);
119 }
120
121 RefPtr<Surface> Surface::create(const RefPtr<Surface> other, Content content, int width, int height)
122 {
123   cairo_surface_t* cobject = cairo_surface_create_similar(other->m_cobject, (cairo_content_t)content, width, height);
124   check_status_and_throw_exception(cairo_surface_status(cobject));
125   return RefPtr<Surface>(new Surface(cobject, true /* has reference */));
126 }
127
128
129
130 ImageSurface::ImageSurface(cairo_surface_t* cobject, bool has_reference)
131 : Surface(cobject, has_reference)
132 { }
133
134 ImageSurface::~ImageSurface()
135 {
136   // surface is destroyed in base class
137 }
138
139 RefPtr<ImageSurface> ImageSurface::create(Format format, int width, int height)
140 {
141   cairo_surface_t* cobject = cairo_image_surface_create((cairo_format_t)format, width, height);
142   check_status_and_throw_exception(cairo_surface_status(cobject));
143   return RefPtr<ImageSurface>(new ImageSurface(cobject, true /* has reference */));
144 }
145
146 RefPtr<ImageSurface> ImageSurface::create(unsigned char* data, Format format, int width, int height, int stride)
147 {
148   cairo_surface_t* cobject = cairo_image_surface_create_for_data(data, (cairo_format_t)format, width, height, stride);
149   check_status_and_throw_exception(cairo_surface_status(cobject));
150   return RefPtr<ImageSurface>(new ImageSurface(cobject, true /* has reference */));
151 }
152
153 #ifdef CAIRO_HAS_PNG_FUNCTIONS
154
155 RefPtr<ImageSurface> ImageSurface::create_from_png(std::string filename)
156 {
157   cairo_surface_t* cobject = cairo_image_surface_create_from_png(filename.c_str());
158   check_status_and_throw_exception(cairo_surface_status(cobject));
159   return RefPtr<ImageSurface>(new ImageSurface(cobject, true /* has reference */));
160 }
161
162 RefPtr<ImageSurface> ImageSurface::create_from_png(cairo_read_func_t read_func, void *closure)
163 {
164   cairo_surface_t* cobject = cairo_image_surface_create_from_png_stream(read_func, closure);
165   check_status_and_throw_exception(cairo_surface_status(cobject));
166   return RefPtr<ImageSurface>(new ImageSurface(cobject, true /* has reference */));
167 }
168
169 #endif // CAIRO_HAS_PNG_FUNCTIONS
170
171 int ImageSurface::get_width() const
172 {
173   const int result = cairo_image_surface_get_width(m_cobject);
174   check_object_status_and_throw_exception(*this);
175   return result;
176 }
177
178 int ImageSurface::get_height() const
179 {
180   const int result = cairo_image_surface_get_height(m_cobject);
181   check_object_status_and_throw_exception(*this);
182   return result;
183 }
184
185 unsigned char* ImageSurface::get_data()
186 {
187   return cairo_image_surface_get_data(m_cobject);
188 }
189
190 const unsigned char* ImageSurface::get_data() const
191 {
192   return cairo_image_surface_get_data(m_cobject);
193 }
194
195 Format ImageSurface::get_format() const
196 {
197   return static_cast<Format>(cairo_image_surface_get_format(m_cobject));
198 }
199
200 int ImageSurface::get_stride() const
201 {
202   return cairo_image_surface_get_stride(m_cobject);
203 }
204
205
206 /*******************************************************************************
207  * THE FOLLOWING SURFACE TYPES ARE EXPERIMENTAL AND NOT FULLY SUPPORTED
208  ******************************************************************************/
209
210 #ifdef CAIRO_HAS_PDF_SURFACE
211
212 PdfSurface::PdfSurface(cairo_surface_t* cobject, bool has_reference) :
213     Surface(cobject, has_reference)
214 {}
215
216 PdfSurface::~PdfSurface()
217 {
218   // surface is destroyed in base class
219 }
220
221 RefPtr<PdfSurface> PdfSurface::create(std::string filename, double width_in_points, double height_in_points)
222 {
223   cairo_surface_t* cobject = cairo_pdf_surface_create(filename.c_str(), width_in_points, height_in_points);
224   check_status_and_throw_exception(cairo_surface_status(cobject));
225   return RefPtr<PdfSurface>(new PdfSurface(cobject, true /* has reference */));
226 }
227
228 RefPtr<PdfSurface> PdfSurface::create(cairo_write_func_t write_func, void *closure, double width_in_points, double height_in_points)
229 {
230   cairo_surface_t* cobject = cairo_pdf_surface_create_for_stream(write_func, closure, width_in_points, height_in_points);
231   check_status_and_throw_exception(cairo_surface_status(cobject));
232   return RefPtr<PdfSurface>(new PdfSurface(cobject, true /* has reference */));
233 }
234
235 void PdfSurface::set_size(double width_in_points, double height_in_points)
236 {
237   cairo_pdf_surface_set_size(m_cobject, width_in_points, height_in_points);
238   check_object_status_and_throw_exception(*this);
239 }
240
241 #endif // CAIRO_HAS_PDF_SURFACE
242
243
244
245
246 #ifdef CAIRO_HAS_PS_SURFACE
247
248 PsSurface::PsSurface(cairo_surface_t* cobject, bool has_reference) :
249     Surface(cobject, has_reference)
250 {}
251
252 PsSurface::~PsSurface()
253 {
254   // surface is destroyed in base class
255 }
256
257 RefPtr<PsSurface> PsSurface::create(std::string filename, double width_in_points, double height_in_points)
258 {
259   cairo_surface_t* cobject = cairo_ps_surface_create(filename.c_str(), width_in_points, height_in_points);
260   check_status_and_throw_exception(cairo_surface_status(cobject));
261   return RefPtr<PsSurface>(new PsSurface(cobject, true /* has reference */));
262 }
263
264 RefPtr<PsSurface> PsSurface::create(cairo_write_func_t write_func, void *closure, double width_in_points, double height_in_points)
265 {
266   cairo_surface_t* cobject = cairo_ps_surface_create_for_stream(write_func, closure, width_in_points, height_in_points);
267   check_status_and_throw_exception(cairo_surface_status(cobject));
268   return RefPtr<PsSurface>(new PsSurface(cobject, true /* has reference */));
269 }
270
271 void PsSurface::set_size(double width_in_points, double height_in_points)
272 {
273   cairo_ps_surface_set_size(m_cobject, width_in_points, height_in_points);
274   check_object_status_and_throw_exception(*this);
275 }
276
277
278 void PsSurface::dsc_comment(std::string comment)
279 {
280   cairo_ps_surface_dsc_comment(m_cobject, comment.c_str());
281   check_object_status_and_throw_exception(*this);
282 }
283
284 void PsSurface::dsc_begin_setup()
285 {
286   cairo_ps_surface_dsc_begin_setup(m_cobject);
287   check_object_status_and_throw_exception(*this);
288 }
289
290 void PsSurface::dsc_begin_page_setup()
291 {
292   cairo_ps_surface_dsc_begin_page_setup(m_cobject);
293   check_object_status_and_throw_exception(*this);
294 }
295
296
297 #endif // CAIRO_HAS_PS_SURFACE
298
299
300
301
302 #ifdef CAIRO_HAS_SVG_SURFACE
303
304 SvgSurface::SvgSurface(cairo_surface_t* cobject, bool has_reference) :
305     Surface(cobject, has_reference)
306 {}
307
308 SvgSurface::~SvgSurface()
309 {
310   // surface is destroyed in base class
311 }
312
313 RefPtr<SvgSurface> SvgSurface::create(std::string filename, double width_in_points, double height_in_points)
314 {
315   cairo_surface_t* cobject = cairo_svg_surface_create(filename.c_str(), width_in_points, height_in_points);
316   check_status_and_throw_exception(cairo_surface_status(cobject));
317   return RefPtr<SvgSurface>(new SvgSurface(cobject, true /* has reference */));
318 }
319
320 RefPtr<SvgSurface> SvgSurface::create(cairo_write_func_t write_func, void *closure, double width_in_points, double height_in_points)
321 {
322   cairo_surface_t* cobject = cairo_svg_surface_create_for_stream(write_func, closure, width_in_points, height_in_points);
323   check_status_and_throw_exception(cairo_surface_status(cobject));
324   return RefPtr<SvgSurface>(new SvgSurface(cobject, true /* has reference */));
325 }
326
327 void SvgSurface::restrict_to_version(SvgVersion version)
328 {
329   cairo_svg_surface_restrict_to_version(m_cobject, static_cast<cairo_svg_version_t>(version));
330   check_object_status_and_throw_exception(*this);
331 }
332
333 const std::vector<SvgVersion> SvgSurface::get_versions()
334 {
335   cairo_svg_version_t const *versions;
336   int num_versions;
337   cairo_svg_get_versions(&versions, &num_versions);
338
339   // Just copy the version array out into a std::vector.  This is a rarely used
340   // function and the array of versions is going to be very small, so there's no
341   // real performance hit.
342   std::vector<SvgVersion> vec;
343   for (int i = 0; i < num_versions; ++i)
344   {
345     vec.push_back(static_cast<SvgVersion>(versions[i]));
346   }
347   return vec;
348 }
349
350 std::string SvgSurface::version_to_string(SvgVersion version)
351 {
352   return std::string(cairo_svg_version_to_string(static_cast<cairo_svg_version_t>(version)));
353 }
354
355 #endif // CAIRO_HAS_SVG_SURFACE
356
357
358
359
360 #ifdef CAIRO_HAS_GLITZ_SURFACE
361
362 GlitzSurface::GlitzSurface(cairo_surface_t* cobject, bool has_reference)
363 : Surface(cobject, has_reference)
364 { }
365
366 GlitzSurface::~GlitzSurface()
367 {
368   // surface is destroyed in base class
369 }
370
371 RefPtr<GlitzSurface> GlitzSurface::create(glitz_surface_t *surface)
372 {
373   cairo_surface_t* cobject = cairo_glitz_surface_create(surface);
374   check_status_and_throw_exception(cairo_surface_status(cobject));
375   return RefPtr<GlitzSurface>(new GlitzSurface(cobject, true /* has reference */));
376 }
377
378 #endif // CAIRO_HAS_GLITZ_SURFACE
379
380 } //namespace Cairo
381
382 // vim: ts=2 sw=2 et