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