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