2
// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
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.
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.
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
21
#include "DynamicShape.h"
28
DynamicShape::DynamicShape()
30
shape_character_def(),
44
m_fill_styles.clear();
45
m_line_styles.clear();
47
_currpath=0; // or would point to invalid memory
48
_currfill = _currline = 0; // or would point to cleared m_fill_style and m_line_styles respectively
50
// TODO: worth setting _changed=true ?
54
DynamicShape::add_path(const path& pth)
56
m_paths.push_back(pth);
57
_currpath = &(m_paths.back());
58
//compute_bound(&m_bound);
62
DynamicShape::endFill()
65
if ( _currpath ) _currpath->close();
67
// Remove reference to the "current" path, as
68
// next drawing will happen on a different one
71
// Remove fill information
74
// TODO: should I also clear _currline ?
78
DynamicShape::beginFill(const rgba& color)
80
// Add the new fill style and set as current
81
fill_style style; style.setSolid(color);
85
_currfill = add_fill_style(style);
86
// TODO: how to know wheter the fill should be set
87
// as *left* or *right* fill ?
88
// A quick test shows that *left* always work fine !
89
path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start new subshapes
94
DynamicShape::beginLinearGradientFill(const std::vector<gradient_record>& grad, const matrix& mat)
96
// Add the new fill style and set as current
97
fill_style style; style.setLinearGradient(grad, mat);
101
_currfill = add_fill_style(style);
102
// TODO: how to know wheter the fill should be set
103
// as *left* or *right* fill ?
104
// A quick test shows that *left* always work fine !
105
path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start new subshapes
110
DynamicShape::beginRadialGradientFill(const std::vector<gradient_record>& grad, const matrix& mat)
112
// Add the new fill style and set as current
113
fill_style style; style.setRadialGradient(grad, mat);
117
_currfill = add_fill_style(style);
118
// TODO: how to know wheter the fill should be set
119
// as *left* or *right* fill ?
120
// A quick test shows that *left* always work fine !
121
path newPath(_x, _y, _currfill, 0, _currline, true); // new fill start new subshapes
126
DynamicShape::startNewPath(bool newShape)
128
// Close any pending filled path
129
if ( _currpath && _currfill) _currpath->close();
131
// The DrawingApiTest.swf file shows we should NOT
132
// necessarely end the current fill when starting a new one.
135
// A quick test shows that *left* always work fine !
136
// More than that, using a *right* fill seems to break the tests !
137
path newPath(_x, _y, _currfill, 0, _currline, newShape);
142
DynamicShape::finalize()
144
// Nothing to do if not changed
145
if ( ! _changed ) return;
147
// Close any pending filled path (_currpath should be last path)
148
if ( _currpath && _currfill)
150
assert( ! m_paths.empty() );
151
assert( _currpath == &(m_paths.back()) );
155
// TODO: check consistency of fills and such !
161
DynamicShape::lineStyle(boost::uint16_t thickness, const rgba& color,
162
bool vScale, bool hScale, bool pixelHinting, bool noClose,
163
cap_style_e startCapStyle, cap_style_e endCapStyle,
164
join_style_e joinStyle, float miterLimitFactor)
166
line_style style(thickness, color, vScale, hScale, pixelHinting,
167
noClose, startCapStyle, endCapStyle, joinStyle,
170
_currline = add_line_style(style);
171
startNewPath(false); // don't make this the start of a new subshape (to verify)
175
DynamicShape::resetLineStyle()
178
startNewPath(false); // don't make this the start of a new subshape (to verify)
182
DynamicShape::moveTo(boost::int32_t x, boost::int32_t y)
184
if ( x != _x || y != _y )
189
// TODO: close previous path if any and filled ?
190
startNewPath(false); // don't make this the start of a new subshape (to verify)
195
DynamicShape::lineTo(boost::int32_t x, boost::int32_t y, int swfVersion)
197
if ( ! _currpath ) startNewPath(true); // first shape is always new (I hope this doesn't break anything)
200
_currpath->drawLineTo(x, y);
203
unsigned thickness = _currline ? m_line_styles[_currline-1].getThickness() : 0;
204
if ( _currpath->size() == 1 ) {
205
_currpath->expandBounds(m_bound, thickness, swfVersion);
207
m_bound.expand_to_circle(x, y, swfVersion < 8 ? thickness : thickness/2.0);
210
// Update current pen position
219
DynamicShape::curveTo(boost::int32_t cx, boost::int32_t cy,
220
boost::int32_t ax, boost::int32_t ay, int swfVersion)
222
if ( ! _currpath ) startNewPath(true); // first shape is always new (I hope this doesn't break anything)
225
_currpath->drawCurveTo(cx, cy, ax, ay);
228
unsigned thickness = _currline ? m_line_styles[_currline-1].getThickness() : 0;
229
if ( _currpath->size() == 1 ) {
230
_currpath->expandBounds(m_bound, thickness, swfVersion);
232
m_bound.expand_to_circle(ax, ay, swfVersion < 8 ? thickness : thickness/2.0);
233
m_bound.expand_to_circle(cx, cy, swfVersion < 8 ? thickness : thickness/2.0);
236
// Update current pen position
245
DynamicShape::add_fill_style(const fill_style& stl)
247
typedef FillStyleVect V;
250
// TODO: check if the style is already in our list
251
// (needs operator== defined for fill_style)
253
return v.size(); // 1-based !
257
DynamicShape::add_line_style(const line_style& stl)
259
typedef LineStyleVect V;
262
// TODO: check if the style is already in our list
263
// (needs operator== defined for line_style)
265
return v.size(); // 1-based !
268
} // end namespace gnash
273
// indent-tabs-mode: t