Gnash  0.8.10
SWFRect.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   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_RECT_H
00021 #define GNASH_RECT_H
00022 
00023 #include <string>
00024 #include <cassert> 
00025 #include <ostream> 
00026 #include <boost/cstdint.hpp>
00027 
00028 #include "dsodefs.h"
00029 #include "Range2d.h"
00030 
00031 // Forward decl
00032 namespace gnash {
00033     class SWFMatrix;
00034     namespace geometry {
00035         class Point2d;
00036     }
00037 }
00038 
00039 namespace gnash {
00040 
00044 class SWFRect
00045 {
00046 
00047 public:
00048 
00049     static const boost::int32_t rectNull = 0x80000000;
00050     static const boost::int32_t rectMax = 0x7fffffff;
00051     
00053     friend std::ostream& operator<< (std::ostream& os, const SWFRect& SWFRect);
00054 
00056     SWFRect()
00057         :
00058        _xMin(rectNull),
00059        _yMin(rectNull),
00060        _xMax(rectNull),
00061        _yMax(rectNull)
00062     {}
00063 
00065     SWFRect(int xmin, int ymin, int xmax, int ymax)
00066         :
00067         _xMin(xmin),
00068         _yMin(ymin),
00069         _xMax(xmax),
00070         _yMax(ymax)
00071     {
00072     }
00073 
00075     bool is_null() const
00076     {
00077         return (_xMin == rectNull && _xMax == rectNull);
00078     }
00079 
00081     void set_null()
00082     {
00083         _xMin = _yMin = _xMax = _yMax = rectNull;
00084     }
00085 
00087     bool is_world() const
00088     {
00089         return _xMin == (- rectMax >> 9) 
00090             && _yMin == (- rectMax >> 9) 
00091             && _xMax == (rectMax >> 9)
00092             && _yMax == (rectMax >> 9);
00093     }
00094 
00096     void set_world()
00097     {
00098         _xMin = _yMin = - rectMax >> 9;
00099         _xMax = _yMax = rectMax >> 9;
00100     }
00101 
00103     boost::int32_t width() const
00104     {
00105         return _xMax - _xMin;
00106     }
00107 
00109     boost::int32_t height() const
00110     {
00111         return _yMax - _yMin;
00112     }
00113 
00115     boost::int32_t get_x_min() const
00116     {
00117         assert(!is_null());
00118         return _xMin;
00119     }
00120 
00122     boost::int32_t get_x_max() const
00123     {
00124         assert(!is_null());
00125         return _xMax;
00126     }
00127 
00129     boost::int32_t get_y_min() const
00130     {
00131         assert(!is_null());
00132         return _yMin;
00133     }
00134 
00136     boost::int32_t get_y_max() const
00137     {
00138         assert(!is_null());
00139         return _yMax;
00140     }
00141     
00143     bool point_test(boost::int32_t x, boost::int32_t y) const
00144     {
00145         if (is_null()) return false;
00146         
00147         if (x < _xMin || x > _xMax || y < _yMin || y > _yMax) {
00148             return false;
00149         } 
00150         return true;
00151     }
00152 
00154     void set_to_point(boost::int32_t x, boost::int32_t y)
00155     {
00156         _xMin = _xMax = x;
00157         _yMin = _yMax = y;
00158     }
00159 
00160     
00161     void set_to_rect(boost::int32_t x1, boost::int32_t y1, boost::int32_t x2,
00162             boost::int32_t y2)
00163     {
00164         _xMin = x1;
00165         _yMin = y1;
00166         _xMax = x2;
00167         _yMax = y2;
00168     }
00169     
00171     void expand_to_point(boost::int32_t x, boost::int32_t y)
00172     {
00173         if (is_null()) {
00174             set_to_point(x, y);
00175         } else {
00176             expand_to(x, y);
00177         }
00178     }
00179 
00183     void enclose_transformed_rect(const SWFMatrix& m, const SWFRect& r);
00184     
00186     void expand_to_circle(boost::int32_t x, boost::int32_t y,
00187             boost::int32_t radius)
00188     {
00189         // I know it's easy to make code work for minus radius.
00190         // would do that untill I see the requirement for a SWF RECTANGLE.
00191         assert(radius >= 0); 
00192         if (is_null()) {
00193             _xMin = x - radius;
00194             _yMin = y - radius;
00195             _xMax = x + radius;
00196             _yMax = y + radius;
00197         } else {
00198             _xMin = std::min(_xMin, x - radius);
00199             _yMin = std::min(_yMin, y - radius);
00200             _xMax = std::max(_xMax, x + radius);
00201             _yMax = std::max(_yMax, y + radius);
00202         }
00203     }
00204       
00207     DSOEXPORT void expand_to_transformed_rect(const SWFMatrix& m,
00208             const SWFRect& r);
00209     
00211     DSOEXPORT void expand_to_rect(const SWFRect& r);
00212     
00213     void set_lerp(const SWFRect& a, const SWFRect& b, float t);
00214 
00218     void clamp(geometry::Point2d& p) const;
00219 
00221     // TODO: deprecate this.
00222     geometry::Range2d<boost::int32_t> getRange() const
00223     {
00224         if (is_null())
00225         {
00226            // Range2d has a differnt idea about what is a null SWFRect.
00227            return geometry::Range2d<boost::int32_t>(geometry::nullRange); 
00228         }
00229         else if( is_world() ) 
00230         {
00231             return geometry::Range2d<boost::int32_t>(geometry::worldRange);
00232         }
00233         else
00234         {
00235             return geometry::Range2d<boost::int32_t>(_xMin, _yMin,
00236                     _xMax, _yMax);
00237         }
00238     }
00239 
00241     std::string toString() const;
00242 
00243 private:
00244 
00245     // make ourself to enclose the given point.
00246     void expand_to(boost::int32_t x, boost::int32_t y)
00247     {
00248         _xMin = std::min(_xMin, x);
00249         _yMin = std::min(_yMin, y);
00250         _xMax = std::max(_xMax, x);
00251         _yMax = std::max(_yMax, y);
00252     }
00253 
00254     boost::int32_t _xMin; // TWIPS
00255     boost::int32_t _yMin; // TWIPS
00256     boost::int32_t _xMax; // TWIPS
00257     boost::int32_t _yMax; // TWIPS
00258 };
00259 
00260 
00261 inline std::ostream&
00262 operator<<(std::ostream& os, const SWFRect& r)
00263 {
00264     if (!r.is_null()) {
00265         os << "RECT(" 
00266            << r.get_x_min() << "," 
00267            << r.get_y_min() << "," 
00268            << r.get_x_max() << "," 
00269            << r.get_y_max() << ")";
00270     }
00271     else {
00272         os << "NULL RECT!";
00273     }
00274 
00275     return os;
00276 }
00277 
00278 }   // namespace gnash
00279 
00280 #endif // GNASH_RECT_H
00281 
00282 
00283 // Local Variables:
00284 // mode: C++
00285 // indent-tabs-mode: t
00286 // End: