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 <vector>
00028 #include <map>
00029 #include <string>
00030 #include <cassert>
00031 #include <boost/cstdint.hpp>
00032 #include <boost/noncopyable.hpp>
00033
00034 #include "Transform.h"
00035 #include "event_id.h"
00036 #include "SWFRect.h"
00037 #include "SWFMatrix.h"
00038 #include "SWFCxForm.h"
00039 #include "dsodefs.h"
00040 #include "snappingrange.h"
00041 #include "VM.h"
00042 #ifdef USE_SWFTREE
00043 # include "tree.hh"
00044 #endif
00045
00046
00047
00048
00049
00050 namespace gnash {
00051 class MovieClip;
00052 class Movie;
00053 class ExecutableCode;
00054 class action_buffer;
00055 class movie_definition;
00056 class StaticText;
00057 class InteractiveObject;
00058 class Renderer;
00059 class as_object;
00060 class as_value;
00061 class as_environment;
00062 namespace SWF {
00063 class TextRecord;
00064 }
00065 }
00066
00067 namespace gnash {
00068
00070
00072 bool isReferenceable(const DisplayObject& d);
00073
00075
00077
00082 bool setDisplayObjectProperty(DisplayObject& obj, string_table::key key,
00083 const as_value& val);
00084
00086
00089
00093 bool getDisplayObjectProperty(DisplayObject& obj, string_table::key key,
00094 as_value& val);
00095
00097
00099
00103 void getIndexedProperty(size_t index, DisplayObject& o, as_value& val);
00104
00106
00108
00113 void setIndexedProperty(size_t index, DisplayObject& o, const as_value& val);
00114
00116
00119 void copyMatrix(const DisplayObject& from, DisplayObject& to);
00120
00122
00125
00129 SWFMatrix getWorldMatrix(const DisplayObject& d, bool includeRoot = true);
00130
00132
00134 SWFCxForm getWorldCxForm(const DisplayObject& d);
00135
00137
00142
00146
00149
00153
00157
00162 class DisplayObject : public GcResource, boost::noncopyable
00163 {
00164 public:
00165
00167
00176 DisplayObject(movie_root& mr, as_object* object, DisplayObject* parent);
00177
00178 virtual ~DisplayObject() {}
00179
00184
00186
00189 static const int lowerAccessibleBound = -16384;
00190
00194 static const int upperAccessibleBound = 2130690044;
00195
00199 static const int staticDepthOffset = lowerAccessibleBound;
00200
00216 static const int removedDepthOffset = -32769;
00217
00220
00224 static const int noClipDepthValue = -1000000;
00225
00227
00230 virtual as_environment& get_environment() {
00231
00232
00233
00234 assert(_parent != NULL);
00235 return _parent->get_environment();
00236 }
00237
00239
00246 virtual void enumerateNonProperties(as_environment&) 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 int get_ratio() const { return _ratio; }
00360
00361 void set_ratio(int 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(string_table::key name) {
00428 _name = name;
00429 }
00430
00431 string_table::key 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(string_table::key key);
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
00622 bool visible() const { return _visible; }
00623
00625 virtual void notifyEvent(const event_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* = 0)
00774 {
00775 saveOriginalTarget();
00776 }
00777
00779
00789 bool unload();
00790
00792 virtual void getLoadedMovie(Movie* newMovie);
00793
00795 bool unloaded() const;
00796
00798
00809 virtual void destroy();
00810
00812
00815 bool isDestroyed() const { return _destroyed; }
00816
00823 bool boundsInClippingArea(Renderer& renderer) const;
00824
00826
00829 std::string getTargetPath() const;
00830
00833
00837 const std::string& getOrigTarget() const
00838 {
00839 return _origTarget;
00840 }
00841
00843
00846 std::string DSOEXPORT getTarget() const;
00847
00849
00853 virtual bool isSelectableTextField() const { return false; }
00854
00859 bool DSOEXPORT allowHandCursor() const;
00860
00861 #ifdef USE_SWFTREE
00862 typedef std::pair<std::string, std::string> StringPair;
00863 typedef tree<StringPair> InfoTree;
00865
00874
00875 virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
00876 InfoTree::iterator it);
00877 #endif
00878
00880 string_table::key 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
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
00945 static as_value blendMode(const fn_call& fn);
00946
00948
00952 virtual void markReachableResources() const;
00953
00955
00957 virtual void markOwnResources() const {}
00958
00959 protected:
00960
00962
00965
00969 class MaskRenderer
00970 {
00971 public:
00972 MaskRenderer(Renderer& r, const DisplayObject& o);
00973 ~MaskRenderer();
00974 private:
00975 Renderer& _renderer;
00976 DisplayObject* _mask;
00977 };
00978
00979 virtual bool unloadChildren() { return false; }
00980
00982 movie_root& stage() const {
00983 return _stage;
00984 }
00985
00992 void saveOriginalTarget()
00993 {
00994 _origTarget=getTarget();
00995 }
00996
00997 const Events& get_event_handlers() const
00998 {
00999 return _event_handlers;
01000 }
01001
01002 void set_event_handlers(const Events& copyfrom);
01003
01005 string_table::key _name;
01006
01007 DisplayObject* _parent;
01008
01010
01013 as_object* getPathElementSeparator(string_table::key key);
01014
01030 InvalidatedRanges m_old_invalidated_ranges;
01031
01032 private:
01033
01035 void setMaskee(DisplayObject* maskee);
01036
01038 as_object* _object;
01039
01041 movie_root& _stage;
01042
01043 Transform _transform;
01044
01045 Events _event_handlers;
01046
01050 double _xscale, _yscale, _rotation;
01051
01053 boost::int32_t _depth;
01054
01056
01063 int _volume;
01064
01065 int _ratio;
01066 int m_clip_depth;
01067
01069 DisplayObject* _mask;
01070
01072 DisplayObject* _maskee;
01073
01075 std::string _origTarget;
01076
01077 BlendMode _blendMode;
01078
01079 bool _visible;
01080
01082
01088 bool _scriptTransformed;
01089
01090 bool _dynamicallyCreated;
01091
01093 bool _unloaded;
01094
01096 bool _destroyed;
01097
01101
01106 bool _invalidated;
01107
01111 bool _child_invalidated;
01112
01113
01114 };
01115
01117 inline const SWFMatrix&
01118 getMatrix(const DisplayObject& o)
01119 {
01120 return o.transform().matrix;
01121 }
01122
01123 inline const SWFCxForm&
01124 getCxForm(const DisplayObject& o)
01125 {
01126 return o.transform().colorTransform;
01127 }
01128
01129 inline SWFMatrix
01130 getWorldMatrix(const DisplayObject& d, bool includeRoot)
01131 {
01132 SWFMatrix m = d.parent() ?
01133 getWorldMatrix(*d.parent(), includeRoot) : SWFMatrix();
01134
01135 if (d.parent() || includeRoot) m.concatenate(getMatrix(d));
01136 return m;
01137 }
01138
01139 inline SWFCxForm
01140 getWorldCxForm(const DisplayObject& d)
01141 {
01142 SWFCxForm cx = d.parent() ? getWorldCxForm(*d.parent()) : SWFCxForm();
01143 cx.concatenate(getCxForm(d));
01144 return cx;
01145 }
01146
01147 inline bool
01148 isReferenceable(const DisplayObject& d)
01149 {
01150 return d.object();
01151 }
01152
01154
01158 inline as_object*
01159 getObject(const DisplayObject* d)
01160 {
01161 return d ? d->object() : 0;
01162 }
01163
01165 std::ostream&
01166 operator<<(std::ostream& o, DisplayObject::BlendMode bm);
01167
01168 }
01169
01170
01171 #ifdef DEBUG_SET_INVALIDATED
01172 #define set_invalidated() set_invalidated(__FILE__, __LINE__)
01173 #endif
01174
01175
01176 #endif // GNASH_CHARACTER_H
01177
01178
01179
01180
01181
01182