Gnash 0.8.9

DisplayObject.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
00003 //   2011 Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 
00020 #ifndef GNASH_DISPLAY_OBJECT_H
00021 #define GNASH_DISPLAY_OBJECT_H
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "gnashconfig.h" // USE_SWFTREE
00025 #endif
00026 
00027 #include <vector>
00028 #include <map>
00029 #include <string>
00030 #include <cassert>
00031 #include <boost/cstdint.hpp> // For C99 int types
00032 #include <boost/noncopyable.hpp>
00033 
00034 #include "ObjectURI.h" 
00035 #include "GC.h"
00036 #include "Transform.h"
00037 #include "event_id.h" 
00038 #include "SWFRect.h"
00039 #include "SWFMatrix.h"
00040 #include "SWFCxForm.h"
00041 #include "dsodefs.h" 
00042 #include "snappingrange.h"
00043 #ifdef USE_SWFTREE
00044 # include "tree.hh"
00045 #endif
00046 
00047 
00048 //#define DEBUG_SET_INVALIDATED 1
00049 
00050 // Forward declarations
00051 namespace gnash {
00052     class MovieClip;
00053     class movie_root;
00054     class fn_call;
00055     class Movie;
00056     class ExecutableCode;
00057     class action_buffer;
00058     class movie_definition;
00059     class StaticText;
00060     class InteractiveObject;
00061     class Renderer;
00062     class as_object;
00063     class as_value;
00064     class as_environment;
00065     class DisplayObject;
00066     class KeyVisitor;
00067     namespace SWF {
00068         class TextRecord;
00069     }
00070 }
00071 
00072 namespace gnash {
00073 
00075 //
00077 bool isReferenceable(const DisplayObject& d);
00078 
00080 //
00082 //
00087 bool setDisplayObjectProperty(DisplayObject& obj, const ObjectURI& uri,
00088         const as_value& val);
00089 
00091 //
00094 //
00098 bool getDisplayObjectProperty(DisplayObject& obj, const ObjectURI& uri,
00099         as_value& val);
00100 
00102 //
00104 //
00108 void getIndexedProperty(size_t index, DisplayObject& o, as_value& val);
00109 
00111 //
00113 //
00118 void setIndexedProperty(size_t index, DisplayObject& o, const as_value& val);
00119 
00121 //
00124 void copyMatrix(const DisplayObject& from, DisplayObject& to);
00125 
00127 //
00130 //
00134 SWFMatrix getWorldMatrix(const DisplayObject& d, bool includeRoot = true);
00135 
00137 //
00139 SWFCxForm getWorldCxForm(const DisplayObject& d);
00140 
00142 //
00147 //
00151 //
00154 //
00158 //
00162 //
00167 class DisplayObject : public GcResource, boost::noncopyable
00168 {
00169 public:
00170 
00172     //
00181     DisplayObject(movie_root& mr, as_object* object, DisplayObject* parent);
00182 
00183     virtual ~DisplayObject() {}
00184 
00189     //
00191     //
00194     static const int lowerAccessibleBound = -16384;
00195     
00199     static const int upperAccessibleBound = 2130690044;
00200 
00204     static const int staticDepthOffset = lowerAccessibleBound;
00205 
00221     static const int removedDepthOffset = -32769; 
00222 
00225     //
00229     static const int noClipDepthValue = -1000000;
00230 
00232     virtual as_environment& get_environment() {
00233         // MovieClip must override this
00234         // and any other DisplayObject will have
00235         // a parent!
00236         assert(_parent != NULL);
00237         return _parent->get_environment();
00238     }
00239 
00241     //
00246     virtual void visitNonProperties(KeyVisitor&) const {}
00247 
00251     DisplayObject* parent() const
00252     {
00253         return _parent;
00254     }
00255 
00257     //
00260     void set_parent(DisplayObject* parent)
00261     {
00262         _parent = parent;
00263     }
00264 
00265     virtual MovieClip* to_movie() { return 0; }
00266 
00267     int get_depth() const { return _depth; }
00268 
00269     void set_depth(int d) { _depth = d; }
00270 
00272     int getVolume() const { return _volume; }
00273 
00275     void setVolume(int vol) { _volume = vol; }
00276 
00278     //
00284     int getWorldVolume() const;
00285 
00287     virtual int getDefinitionVersion() const {
00288         return -1;
00289     }
00290     
00291     const Transform& transform() const {
00292         return _transform;
00293     }
00294 
00295 
00297     //
00303     void setMatrix(const SWFMatrix& m, bool updateCache = false);
00304 
00306     //
00312     void set_x_scale(double factor);
00313 
00315     //
00321     void set_y_scale(double factor);
00322 
00324     //
00332     void set_rotation(double rot);
00333 
00335     //
00339     //
00341     virtual void setWidth(double width);
00342 
00344     //
00349     virtual void setHeight(double height);
00350 
00351     void setCxForm(const SWFCxForm& cx) 
00352     {       
00353         if (_transform.colorTransform != cx) {
00354             set_invalidated();
00355             _transform.colorTransform = cx;
00356         }
00357     }
00358 
00359     boost::uint16_t get_ratio() const { return _ratio; }
00360 
00361     void set_ratio(boost::uint16_t r) {
00362         if (r != _ratio) set_invalidated(); 
00363         _ratio = r;       
00364     }
00365 
00374     int get_clip_depth() const { return m_clip_depth; }
00375 
00377     void set_clip_depth(int d)
00378     {
00379         m_clip_depth = d;
00380     }
00381         
00389     bool isMaskLayer() const
00390     {
00391         return (m_clip_depth != noClipDepthValue && !_maskee);
00392     }
00393 
00403     bool isDynamicMask() const
00404     {
00405         return (_maskee);
00406     }
00407 
00409     DisplayObject* getMask() const
00410     {
00411 #if GNASH_PARANOIA_LEVEL > 1
00412         if (_mask) assert(_mask->_maskee == this);
00413 #endif
00414         return _mask;
00415     }
00416 
00424     void setMask(DisplayObject* mask);
00425 
00427     void set_name(const ObjectURI& uri) {
00428         _name = uri;
00429     }
00430 
00431     const ObjectURI& get_name() const { return _name; }
00432 
00434     //
00441     std::auto_ptr<ExecutableCode> get_event_handler(const event_id& id) const;
00442 
00444     //
00462     void add_event_handler(const event_id& id, const action_buffer& code);
00463 
00465     //
00467         virtual void display(Renderer& renderer, const Transform& xform) = 0;
00468 
00470     //
00474     virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>&,
00475             size_t&) {
00476         return 0;
00477     }
00478 
00479         virtual SWFRect getBounds() const = 0;
00480 
00482     //
00487     bool pointInBounds(boost::int32_t x, boost::int32_t y) const
00488     {
00489         SWFRect bounds = getBounds();
00490         const SWFMatrix wm = getWorldMatrix(*this, false);
00491         wm.transform(bounds);
00492         return bounds.point_test(x, y);
00493     }
00494 
00496     //
00500         virtual bool pointInShape(boost::int32_t  x, boost::int32_t  y) const = 0;
00501 
00503     //
00514     virtual bool pointInVisibleShape(boost::int32_t x, boost::int32_t y) const
00515     {
00516         if (!visible()) return false;
00517         if (isDynamicMask() || isMaskLayer()) return false;
00518         return pointInShape(x, y);
00519     }
00520 
00522     //
00530     virtual Movie* get_root() const {
00531         return parent()->get_root();
00532     }
00533 
00535     //
00539     virtual MovieClip* getAsRoot();
00540 
00560     virtual as_object* pathElement(const ObjectURI& uri);
00561 
00565     //
00572     bool get_accept_anim_moves() const
00573     {
00574         return ! _scriptTransformed && ! _dynamicallyCreated;
00575     }
00576 
00578     //
00591     bool isDynamic() const {
00592         return _dynamicallyCreated;
00593     }
00594 
00596     void setDynamic() {
00597         _dynamicallyCreated = true;
00598     }
00599 
00603     //
00610     void transformedByScript() 
00611     {
00612         _scriptTransformed = true;
00613     }
00614 
00616     //
00619     void set_visible(bool visible);
00620 
00621     // Return true if this DisplayObject should be rendered
00622     bool visible() const { return _visible; }
00623 
00625     virtual void notifyEvent(const event_id& /*id*/)
00626     {
00627     }
00628 
00630     //
00633     void queueEvent(const event_id& id, int lvl);
00634 
00636     //
00642     bool hasEventHandler(const event_id& id) const;
00643 
00645     //
00647         virtual InteractiveObject* topmostMouseEntity(boost::int32_t, 
00648             boost::int32_t) {
00649         return 0;
00650     }
00651         
00654     //
00656     virtual const DisplayObject* findDropTarget(boost::int32_t x, 
00657             boost::int32_t y, DisplayObject* dragging) const
00658     {
00659         if (this != dragging && visible() && pointInVisibleShape(x, y)) {
00660             return this;
00661         }
00662         
00663         return 0;
00664     }
00665 
00667     bool invalidated() const {
00668         return _invalidated;
00669     }
00670 
00672     bool childInvalidated() const {
00673         return _child_invalidated;
00674     }
00675 
00677     virtual void update() {
00678         set_invalidated();
00679     }
00680 
00685     //
00702     void set_invalidated();
00703     void set_invalidated(const char* debug_file, int debug_line);
00704     
00705     
00709     void extend_invalidated_bounds(const InvalidatedRanges& ranges);
00710     
00711     
00716     void set_child_invalidated();
00717 
00730     void clear_invalidated() {
00731         _invalidated = false;
00732         _child_invalidated = false;        
00733         m_old_invalidated_ranges.setNull();
00734     }
00735     
00738     //
00755     virtual void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
00756 
00760     virtual void omit_display() { clear_invalidated(); }; 
00761     
00763     //
00773     virtual void construct(as_object* /*init*/ = 0)
00774     {
00775         saveOriginalTarget();
00776     }
00777 
00779     //
00789     bool unload();
00790 
00792     virtual void getLoadedMovie(Movie* newMovie);
00793 
00795     bool unloaded() const {
00796         return _unloaded;
00797     }
00798 
00800     //
00811     virtual void destroy();
00812 
00814     //
00817     bool isDestroyed() const { return _destroyed; }
00818     
00825     bool boundsInClippingArea(Renderer& renderer) const; 
00826 
00828     //
00831     std::string getTargetPath() const;
00832 
00835     //
00839     const std::string& getOrigTarget() const
00840     {
00841         return _origTarget;
00842     }
00843 
00845     //
00848     std::string DSOEXPORT getTarget() const;
00849 
00851     //
00855     virtual bool isSelectableTextField() const { return false; }
00856 
00861     bool DSOEXPORT allowHandCursor() const;
00862 
00863 #ifdef USE_SWFTREE
00864     typedef tree<std::pair<std::string, std::string> > InfoTree; 
00866     //
00874     virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
00875             InfoTree::iterator it);
00876 #endif
00877     
00879     ObjectURI getNextUnnamedInstanceName();
00880 
00881     enum BlendMode
00882     {
00883         BLENDMODE_UNDEFINED = 0,
00884         BLENDMODE_NORMAL = 1,
00885         BLENDMODE_LAYER,
00886         BLENDMODE_MULTIPLY,
00887         BLENDMODE_SCREEN,
00888         BLENDMODE_LIGHTEN,
00889         BLENDMODE_DARKEN,
00890         BLENDMODE_DIFFERENCE,
00891         BLENDMODE_ADD,
00892         BLENDMODE_SUBTRACT,
00893         BLENDMODE_INVERT,
00894         BLENDMODE_ALPHA,
00895         BLENDMODE_ERASE,
00896         BLENDMODE_OVERLAY,
00897         BLENDMODE_HARDLIGHT = 14
00898     };
00899 
00900     BlendMode getBlendMode() const {
00901         return _blendMode;
00902     }
00903  
00904     void setBlendMode(BlendMode bm) {
00905         _blendMode = bm;
00906     }
00907 
00908     // action_buffer is externally owned
00909     typedef std::vector<const action_buffer*> BufferList;
00910     typedef std::map<event_id, BufferList> Events;
00911 
00913     //
00916     //
00920     virtual bool handleFocus() { 
00921         return false;
00922     }
00923 
00925     //
00927     virtual void killFocus() {}
00928   
00929     double rotation() const {
00930         return _rotation;
00931     }
00932 
00933     double scaleX() const {
00934         return _xscale;
00935     }
00936 
00937     double scaleY() const {
00938         return _yscale;
00939     }
00940 
00941     as_object* object() const {
00942         return _object;
00943     }
00944 
00946     static as_value blendMode(const fn_call& fn);
00947   
00949     //
00953     virtual void markReachableResources() const;
00954 
00956     //
00958     virtual void markOwnResources() const {}
00959 
00960 protected:
00961     
00963     //
00966     //
00970     class MaskRenderer
00971     {
00972     public:
00973         MaskRenderer(Renderer& r, const DisplayObject& o);
00974         ~MaskRenderer();
00975     private:
00976         Renderer& _renderer;
00977         DisplayObject* _mask;
00978     };
00979 
00980     virtual bool unloadChildren() { return false; }
00981 
00983     movie_root& stage() const {
00984         return _stage;
00985     }
00986 
00993     void saveOriginalTarget()
00994     {
00995         _origTarget=getTarget();
00996     }
00997 
00998     const Events& get_event_handlers() const
00999     {
01000         return _event_handlers;
01001     }
01002 
01003     void set_event_handlers(const Events& copyfrom);
01004 
01006     ObjectURI _name; 
01007 
01008     DisplayObject* _parent;
01009 
01011     //
01014     as_object* getPathElementSeparator(string_table::key key);
01015 
01031     InvalidatedRanges m_old_invalidated_ranges;
01032 
01033 private:
01034 
01036     void setMaskee(DisplayObject* maskee);
01037 
01039     as_object* _object;
01040 
01042     movie_root& _stage;
01043 
01044     Transform _transform;
01045     
01046     Events _event_handlers;
01047 
01051     double _xscale, _yscale, _rotation;
01052 
01054     boost::int32_t _depth;
01055 
01057     //
01064     int _volume;
01065 
01066     boost::uint16_t _ratio;
01067     int m_clip_depth;
01068 
01070     DisplayObject* _mask;
01071 
01073     DisplayObject* _maskee;
01074 
01076     std::string _origTarget;
01077 
01078     BlendMode _blendMode;
01079 
01080     bool _visible;
01081 
01083     //
01089     bool _scriptTransformed;
01090 
01091     bool _dynamicallyCreated;
01092 
01094     bool _unloaded;
01095 
01097     bool _destroyed;
01098 
01102     //
01107     bool _invalidated;
01108 
01112     bool _child_invalidated;
01113 
01114 
01115 };
01116 
01118 inline const SWFMatrix&
01119 getMatrix(const DisplayObject& o)
01120 { 
01121     return o.transform().matrix;
01122 }
01123 
01124 inline const SWFCxForm&
01125 getCxForm(const DisplayObject& o) 
01126 {
01127     return o.transform().colorTransform;
01128 }
01129 
01130 inline SWFMatrix
01131 getWorldMatrix(const DisplayObject& d, bool includeRoot)
01132 {
01133     SWFMatrix m = d.parent() ?
01134         getWorldMatrix(*d.parent(), includeRoot) : SWFMatrix();
01135 
01136     if (d.parent() || includeRoot) m.concatenate(getMatrix(d));
01137     return m;
01138 }
01139 
01140 inline SWFCxForm
01141 getWorldCxForm(const DisplayObject& d)
01142 {
01143     SWFCxForm cx = d.parent() ? getWorldCxForm(*d.parent()) : SWFCxForm();
01144     cx.concatenate(getCxForm(d));
01145     return cx;
01146 }
01147 
01148 inline bool
01149 isReferenceable(const DisplayObject& d)
01150 {
01151     return d.object();
01152 }
01153 
01155 //
01159 inline as_object*
01160 getObject(const DisplayObject* d)
01161 {
01162     return d ? d->object() : 0;
01163 }
01164 
01166 std::ostream&
01167 operator<<(std::ostream& o, DisplayObject::BlendMode bm);
01168 
01169 } // end namespace gnash
01170 
01171 
01172 #ifdef DEBUG_SET_INVALIDATED
01173 #define set_invalidated() set_invalidated(__FILE__, __LINE__)
01174 #endif
01175 
01176 
01177 #endif // GNASH_CHARACTER_H
01178 
01179 
01180 // Local Variables:
01181 // mode: C++
01182 // indent-tabs-mode: t
01183 // End: