Anti-Grain Geometry - AGG (libagg)
2.5
|
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