00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GNASH_DISPLAY_OBJECT_H
00021 #define GNASH_DISPLAY_OBJECT_H
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include "gnashconfig.h"
00025 #endif
00026
00027 #include "event_id.h"
00028 #include "SWFRect.h"
00029 #include "SWFMatrix.h"
00030 #include "cxform.h"
00031 #include "dsodefs.h"
00032 #include "snappingrange.h"
00033 #include "VM.h"
00034 #ifdef USE_SWFTREE
00035 # include "tree.hh"
00036 #endif
00037
00038 #include <vector>
00039 #include <map>
00040 #include <string>
00041 #include <cassert>
00042 #include <boost/cstdint.hpp>
00043 #include <boost/noncopyable.hpp>
00044
00045
00046
00047
00048 namespace gnash {
00049 class MovieClip;
00050 class Movie;
00051 class ExecutableCode;
00052 class action_buffer;
00053 class movie_definition;
00054 class StaticText;
00055 class InteractiveObject;
00056 class Renderer;
00057 class as_object;
00058 class as_value;
00059 class as_environment;
00060 namespace SWF {
00061 class TextRecord;
00062 }
00063 }
00064
00065 namespace gnash {
00066
00068
00070 bool isReferenceable(const DisplayObject& d);
00071
00073
00075
00080 bool setDisplayObjectProperty(DisplayObject& obj, string_table::key key,
00081 const as_value& val);
00082
00084
00087
00091 bool getDisplayObjectProperty(DisplayObject& obj, string_table::key key,
00092 as_value& val);
00093
00095
00097
00101 void getIndexedProperty(size_t index, DisplayObject& o, as_value& val);
00102
00104
00106
00111 void setIndexedProperty(size_t index, DisplayObject& o, const as_value& val);
00112
00114
00117 void copyMatrix(const DisplayObject& from, DisplayObject& to);
00118
00120
00125
00129
00132
00136
00140
00145 class DisplayObject : public GcResource, boost::noncopyable
00146 {
00147 public:
00148
00150
00159 DisplayObject(movie_root& mr, as_object* object, DisplayObject* parent);
00160
00161 virtual ~DisplayObject() {}
00162
00167
00169
00172 static const int lowerAccessibleBound = -16384;
00173
00177 static const int upperAccessibleBound = 2130690044;
00178
00182 static const int staticDepthOffset = lowerAccessibleBound;
00183
00199 static const int removedDepthOffset = -32769;
00200
00203
00207 static const int noClipDepthValue = -1000000;
00208
00210
00213 virtual as_environment& get_environment() {
00214
00215
00216
00217 assert(_parent != NULL);
00218 return _parent->get_environment();
00219 }
00220
00222
00229 virtual void enumerateNonProperties(as_environment&) const {}
00230
00234 DisplayObject* get_parent() const
00235 {
00236 return _parent;
00237 }
00238
00240
00243 void set_parent(DisplayObject* parent)
00244 {
00245 _parent = parent;
00246 }
00247
00248 virtual MovieClip* to_movie() { return 0; }
00249
00250 int get_depth() const { return _depth; }
00251
00252 void set_depth(int d) { _depth = d; }
00253
00255 int getVolume() const { return _volume; }
00256
00258 void setVolume(int vol) { _volume = vol; }
00259
00261
00267 int getWorldVolume() const;
00268
00270 virtual int getDefinitionVersion() const {
00271 return -1;
00272 }
00273
00275 const SWFMatrix& getMatrix() const { return m_matrix; }
00276
00278
00284 void setMatrix(const SWFMatrix& m, bool updateCache = false);
00285
00287
00293 void set_x_scale(double factor);
00294
00296
00302 void set_y_scale(double factor);
00303
00305
00313 void set_rotation(double rot);
00314
00316
00320
00322 virtual void setWidth(double width);
00323
00325
00330 virtual void setHeight(double height);
00331
00332 const cxform& get_cxform() const { return m_color_transform; }
00333
00334 void set_cxform(const cxform& cx)
00335 {
00336 if (cx != m_color_transform) {
00337 set_invalidated(__FILE__, __LINE__);
00338 m_color_transform = cx;
00339 }
00340 }
00341
00342 int get_ratio() const { return _ratio; }
00343
00344 void set_ratio(int r)
00345 {
00346 if (r != _ratio) set_invalidated(__FILE__, __LINE__);
00347 _ratio = r;
00348 }
00349
00358 int get_clip_depth() const { return m_clip_depth; }
00359
00361 void set_clip_depth(int d)
00362 {
00363 m_clip_depth = d;
00364 }
00365
00373 bool isMaskLayer() const
00374 {
00375 return (m_clip_depth != noClipDepthValue && !_maskee);
00376 }
00377
00387 bool isDynamicMask() const
00388 {
00389 return (_maskee);
00390 }
00391
00393 DisplayObject* getMask() const
00394 {
00395 #if GNASH_PARANOIA_LEVEL > 1
00396 if (_mask) assert(_mask->_maskee == this);
00397 #endif
00398 return _mask;
00399 }
00400
00408 void setMask(DisplayObject* mask);
00409
00411 void set_name(string_table::key name) {
00412 _name = name;
00413 }
00414
00415 string_table::key get_name() const { return _name; }
00416
00423
00427 DSOEXPORT SWFMatrix getWorldMatrix(bool includeRoot = true) const;
00428
00434 virtual cxform get_world_cxform() const;
00435
00437
00444 std::auto_ptr<ExecutableCode> get_event_handler(const event_id& id) const;
00445
00447
00465 void add_event_handler(const event_id& id, const action_buffer& code);
00466
00468
00470 virtual void display(Renderer& renderer) = 0;
00471
00473
00477 virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>&,
00478 size_t&) {
00479 return 0;
00480 }
00481
00482 virtual SWFRect getBounds() const = 0;
00483
00485
00490 bool pointInBounds(boost::int32_t x, boost::int32_t y) const
00491 {
00492 SWFRect bounds = getBounds();
00493 SWFMatrix wm = getWorldMatrix(false);
00494 wm.transform(bounds);
00495 return bounds.point_test(x, y);
00496 }
00497
00499
00503 virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const = 0;
00504
00506
00517 virtual bool pointInVisibleShape(boost::int32_t x, boost::int32_t y) const
00518 {
00519 if (!visible()) return false;
00520 if (isDynamicMask() || isMaskLayer()) return false;
00521 return pointInShape(x, y);
00522 }
00523
00525
00533 virtual Movie* get_root() const {
00534 return get_parent()->get_root();
00535 }
00536
00538
00542 virtual MovieClip* getAsRoot();
00543
00563 virtual as_object* pathElement(string_table::key key);
00564
00568
00575 bool get_accept_anim_moves() const
00576 {
00577 return ! _scriptTransformed && ! _dynamicallyCreated;
00578 }
00579
00581
00594 bool isDynamic() const {
00595 return _dynamicallyCreated;
00596 }
00597
00599 void setDynamic() {
00600 _dynamicallyCreated = true;
00601 }
00602
00606
00613 void transformedByScript()
00614 {
00615 _scriptTransformed = true;
00616 }
00617
00619
00622 void set_visible(bool visible);
00623
00624
00625 bool visible() const { return _visible; }
00626
00628 virtual void notifyEvent(const event_id& )
00629 {
00630 }
00631
00633
00636 void queueEvent(const event_id& id, int lvl);
00637
00639
00645 bool hasEventHandler(const event_id& id) const;
00646
00648
00650 virtual InteractiveObject* topmostMouseEntity(boost::int32_t,
00651 boost::int32_t) {
00652 return 0;
00653 }
00654
00657
00659 virtual const DisplayObject* findDropTarget(boost::int32_t x,
00660 boost::int32_t y, DisplayObject* dragging) const
00661 {
00662 if (this != dragging && visible() && pointInVisibleShape(x, y)) {
00663 return this;
00664 }
00665
00666 return 0;
00667 }
00668
00670 bool invalidated() const {
00671 return _invalidated;
00672 }
00673
00675 bool childInvalidated() const {
00676 return _child_invalidated;
00677 }
00678
00680 virtual void update() {
00681 set_invalidated();
00682 }
00683
00688
00705 void set_invalidated();
00706 void set_invalidated(const char* debug_file, int debug_line);
00707
00708
00712 void extend_invalidated_bounds(const InvalidatedRanges& ranges);
00713
00714
00719 void set_child_invalidated();
00720
00733 void clear_invalidated() {
00734 _invalidated = false;
00735 _child_invalidated = false;
00736 m_old_invalidated_ranges.setNull();
00737 }
00738
00741
00758 virtual void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
00759
00763 virtual void omit_display() { clear_invalidated(); };
00764
00766
00776 virtual void construct(as_object* = 0)
00777 {
00778 saveOriginalTarget();
00779 }
00780
00782
00792 bool unload();
00793
00795 virtual void getLoadedMovie(Movie* newMovie);
00796
00798 bool unloaded() const;
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 std::pair<std::string, std::string> StringPair;
00866 typedef tree<StringPair> InfoTree;
00868
00877
00878 virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
00879 InfoTree::iterator it);
00880 #endif
00881
00883 string_table::key getNextUnnamedInstanceName();
00884
00885 enum BlendMode
00886 {
00887 BLENDMODE_UNDEFINED = 0,
00888 BLENDMODE_NORMAL = 1,
00889 BLENDMODE_LAYER,
00890 BLENDMODE_MULTIPLY,
00891 BLENDMODE_SCREEN,
00892 BLENDMODE_LIGHTEN,
00893 BLENDMODE_DARKEN,
00894 BLENDMODE_DIFFERENCE,
00895 BLENDMODE_ADD,
00896 BLENDMODE_SUBTRACT,
00897 BLENDMODE_INVERT,
00898 BLENDMODE_ALPHA,
00899 BLENDMODE_ERASE,
00900 BLENDMODE_OVERLAY,
00901 BLENDMODE_HARDLIGHT = 14
00902 };
00903
00904 BlendMode getBlendMode() const {
00905 return _blendMode;
00906 }
00907
00908 void setBlendMode(BlendMode bm) {
00909 _blendMode = bm;
00910 }
00911
00912
00913 typedef std::vector<const action_buffer*> BufferList;
00914 typedef std::map<event_id, BufferList> Events;
00915
00917
00920
00924 virtual bool handleFocus() {
00925 return false;
00926 }
00927
00929
00931 virtual void killFocus() {}
00932
00933 double rotation() const {
00934 return _rotation;
00935 }
00936
00937 double scaleX() const {
00938 return _xscale;
00939 }
00940
00941 double scaleY() const {
00942 return _yscale;
00943 }
00944
00945 as_object* object() const;
00946
00948 static as_value blendMode(const fn_call& fn);
00949
00951
00955 virtual void markReachableResources() const;
00956
00958
00960 virtual void markOwnResources() const {}
00961
00962 protected:
00963
00964 virtual bool unloadChildren() { return false; }
00965
00967 movie_root& stage() const {
00968 return _stage;
00969 }
00970
00977 void saveOriginalTarget()
00978 {
00979 _origTarget=getTarget();
00980 }
00981
00982
00983 const Events& get_event_handlers() const
00984 {
00985 return _event_handlers;
00986 }
00987
00988 void set_event_handlers(const Events& copyfrom);
00989
00991 string_table::key _name;
00992
00993 DisplayObject* _parent;
00994
00996
00999 as_object* getPathElementSeparator(string_table::key key);
01000
01016 InvalidatedRanges m_old_invalidated_ranges;
01017
01018 private:
01019
01021 void setMaskee(DisplayObject* maskee);
01022
01024 as_object* _object;
01025
01027 movie_root& _stage;
01028
01029 cxform m_color_transform;
01030
01031 SWFMatrix m_matrix;
01032
01033 Events _event_handlers;
01034
01038 double _xscale, _yscale, _rotation;
01039
01041 boost::int32_t _depth;
01042
01044
01051 int _volume;
01052
01053 int _ratio;
01054 int m_clip_depth;
01055
01057 DisplayObject* _mask;
01058
01060 DisplayObject* _maskee;
01061
01063 std::string _origTarget;
01064
01065 BlendMode _blendMode;
01066
01067 bool _visible;
01068
01070
01076 bool _scriptTransformed;
01077
01078 bool _dynamicallyCreated;
01079
01081 bool _unloaded;
01082
01084 bool _destroyed;
01085
01089
01094 bool _invalidated;
01095
01099 bool _child_invalidated;
01100
01101
01102 };
01103
01104 inline bool
01105 isReferenceable(const DisplayObject& d)
01106 {
01107 return d.object();
01108 }
01109
01111
01115 inline as_object*
01116 getObject(const DisplayObject* d)
01117 {
01118 return d ? d->object() : 0;
01119 }
01120
01122 std::ostream&
01123 operator<<(std::ostream& o, DisplayObject::BlendMode bm);
01124
01125 }
01126
01127
01128 #ifdef DEBUG_SET_INVALIDATED
01129 #define set_invalidated() set_invalidated(__FILE__, __LINE__)
01130 #endif
01131
01132
01133 #endif // GNASH_CHARACTER_H
01134
01135
01136
01137
01138
01139