more updates
[synfig.git] / synfig-core / trunk / src / synfig / surface.h
1 /* === S I N F G =========================================================== */
2 /*!     \file surface.h
3 **      \brief Surface and Pen Definitions
4 **
5 **      $Id: surface.h,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SINFG_SURFACE_H
25 #define __SINFG_SURFACE_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include "color.h"
30 #include "renddesc.h"
31 #include <ETL/pen>
32 #include <ETL/surface>
33 #include <ETL/handle>
34
35 /* === M A C R O S ========================================================= */
36
37 /* === T Y P E D E F S ===================================================== */
38
39 /* === C L A S S E S & S T R U C T S ======================================= */
40
41 namespace sinfg {
42
43 class Target;
44 class Target_Scanline;
45
46 class ColorPrep
47 {
48 public:
49         ColorAccumulator cook(Color x)const
50         {
51                 x.set_r(x.get_r()*x.get_a());
52                 x.set_g(x.get_g()*x.get_a());
53                 x.set_b(x.get_b()*x.get_a());
54                 return x;
55         }
56         Color uncook(ColorAccumulator x)const
57         {
58                 if(!x.get_a())
59                         return Color::alpha();
60                 
61                 const float a(1.0f/x.get_a());
62                 
63                 x.set_r(x.get_r()*a);
64                 x.set_g(x.get_g()*a);
65                 x.set_b(x.get_b()*a);
66                 return x;
67         }
68 };
69
70 /*!     \class Surface
71 **      \brief Bitmap Surface
72 **      \todo writeme
73 */
74 class Surface : public etl::surface<Color, ColorAccumulator, ColorPrep>
75 {
76 public:
77         typedef Color value_type;
78         class alpha_pen;
79
80         Surface() { }
81
82         Surface(const size_type::value_type &w, const size_type::value_type &h):
83                 etl::surface<Color, ColorAccumulator,ColorPrep>(w,h) { }
84
85         Surface(const size_type &s):
86                 etl::surface<Color, ColorAccumulator,ColorPrep>(s) { }
87
88         template <typename _pen>
89         Surface(const _pen &_begin, const _pen &_end):
90                 etl::surface<Color, ColorAccumulator,ColorPrep>(_begin,_end) { }
91
92         template <class _pen> void blit_to(_pen &pen)
93         { return blit_to(pen,0,0, get_w(),get_h()); }
94
95         template <class _pen> void
96         blit_to(_pen& DEST_PEN, int x, int y, int w, int h)
97         {
98                 etl::surface<Color, ColorAccumulator, ColorPrep>::blit_to(DEST_PEN,x,y,w,h);
99         }
100
101         void clear();
102
103         void blit_to(alpha_pen& DEST_PEN, int x, int y, int w, int h);
104 };      // END of class Surface
105
106 #ifndef DOXYGEN_SKIP
107
108 /*! \internal Used by Pen_Alpha */
109 struct _BlendFunc
110 {
111         Color::BlendMethod blend_method;
112
113         _BlendFunc(Color::BlendMethod b= Color::BLEND_COMPOSITE):blend_method(b) { }
114
115         Color operator()(const Color &a,const Color &b,const Color::value_type &t)const
116         {
117                 return Color::blend(b,a,t,blend_method);
118         }
119 };      // END of class _BlendFunc
120
121 #endif
122
123 /*!     \class Surface::alpha_pen
124 **      \brief Alpha-Blending Pen
125 **
126 **      This pen works like a normal alpha pen, except that it supports
127 **      a variety of blending methods. Use set_blend_method() to select
128 **      which blending method you want to use.
129 **      The default blending method is Color::BLEND_COMPOSITE.
130 **      \see Color::BlendMethod
131 */
132 class Surface::alpha_pen : public etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >
133 {
134 public:
135         alpha_pen() { }
136         alpha_pen(const etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc > &x):
137                 etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >(x)
138         { }
139         
140         alpha_pen(const etl::generic_pen<Color, ColorAccumulator>& pen, const Color::value_type &a = 1, const _BlendFunc &func = _BlendFunc()):
141                 etl::alpha_pen< etl::generic_pen<Color, ColorAccumulator>, Color::value_type, _BlendFunc >(pen,a,func)
142         { }
143
144         //! Sets the blend method to that described by \a method
145         void set_blend_method(Color::BlendMethod method) { affine_func_.blend_method=method; }
146
147         //! Returns the blend method being used for this pen
148         Color::BlendMethod get_blend_method()const { return affine_func_.blend_method; }
149 };      // END of class Surface::alpha_pen
150
151 //! Creates a target that will render to \a surface
152 etl::handle<Target_Scanline> surface_target(Surface *surface);
153
154 }; // END of namespace sinfg
155
156 /* === E N D =============================================================== */
157
158 #endif