Gnash 0.8.10dev
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 #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     virtual void notifyEvent(const event_id& /*id*/)
00627     {
00628     }
00629 
00631     //
00634     void queueEvent(const event_id& id, int lvl);
00635 
00637     //
00643     bool hasEventHandler(const event_id& id) const;
00644 
00646     //
00648         virtual InteractiveObject* topmostMouseEntity(boost::int32_t, 
00649             boost::int32_t) {
00650         return 0;
00651     }
00652         
00655     //
00657     virtual const DisplayObject* findDropTarget(boost::int32_t x, 
00658             boost::int32_t y, DisplayObject* dragging) const
00659     {
00660         if (this != dragging && visible() && pointInVisibleShape(x, y)) {
00661             return this;
00662         }
00663         
00664         return 0;
00665     }
00666 
00668     bool invalidated() const {
00669         return _invalidated;
00670     }
00671 
00673     bool childInvalidated() const {
00674         return _child_invalidated;
00675     }
00676 
00678     virtual void update() {
00679         set_invalidated();
00680     }
00681 
00686     //
00703     void set_invalidated();
00704     void set_invalidated(const char* debug_file, int debug_line);
00705     
00706     
00710     void extend_invalidated_bounds(const InvalidatedRanges& ranges);
00711     
00712     
00717     void set_child_invalidated();
00718 
00731     void clear_invalidated() {
00732         _invalidated = false;
00733         _child_invalidated = false;        
00734         m_old_invalidated_ranges.setNull();
00735     }
00736     
00739     //
00756     virtual void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
00757 
00761     virtual void omit_display() { clear_invalidated(); }; 
00762     
00764     //
00774     virtual void construct(as_object* /*init*/ = 0)
00775     {
00776         saveOriginalTarget();
00777     }
00778 
00780     //
00790     bool unload();
00791 
00793     virtual void getLoadedMovie(Movie* newMovie);
00794 
00796     bool unloaded() const {
00797         return _unloaded;
00798     }
00799 
00801     //
00812     virtual void destroy();
00813 
00815     //
00818     bool isDestroyed() const { return _destroyed; }
00819     
00826     bool boundsInClippingArea(Renderer& renderer) const; 
00827 
00829     //
00832     std::string getTargetPath() const;
00833 
00836     //
00840     const std::string& getOrigTarget() const
00841     {
00842         return _origTarget;
00843     }
00844 
00846     //
00849     std::string DSOEXPORT getTarget() const;
00850 
00852     //
00856     virtual bool isSelectableTextField() const { return false; }
00857 
00862     bool DSOEXPORT allowHandCursor() const;
00863 
00864 #ifdef USE_SWFTREE
00865     typedef tree<std::pair<std::string, std::string> > InfoTree; 
00867     //
00875     virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
00876             InfoTree::iterator it);
00877 #endif
00878     
00880     ObjectURI getNextUnnamedInstanceName();
00881 
00882     enum BlendMode
00883     {
00884         BLENDMODE_UNDEFINED = 0,
00885         BLENDMODE_NORMAL = 1,
00886         BLENDMODE_LAYER,
00887         BLENDMODE_MULTIPLY,
00888         BLENDMODE_SCREEN,
00889         BLENDMODE_LIGHTEN,
00890         BLENDMODE_DARKEN,
00891         BLENDMODE_DIFFERENCE,
00892         BLENDMODE_ADD,
00893         BLENDMODE_SUBTRACT,
00894         BLENDMODE_INVERT,
00895         BLENDMODE_ALPHA,
00896         BLENDMODE_ERASE,
00897         BLENDMODE_OVERLAY,
00898         BLENDMODE_HARDLIGHT = 14
00899     };
00900 
00901     BlendMode getBlendMode() const {
00902         return _blendMode;
00903     }
00904  
00905     void setBlendMode(BlendMode bm) {
00906         _blendMode = bm;
00907     }
00908 
00909     // action_buffer is externally owned
00910     typedef std::vector<const action_buffer*> BufferList;
00911     typedef std::map<event_id, BufferList> Events;
00912 
00914     //
00917     //
00921     virtual bool handleFocus() { 
00922         return false;
00923     }
00924 
00926     //
00928     virtual void killFocus() {}
00929   
00930     double rotation() const {
00931         return _rotation;
00932     }
00933 
00934     double scaleX() const {
00935         return _xscale;
00936     }
00937 
00938     double scaleY() const {
00939         return _yscale;
00940     }
00941 
00942     as_object* object() const {
00943         return _object;
00944     }
00945 
00947     static as_value blendMode(const fn_call& fn);
00948   
00950     //
00954     virtual void markReachableResources() const;
00955 
00957     //
00959     virtual void markOwnResources() const {}
00960 
00961     boost::tribool focusRect() const {
00962         return _focusRect;
00963     }
00964 
00965     void focusRect(boost::tribool focus) {
00966         _focusRect = focus;
00967     }
00968 
00969 protected:
00970     
00972     //
00975     //
00979     class MaskRenderer
00980     {
00981     public:
00982         MaskRenderer(Renderer& r, const DisplayObject& o);
00983         ~MaskRenderer();
00984     private:
00985         Renderer& _renderer;
00986         DisplayObject* _mask;
00987     };
00988 
00989     virtual bool unloadChildren() { return false; }
00990 
00992     movie_root& stage() const {
00993         return _stage;
00994     }
00995 
01002     void saveOriginalTarget()
01003     {
01004         _origTarget=getTarget();
01005     }
01006 
01007     const Events& get_event_handlers() const
01008     {
01009         return _event_handlers;
01010     }
01011 
01012     void set_event_handlers(const Events& copyfrom);
01013 
01015     ObjectURI _name; 
01016 
01017     DisplayObject* _parent;
01018 
01020     //
01023     as_object* getPathElementSeparator(string_table::key key);
01024 
01040     InvalidatedRanges m_old_invalidated_ranges;
01041 
01042 private:
01043 
01045     void setMaskee(DisplayObject* maskee);
01046 
01048     as_object* _object;
01049 
01051     movie_root& _stage;
01052 
01053     Transform _transform;
01054     
01055     Events _event_handlers;
01056 
01060     double _xscale, _yscale, _rotation;
01061 
01063     boost::int32_t _depth;
01064 
01065     boost::tribool _focusRect;
01066 
01068     //
01075     int _volume;
01076 
01077     boost::uint16_t _ratio;
01078     int m_clip_depth;
01079 
01081     DisplayObject* _mask;
01082 
01084     DisplayObject* _maskee;
01085 
01087     std::string _origTarget;
01088 
01089     BlendMode _blendMode;
01090 
01091     bool _visible;
01092 
01094     //
01100     bool _scriptTransformed;
01101 
01102     bool _dynamicallyCreated;
01103 
01105     bool _unloaded;
01106 
01108     bool _destroyed;
01109 
01113     //
01118     bool _invalidated;
01119 
01123     bool _child_invalidated;
01124 
01125 
01126 };
01127 
01129 inline const SWFMatrix&
01130 getMatrix(const DisplayObject& o)
01131 { 
01132     return o.transform().matrix;
01133 }
01134 
01135 inline const SWFCxForm&
01136 getCxForm(const DisplayObject& o) 
01137 {
01138     return o.transform().colorTransform;
01139 }
01140 
01141 inline SWFMatrix
01142 getWorldMatrix(const DisplayObject& d, bool includeRoot)
01143 {
01144     SWFMatrix m = d.parent() ?
01145         getWorldMatrix(*d.parent(), includeRoot) : SWFMatrix();
01146 
01147     if (d.parent() || includeRoot) m.concatenate(getMatrix(d));
01148     return m;
01149 }
01150 
01151 inline SWFCxForm
01152 getWorldCxForm(const DisplayObject& d)
01153 {
01154     SWFCxForm cx = d.parent() ? getWorldCxForm(*d.parent()) : SWFCxForm();
01155     cx.concatenate(getCxForm(d));
01156     return cx;
01157 }
01158 
01159 inline bool
01160 isReferenceable(const DisplayObject& d)
01161 {
01162     return d.object();
01163 }
01164 
01166 //
01170 inline as_object*
01171 getObject(const DisplayObject* d)
01172 {
01173     return d ? d->object() : 0;
01174 }
01175 
01177 std::ostream&
01178 operator<<(std::ostream& o, DisplayObject::BlendMode bm);
01179 
01180 } // end namespace gnash
01181 
01182 
01183 #ifdef DEBUG_SET_INVALIDATED
01184 #define set_invalidated() set_invalidated(__FILE__, __LINE__)
01185 #endif
01186 
01187 
01188 #endif // GNASH_CHARACTER_H
01189 
01190 
01191 // Local Variables:
01192 // mode: C++
01193 // indent-tabs-mode: t
01194 // End: