Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_basics.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 
00025 #ifndef AGG_BASICS_INCLUDED
00026 #define AGG_BASICS_INCLUDED
00027 
00028 #include <math.h>
00029 #include "agg_config.h"
00030 
00031 //---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
00032 #ifdef AGG_CUSTOM_ALLOCATOR
00033 #include "agg_allocator.h"
00034 #else
00035 namespace agg
00036 {
00037     // The policy of all AGG containers and memory allocation strategy 
00038     // in general is that no allocated data requires explicit construction.
00039     // It means that the allocator can be really simple; you can even
00040     // replace new/delete to malloc/free. The constructors and destructors 
00041     // won't be called in this case, however everything will remain working. 
00042     // The second argument of deallocate() is the size of the allocated 
00043     // block. You can use this information if you wish.
00044     //------------------------------------------------------------pod_allocator
00045     template<class T> struct pod_allocator
00046     {
00047         static T*   allocate(unsigned num)       { return new T [num]; }
00048         static void deallocate(T* ptr, unsigned) { delete [] ptr;      }
00049     };
00050 
00051     // Single object allocator. It's also can be replaced with your custom
00052     // allocator. The difference is that it can only allocate a single 
00053     // object and the constructor and destructor must be called. 
00054     // In AGG there is no need to allocate an array of objects with
00055     // calling their constructors (only single ones). So that, if you
00056     // replace these new/delete to malloc/free make sure that the in-place
00057     // new is called and take care of calling the destructor too.
00058     //------------------------------------------------------------obj_allocator
00059     template<class T> struct obj_allocator
00060     {
00061         static T*   allocate()         { return new T; }
00062         static void deallocate(T* ptr) { delete ptr;   }
00063     };
00064 }
00065 #endif
00066 
00067 
00068 //-------------------------------------------------------- Default basic types
00069 //
00070 // If the compiler has different capacity of the basic types you can redefine
00071 // them via the compiler command line or by generating agg_config.h that is
00072 // empty by default.
00073 //
00074 #ifndef AGG_INT8
00075 #define AGG_INT8 signed char
00076 #endif
00077 
00078 #ifndef AGG_INT8U
00079 #define AGG_INT8U unsigned char
00080 #endif
00081 
00082 #ifndef AGG_INT16
00083 #define AGG_INT16 short
00084 #endif
00085 
00086 #ifndef AGG_INT16U
00087 #define AGG_INT16U unsigned short
00088 #endif
00089 
00090 #ifndef AGG_INT32
00091 #define AGG_INT32 int
00092 #endif
00093 
00094 #ifndef AGG_INT32U
00095 #define AGG_INT32U unsigned
00096 #endif
00097 
00098 #ifndef AGG_INT64
00099 #if defined(_MSC_VER) || defined(__BORLANDC__)
00100 #define AGG_INT64 signed __int64
00101 #else
00102 #define AGG_INT64 signed long long
00103 #endif
00104 #endif
00105 
00106 #ifndef AGG_INT64U
00107 #if defined(_MSC_VER) || defined(__BORLANDC__)
00108 #define AGG_INT64U unsigned __int64
00109 #else
00110 #define AGG_INT64U unsigned long long
00111 #endif
00112 #endif
00113 
00114 //------------------------------------------------ Some fixes for MS Visual C++
00115 #if defined(_MSC_VER)
00116 #pragma warning(disable:4786) // Identifier was truncated...
00117 #endif
00118 
00119 #if defined(_MSC_VER)
00120 #define AGG_INLINE __forceinline
00121 #else
00122 #define AGG_INLINE inline
00123 #endif
00124 
00125 namespace agg
00126 {
00127     //-------------------------------------------------------------------------
00128     typedef AGG_INT8   int8;         //----int8
00129     typedef AGG_INT8U  int8u;        //----int8u
00130     typedef AGG_INT16  int16;        //----int16
00131     typedef AGG_INT16U int16u;       //----int16u
00132     typedef AGG_INT32  int32;        //----int32
00133     typedef AGG_INT32U int32u;       //----int32u
00134     typedef AGG_INT64  int64;        //----int64
00135     typedef AGG_INT64U int64u;       //----int64u
00136 
00137 #if defined(AGG_FISTP)
00138 #pragma warning(push)
00139 #pragma warning(disable : 4035) //Disable warning "no return value"
00140     AGG_INLINE int iround(double v)              //-------iround
00141     {
00142         int t;
00143         __asm fld   qword ptr [v]
00144         __asm fistp dword ptr [t]
00145         __asm mov eax, dword ptr [t]
00146     }
00147     AGG_INLINE unsigned uround(double v)         //-------uround
00148     {
00149         unsigned t;
00150         __asm fld   qword ptr [v]
00151         __asm fistp dword ptr [t]
00152         __asm mov eax, dword ptr [t]
00153     }
00154 #pragma warning(pop)
00155     AGG_INLINE unsigned ufloor(double v)         //-------ufloor
00156     {
00157         return unsigned(floor(v));
00158     }
00159     AGG_INLINE unsigned uceil(double v)          //--------uceil
00160     {
00161         return unsigned(ceil(v));
00162     }
00163 #elif defined(AGG_QIFIST)
00164     AGG_INLINE int iround(double v)
00165     {
00166         return int(v);
00167     }
00168     AGG_INLINE int uround(double v)
00169     {
00170         return unsigned(v);
00171     }
00172     AGG_INLINE unsigned ufloor(double v)
00173     {
00174         return unsigned(floor(v));
00175     }
00176     AGG_INLINE unsigned uceil(double v)
00177     {
00178         return unsigned(ceil(v));
00179     }
00180 #else
00181     AGG_INLINE int iround(double v)
00182     {
00183         return int((v < 0.0) ? v - 0.5 : v + 0.5);
00184     }
00185     AGG_INLINE int uround(double v)
00186     {
00187         return unsigned(v + 0.5);
00188     }
00189     AGG_INLINE unsigned ufloor(double v)
00190     {
00191         return unsigned(v);
00192     }
00193     AGG_INLINE unsigned uceil(double v)
00194     {
00195         return unsigned(ceil(v));
00196     }
00197 #endif
00198 
00199     //---------------------------------------------------------------saturation
00200     template<int Limit> struct saturation
00201     {
00202         AGG_INLINE static int iround(double v)
00203         {
00204             if(v < double(-Limit)) return -Limit;
00205             if(v > double( Limit)) return  Limit;
00206             return agg::iround(v);
00207         }
00208     };
00209 
00210     //------------------------------------------------------------------mul_one
00211     template<unsigned Shift> struct mul_one
00212     {
00213         AGG_INLINE static unsigned mul(unsigned a, unsigned b)
00214         {
00215             register unsigned q = a * b + (1 << (Shift-1));
00216             return (q + (q >> Shift)) >> Shift;
00217         }
00218     };
00219 
00220     //-------------------------------------------------------------------------
00221     typedef unsigned char cover_type;    //----cover_type
00222     enum cover_scale_e
00223     {
00224         cover_shift = 8,                 //----cover_shift
00225         cover_size  = 1 << cover_shift,  //----cover_size 
00226         cover_mask  = cover_size - 1,    //----cover_mask 
00227         cover_none  = 0,                 //----cover_none 
00228         cover_full  = cover_mask         //----cover_full 
00229     };
00230 
00231     //----------------------------------------------------poly_subpixel_scale_e
00232     // These constants determine the subpixel accuracy, to be more precise, 
00233     // the number of bits of the fractional part of the coordinates. 
00234     // The possible coordinate capacity in bits can be calculated by formula:
00235     // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
00236     // 8-bits fractional part the capacity is 24 bits.
00237     enum poly_subpixel_scale_e
00238     {
00239         poly_subpixel_shift = 8,                      //----poly_subpixel_shift
00240         poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale 
00241         poly_subpixel_mask  = poly_subpixel_scale-1,  //----poly_subpixel_mask 
00242     };
00243 
00244     //----------------------------------------------------------filling_rule_e
00245     enum filling_rule_e
00246     {
00247         fill_non_zero,
00248         fill_even_odd
00249     };
00250 
00251     //-----------------------------------------------------------------------pi
00252     const double pi = 3.14159265358979323846;
00253 
00254     //------------------------------------------------------------------deg2rad
00255     inline double deg2rad(double deg)
00256     {
00257         return deg * pi / 180.0;
00258     }
00259 
00260     //------------------------------------------------------------------rad2deg
00261     inline double rad2deg(double rad)
00262     {
00263         return rad * 180.0 / pi;
00264     }
00265  
00266     //----------------------------------------------------------------rect_base
00267     template<class T> struct rect_base
00268     {
00269         typedef T            value_type;
00270         typedef rect_base<T> self_type;
00271         T x1, y1, x2, y2;
00272 
00273         rect_base() {}
00274         rect_base(T x1_, T y1_, T x2_, T y2_) :
00275             x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
00276 
00277         void init(T x1_, T y1_, T x2_, T y2_) 
00278         {
00279             x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; 
00280         }
00281 
00282         const self_type& normalize()
00283         {
00284             T t;
00285             if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
00286             if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
00287             return *this;
00288         }
00289 
00290         bool clip(const self_type& r)
00291         {
00292             if(x2 > r.x2) x2 = r.x2;
00293             if(y2 > r.y2) y2 = r.y2;
00294             if(x1 < r.x1) x1 = r.x1;
00295             if(y1 < r.y1) y1 = r.y1;
00296             return x1 <= x2 && y1 <= y2;
00297         }
00298 
00299         bool is_valid() const
00300         {
00301             return x1 <= x2 && y1 <= y2;
00302         }
00303 
00304         bool hit_test(T x, T y) const
00305         {
00306             return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
00307         }
00308     };
00309 
00310     //-----------------------------------------------------intersect_rectangles
00311     template<class Rect> 
00312     inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
00313     {
00314         Rect r = r1;
00315 
00316         // First process x2,y2 because the other order 
00317         // results in Internal Compiler Error under 
00318         // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in 
00319         // case of "Maximize Speed" optimization option.
00320         //-----------------
00321         if(r.x2 > r2.x2) r.x2 = r2.x2; 
00322         if(r.y2 > r2.y2) r.y2 = r2.y2;
00323         if(r.x1 < r2.x1) r.x1 = r2.x1;
00324         if(r.y1 < r2.y1) r.y1 = r2.y1;
00325         return r;
00326     }
00327 
00328 
00329     //---------------------------------------------------------unite_rectangles
00330     template<class Rect> 
00331     inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
00332     {
00333         Rect r = r1;
00334         if(r.x2 < r2.x2) r.x2 = r2.x2;
00335         if(r.y2 < r2.y2) r.y2 = r2.y2;
00336         if(r.x1 > r2.x1) r.x1 = r2.x1;
00337         if(r.y1 > r2.y1) r.y1 = r2.y1;
00338         return r;
00339     }
00340 
00341     typedef rect_base<int>    rect_i; //----rect_i
00342     typedef rect_base<float>  rect_f; //----rect_f
00343     typedef rect_base<double> rect_d; //----rect_d
00344 
00345     //---------------------------------------------------------path_commands_e
00346     enum path_commands_e
00347     {
00348         path_cmd_stop     = 0,        //----path_cmd_stop    
00349         path_cmd_move_to  = 1,        //----path_cmd_move_to 
00350         path_cmd_line_to  = 2,        //----path_cmd_line_to 
00351         path_cmd_curve3   = 3,        //----path_cmd_curve3  
00352         path_cmd_curve4   = 4,        //----path_cmd_curve4  
00353         path_cmd_curveN   = 5,        //----path_cmd_curveN
00354         path_cmd_catrom   = 6,        //----path_cmd_catrom
00355         path_cmd_ubspline = 7,        //----path_cmd_ubspline
00356         path_cmd_end_poly = 0x0F,     //----path_cmd_end_poly
00357         path_cmd_mask     = 0x0F      //----path_cmd_mask    
00358     };
00359 
00360     //------------------------------------------------------------path_flags_e
00361     enum path_flags_e
00362     {
00363         path_flags_none  = 0,         //----path_flags_none 
00364         path_flags_ccw   = 0x10,      //----path_flags_ccw  
00365         path_flags_cw    = 0x20,      //----path_flags_cw   
00366         path_flags_close = 0x40,      //----path_flags_close
00367         path_flags_mask  = 0xF0       //----path_flags_mask 
00368     };
00369 
00370     //---------------------------------------------------------------is_vertex
00371     inline bool is_vertex(unsigned c)
00372     {
00373         return c >= path_cmd_move_to && c < path_cmd_end_poly;
00374     }
00375 
00376     //--------------------------------------------------------------is_drawing
00377     inline bool is_drawing(unsigned c)
00378     {
00379         return c >= path_cmd_line_to && c < path_cmd_end_poly;
00380     }
00381 
00382     //-----------------------------------------------------------------is_stop
00383     inline bool is_stop(unsigned c)
00384     { 
00385         return c == path_cmd_stop;
00386     }
00387 
00388     //--------------------------------------------------------------is_move_to
00389     inline bool is_move_to(unsigned c)
00390     {
00391         return c == path_cmd_move_to;
00392     }
00393 
00394     //--------------------------------------------------------------is_line_to
00395     inline bool is_line_to(unsigned c)
00396     {
00397         return c == path_cmd_line_to;
00398     }
00399 
00400     //----------------------------------------------------------------is_curve
00401     inline bool is_curve(unsigned c)
00402     {
00403         return c == path_cmd_curve3 || c == path_cmd_curve4;
00404     }
00405 
00406     //---------------------------------------------------------------is_curve3
00407     inline bool is_curve3(unsigned c)
00408     {
00409         return c == path_cmd_curve3;
00410     }
00411 
00412     //---------------------------------------------------------------is_curve4
00413     inline bool is_curve4(unsigned c)
00414     {
00415         return c == path_cmd_curve4;
00416     }
00417 
00418     //-------------------------------------------------------------is_end_poly
00419     inline bool is_end_poly(unsigned c)
00420     {
00421         return (c & path_cmd_mask) == path_cmd_end_poly;
00422     }
00423 
00424     //----------------------------------------------------------------is_close
00425     inline bool is_close(unsigned c)
00426     {
00427         return (c & ~(path_flags_cw | path_flags_ccw)) ==
00428                (path_cmd_end_poly | path_flags_close); 
00429     }
00430 
00431     //------------------------------------------------------------is_next_poly
00432     inline bool is_next_poly(unsigned c)
00433     {
00434         return is_stop(c) || is_move_to(c) || is_end_poly(c);
00435     }
00436 
00437     //-------------------------------------------------------------------is_cw
00438     inline bool is_cw(unsigned c)
00439     {
00440         return (c & path_flags_cw) != 0;
00441     }
00442 
00443     //------------------------------------------------------------------is_ccw
00444     inline bool is_ccw(unsigned c)
00445     {
00446         return (c & path_flags_ccw) != 0;
00447     }
00448 
00449     //-------------------------------------------------------------is_oriented
00450     inline bool is_oriented(unsigned c)
00451     {
00452         return (c & (path_flags_cw | path_flags_ccw)) != 0; 
00453     }
00454 
00455     //---------------------------------------------------------------is_closed
00456     inline bool is_closed(unsigned c)
00457     {
00458         return (c & path_flags_close) != 0; 
00459     }
00460 
00461     //----------------------------------------------------------get_close_flag
00462     inline unsigned get_close_flag(unsigned c)
00463     {
00464         return c & path_flags_close; 
00465     }
00466 
00467     //-------------------------------------------------------clear_orientation
00468     inline unsigned clear_orientation(unsigned c)
00469     {
00470         return c & ~(path_flags_cw | path_flags_ccw);
00471     }
00472 
00473     //---------------------------------------------------------get_orientation
00474     inline unsigned get_orientation(unsigned c)
00475     {
00476         return c & (path_flags_cw | path_flags_ccw);
00477     }
00478 
00479     //---------------------------------------------------------set_orientation
00480     inline unsigned set_orientation(unsigned c, unsigned o)
00481     {
00482         return clear_orientation(c) | o;
00483     }
00484 
00485     //--------------------------------------------------------------point_base
00486     template<class T> struct point_base
00487     {
00488         typedef T value_type;
00489         T x,y;
00490         point_base() {}
00491         point_base(T x_, T y_) : x(x_), y(y_) {}
00492     };
00493     typedef point_base<int>    point_i; //-----point_i
00494     typedef point_base<float>  point_f; //-----point_f
00495     typedef point_base<double> point_d; //-----point_d
00496 
00497     //-------------------------------------------------------------vertex_base
00498     template<class T> struct vertex_base
00499     {
00500         typedef T value_type;
00501         T x,y;
00502         unsigned cmd;
00503         vertex_base() {}
00504         vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
00505     };
00506     typedef vertex_base<int>    vertex_i; //-----vertex_i
00507     typedef vertex_base<float>  vertex_f; //-----vertex_f
00508     typedef vertex_base<double> vertex_d; //-----vertex_d
00509 
00510     //----------------------------------------------------------------row_info
00511     template<class T> struct row_info
00512     {
00513         int x1, x2;
00514         T* ptr;
00515         row_info() {}
00516         row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
00517     };
00518 
00519     //----------------------------------------------------------const_row_info
00520     template<class T> struct const_row_info
00521     {
00522         int x1, x2;
00523         const T* ptr;
00524         const_row_info() {}
00525         const_row_info(int x1_, int x2_, const T* ptr_) : 
00526             x1(x1_), x2(x2_), ptr(ptr_) {}
00527     };
00528 
00529     //------------------------------------------------------------is_equal_eps
00530     template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
00531     {
00532         return fabs(v1 - v2) <= double(epsilon);
00533     }
00534 
00535 }
00536 
00537 
00538 #endif
00539 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines