Drop the bool operator for ObjectURI, to avoid getting the kind of side-effect that...
[gnash.git] / libcore / LineStyle.cpp
blob12365fab4c562180e09cd3100abd656ab0195af7
1 // LineStyle.cpp Line style types.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
4 // Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 // Based on public domain work by Thatcher Ulrich <tu@tulrich.com> 2003
21 // styles.cpp -- Thatcher Ulrich <tu@tulrich.com> 2003
23 #include "LineStyle.h"
25 #include "TypesParser.h"
26 #include "RunResources.h"
27 #include "log.h"
28 #include "SWFStream.h"
29 #include "smart_ptr.h"
30 #include "movie_definition.h"
31 #include "SWF.h"
32 #include "GnashException.h"
33 #include "FillStyle.h"
34 #include "GnashNumeric.h"
36 namespace gnash {
38 namespace {
40 class GetColor : public boost::static_visitor<rgba>
42 public:
43 rgba operator()(const SolidFill& f) const {
44 return f.color();
46 rgba operator()(const GradientFill&) const {
47 return rgba();
49 rgba operator()(const BitmapFill&) const {
50 return rgba();
56 LineStyle::LineStyle()
58 m_width(0),
59 m_color(),
60 _scaleVertically(true),
61 _scaleHorizontally(true),
62 _pixelHinting(false),
63 _noClose(false),
64 _startCapStyle(CAP_ROUND),
65 _endCapStyle(CAP_ROUND),
66 _joinStyle(JOIN_ROUND),
67 _miterLimitFactor(1.0f)
71 void
72 LineStyle::read_morph(SWFStream& in, SWF::TagType t, movie_definition& md,
73 const RunResources& /*r*/, LineStyle *pOther)
75 if (t == SWF::DEFINEMORPHSHAPE)
77 in.ensureBytes(2 + 2);
78 m_width = in.read_u16();
79 pOther->m_width = in.read_u16();
80 m_color = readRGBA(in);
81 pOther->m_color = readRGBA(in);
82 return;
85 assert(t == SWF::DEFINEMORPHSHAPE2 || t == SWF::DEFINEMORPHSHAPE2_);
87 // MorphShape 2 from here down.
88 in.ensureBytes(4 + 2);
90 m_width = in.read_u16();
91 pOther->m_width = in.read_u16();
93 int flags1 = in.read_u8();
94 int flags2 = in.read_u8();
95 _startCapStyle = (CapStyle)((flags1 & 0xC0) >> 6);
96 _joinStyle = (JoinStyle)((flags1 & 0x30) >> 4);
97 bool has_fill = flags1 & (1 << 3);
98 _scaleHorizontally = !(flags1 & (1 << 2));
99 _scaleVertically = !(flags1 & (1 << 1));
100 _pixelHinting = flags1 & (1 << 0);
101 _noClose = flags2 & (1 << 2);
102 _endCapStyle = (CapStyle) (flags2 & 0x03);
104 if (_joinStyle == JOIN_MITER)
106 in.ensureBytes(2);
107 _miterLimitFactor = in.read_short_ufixed();
109 if (has_fill) {
110 OptionalFillPair fp = readFills(in, t, md, true);
112 // TODO: store a fill style properly, removing the need for the
113 // visitor.
114 m_color = boost::apply_visitor(GetColor(), fp.first.fill);
115 pOther->m_color = boost::apply_visitor(GetColor(), fp.second->fill);
117 else {
118 m_color = readRGBA(in);
119 pOther->m_color = readRGBA(in);
123 void
124 LineStyle::read(SWFStream& in, SWF::TagType t, movie_definition& md,
125 const RunResources& /*r*/)
127 switch (t) {
129 default:
130 in.ensureBytes(2);
131 m_width = in.read_u16();
132 m_color = readRGBA(in);
133 return;
135 case SWF::DEFINESHAPE:
136 case SWF::DEFINESHAPE2:
137 in.ensureBytes(2);
138 m_width = in.read_u16();
139 m_color = readRGB(in);
140 return;
142 case SWF::DEFINESHAPE4:
143 case SWF::DEFINESHAPE4_:
145 // TODO: Unfinished. Temporary to allow DefineShape4 to work in
146 // many cases, but does not work correctly in all cases.
147 in.ensureBytes(2+2);
148 m_width = in.read_u16();
150 const boost::uint8_t flags1 = in.read_u8();
151 const boost::uint8_t flags2 = in.read_u8();
153 _startCapStyle = (CapStyle)((flags1 & 0xC0) >> 6);
154 _joinStyle = (JoinStyle)((flags1 & 0x30) >> 4);
155 const bool has_fill = flags1 & (1 << 3);
156 _scaleHorizontally = !(flags1 & (1 << 2));
157 _scaleVertically = !(flags1 & (1 << 1));
158 _pixelHinting = flags1 & (1 << 0);
159 _noClose = flags2 & (1 << 2);
160 _endCapStyle = (CapStyle) (flags2 & 0x03);
162 if (_joinStyle == JOIN_MITER) {
163 in.ensureBytes(2);
164 _miterLimitFactor = in.read_short_ufixed();
166 if (has_fill) {
167 // TODO: store a fill style properly, removing the need for the
168 // visitor.
169 OptionalFillPair fp = readFills(in, t, md, false);
170 m_color = boost::apply_visitor(GetColor(), fp.first.fill);
172 else {
173 m_color = readRGBA(in);
179 void
180 LineStyle::set_lerp(const LineStyle& ls1, const LineStyle& ls2, float ratio)
182 m_width = static_cast<boost::uint16_t>(
183 frnd(lerp<float>(ls1.getThickness(), ls2.getThickness(), ratio)));
184 m_color.set_lerp(ls1.get_color(), ls2.get_color(), ratio);
185 if ( ls1._scaleVertically != ls2._scaleVertically )
187 LOG_ONCE( log_error("UNTESTED: Dunno how to interpolate line styles with different vertical thickness scaling") );
189 if ( ls1._scaleHorizontally != ls2._scaleHorizontally )
191 LOG_ONCE( log_error("UNTESTED: Dunno how to interpolate line styles with different horizontal thickness scaling") );
195 } // namespace gnash
198 // Local Variables:
199 // mode: C++
200 // End: