1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 16 #ifndef AGG_BASICS_INCLUDED 17 #define AGG_BASICS_INCLUDED 18 19 #include <math.h> 20 #include "agg_config.h" 21 22 //---------------------------------------------------------AGG_CUSTOM_ALLOCATOR 23 #ifdef AGG_CUSTOM_ALLOCATOR 24 #include "agg_allocator.h" 25 #else 26 namespace agg 27 { 28 // The policy of all AGG containers and memory allocation strategy 29 // in general is that no allocated data requires explicit construction. 30 // It means that the allocator can be really simple; you can even 31 // replace new/delete to malloc/free. The constructors and destructors 32 // won't be called in this case, however everything will remain working. 33 // The second argument of deallocate() is the size of the allocated 34 // block. You can use this information if you wish. 35 //------------------------------------------------------------pod_allocator 36 template<class T> struct pod_allocator 37 { 38 static T* allocate(unsigned num) { return new T [num]; } 39 static void deallocate(T* ptr, unsigned) { delete [] ptr; } 40 }; 41 42 // Single object allocator. It's also can be replaced with your custom 43 // allocator. The difference is that it can only allocate a single 44 // object and the constructor and destructor must be called. 45 // In AGG there is no need to allocate an array of objects with 46 // calling their constructors (only single ones). So that, if you 47 // replace these new/delete to malloc/free make sure that the in-place 48 // new is called and take care of calling the destructor too. 49 //------------------------------------------------------------obj_allocator 50 template<class T> struct obj_allocator 51 { 52 static T* allocate() { return new T; } 53 static void deallocate(T* ptr) { delete ptr; } 54 }; 55 } 56 #endif 57 58 59 //-------------------------------------------------------- Default basic types 60 // 61 // If the compiler has different capacity of the basic types you can redefine 62 // them via the compiler command line or by generating agg_config.h that is 63 // empty by default. 64 // 65 #ifndef AGG_INT8 66 #define AGG_INT8 signed char 67 #endif 68 69 #ifndef AGG_INT8U 70 #define AGG_INT8U unsigned char 71 #endif 72 73 #ifndef AGG_INT16 74 #define AGG_INT16 short 75 #endif 76 77 #ifndef AGG_INT16U 78 #define AGG_INT16U unsigned short 79 #endif 80 81 #ifndef AGG_INT32 82 #define AGG_INT32 int 83 #endif 84 85 #ifndef AGG_INT32U 86 #define AGG_INT32U unsigned 87 #endif 88 89 #ifndef AGG_INT64 90 #if defined(_MSC_VER) || defined(__BORLANDC__) 91 #define AGG_INT64 signed __int64 92 #else 93 #define AGG_INT64 signed long long 94 #endif 95 #endif 96 97 #ifndef AGG_INT64U 98 #if defined(_MSC_VER) || defined(__BORLANDC__) 99 #define AGG_INT64U unsigned __int64 100 #else 101 #define AGG_INT64U unsigned long long 102 #endif 103 #endif 104 105 //------------------------------------------------ Some fixes for MS Visual C++ 106 #if defined(_MSC_VER) 107 #pragma warning(disable:4786) // Identifier was truncated... 108 #endif 109 110 #if defined(_MSC_VER) 111 #define AGG_INLINE __forceinline 112 #else 113 #define AGG_INLINE inline 114 #endif 115 116 namespace agg 117 { 118 //------------------------------------------------------------------------- 119 typedef AGG_INT8 int8; //----int8 120 typedef AGG_INT8U int8u; //----int8u 121 typedef AGG_INT16 int16; //----int16 122 typedef AGG_INT16U int16u; //----int16u 123 typedef AGG_INT32 int32; //----int32 124 typedef AGG_INT32U int32u; //----int32u 125 typedef AGG_INT64 int64; //----int64 126 typedef AGG_INT64U int64u; //----int64u 127 128 #if defined(AGG_FISTP) 129 #pragma warning(push) 130 #pragma warning(disable : 4035) //Disable warning "no return value" 131 AGG_INLINE int iround(double v) //-------iround 132 { 133 int t; 134 __asm fld qword ptr [v] 135 __asm fistp dword ptr [t] 136 __asm mov eax, dword ptr [t] 137 } 138 AGG_INLINE unsigned uround(double v) //-------uround 139 { 140 unsigned t; 141 __asm fld qword ptr [v] 142 __asm fistp dword ptr [t] 143 __asm mov eax, dword ptr [t] 144 } 145 #pragma warning(pop) 146 AGG_INLINE unsigned ufloor(double v) //-------ufloor 147 { 148 return unsigned(floor(v)); 149 } 150 AGG_INLINE unsigned uceil(double v) //--------uceil 151 { 152 return unsigned(ceil(v)); 153 } 154 #elif defined(AGG_QIFIST) 155 AGG_INLINE int iround(double v) 156 { 157 return int(v); 158 } 159 AGG_INLINE int uround(double v) 160 { 161 return unsigned(v); 162 } 163 AGG_INLINE unsigned ufloor(double v) 164 { 165 return unsigned(floor(v)); 166 } 167 AGG_INLINE unsigned uceil(double v) 168 { 169 return unsigned(ceil(v)); 170 } 171 #else 172 AGG_INLINE int iround(double v) 173 { 174 return int((v < 0.0) ? v - 0.5 : v + 0.5); 175 } 176 AGG_INLINE int uround(double v) 177 { 178 return unsigned(v + 0.5); 179 } 180 AGG_INLINE unsigned ufloor(double v) 181 { 182 return unsigned(v); 183 } 184 AGG_INLINE unsigned uceil(double v) 185 { 186 return unsigned(ceil(v)); 187 } 188 #endif 189 190 //---------------------------------------------------------------saturation 191 template<int Limit> struct saturation 192 { 193 AGG_INLINE static int iround(double v) 194 { 195 if(v < double(-Limit)) return -Limit; 196 if(v > double( Limit)) return Limit; 197 return agg::iround(v); 198 } 199 }; 200 201 //------------------------------------------------------------------mul_one 202 template<unsigned Shift> struct mul_one 203 { 204 AGG_INLINE static unsigned mul(unsigned a, unsigned b) 205 { 206 register unsigned q = a * b + (1 << (Shift-1)); 207 return (q + (q >> Shift)) >> Shift; 208 } 209 }; 210 211 //------------------------------------------------------------------------- 212 typedef unsigned char cover_type; //----cover_type 213 enum cover_scale_e 214 { 215 cover_shift = 8, //----cover_shift 216 cover_size = 1 << cover_shift, //----cover_size 217 cover_mask = cover_size - 1, //----cover_mask 218 cover_none = 0, //----cover_none 219 cover_full = cover_mask //----cover_full 220 }; 221 222 //----------------------------------------------------poly_subpixel_scale_e 223 // These constants determine the subpixel accuracy, to be more precise, 224 // the number of bits of the fractional part of the coordinates. 225 // The possible coordinate capacity in bits can be calculated by formula: 226 // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and 227 // 8-bits fractional part the capacity is 24 bits. 228 enum poly_subpixel_scale_e 229 { 230 poly_subpixel_shift = 8, //----poly_subpixel_shift 231 poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale 232 poly_subpixel_mask = poly_subpixel_scale-1, //----poly_subpixel_mask 233 }; 234 235 //----------------------------------------------------------filling_rule_e 236 enum filling_rule_e 237 { 238 fill_non_zero, 239 fill_even_odd 240 }; 241 242 //-----------------------------------------------------------------------pi 243 const double pi = 3.14159265358979323846; 244 245 //------------------------------------------------------------------deg2rad 246 inline double deg2rad(double deg) 247 { 248 return deg * pi / 180.0; 249 } 250 251 //------------------------------------------------------------------rad2deg 252 inline double rad2deg(double rad) 253 { 254 return rad * 180.0 / pi; 255 } 256 257 //----------------------------------------------------------------rect_base 258 template<class T> struct rect_base 259 { 260 typedef rect_base<T> self_type; 261 T x1; 262 T y1; 263 T x2; 264 T y2; 265 266 rect_base() {} 267 rect_base(T x1_, T y1_, T x2_, T y2_) : 268 x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} 269 270 const self_type& normalize() 271 { 272 T t; 273 if(x1 > x2) { t = x1; x1 = x2; x2 = t; } 274 if(y1 > y2) { t = y1; y1 = y2; y2 = t; } 275 return *this; 276 } 277 278 bool clip(const self_type& r) 279 { 280 if(x2 > r.x2) x2 = r.x2; 281 if(y2 > r.y2) y2 = r.y2; 282 if(x1 < r.x1) x1 = r.x1; 283 if(y1 < r.y1) y1 = r.y1; 284 return x1 <= x2 && y1 <= y2; 285 } 286 287 bool is_valid() const 288 { 289 return x1 <= x2 && y1 <= y2; 290 } 291 }; 292 293 //-----------------------------------------------------intersect_rectangles 294 template<class Rect> 295 inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) 296 { 297 Rect r = r1; 298 299 // First process x2,y2 because the other order 300 // results in Internal Compiler Error under 301 // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in 302 // case of "Maximize Speed" optimization option. 303 //----------------- 304 if(r.x2 > r2.x2) r.x2 = r2.x2; 305 if(r.y2 > r2.y2) r.y2 = r2.y2; 306 if(r.x1 < r2.x1) r.x1 = r2.x1; 307 if(r.y1 < r2.y1) r.y1 = r2.y1; 308 return r; 309 } 310 311 312 //---------------------------------------------------------unite_rectangles 313 template<class Rect> 314 inline Rect unite_rectangles(const Rect& r1, const Rect& r2) 315 { 316 Rect r = r1; 317 if(r.x2 < r2.x2) r.x2 = r2.x2; 318 if(r.y2 < r2.y2) r.y2 = r2.y2; 319 if(r.x1 > r2.x1) r.x1 = r2.x1; 320 if(r.y1 > r2.y1) r.y1 = r2.y1; 321 return r; 322 } 323 324 typedef rect_base<int> rect_i; //----rect_i 325 typedef rect_base<float> rect_f; //----rect_f 326 typedef rect_base<double> rect_d; //----rect_d 327 328 //---------------------------------------------------------path_commands_e 329 enum path_commands_e 330 { 331 path_cmd_stop = 0, //----path_cmd_stop 332 path_cmd_move_to = 1, //----path_cmd_move_to 333 path_cmd_line_to = 2, //----path_cmd_line_to 334 path_cmd_curve3 = 3, //----path_cmd_curve3 335 path_cmd_curve4 = 4, //----path_cmd_curve4 336 path_cmd_curveN = 5, //----path_cmd_curveN 337 path_cmd_catrom = 6, //----path_cmd_catrom 338 path_cmd_ubspline = 7, //----path_cmd_ubspline 339 path_cmd_end_poly = 0x0F, //----path_cmd_end_poly 340 path_cmd_mask = 0x0F //----path_cmd_mask 341 }; 342 343 //------------------------------------------------------------path_flags_e 344 enum path_flags_e 345 { 346 path_flags_none = 0, //----path_flags_none 347 path_flags_ccw = 0x10, //----path_flags_ccw 348 path_flags_cw = 0x20, //----path_flags_cw 349 path_flags_close = 0x40, //----path_flags_close 350 path_flags_mask = 0xF0 //----path_flags_mask 351 }; 352 353 //---------------------------------------------------------------is_vertex 354 inline bool is_vertex(unsigned c) 355 { 356 return c >= path_cmd_move_to && c < path_cmd_end_poly; 357 } 358 359 //--------------------------------------------------------------is_drawing 360 inline bool is_drawing(unsigned c) 361 { 362 return c >= path_cmd_line_to && c < path_cmd_end_poly; 363 } 364 365 //-----------------------------------------------------------------is_stop 366 inline bool is_stop(unsigned c) 367 { 368 return c == path_cmd_stop; 369 } 370 371 //--------------------------------------------------------------is_move_to 372 inline bool is_move_to(unsigned c) 373 { 374 return c == path_cmd_move_to; 375 } 376 377 //--------------------------------------------------------------is_line_to 378 inline bool is_line_to(unsigned c) 379 { 380 return c == path_cmd_line_to; 381 } 382 383 //----------------------------------------------------------------is_curve 384 inline bool is_curve(unsigned c) 385 { 386 return c == path_cmd_curve3 || c == path_cmd_curve4; 387 } 388 389 //---------------------------------------------------------------is_curve3 390 inline bool is_curve3(unsigned c) 391 { 392 return c == path_cmd_curve3; 393 } 394 395 //---------------------------------------------------------------is_curve4 396 inline bool is_curve4(unsigned c) 397 { 398 return c == path_cmd_curve4; 399 } 400 401 //-------------------------------------------------------------is_end_poly 402 inline bool is_end_poly(unsigned c) 403 { 404 return (c & path_cmd_mask) == path_cmd_end_poly; 405 } 406 407 //----------------------------------------------------------------is_close 408 inline bool is_close(unsigned c) 409 { 410 return (c & ~(path_flags_cw | path_flags_ccw)) == 411 (path_cmd_end_poly | path_flags_close); 412 } 413 414 //------------------------------------------------------------is_next_poly 415 inline bool is_next_poly(unsigned c) 416 { 417 return is_stop(c) || is_move_to(c) || is_end_poly(c); 418 } 419 420 //-------------------------------------------------------------------is_cw 421 inline bool is_cw(unsigned c) 422 { 423 return (c & path_flags_cw) != 0; 424 } 425 426 //------------------------------------------------------------------is_ccw 427 inline bool is_ccw(unsigned c) 428 { 429 return (c & path_flags_ccw) != 0; 430 } 431 432 //-------------------------------------------------------------is_oriented 433 inline bool is_oriented(unsigned c) 434 { 435 return (c & (path_flags_cw | path_flags_ccw)) != 0; 436 } 437 438 //---------------------------------------------------------------is_closed 439 inline bool is_closed(unsigned c) 440 { 441 return (c & path_flags_close) != 0; 442 } 443 444 //----------------------------------------------------------get_close_flag 445 inline unsigned get_close_flag(unsigned c) 446 { 447 return c & path_flags_close; 448 } 449 450 //-------------------------------------------------------clear_orientation 451 inline unsigned clear_orientation(unsigned c) 452 { 453 return c & ~(path_flags_cw | path_flags_ccw); 454 } 455 456 //---------------------------------------------------------get_orientation 457 inline unsigned get_orientation(unsigned c) 458 { 459 return c & (path_flags_cw | path_flags_ccw); 460 } 461 462 //---------------------------------------------------------set_orientation 463 inline unsigned set_orientation(unsigned c, unsigned o) 464 { 465 return clear_orientation(c) | o; 466 } 467 468 //--------------------------------------------------------------point_base 469 template<class T> struct point_base 470 { 471 typedef T value_type; 472 T x,y; 473 point_base() {} 474 point_base(T x_, T y_) : x(x_), y(y_) {} 475 }; 476 typedef point_base<int> point_i; //-----point_i 477 typedef point_base<float> point_f; //-----point_f 478 typedef point_base<double> point_d; //-----point_d 479 480 //-------------------------------------------------------------vertex_base 481 template<class T> struct vertex_base 482 { 483 typedef T value_type; 484 T x,y; 485 unsigned cmd; 486 vertex_base() {} 487 vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {} 488 }; 489 typedef vertex_base<int> vertex_i; //-----vertex_i 490 typedef vertex_base<float> vertex_f; //-----vertex_f 491 typedef vertex_base<double> vertex_d; //-----vertex_d 492 493 } 494 495 496 #endif 497 498