1 // FillStyle.cpp: Graphical region filling styles, for Gnash.
3 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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.
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"
23 #include <boost/variant.hpp>
25 #include "smart_ptr.h"
26 #include "CachedBitmap.h"
27 #include "movie_definition.h"
29 #include "GnashNumeric.h"
30 #include "RunResources.h"
31 #include "GnashImage.h"
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
<>
44 SetLerp(const FillStyle::Fill
& a
, const FillStyle::Fill
& b
, double 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
);
59 const FillStyle::Fill
& _a
;
60 const FillStyle::Fill
& _b
;
68 gradientMatrix(GradientFill::Type t
, const SWFMatrix
& m
)
72 case GradientFill::LINEAR
:
73 base
.set_translation(128, 0);
74 base
.set_scale(1.0 / 128, 1.0 / 128);
76 case GradientFill::RADIAL
:
77 base
.set_scale(1.0 / 512, 1.0 / 512);
84 GradientFill::GradientFill(Type t
, const SWFMatrix
& m
,
85 const GradientRecords
& recs
)
88 interpolation(SWF::GRADIENT_INTERPOLATION_NORMAL
),
92 _matrix(gradientMatrix(t
, m
))
94 assert(recs
.empty() || recs
.size() > 1);
98 GradientFill::setFocalPoint(double d
)
100 _focalPoint
= clamp
<float>(d
, -1, 1);
103 BitmapFill::BitmapFill(Type t
, const CachedBitmap
* bi
, const SWFMatrix
& m
,
107 _smoothingPolicy(pol
),
115 BitmapFill::BitmapFill(SWF::FillType t
, movie_definition
* md
,
116 boost::uint16_t id
, const SWFMatrix
& m
)
127 _smoothingPolicy
= md
->get_version() >= 8 ?
128 BitmapFill::SMOOTHING_ON
: BitmapFill::SMOOTHING_UNSPECIFIED
;
131 case SWF::FILL_TILED_BITMAP_HARD
:
132 _type
= BitmapFill::TILED
;
133 _smoothingPolicy
= BitmapFill::SMOOTHING_OFF
;
136 case SWF::FILL_TILED_BITMAP
:
137 _type
= BitmapFill::TILED
;
140 case SWF::FILL_CLIPPED_BITMAP_HARD
:
141 _type
= BitmapFill::CLIPPED
;
142 _smoothingPolicy
= BitmapFill::SMOOTHING_OFF
;
145 case SWF::FILL_CLIPPED_BITMAP
:
146 _type
= BitmapFill::CLIPPED
;
154 BitmapFill::BitmapFill(const BitmapFill
& other
)
157 _smoothingPolicy(other
._smoothingPolicy
),
158 _matrix(other
._matrix
),
159 _bitmapInfo(other
._bitmapInfo
),
165 BitmapFill::~BitmapFill()
170 BitmapFill::operator=(const BitmapFill
& other
)
173 _smoothingPolicy
= other
._smoothingPolicy
;
174 _matrix
= other
._matrix
;
175 _bitmapInfo
= other
._bitmapInfo
;
182 BitmapFill::bitmap() const
185 return _bitmapInfo
->disposed() ? 0 : _bitmapInfo
.get();
188 _bitmapInfo
= _md
->getBitmap(_id
);
191 return _bitmapInfo
.get();
195 GradientFill::setLerp(const GradientFill
& a
, const GradientFill
& b
,
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
);
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]
219 setLerp(FillStyle
& f
, const FillStyle
& a
, const FillStyle
& b
, double t
)
221 assert(t
>= 0 && t
<= 1);
223 boost::apply_visitor(SetLerp(a
.fill
, b
.fill
, t
), f
.fill
);
228 operator<<(std::ostream
& os
, const BitmapFill::SmoothingPolicy
& p
)
231 case BitmapFill::SMOOTHING_UNSPECIFIED
:
234 case BitmapFill::SMOOTHING_ON
:
237 case BitmapFill::SMOOTHING_OFF
:
241 // cast to int required to avoid infinite recursion
242 os
<< "unknown " << +p
;