drop libxv, add lsb-release
[gnash.git] / libcore / DynamicShape.cpp
blobdf2c6447816746fc45a25e156372d6018c974233
1 //
2 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #include "smart_ptr.h"
19 #include "DynamicShape.h"
20 #include "FillStyle.h"
21 #include "Renderer.h"
22 #include "DisplayObject.h"
24 #include <vector>
26 namespace gnash {
28 DynamicShape::DynamicShape()
30 _currpath(0),
31 _currfill(0),
32 _currline(0),
33 _x(0),
34 _y(0),
35 _changed(false)
38 void
39 DynamicShape::clear()
41 _shape.clear();
42 _currpath = 0;
43 _currfill = _currline = 0;
44 // TODO: worth setting _changed=true ?
47 void
48 DynamicShape::display(Renderer& renderer, const Transform& xform) const
50 renderer.drawShape(_shape, xform);
53 void
54 DynamicShape::add_path(const Path& pth)
56 _shape.addPath(pth);
57 _currpath = &_shape.currentPath();
60 void
61 DynamicShape::endFill()
63 // Close the path
64 if ( _currpath && _currfill )
66 // TODO: should not just close the last path
67 // but rather append the point where
68 // the fill actually begun (could be
69 // in a previous path).
71 // NOTE that doing so will require changing
72 // the hitTest code to do stop considering
73 // each path in isolation when doing PIP testing
76 _currpath->close();
78 // reset _x and _y to reflect closing point
79 _x = _currpath->ap.x;
80 _y = _currpath->ap.y;
83 // Remove reference to the "current" path, as
84 // next drawing will happen on a different one
85 _currpath = 0;
86 // Remove fill information
87 _currfill = 0;
90 void
91 DynamicShape::beginFill(const FillStyle& f)
93 // End previous fill
94 endFill();
96 _currfill = addFillStyle(f);
98 // TODO: how to know wheter the fill should be set
99 // as *left* or *right* fill ?
100 // A quick test shows that *left* always work fine !
101 Path newPath(_x, _y, _currfill, 0, _currline, true);
102 add_path(newPath);
105 void
106 DynamicShape::startNewPath(bool newShape)
108 // Close any pending filled path
109 if ( _currpath && _currfill)
111 // TODO: this is probably bogus
112 _currpath->close();
115 // The DrawingApiTest.swf file shows we should not
116 // end the current fill when starting a new path.
118 // A quick test shows that *left* always work fine !
119 // More than that, using a *right* fill seems to break the tests !
120 Path newPath(_x, _y, _currfill, 0, _currline, newShape);
121 add_path(newPath);
124 void
125 DynamicShape::finalize() const
127 // Nothing to do if not changed
128 if ( ! _changed ) return;
130 // Close any pending filled path (_currpath should be last path)
131 if ( _currpath && _currfill)
133 assert(!_shape.paths().empty());
134 assert(_currpath == &(_shape.paths().back()));
135 _currpath->close();
138 // TODO: check consistency of fills and such !
140 _changed = false;
143 void
144 DynamicShape::lineStyle(boost::uint16_t thickness, const rgba& color,
145 bool vScale, bool hScale, bool pixelHinting, bool noClose,
146 CapStyle startCapStyle, CapStyle endCapStyle,
147 JoinStyle joinStyle, float miterLimitFactor)
149 LineStyle style(thickness, color, vScale, hScale, pixelHinting,
150 noClose, startCapStyle, endCapStyle, joinStyle,
151 miterLimitFactor);
153 _currline = add_line_style(style);
154 startNewPath(false);
157 void
158 DynamicShape::resetLineStyle()
160 _currline = 0;
161 startNewPath(false);
164 void
165 DynamicShape::moveTo(boost::int32_t x, boost::int32_t y)
167 // It was manually tested that a moveTo, even
168 // when moving to the same point of current cursor,
169 // will start a new path.
171 _x = x;
172 _y = y;
173 startNewPath(false);
176 void
177 DynamicShape::lineTo(boost::int32_t x, boost::int32_t y, int swfVersion)
179 if (!_currpath) startNewPath(true);
180 assert(_currpath);
182 _currpath->drawLineTo(x, y);
184 // Update bounds
185 SWFRect bounds = _shape.getBounds();
187 unsigned thickness = _currline ?
188 _shape.lineStyles().back().getThickness() : 0;
190 if (_currpath->size() == 1) {
191 _currpath->expandBounds(bounds, thickness, swfVersion);
192 } else {
193 bounds.expand_to_circle(x, y, swfVersion < 8 ? thickness :
194 thickness / 2.0);
197 _shape.setBounds(bounds);
199 // Update current pen position
200 _x = x;
201 _y = y;
203 // Mark as changed
204 _changed = true;
207 void
208 DynamicShape::curveTo(boost::int32_t cx, boost::int32_t cy,
209 boost::int32_t ax, boost::int32_t ay, int swfVersion)
211 if (!_currpath) startNewPath(true);
212 assert(_currpath);
214 _currpath->drawCurveTo(cx, cy, ax, ay);
216 SWFRect bounds = _shape.getBounds();
218 unsigned thickness = _currline ?
219 _shape.lineStyles().back().getThickness() : 0;
221 if (_currpath->size() == 1) {
222 _currpath->expandBounds(bounds, thickness, swfVersion);
224 else {
225 bounds.expand_to_circle(ax, ay,
226 swfVersion < 8 ? thickness : thickness / 2.0);
227 bounds.expand_to_circle(cx, cy,
228 swfVersion < 8 ? thickness : thickness / 2.0);
231 _shape.setBounds(bounds);
233 // Update current pen position
234 _x = ax;
235 _y = ay;
237 // Mark as changed
238 _changed = true;
241 size_t
242 DynamicShape::addFillStyle(const FillStyle& stl)
244 _shape.addFillStyle(stl);
245 return _shape.fillStyles().size();
248 size_t
249 DynamicShape::add_line_style(const LineStyle& stl)
251 _shape.addLineStyle(stl);
252 return _shape.lineStyles().size();
255 } // end namespace gnash
258 // Local Variables:
259 // mode: C++
260 // indent-tabs-mode: t
261 // End: