1 // sprite_definition.cpp:  for Gnash.
2 //
3 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 //   Free Software 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
19 
20 #include "RunResources.h"
21 #include "MovieClip.h"
22 #include "sprite_definition.h"
23 #include "ControlTag.h" // for dtor visibility
24 #include "as_function.h"
25 #include "SWFStream.h"
26 #include "GnashAlgorithm.h"
27 #include "SWFParser.h"
28 #include "namedStrings.h"
29 #include "Global_as.h"
30 
31 #include <vector>
32 #include <string>
33 #include <cassert>
34 
35 
36 namespace gnash {
37 
38 DisplayObject*
createDisplayObject(Global_as & gl,DisplayObject * parent) const39 sprite_definition::createDisplayObject(Global_as& gl, DisplayObject* parent)
40     const
41 {
42     // Should not call MovieClip constructor (probably), but should
43     // attach MovieClip.prototype
44     as_object* obj = getObjectWithPrototype(gl, NSV::CLASS_MOVIE_CLIP);
45     DisplayObject* mc = new MovieClip(obj, this, parent->get_root(), parent);
46 	return mc;
47 }
48 
~sprite_definition()49 sprite_definition::~sprite_definition()
50 {
51 }
52 
53 /*private*/
54 // only called from constructors
55 void
read(SWFStream & in,const RunResources & runResources)56 sprite_definition::read(SWFStream& in, const RunResources& runResources)
57 {
58     const size_t tag_end = in.get_tag_end_position();
59 
60     in.ensureBytes(2);
61     m_frame_count = in.read_u16();
62 
63     IF_VERBOSE_PARSE (
64         log_parse(_("  frames = %d"), m_frame_count);
65     );
66 
67 	m_loading_frame = 0;
68 
69     SWFParser parser(in, this, runResources);
70 
71     // This can throw a ParserException; we will let the SWFMovieDefintion
72     // catch it, as a failure means the whole stream is invalid.
73     parser.read(tag_end - in.tell());
74 
75     if (m_frame_count > m_loading_frame) {
76         IF_VERBOSE_MALFORMED_SWF(
77         log_swferror(_("%d frames advertised in header, but "
78                 "only %d SHOWFRAME tags found in define "
79                 "sprite."), m_frame_count, m_loading_frame );
80         );
81 
82         // this should be safe
83         m_loading_frame = m_frame_count;
84     }
85 
86     IF_VERBOSE_PARSE(
87         log_parse(_("  -- sprite END --"));
88     );
89 }
90 
91 void
add_frame_name(const std::string & name)92 sprite_definition::add_frame_name(const std::string& name)
93 {
94 
95     // It's fine for loaded frames to exceed frame count. Should be
96     // adjusted at the end of parsing.
97     _namedFrames.insert(std::make_pair(name, m_loading_frame));
98 }
99 
100 bool
get_labeled_frame(const std::string & label,size_t & frame_number) const101 sprite_definition::get_labeled_frame(const std::string& label,
102         size_t& frame_number) const
103 {
104     NamedFrameMap::const_iterator it = _namedFrames.find(label);
105     if ( it == _namedFrames.end() ) return false;
106     frame_number = it->second;
107     return true;
108 }
109 
sprite_definition(movie_definition & m,SWFStream & in,const RunResources & runResources,std::uint16_t id)110 sprite_definition::sprite_definition(movie_definition& m, SWFStream& in,
111         const RunResources& runResources, std::uint16_t id)
112 	:
113     movie_definition(id),
114 	m_movie_def(m),
115 	m_frame_count(0),
116 	m_loading_frame(0),
117 	_loadingSoundStream(-1)
118 {
119 	read(in, runResources);
120 }
121 
122 } // namespace gnash
123