Gnash  0.8.10
DisplayObject.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   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 #include <boost/logic/tribool.hpp>
00034 
00035 #include "ObjectURI.h" 
00036 #include "GC.h"
00037 #include "Transform.h"
00038 #include "event_id.h" 
00039 #include "SWFRect.h"
00040 #include "SWFMatrix.h"
00041 #include "SWFCxForm.h"
00042 #include "dsodefs.h" 
00043 #include "snappingrange.h"
00044 #ifdef USE_SWFTREE
00045 # include "tree.hh"
00046 #endif
00047 
00048 
00049 //#define DEBUG_SET_INVALIDATED 1
00050 
00051 // Forward declarations
00052 namespace gnash {
00053     class MovieClip;
00054     class movie_root;
00055     class fn_call;
00056     class Movie;
00057     class ExecutableCode;
00058     class action_buffer;
00059     class movie_definition;
00060     class StaticText;
00061     class InteractiveObject;
00062     class Renderer;
00063     class as_object;
00064     class as_value;
00065     class as_environment;
00066     class DisplayObject;
00067     class KeyVisitor;
00068     namespace SWF {
00069         class TextRecord;
00070     }
00071 }
00072 
00073 namespace gnash {
00074 
00076 //
00078 bool isReferenceable(const DisplayObject& d);
00079 
00081 //
00083 //
00088 bool setDisplayObjectProperty(DisplayObject& obj, const ObjectURI& uri,
00089         const as_value& val);
00090 
00092 //
00095 //
00099 bool getDisplayObjectProperty(DisplayObject& obj, const ObjectURI& uri,
00100         as_value& val);
00101 
00103 //
00105 //
00109 void getIndexedProperty(size_t index, DisplayObject& o, as_value& val);
00110 
00112 //
00114 //
00119 void setIndexedProperty(size_t index, DisplayObject& o, const as_value& val);
00120 
00122 //
00125 void copyMatrix(const DisplayObject& from, DisplayObject& to);
00126 
00128 //
00131 //
00135 SWFMatrix getWorldMatrix(const DisplayObject& d, bool includeRoot = true);
00136 
00138 //
00140 SWFCxForm getWorldCxForm(const DisplayObject& d);
00141 
00143 //
00148 //
00152 //
00155 //
00159 //
00163 //
00168 class DisplayObject : public GcResource, boost::noncopyable
00169 {
00170 public:
00171 
00173     //
00182     DisplayObject(movie_root& mr, as_object* object, DisplayObject* parent);
00183 
00184     virtual ~DisplayObject() {}
00185 
00190     //
00192     //
00195     static const int lowerAccessibleBound = -16384;
00196     
00200     static const int upperAccessibleBound = 2130690044;
00201 
00205     static const int staticDepthOffset = lowerAccessibleBound;
00206 
00222     static const int removedDepthOffset = -32769; 
00223 
00226     //
00230     static const int noClipDepthValue = -1000000;
00231 
00233     virtual as_environment& get_environment() {
00234         // MovieClip must override this
00235         // and any other DisplayObject will have
00236         // a parent!
00237         assert(_parent != NULL);
00238         return _parent->get_environment();
00239     }
00240 
00242     //
00247     virtual void visitNonProperties(KeyVisitor&) const {}
00248 
00252     DisplayObject* parent() const
00253     {
00254         return _parent;
00255     }
00256 
00258     //
00261     void set_parent(DisplayObject* parent)
00262     {
00263         _parent = parent;
00264     }
00265 
00266     virtual MovieClip* to_movie() { return 0; }
00267 
00268     int get_depth() const { return _depth; }
00269 
00270     void set_depth(int d) { _depth = d; }
00271 
00273     int getVolume() const { return _volume; }
00274 
00276     void setVolume(int vol) { _volume = vol; }
00277 
00279     //
00285     int getWorldVolume() const;
00286 
00288     virtual int getDefinitionVersion() const {
00289         return -1;
00290     }
00291     
00292     const Transform& transform() const {
00293         return _transform;
00294     }
00295 
00296 
00298     //
00304     void setMatrix(const SWFMatrix& m, bool updateCache = false);
00305 
00307     //
00313     void set_x_scale(double factor);
00314 
00316     //
00322     void set_y_scale(double factor);
00323 
00325     //
00333     void set_rotation(double rot);
00334 
00336     //
00340     //
00342     virtual void setWidth(double width);
00343 
00345     //
00350     virtual void setHeight(double height);
00351 
00352     void setCxForm(const SWFCxForm& cx) 
00353     {       
00354         if (_transform.colorTransform != cx) {
00355             set_invalidated();
00356             _transform.colorTransform = cx;
00357         }
00358     }
00359 
00360     boost::uint16_t get_ratio() const { return _ratio; }
00361 
00362     void set_ratio(boost::uint16_t r) {
00363         if (r != _ratio) set_invalidated(); 
00364         _ratio = r;       
00365     }
00366 
00375     int get_clip_depth() const { return m_clip_depth; }
00376 
00378     void set_clip_depth(int d)
00379     {
00380         m_clip_depth = d;
00381     }
00382         
00390     bool isMaskLayer() const
00391     {
00392         return (m_clip_depth != noClipDepthValue && !_maskee);
00393     }
00394 
00404     bool isDynamicMask() const
00405     {
00406         return (_maskee);
00407     }
00408 
00410     DisplayObject* getMask() const
00411     {
00412 #if GNASH_PARANOIA_LEVEL > 1
00413         if (_mask) assert(_mask->_maskee == this);
00414 #endif
00415         return _mask;
00416     }
00417 
00425     void setMask(DisplayObject* mask);
00426 
00428     void set_name(const ObjectURI& uri) {
00429         _name = uri;
00430     }
00431 
00432     const ObjectURI& get_name() const { return _name; }
00433 
00435     //
00442     std::auto_ptr<ExecutableCode> get_event_handler(const event_id& id) const;
00443 
00445     //
00463     void add_event_handler(const event_id& id, const action_buffer& code);
00464 
00466     //
00468         virtual void display(Renderer& renderer, const Transform& xform) = 0;
00469 
00471     //
00475     virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>&,
00476             size_t&) {
00477         return 0;
00478     }
00479 
00480         virtual SWFRect getBounds() const = 0;
00481 
00483     //
00488     bool pointInBounds(boost::int32_t x, boost::int32_t y) const
00489     {
00490         SWFRect bounds = getBounds();
00491         const SWFMatrix wm = getWorldMatrix(*this, false);
00492         wm.transform(bounds);
00493         return bounds.point_test(x, y);
00494     }
00495 
00497     //
00501         virtual bool pointInShape(boost::int32_t  x, boost::int32_t  y) const = 0;
00502 
00504     //
00515     virtual bool pointInVisibleShape(boost::int32_t x, boost::int32_t y) const
00516     {
00517         if (!visible()) return false;
00518         if (isDynamicMask() || isMaskLayer()) return false;
00519         return pointInShape(x, y);
00520     }
00521 
00523     //
00531     virtual Movie* get_root() const {
00532         return parent()->get_root();
00533     }
00534 
00536     //
00540     virtual MovieClip* getAsRoot();
00541 
00561     virtual as_object* pathElement(const ObjectURI& uri);
00562 
00566     //
00573     bool get_accept_anim_moves() const
00574     {
00575         return ! _scriptTransformed && ! _dynamicallyCreated;
00576     }
00577 
00579     //
00592     bool isDynamic() const {
00593         return _dynamicallyCreated;
00594     }
00595 
00597     void setDynamic() {
00598         _dynamicallyCreated = true;
00599     }
00600 
00604     //
00611     void transformedByScript() 
00612     {
00613         _scriptTransformed = true;
00614     }
00615 
00617     //
00620     void set_visible(bool visible);
00621 
00622     // Return true if this DisplayObject should be rendered
00623     bool visible() const { return _visible; }
00624 
00626     //
00632     bool hasEventHandler(const event_id& id) const;
00633 
00635     //
00637         virtual InteractiveObject* topmostMouseEntity(boost::int32_t, 
00638             boost::int32_t) {
00639         return 0;
00640     }
00641         
00644     //
00646     virtual const DisplayObject* findDropTarget(boost::int32_t x, 
00647             boost::int32_t y, DisplayObject* dragging) const
00648     {
00649         if (this != dragging && visible() && pointInVisibleShape(x, y)) {
00650             return this;
00651         }
00652         
00653         return 0;
00654     }
00655 
00657     bool invalidated() const {
00658         return _invalidated;
00659     }
00660 
00662     bool childInvalidated() const {
00663         return _child_invalidated;
00664     }
00665 
00667     virtual void update() {
00668         set_invalidated();
00669     }
00670 
00675     //
00692     void set_invalidated();
00693     void set_invalidated(const char* debug_file, int debug_line);
00694     
00695     
00699     void extend_invalidated_bounds(const InvalidatedRanges& ranges);
00700     
00701     
00706     void set_child_invalidated();
00707 
00720     void clear_invalidated() {
00721         _invalidated = false;
00722         _child_invalidated = false;        
00723         m_old_invalidated_ranges.setNull();
00724     }
00725     
00728     //
00745     virtual void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
00746 
00750     virtual void omit_display() { clear_invalidated(); }; 
00751     
00753     //
00763     virtual void construct(as_object* /*init*/ = 0)
00764     {
00765         saveOriginalTarget();
00766     }
00767 
00769     //
00779     bool unload();
00780 
00782     virtual void getLoadedMovie(Movie* newMovie);
00783 
00785     bool unloaded() const {
00786         return _unloaded;
00787     }
00788 
00790     //
00801     virtual void destroy();
00802 
00804     //
00807     bool isDestroyed() const { return _destroyed; }
00808     
00815     bool boundsInClippingArea(Renderer& renderer) const; 
00816 
00818     //
00821     std::string getTargetPath() const;
00822 
00825     //
00829     const std::string& getOrigTarget() const
00830     {
00831         return _origTarget;
00832     }
00833 
00835     //
00838     std::string DSOEXPORT getTarget() const;
00839 
00841     //
00845     virtual bool isSelectableTextField() const { return false; }
00846 
00851     bool DSOEXPORT allowHandCursor() const;
00852 
00853 #ifdef USE_SWFTREE
00854     typedef tree<std::pair<std::string, std::string> > InfoTree; 
00856     //
00864     virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
00865             InfoTree::iterator it);
00866 #endif
00867     
00869     ObjectURI getNextUnnamedInstanceName();
00870 
00871     enum BlendMode
00872     {
00873         BLENDMODE_UNDEFINED = 0,
00874         BLENDMODE_NORMAL = 1,
00875         BLENDMODE_LAYER,
00876         BLENDMODE_MULTIPLY,
00877         BLENDMODE_SCREEN,
00878         BLENDMODE_LIGHTEN,
00879         BLENDMODE_DARKEN,
00880         BLENDMODE_DIFFERENCE,
00881         BLENDMODE_ADD,
00882         BLENDMODE_SUBTRACT,
00883         BLENDMODE_INVERT,
00884         BLENDMODE_ALPHA,
00885         BLENDMODE_ERASE,
00886         BLENDMODE_OVERLAY,
00887         BLENDMODE_HARDLIGHT = 14
00888     };
00889 
00890     BlendMode getBlendMode() const {
00891         return _blendMode;
00892     }
00893  
00894     void setBlendMode(BlendMode bm) {
00895         _blendMode = bm;
00896     }
00897 
00898     // action_buffer is externally owned
00899     typedef std::vector<const action_buffer*> BufferList;
00900     typedef std::map<event_id, BufferList> Events;
00901 
00903     //
00906     //
00910     virtual bool handleFocus() { 
00911         return false;
00912     }
00913 
00915     //
00917     virtual void killFocus() {}
00918   
00919     double rotation() const {
00920         return _rotation;
00921     }
00922 
00923     double scaleX() const {
00924         return _xscale;
00925     }
00926 
00927     double scaleY() const {
00928         return _yscale;
00929     }
00930 
00931     as_object* object() const {
00932         return _object;
00933     }
00934 
00936     static as_value blendMode(const fn_call& fn);
00937   
00939     //
00943     virtual void markReachableResources() const;
00944 
00946     //
00948     virtual void markOwnResources() const {}
00949 
00950     boost::tribool focusRect() const {
00951         return _focusRect;
00952     }
00953 
00954     void focusRect(boost::tribool focus) {
00955         _focusRect = focus;
00956     }
00957 
00958 protected:
00959     
00961     //
00964     //
00968     class MaskRenderer
00969     {
00970     public:
00971         MaskRenderer(Renderer& r, const DisplayObject& o);
00972         ~MaskRenderer();
00973     private:
00974         Renderer& _renderer;
00975         DisplayObject* _mask;
00976     };
00977 
00978     virtual bool unloadChildren() { return false; }
00979 
00981     movie_root& stage() const {
00982         return _stage;
00983     }
00984 
00991     void saveOriginalTarget()
00992     {
00993         _origTarget=getTarget();
00994     }
00995 
00996     const Events& get_event_handlers() const
00997     {
00998         return _event_handlers;
00999     }
01000 
01001     void set_event_handlers(const Events& copyfrom);
01002 
01004     ObjectURI _name; 
01005 
01006     DisplayObject* _parent;
01007 
01009     //
01012     as_object* getPathElementSeparator(string_table::key key);
01013 
01029     InvalidatedRanges m_old_invalidated_ranges;
01030 
01031 private:
01032 
01034     void setMaskee(DisplayObject* maskee);
01035 
01037     as_object* _object;
01038 
01040     movie_root& _stage;
01041 
01042     Transform _transform;
01043     
01044     Events _event_handlers;
01045 
01049     double _xscale, _yscale, _rotation;
01050 
01052     boost::int32_t _depth;
01053 
01054     boost::tribool _focusRect;
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: