synfig-core  1.0.3
surface.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
22 /* ========================================================================= */
23 
24 /* === S T A R T =========================================================== */
25 
26 #ifndef __SYNFIG_SURFACE_H
27 #define __SYNFIG_SURFACE_H
28 
29 /* === H E A D E R S ======================================================= */
30 
31 #include "color.h"
32 #include "renddesc.h"
33 #include <ETL/pen>
34 #include <ETL/surface>
35 #include <ETL/handle>
36 
37 #include "cairo.h"
38 
39 /* === M A C R O S ========================================================= */
40 
41 /* === T Y P E D E F S ===================================================== */
42 
43 /* === C L A S S E S & S T R U C T S ======================================= */
44 
45 namespace synfig {
46 
47 class Target;
48 class Target_Scanline;
49 class Target_Cairo;
50 
51 class ColorPrep
52 {
53 public:
55  {
56  x.set_r(x.get_r()*x.get_a());
57  x.set_g(x.get_g()*x.get_a());
58  x.set_b(x.get_b()*x.get_a());
59  return x;
60  }
62  {
63  if(!x.get_a())
64  return Color::alpha();
65 
66  const float a(1.0f/x.get_a());
67 
68  x.set_r(x.get_r()*a);
69  x.set_g(x.get_g()*a);
70  x.set_b(x.get_b()*a);
71  return x;
72  }
73 };
74 
76 {
77 public:
79  {
80  return x.premult_alpha();
81  }
83  {
84  return x.demult_alpha();
85  }
86 };
87 
92 class Surface : public etl::surface<Color, ColorAccumulator, ColorPrep>
93 {
94 public:
95  typedef Color value_type;
96  class alpha_pen;
97 
98  Surface() { }
99 
100  Surface(const size_type::value_type &w, const size_type::value_type &h):
101  etl::surface<Color, ColorAccumulator,ColorPrep>(w,h) { }
102 
103  Surface(const size_type &s):
104  etl::surface<Color, ColorAccumulator,ColorPrep>(s) { }
105 
106  template <typename _pen>
107  Surface(const _pen &_begin, const _pen &_end):
108  etl::surface<Color, ColorAccumulator,ColorPrep>(_begin,_end) { }
109 
110  template <class _pen> void blit_to(_pen &pen)
111  { return blit_to(pen,0,0, get_w(),get_h()); }
112 
113  template <class _pen> void
114  blit_to(_pen& DEST_PEN, int x, int y, int w, int h)
115  {
117  }
118 
119  void clear();
120 
121  void blit_to(alpha_pen& DEST_PEN, int x, int y, int w, int h);
122 }; // END of class Surface
123 
124 
130 class CairoSurface : public etl::surface<CairoColor, CairoColorAccumulator, CairoColorPrep>
131 {
132  // This is the Cairo surface pointer
133  // It is NULL if the not initialized
134  cairo_surface_t *cs_;
135  // This pointer is used when map and unmap the cairo_surface to a cairo_image_surface
136  // see map_cairo_surface() unmap_cairo_surface();
137  cairo_surface_t *cs_image_;
138 
139 public:
141  class alpha_pen;
142 
143  CairoSurface():cs_(NULL), cs_image_(NULL) { }
144  CairoSurface(cairo_surface_t *cs):cs_(NULL), cs_image_(NULL) { set_cairo_surface(cs); }
146  if(cs_!= NULL) cairo_surface_destroy(cs_);
147  if(cs_image_!=NULL) cairo_surface_destroy(cs_image_); }
148 
149 
150  // If cs_ is set then the set_wh does nothing
151  // If cs_ is not set then set_wh creates a cairo_surface_image on cs_image_
152  // of size wxh
153  void set_wh(int w, int h, int pitch=0);
154  // Use whits version of set_wh to directly give to the etl::surface the
155  // pointer to data, the width, height and pitch (stride) between rows
156  void set_wh(int w, int h, unsigned char* data, int pitch)
158  // specialization of etl::surface::blit_to that considers the possibility of
159  // don't blend colors when blend method is straight and alpha is 1.0
160  void blit_to(alpha_pen& DEST_PEN, int x, int y, int w, int h);
161 
162  // Use this function to reference one given generic cairo_surface
163  // by this surface class.
164  // When the CairoSurface instance is destructed the reference counter of the
165  // cairo_surface_t shoud be decreased.
166  // It is also possible to detach the cairo surface passing NULL as argument.
167  // If the cairo surface is mapped at the time of call this function, then
168  // it is unmaped first.
169  void set_cairo_surface(cairo_surface_t *cs);
170  // Returns an increased reference pointer of the surface. The receiver is responsible
171  // of destroy the surface once referenced.
172  cairo_surface_t* get_cairo_surface()const;
173  // Returns an increased reference pointer of the image surface. The receiver is responsible
174  // of destroy the surface once referenced.
175  cairo_surface_t* get_cairo_image_surface()const;
176  // Maps cs_ to cs_image_ and extract the *data to etl::surface::data for further modifications
177  // It will flush any remaining painting operation to the cs_
178  // returns true on success or false if something failed
179  bool map_cairo_image();
180  // Unmap the cs_image_ to cs_ after external modification has been done via *data
181  // It will mark cs_ as dirty
182  void unmap_cairo_image();
183  // Returns true if the cairo_surface_t* cs_ is mapped on cs_image_
184  bool is_mapped()const;
185 
186 }; // END of class Surface
187 
188 
189 #ifndef DOXYGEN_SKIP
190 
192 template <class C, typename A=Color::value_type>
193 struct _BlendFunc
194 {
195  Color::BlendMethod blend_method;
196 
197  _BlendFunc(typename Color::BlendMethod b= Color::BLEND_COMPOSITE):blend_method(b) { }
198 
199  C operator()(const C &a,const C &b,const A &t)const
200  {
201  return C::blend(b,a,t,blend_method);
202  }
203 }; // END of class _BlendFunc
204 
205 #endif
206 
216 class Surface::alpha_pen : public etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc<Color> >
217 {
218 public:
219  alpha_pen() { }
220  alpha_pen(const etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc<Color> > &x):
221  etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc<Color> >(x)
222  { }
223 
224  alpha_pen(const etl::generic_pen<Color, ColorAccumulator>& pen, const Color::value_type &a = 1, const _BlendFunc<Color> &func = _BlendFunc<Color>()):
225  etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc<Color> >(pen,a,func)
226  { }
227 
229  void set_blend_method(Color::BlendMethod method) { affine_func_.blend_method=method; }
230 
232  Color::BlendMethod get_blend_method()const { return affine_func_.blend_method; }
233 }; // END of class Surface::alpha_pen
234 
235 
236 
246 class CairoSurface::alpha_pen : public etl::alpha_pen< etl::generic_pen<CairoColor, CairoColorAccumulator>, float, _BlendFunc<CairoColor> >
247 {
248 public:
249  alpha_pen() { }
250  alpha_pen(const etl::alpha_pen< etl::generic_pen<CairoColor, CairoColorAccumulator>, float, _BlendFunc<CairoColor> > &x):
251  etl::alpha_pen< etl::generic_pen<CairoColor, CairoColorAccumulator>, float, _BlendFunc<CairoColor> >(x)
252  { }
253 
254  alpha_pen(const etl::generic_pen<CairoColor, CairoColorAccumulator>& pen, const float &a = 1, const _BlendFunc<CairoColor> &func = _BlendFunc<CairoColor>()):
255  etl::alpha_pen< etl::generic_pen<CairoColor, CairoColorAccumulator>, float, _BlendFunc<CairoColor> >(pen,a,func)
256  { }
257 
259  void set_blend_method(Color::BlendMethod method) { affine_func_.blend_method=method; }
260 
262  Color::BlendMethod get_blend_method()const { return affine_func_.blend_method; }
263 }; // END of class CairoSurface::alpha_pen
264 
265 
266 
268 etl::handle<Target_Scanline> surface_target(Surface *surface);
270 etl::handle<Target_Cairo> cairo_image_target(cairo_surface_t** surface);
271 
272 }; // END of namespace synfig
273 
274 /* === E N D =============================================================== */
275 
276 #endif