Gnash
0.8.10
|
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: