Using mutexes around accesses to refcounts seems to make the Windows build much less...
[synfig.git] / synfig-core / trunk / src / synfig / surface.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file surface.h
3 **      \brief Surface and Pen Definitions
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_SURFACE_H
26 #define __SYNFIG_SURFACE_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include "color.h"
31 #include "renddesc.h"
32 #include <ETL/pen>
33 #include <ETL/surface>
34 #include <ETL/handle>
35
36 /* === M A C R O S ========================================================= */
37
38 /* === T Y P E D E F S ===================================================== */
39
40 /* === C L A S S E S & S T R U C T S ======================================= */
41
42 namespace synfig {
43
44 class Target;
45 class Target_Scanline;
46
47 class ColorPrep
48 {
49 public:
50         ColorAccumulator cook(Color x)const
51         {
52                 x.set_r(x.get_r()*x.get_a());
53                 x.set_g(x.get_g()*x.get_a());
54                 x.set_b(x.get_b()*x.get_a());
55                 return x;
56         }
57         Color uncook(ColorAccumulator x)const
58         {
59                 if(!x.get_a())
60                         return Color::alpha();
61
62                 const float a(1.0f/x.get_a());
63
64                 x.set_r(x.get_r()*a);
65                 x.set_g(x.get_g()*a);
66                 x.set_b(x.get_b()*a);
67                 return x;
68         }
69 };
70
71 /*!     \class Surface
72 **      \brief Bitmap Surface
73 **      \todo writeme
74 */
75 class Surface : public etl::surface<Color, ColorAccumulator, ColorPrep>
76 {
77 public:
78         typedef Color value_type;
79         class alpha_pen;
80
81         Surface() { }
82
83         Surface(const size_type::value_type &w, const size_type::value_type &h):
84                 etl::surface<Color, ColorAccumulator,ColorPrep>(w,h) { }
85
86         Surface(const size_type &s):
87                 etl::surface<Color, ColorAccumulator,ColorPrep>(s) { }
88
89         template <typename _pen>
90         Surface(const _pen &_begin, const _pen &_end):
91                 etl::surface<Color, ColorAccumulator,ColorPrep>(_begin,_end) { }
92
93         template <class _pen> void blit_to(_pen &pen)
94         { return blit_to(pen,0,0, get_w(),get_h()); }
95
96         template <class _pen> void
97         blit_to(_pen& DEST_PEN, int x, int y, int w, int h)
98         {
99                 etl::surface<Color, ColorAccumulator, ColorPrep>::blit_to(DEST_PEN,x,y,w,h);
100         }
101
102         void clear();
103
104         void blit_to(alpha_pen& DEST_PEN, int x, int y, int w, int h);
105 };      // END of class Surface
106
107 #ifndef DOXYGEN_SKIP
108
109 /*! \internal Used by Pen_Alpha */
110 struct _BlendFunc
111 {
112         Color::BlendMethod blend_method;
113
114         _BlendFunc(Color::BlendMethod b= Color::BLEND_COMPOSITE):blend_method(b) { }
115
116         Color operator()(const Color &a,const Color &b,const Color::value_type &t)const
117         {
118                 return Color::blend(b,a,t,blend_method);
119         }
120 };      // END of class _BlendFunc
121
122 #endif
123
124 /*!     \class Surface::alpha_pen
125 **      \brief Alpha-Blending Pen
126 **
127 **      This pen works like a normal alpha pen, except that it supports
128 **      a variety of blending methods. Use set_blend_method() to select
129 **      which blending method you want to use.
130 **      The default blending method is Color::BLEND_COMPOSITE.
131 **      \see Color::BlendMethod
132 */
133 class Surface::alpha_pen : public etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >
134 {
135 public:
136         alpha_pen() { }
137         alpha_pen(const etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc > &x):
138                 etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >(x)
139         { }
140
141         alpha_pen(const etl::generic_pen<Color, ColorAccumulator>& pen, const Color::value_type &a = 1, const _BlendFunc &func = _BlendFunc()):
142                 etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >(pen,a,func)
143         { }
144
145         //! Sets the blend method to that described by \a method
146         void set_blend_method(Color::BlendMethod method) { affine_func_.blend_method=method; }
147
148         //! Returns the blend method being used for this pen
149         Color::BlendMethod get_blend_method()const { return affine_func_.blend_method; }
150 };      // END of class Surface::alpha_pen
151
152 //! Creates a target that will render to \a surface
153 etl::handle<Target_Scanline> surface_target(Surface *surface);
154
155 }; // END of namespace synfig
156
157 /* === E N D =============================================================== */
158
159 #endif