Update with current status
[gnash.git] / libcore / swf / ShapeRecord.h
blob478cd830f7b1eaa8ab072e5d7aeb7b48539cc06d
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // 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.
14 //
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 #ifndef GNASH_SWF_SHAPERECORD_H
21 #define GNASH_SWF_SHAPERECORD_H
23 #include "Geometry.h"
24 #include "LineStyle.h"
25 #include "FillStyle.h"
26 #include "SWFRect.h"
28 #include <vector>
31 namespace gnash {
32 class movie_definition;
33 class RunResources;
36 namespace gnash {
37 namespace SWF {
41 class Subshape {
43 public:
44 typedef std::vector<FillStyle> FillStyles;
45 typedef std::vector<LineStyle> LineStyles;
46 typedef std::vector<Path> Paths;
48 const FillStyles& fillStyles() const {
49 return _fillStyles;
52 FillStyles& fillStyles() {
53 return _fillStyles;
56 const LineStyles& lineStyles() const {
57 return _lineStyles;
60 LineStyles& lineStyles() {
61 return _lineStyles;
64 const Paths& paths() const {
65 return _paths;
68 Paths& paths() {
69 return _paths;
72 /// For DynamicShape
74 /// TODO: rewrite DynamicShape to push paths when they're
75 /// finished and drop this.
76 Path& currentPath() {
77 return _paths.back();
80 void addFillStyle(const FillStyle& fs);
82 void addPath(const Path& path) {
83 _paths.push_back(path);
86 void addLineStyle(const LineStyle& ls) {
87 _lineStyles.push_back(ls);
90 void clear() {
91 _fillStyles.clear();
92 _lineStyles.clear();
93 _paths.clear();
96 SWFRect computeBounds(int swfVersion) const;
98 private:
99 FillStyles _fillStyles;
100 LineStyles _lineStyles;
101 Paths _paths;
106 /// Holds information needed to draw a shape.
108 /// This does not correspond exactly to parsed record in a SWF file, but
109 /// is used to create both mutable and immutable shapes.
111 /// A ShapeRecord should have enough methods to implement the AS3 Graphics
112 /// object (the drawing API of Shape and Sprite). This is restricted to
113 /// adding fills, paths and line styles (which must be constructed outside
114 /// this ShapeRecord before being added) and clearing everything. There
115 /// is no support for removing single elements.
117 /// ShapeRecord objects are not ref-counted, so they may be stack-allocated
118 /// or used in smart pointers.
120 /// A shape can have sub-shapes. This can happen when there are multiple
121 /// layers of the same frame count. Flash combines them to one single shape.
122 /// The problem with sub-shapes is, that outlines can be hidden by other
123 /// layers so they must be rendered separately. In order to be sure outlines
124 /// are show correctly, draw the subshapes contained in the ShapeRecord in
125 /// sequence.
126 class ShapeRecord
128 public:
129 typedef Subshape::FillStyles FillStyles;
130 typedef Subshape::LineStyles LineStyles;
131 typedef Subshape::Paths Paths;
132 typedef std::vector<Subshape> Subshapes;
134 /// Construct a ShapeRecord.
136 /// This should only really be used for DynamicShapes.
138 /// Ideally all immutable ShapeRecords should be constructed with the
139 /// ctor taking an SWFStream, but some tag formats do not allow this.
140 ShapeRecord();
142 /// Construct a ShapeRecord from a SWFStream.
144 /// This is useful for constructing immutable tags.
145 ShapeRecord(SWFStream& in, SWF::TagType tag, movie_definition& m,
146 const RunResources& r);
149 ~ShapeRecord();
151 /// Parse path data from a SWFStream.
153 /// This is used by DefineMorphShapeTag as part of parsing its
154 /// more complex ShapeRecords.
155 void read(SWFStream& in, SWF::TagType tag, movie_definition& m,
156 const RunResources& r);
158 const Subshapes& subshapes() const {
159 return _subshapes;
162 void addSubshape(const Subshape& subshape) {
163 _subshapes.push_back(subshape);
166 const SWFRect& getBounds() const {
167 return _bounds;
170 /// Set to the lerp of two ShapeRecords.
172 /// Used in shape morphing.
173 void setLerp(const ShapeRecord& a, const ShapeRecord& b,
174 const double ratio);
176 /// Reset all shape data.
177 void clear();
179 void setBounds(const SWFRect& bounds) {
180 _bounds = bounds;
183 bool pointTest(std::int32_t x, std::int32_t y,
184 const SWFMatrix& wm) const {
185 for (const Subshape& subshape : _subshapes) {
187 if (geometry::pointTest(subshape.paths(), subshape.lineStyles(), x, y, wm)) {
188 return true;
191 return false;
194 private:
196 unsigned readStyleChange(SWFStream& in, size_t num_fill_bits, size_t numStyles);
198 /// Shape record flags for use in parsing.
199 enum ShapeRecordFlags {
200 SHAPE_END = 0x00,
201 SHAPE_MOVE = 0x01,
202 SHAPE_FILLSTYLE0_CHANGE = 0x02,
203 SHAPE_FILLSTYLE1_CHANGE = 0x04,
204 SHAPE_LINESTYLE_CHANGE = 0x08,
205 SHAPE_HAS_NEW_STYLES = 0x10
208 SWFRect _bounds;
209 Subshapes _subshapes;
212 std::ostream& operator<<(std::ostream& o, const ShapeRecord& sh);
214 } // namespace SWF
215 } // namespace gnash
217 #endif