Drop extra semicolon
[gnash.git] / libcore / FillStyle.cpp
blob70b97c01cc0f3f5da76c19a657c436fcbd64f190
1 // FillStyle.cpp: Graphical region filling styles, for Gnash.
2 //
3 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "FillStyle.h"
22 #include <ostream>
23 #include <boost/variant.hpp>
25 #include "smart_ptr.h"
26 #include "CachedBitmap.h"
27 #include "movie_definition.h"
28 #include "SWF.h"
29 #include "GnashNumeric.h"
30 #include "RunResources.h"
31 #include "GnashImage.h"
33 namespace gnash {
35 namespace {
37 /// Create a lerped version of two other FillStyles.
39 /// The two fill styles must have exactly the same types. Callers are
40 /// responsible for ensuring this.
41 class SetLerp : public boost::static_visitor<>
43 public:
44 SetLerp(const FillStyle::Fill& a, const FillStyle::Fill& b, double ratio)
46 _a(a),
47 _b(b),
48 _ratio(ratio)
52 template<typename T> void operator()(T& f) const {
53 const T& a = boost::get<T>(_a);
54 const T& b = boost::get<T>(_b);
55 f.setLerp(a, b, _ratio);
58 private:
59 const FillStyle::Fill& _a;
60 const FillStyle::Fill& _b;
61 const double _ratio;
67 SWFMatrix
68 gradientMatrix(GradientFill::Type t, const SWFMatrix& m)
70 SWFMatrix base;
71 switch (t) {
72 case GradientFill::LINEAR:
73 base.set_translation(128, 0);
74 base.set_scale(1.0 / 128, 1.0 / 128);
75 break;
76 case GradientFill::RADIAL:
77 base.set_scale(1.0 / 512, 1.0 / 512);
78 break;
80 base.concatenate(m);
81 return base;
84 GradientFill::GradientFill(Type t, const SWFMatrix& m,
85 const GradientRecords& recs)
87 spreadMode(PAD),
88 interpolation(RGB),
89 _focalPoint(0.0),
90 _gradients(recs),
91 _type(t),
92 _matrix(gradientMatrix(t, m))
94 assert(recs.empty() || recs.size() > 1);
97 void
98 GradientFill::setFocalPoint(double d)
100 _focalPoint = clamp<float>(d, -1, 1);
103 BitmapFill::BitmapFill(Type t, const CachedBitmap* bi, const SWFMatrix& m,
104 SmoothingPolicy pol)
106 _type(t),
107 _smoothingPolicy(pol),
108 _matrix(m),
109 _bitmapInfo(bi),
110 _md(0),
111 _id(0)
115 BitmapFill::BitmapFill(SWF::FillType t, movie_definition* md,
116 boost::uint16_t id, const SWFMatrix& m)
118 _type(),
119 _smoothingPolicy(),
120 _matrix(m),
121 _bitmapInfo(0),
122 _md(md),
123 _id(id)
125 assert(md);
127 _smoothingPolicy = md->get_version() >= 8 ?
128 BitmapFill::SMOOTHING_ON : BitmapFill::SMOOTHING_UNSPECIFIED;
130 switch (t) {
131 case SWF::FILL_TILED_BITMAP_HARD:
132 _type = BitmapFill::TILED;
133 _smoothingPolicy = BitmapFill::SMOOTHING_OFF;
134 break;
136 case SWF::FILL_TILED_BITMAP:
137 _type = BitmapFill::TILED;
138 break;
140 case SWF::FILL_CLIPPED_BITMAP_HARD:
141 _type = BitmapFill::CLIPPED;
142 _smoothingPolicy = BitmapFill::SMOOTHING_OFF;
143 break;
145 case SWF::FILL_CLIPPED_BITMAP:
146 _type = BitmapFill::CLIPPED;
147 break;
149 default:
150 std::abort();
154 BitmapFill::BitmapFill(const BitmapFill& other)
156 _type(other._type),
157 _smoothingPolicy(other._smoothingPolicy),
158 _matrix(other._matrix),
159 _bitmapInfo(other._bitmapInfo),
160 _md(other._md),
161 _id(other._id)
165 BitmapFill::~BitmapFill()
169 BitmapFill&
170 BitmapFill::operator=(const BitmapFill& other)
172 _type = other._type;
173 _smoothingPolicy = other._smoothingPolicy;
174 _matrix = other._matrix;
175 _bitmapInfo = other._bitmapInfo;
176 _md = other._md;
177 _id = other._id;
178 return *this;
181 const CachedBitmap*
182 BitmapFill::bitmap() const
184 if (_bitmapInfo) {
185 return _bitmapInfo->disposed() ? 0 : _bitmapInfo.get();
187 if (!_md) return 0;
188 _bitmapInfo = _md->getBitmap(_id);
190 // May still be 0!
191 return _bitmapInfo.get();
194 void
195 GradientFill::setLerp(const GradientFill& a, const GradientFill& b,
196 double ratio)
198 assert(type() == a.type());
199 assert(_gradients.size() == a.recordCount());
200 assert(_gradients.size() == b.recordCount());
202 for (size_t i = 0, e = _gradients.size(); i < e; ++i) {
203 const GradientRecord& ra = a.record(i);
204 const GradientRecord& rb = b.record(i);
205 _gradients[i].ratio = frnd(lerp<float>(ra.ratio, rb.ratio, ratio));
206 _gradients[i].color.set_lerp(ra.color, rb.color, ratio);
208 _matrix.set_lerp(a.matrix(), b.matrix(), ratio);
211 void
212 BitmapFill::setLerp(const BitmapFill& a, const BitmapFill& b, double ratio)
214 _matrix.set_lerp(a.matrix(), b.matrix(), ratio);
217 // Sets this style to a blend of a and b. t = [0,1]
218 void
219 setLerp(FillStyle& f, const FillStyle& a, const FillStyle& b, double t)
221 assert(t >= 0 && t <= 1);
222 f.fill = a.fill;
223 boost::apply_visitor(SetLerp(a.fill, b.fill, t), f.fill);
227 std::ostream&
228 operator<<(std::ostream& os, const BitmapFill::SmoothingPolicy& p)
230 switch (p) {
231 case BitmapFill::SMOOTHING_UNSPECIFIED:
232 os << "unspecified";
233 break;
234 case BitmapFill::SMOOTHING_ON:
235 os << "on";
236 break;
237 case BitmapFill::SMOOTHING_OFF:
238 os << "off";
239 break;
240 default:
241 // cast to int required to avoid infinite recursion
242 os << "unknown " << +p;
243 break;
245 return os;
248 } // namespace gnash
251 // Local Variables:
252 // mode: C++
253 // End: