Gnash  0.8.10
DisplayList.h
Go to the documentation of this file.
00001 // dlist.h:  Display list definitions, for Gnash.
00002 // 
00003 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00004 //   Free Software Foundation, Inc
00005 // 
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 3 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // This program is distributed in the hope that it will be useful,
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_DLIST_H
00021 #define GNASH_DLIST_H
00022 
00023 #include "snappingrange.h"
00024 
00025 #include <string>
00026 #include <list>
00027 #include <iosfwd>
00028 #if GNASH_PARANOIA_LEVEL > 1 && !defined(NDEBUG)
00029 #include "DisplayObject.h"
00030 #include <set>  // for testInvariant
00031 #include <algorithm>
00032 #include "log.h"
00033 #endif
00034 
00035 // GNASH_PARANOIA_LEVEL:
00036 // 0 : (not unimplemented)
00037 // 1 : quick assertions
00038 // 2 : add testInvariant
00039 //
00040 #ifndef GNASH_PARANOIA_LEVEL
00041 # define GNASH_PARANOIA_LEVEL 1
00042 #endif
00043 
00044 namespace gnash {
00045     class SWFCxForm;
00046     class Renderer;
00047     struct ObjectURI;
00048     class Transform;
00049     class string_table;
00050     class DisplayObject;
00051     class SWFMatrix;
00052 }
00053 
00054 namespace gnash {
00055 
00057 //
00063 class DisplayList
00064 {
00065 
00066 public:
00067 
00068         typedef std::list<DisplayObject*> container_type;
00069         typedef container_type::iterator iterator;
00070         typedef container_type::const_iterator const_iterator;
00071         typedef container_type::reverse_iterator reverse_iterator;
00072         typedef container_type::const_reverse_iterator const_reverse_iterator;
00073 
00074     DisplayList() {}
00075     ~DisplayList() {}
00076 
00078         friend std::ostream& operator<< (std::ostream&, const DisplayList&);
00079 
00083         //
00096     void placeDisplayObject(DisplayObject* ch, int depth);
00097 
00101         //
00117         void replaceDisplayObject(DisplayObject* ch, int depth, bool use_old_cxform,
00118                 bool use_old_matrix);
00119 
00123         //
00143         void swapDepths(DisplayObject* ch, int depth);
00144 
00148         //
00154         //
00162         void moveDisplayObject(int depth, const SWFCxForm* color_xform,
00163             const SWFMatrix* mat, boost::uint16_t* ratio);
00164 
00166         //
00168         void removeDisplayObject(int depth);
00169 
00171         //
00178         void removeUnloaded();
00179 
00186         bool unload();
00187 
00189         void destroy();
00190 
00192         //
00200         void add(DisplayObject* ch, bool replace);
00201 
00203     //
00206     //
00212     void insertDisplayObject(DisplayObject* obj, int index);
00213 
00215     //
00217         void display(Renderer& renderer, const Transform& xform);
00218         
00219         void omit_display();
00220 
00222         DisplayObject* getDisplayObjectAtDepth(int depth) const;
00223 
00225         //
00235         DisplayObject* getDisplayObjectByName(string_table& st,
00236             const ObjectURI& uri, bool caseless) const;
00237 
00241         //
00250         template <class V> inline void visitBackward(V& visitor);
00251     template <class V> inline void visitBackward(V& visitor) const;
00252 
00255         //
00265         template <class V> inline void visitAll(V& visitor);
00266         template <class V> inline void visitAll(V& visitor) const;
00267 
00270         void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);     
00271         
00273         size_t size() const { 
00274                 return _charsByDepth.size();
00275         }
00276 
00278         bool empty() const {
00279                 return _charsByDepth.empty();
00280         }
00281 
00283         //
00288         int getNextHighestDepth() const;
00289         
00291     //
00294         void mergeDisplayList(DisplayList& newList, DisplayObject& o);
00295 
00296         bool operator==(const DisplayList& other) const {
00297         return _charsByDepth == other._charsByDepth;
00298     }
00299 
00300         bool operator!=(const DisplayList& other) const {
00301         return _charsByDepth != other._charsByDepth;
00302     }
00303         
00304 #if GNASH_PARANOIA_LEVEL > 1 && !defined(NDEBUG)
00305     DisplayList::const_iterator nonRemoved() const;
00306 
00307     void testInvariant() const
00308         {
00309                 DisplayList sorted = *this;
00310 
00311         // check no duplicated depths above non-removed zone.
00312                 std::set<int> depths;
00313                 for (const_iterator it = nonRemoved(),
00314                 itEnd = _charsByDepth.end(); it != itEnd; ++it) {
00315 
00316                         DisplayObject* ch = *it;
00317                         int depth = ch->get_depth();
00318                         if (!depths.insert(depth).second) {
00319                                 log_debug("Depth %d is duplicated in DisplayList %p",
00320                         depth, (const void*)this);
00321                 std::abort();
00322                         }
00323                 }
00324         if (_charsByDepth.empty()) return;
00325                 // check we didn't screw up ordering
00326         assert(std::adjacent_find(_charsByDepth.begin(), _charsByDepth.end(),
00327             DepthGreaterThan()) == _charsByDepth.end());
00328         }
00329 #else
00330     void testInvariant() const {}
00331 #endif 
00332 
00333 private:
00334 
00338         //
00345         void reinsertRemovedCharacter(DisplayObject* ch);
00346 
00347         container_type _charsByDepth;
00348 };
00349 
00350 template <class V>
00351 void
00352 DisplayList::visitBackward(V& visitor)
00353 {
00354         for (reverse_iterator it = _charsByDepth.rbegin(),
00355                         itEnd = _charsByDepth.rend(); it != itEnd; ++it) {
00356                 if (!visitor(*it)) break;
00357         }
00358 }
00359 
00360 template <class V>
00361 void
00362 DisplayList::visitBackward(V& visitor) const
00363 {
00364         for (const_reverse_iterator it = _charsByDepth.rbegin(),
00365                         itEnd = _charsByDepth.rend(); it != itEnd; ++it) {
00366                 if (!visitor(*it)) break;
00367         }
00368 }
00369 
00370 template <class V>
00371 void
00372 DisplayList::visitAll(V& visitor)
00373 {
00374         for (iterator it = _charsByDepth.begin(), itEnd = _charsByDepth.end();
00375                 it != itEnd; ++it) {
00376 
00377                 visitor(*it);
00378         }
00379 }
00380 
00381 template <class V>
00382 void
00383 DisplayList::visitAll(V& visitor) const
00384 {
00385         for (const_iterator it = _charsByDepth.begin(),
00386             itEnd = _charsByDepth.end(); it != itEnd; ++it) {
00387 
00388                 visitor(*it);
00389         }
00390 }
00391 
00392 std::ostream& operator<< (std::ostream&, const DisplayList&);
00393 
00394 } // namespace gnash
00395 
00396 
00397 #endif // GNASH_DLIST_H
00398 
00399 
00400 
00401 // Local Variables:
00402 // mode: C++
00403 // c-basic-offset: 8 
00404 // tab-width: 8
00405 // indent-tabs-mode: t
00406 // End: