Gnash  0.8.11dev
DisplayObject.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 
20 #ifndef GNASH_DISPLAY_OBJECT_H
21 #define GNASH_DISPLAY_OBJECT_H
22 
23 #ifdef HAVE_CONFIG_H
24 #include "gnashconfig.h" // USE_SWFTREE
25 #endif
26 
27 #include <vector>
28 #include <map>
29 #include <string>
30 #include <cassert>
31 #include <boost/cstdint.hpp> // For C99 int types
32 #include <boost/noncopyable.hpp>
33 #include <boost/logic/tribool.hpp>
34 
35 #include "ObjectURI.h"
36 #include "GC.h"
37 #include "Transform.h"
38 #include "event_id.h"
39 #include "SWFRect.h"
40 #include "SWFMatrix.h"
41 #include "SWFCxForm.h"
42 #include "dsodefs.h"
43 #include "snappingrange.h"
44 #ifdef USE_SWFTREE
45 # include "tree.hh"
46 #endif
47 
48 
49 //#define DEBUG_SET_INVALIDATED 1
50 
51 // Forward declarations
52 namespace gnash {
53  class MovieClip;
54  class movie_root;
55  class fn_call;
56  class Movie;
57  class ExecutableCode;
58  class action_buffer;
59  class movie_definition;
60  class StaticText;
61  class InteractiveObject;
62  class Renderer;
63  class as_object;
64  class as_value;
65  class as_environment;
66  class DisplayObject;
67  class KeyVisitor;
68  namespace SWF {
69  class TextRecord;
70  }
71 }
72 
73 namespace gnash {
74 
76 //
78 bool isReferenceable(const DisplayObject& d);
79 
81 //
83 //
88 bool setDisplayObjectProperty(DisplayObject& obj, const ObjectURI& uri,
89  const as_value& val);
90 
92 //
95 //
99 bool getDisplayObjectProperty(DisplayObject& obj, const ObjectURI& uri,
100  as_value& val);
101 
103 //
105 //
109 void getIndexedProperty(size_t index, DisplayObject& o, as_value& val);
110 
112 //
114 //
119 void setIndexedProperty(size_t index, DisplayObject& o, const as_value& val);
120 
122 //
125 void copyMatrix(const DisplayObject& from, DisplayObject& to);
126 
128 //
131 //
135 SWFMatrix getWorldMatrix(const DisplayObject& d, bool includeRoot = true);
136 
138 //
140 SWFCxForm getWorldCxForm(const DisplayObject& d);
141 
143 //
148 //
152 //
155 //
159 //
163 //
168 class DSOTEXPORT DisplayObject : public GcResource, boost::noncopyable
169 {
170 public:
171 
173  //
182  DisplayObject(movie_root& mr, as_object* object, DisplayObject* parent);
183 
184  virtual ~DisplayObject() {}
185 
190  //
192  //
195  static const int lowerAccessibleBound = -16384;
196 
200  static const int upperAccessibleBound = 2130690044;
201 
205  static const int staticDepthOffset = lowerAccessibleBound;
206 
222  static const int removedDepthOffset = -32769;
223 
226  //
230  static const int noClipDepthValue = -1000000;
231 
234  // MovieClip must override this
235  // and any other DisplayObject will have
236  // a parent!
237  assert(_parent != NULL);
238  return _parent->get_environment();
239  }
240 
242  //
247  virtual void visitNonProperties(KeyVisitor&) const {}
248 
252  DisplayObject* parent() const
253  {
254  return _parent;
255  }
256 
258  //
261  void set_parent(DisplayObject* parent)
262  {
263  _parent = parent;
264  }
265 
266  virtual MovieClip* to_movie() { return 0; }
267 
268  int get_depth() const { return _depth; }
269 
270  void set_depth(int d) { _depth = d; }
271 
273  int getVolume() const { return _volume; }
274 
276  void setVolume(int vol) { _volume = vol; }
277 
279  //
285  int getWorldVolume() const;
286 
288  virtual int getDefinitionVersion() const {
289  return -1;
290  }
291 
292  const Transform& transform() const {
293  return _transform;
294  }
295 
296 
298  //
304  void setMatrix(const SWFMatrix& m, bool updateCache = false);
305 
307  //
313  void set_x_scale(double factor);
314 
316  //
322  void set_y_scale(double factor);
323 
325  //
333  void set_rotation(double rot);
334 
336  //
340  //
342  virtual void setWidth(double width);
343 
345  //
350  virtual void setHeight(double height);
351 
352  void setCxForm(const SWFCxForm& cx)
353  {
354  if (_transform.colorTransform != cx) {
355  set_invalidated();
356  _transform.colorTransform = cx;
357  }
358  }
359 
360  boost::uint16_t get_ratio() const { return _ratio; }
361 
362  void set_ratio(boost::uint16_t r) {
363  if (r != _ratio) set_invalidated();
364  _ratio = r;
365  }
366 
375  int get_clip_depth() const { return m_clip_depth; }
376 
378  void set_clip_depth(int d)
379  {
380  m_clip_depth = d;
381  }
382 
390  bool isMaskLayer() const
391  {
392  return (m_clip_depth != noClipDepthValue && !_maskee);
393  }
394 
404  bool isDynamicMask() const
405  {
406  return (_maskee);
407  }
408 
410  DisplayObject* getMask() const
411  {
412 #if GNASH_PARANOIA_LEVEL > 1
413  if (_mask) assert(_mask->_maskee == this);
414 #endif
415  return _mask;
416  }
417 
425  void setMask(DisplayObject* mask);
426 
428  void set_name(const ObjectURI& uri) {
429  _name = uri;
430  }
431 
432  const ObjectURI& get_name() const { return _name; }
433 
435  //
442  std::auto_ptr<ExecutableCode> get_event_handler(const event_id& id) const;
443 
445  //
463  void add_event_handler(const event_id& id, const action_buffer& code);
464 
466  //
468  virtual void display(Renderer& renderer, const Transform& xform) = 0;
469 
471  //
475  virtual StaticText* getStaticText(std::vector<const SWF::TextRecord*>&,
476  size_t&) {
477  return 0;
478  }
479 
480  virtual SWFRect getBounds() const = 0;
481 
483  //
488  bool pointInBounds(boost::int32_t x, boost::int32_t y) const
489  {
490  SWFRect bounds = getBounds();
491  const SWFMatrix wm = getWorldMatrix(*this, false);
492  wm.transform(bounds);
493  return bounds.point_test(x, y);
494  }
495 
497  //
501  virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const = 0;
502 
504  //
515  virtual bool pointInVisibleShape(boost::int32_t x, boost::int32_t y) const
516  {
517  if (!visible()) return false;
518  if (isDynamicMask() || isMaskLayer()) return false;
519  return pointInShape(x, y);
520  }
521 
523  //
531  virtual Movie* get_root() const {
532  return parent()->get_root();
533  }
534 
536  //
540  virtual MovieClip* getAsRoot();
541 
561  virtual as_object* pathElement(const ObjectURI& uri);
562 
566  //
573  bool get_accept_anim_moves() const
574  {
575  return ! _scriptTransformed && ! _dynamicallyCreated;
576  }
577 
579  //
592  bool isDynamic() const {
593  return _dynamicallyCreated;
594  }
595 
597  void setDynamic() {
598  _dynamicallyCreated = true;
599  }
600 
604  //
611  void transformedByScript()
612  {
613  _scriptTransformed = true;
614  }
615 
617  //
620  void set_visible(bool visible);
621 
622  // Return true if this DisplayObject should be rendered
623  bool visible() const { return _visible; }
624 
626  //
632  bool hasEventHandler(const event_id& id) const;
633 
635  //
637  virtual InteractiveObject* topmostMouseEntity(boost::int32_t,
638  boost::int32_t) {
639  return 0;
640  }
641 
644  //
646  virtual const DisplayObject* findDropTarget(boost::int32_t x,
647  boost::int32_t y, DisplayObject* dragging) const
648  {
649  if (this != dragging && visible() && pointInVisibleShape(x, y)) {
650  return this;
651  }
652 
653  return 0;
654  }
655 
657  bool invalidated() const {
658  return _invalidated;
659  }
660 
662  bool childInvalidated() const {
663  return _child_invalidated;
664  }
665 
667  virtual void update() {
668  set_invalidated();
669  }
670 
675  //
692  void set_invalidated();
693  void set_invalidated(const char* debug_file, int debug_line);
694 
695 
699  void extend_invalidated_bounds(const InvalidatedRanges& ranges);
700 
701 
706  void set_child_invalidated();
707 
721  _invalidated = false;
722  _child_invalidated = false;
723  m_old_invalidated_ranges.setNull();
724  }
725 
728  //
745  virtual void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
746 
750  virtual void omit_display() { clear_invalidated(); };
751 
753  //
763  virtual void construct(as_object* /*init*/ = 0)
764  {
765  saveOriginalTarget();
766  }
767 
769  //
779  bool unload();
780 
782  virtual void getLoadedMovie(Movie* newMovie);
783 
785  bool unloaded() const {
786  return _unloaded;
787  }
788 
790  //
801  virtual void destroy();
802 
804  //
807  bool isDestroyed() const { return _destroyed; }
808 
815  bool boundsInClippingArea(Renderer& renderer) const;
816 
818  //
821  std::string getTargetPath() const;
822 
825  //
829  const std::string& getOrigTarget() const
830  {
831  return _origTarget;
832  }
833 
835  //
838  std::string DSOEXPORT getTarget() const;
839 
841  //
845  virtual bool isSelectableTextField() const { return false; }
846 
851  bool DSOEXPORT allowHandCursor() const;
852 
853 #ifdef USE_SWFTREE
854  typedef tree<std::pair<std::string, std::string> > InfoTree;
856  //
864  virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
865  InfoTree::iterator it);
866 #endif
867 
869  ObjectURI getNextUnnamedInstanceName();
870 
872  {
873  BLENDMODE_UNDEFINED = 0,
874  BLENDMODE_NORMAL = 1,
887  BLENDMODE_HARDLIGHT = 14
888  };
889 
891  return _blendMode;
892  }
893 
895  _blendMode = bm;
896  }
897 
898  // action_buffer is externally owned
899  typedef std::vector<const action_buffer*> BufferList;
900  typedef std::map<event_id, BufferList> Events;
901 
903  //
906  //
910  virtual bool handleFocus() {
911  return false;
912  }
913 
915  //
917  virtual void killFocus() {}
918 
919  double rotation() const {
920  return _rotation;
921  }
922 
923  double scaleX() const {
924  return _xscale;
925  }
926 
927  double scaleY() const {
928  return _yscale;
929  }
930 
931  as_object* object() const {
932  return _object;
933  }
934 
936  static as_value blendMode(const fn_call& fn);
937 
939  //
943  virtual void markReachableResources() const;
944 
946  //
948  virtual void markOwnResources() const {}
949 
950  boost::tribool focusRect() const {
951  return _focusRect;
952  }
953 
954  void focusRect(boost::tribool focus) {
955  _focusRect = focus;
956  }
957 
958 protected:
959 
961  //
964  //
969  {
970  public:
972  ~MaskRenderer();
973  private:
975  DisplayObject* _mask;
976  };
977 
978  virtual bool unloadChildren() { return false; }
979 
981  movie_root& stage() const {
982  return _stage;
983  }
984 
991  void saveOriginalTarget()
992  {
993  _origTarget=getTarget();
994  }
995 
996  const Events& get_event_handlers() const
997  {
998  return _event_handlers;
999  }
1000 
1001  void set_event_handlers(const Events& copyfrom);
1002 
1005 
1007 
1009  //
1012  as_object* getPathElementSeparator(string_table::key key);
1013 
1030 
1031 private:
1032 
1034  void setMaskee(DisplayObject* maskee);
1035 
1037  as_object* _object;
1038 
1040  movie_root& _stage;
1041 
1042  Transform _transform;
1043 
1044  Events _event_handlers;
1045 
1049  double _xscale, _yscale, _rotation;
1050 
1052  boost::int32_t _depth;
1053 
1054  boost::tribool _focusRect;
1055 
1057  //
1064  int _volume;
1065 
1066  boost::uint16_t _ratio;
1067  int m_clip_depth;
1068 
1070  DisplayObject* _mask;
1071 
1073  DisplayObject* _maskee;
1074 
1076  std::string _origTarget;
1077 
1078  BlendMode _blendMode;
1079 
1080  bool _visible;
1081 
1083  //
1089  bool _scriptTransformed;
1090 
1091  bool _dynamicallyCreated;
1092 
1094  bool _unloaded;
1095 
1097  bool _destroyed;
1098 
1102  //
1107  bool _invalidated;
1108 
1112  bool _child_invalidated;
1113 
1114 
1115 };
1116 
1118 inline const SWFMatrix&
1120 {
1121  return o.transform().matrix;
1122 }
1123 
1124 inline const SWFCxForm&
1126 {
1127  return o.transform().colorTransform;
1128 }
1129 
1130 inline SWFMatrix
1131 getWorldMatrix(const DisplayObject& d, bool includeRoot)
1132 {
1133  SWFMatrix m = d.parent() ?
1134  getWorldMatrix(*d.parent(), includeRoot) : SWFMatrix();
1135 
1136  if (d.parent() || includeRoot) m.concatenate(getMatrix(d));
1137  return m;
1138 }
1139 
1140 inline SWFCxForm
1142 {
1143  SWFCxForm cx = d.parent() ? getWorldCxForm(*d.parent()) : SWFCxForm();
1144  cx.concatenate(getCxForm(d));
1145  return cx;
1146 }
1147 
1148 inline bool
1150 {
1151  return d.object();
1152 }
1153 
1155 //
1159 inline as_object*
1161 {
1162  return d ? d->object() : 0;
1163 }
1164 
1166 std::ostream&
1167 operator<<(std::ostream& o, DisplayObject::BlendMode bm);
1168 
1169 } // end namespace gnash
1170 
1171 
1172 #ifdef DEBUG_SET_INVALIDATED
1173 #define set_invalidated() set_invalidated(__FILE__, __LINE__)
1174 #endif
1175 
1176 
1177 #endif // GNASH_CHARACTER_H
1178 
1179 
1180 // Local Variables:
1181 // mode: C++
1182 // indent-tabs-mode: t
1183 // End: