btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / agg / agg_basics.h
blob309713002b37c58f8461fff27b533c95192bb766
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 //----------------------------------------------------------------------------
16 #ifndef AGG_BASICS_INCLUDED
17 #define AGG_BASICS_INCLUDED
19 #include <math.h>
20 #include "agg_config.h"
22 //---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
23 #ifdef AGG_CUSTOM_ALLOCATOR
24 #include "agg_allocator.h"
25 #else
26 namespace agg
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
38 static T* allocate(unsigned num) { return new T [num]; }
39 static void deallocate(T* ptr, unsigned) { delete [] ptr; }
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
52 static T* allocate() { return new T; }
53 static void deallocate(T* ptr) { delete ptr; }
56 #endif
59 //-------------------------------------------------------- Default basic types
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.
65 #ifndef AGG_INT8
66 #define AGG_INT8 signed char
67 #endif
69 #ifndef AGG_INT8U
70 #define AGG_INT8U unsigned char
71 #endif
73 #ifndef AGG_INT16
74 #define AGG_INT16 short
75 #endif
77 #ifndef AGG_INT16U
78 #define AGG_INT16U unsigned short
79 #endif
81 #ifndef AGG_INT32
82 #define AGG_INT32 int
83 #endif
85 #ifndef AGG_INT32U
86 #define AGG_INT32U unsigned
87 #endif
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
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
105 //------------------------------------------------ Some fixes for MS Visual C++
106 #if defined(_MSC_VER)
107 #pragma warning(disable:4786) // Identifier was truncated...
108 #endif
110 #if defined(_MSC_VER)
111 #define AGG_INLINE __forceinline
112 #else
113 #define AGG_INLINE inline
114 #endif
116 namespace agg
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
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
133 int t;
134 __asm fld qword ptr [v]
135 __asm fistp dword ptr [t]
136 __asm mov eax, dword ptr [t]
138 AGG_INLINE unsigned uround(double v) //-------uround
140 unsigned t;
141 __asm fld qword ptr [v]
142 __asm fistp dword ptr [t]
143 __asm mov eax, dword ptr [t]
145 #pragma warning(pop)
146 AGG_INLINE int ifloor(double v)
148 return int(floor(v));
150 AGG_INLINE unsigned ufloor(double v) //-------ufloor
152 return unsigned(floor(v));
154 AGG_INLINE int iceil(double v)
156 return int(ceil(v));
158 AGG_INLINE unsigned uceil(double v) //--------uceil
160 return unsigned(ceil(v));
162 #elif defined(AGG_QIFIST)
163 AGG_INLINE int iround(double v)
165 return int(v);
167 AGG_INLINE int uround(double v)
169 return unsigned(v);
171 AGG_INLINE int ifloor(double v)
173 return int(floor(v));
175 AGG_INLINE unsigned ufloor(double v)
177 return unsigned(floor(v));
179 AGG_INLINE int iceil(double v)
181 return int(ceil(v));
183 AGG_INLINE unsigned uceil(double v)
185 return unsigned(ceil(v));
187 #else
188 AGG_INLINE int iround(double v)
190 return int((v < 0.0) ? v - 0.5 : v + 0.5);
192 AGG_INLINE int uround(double v)
194 return unsigned(v + 0.5);
196 AGG_INLINE int ifloor(double v)
198 int i = int(v);
199 return i - (i > v);
201 AGG_INLINE unsigned ufloor(double v)
203 return unsigned(v);
205 AGG_INLINE int iceil(double v)
207 return int(ceil(v));
209 AGG_INLINE unsigned uceil(double v)
211 return unsigned(ceil(v));
213 #endif
215 //---------------------------------------------------------------saturation
216 template<int Limit> struct saturation
218 AGG_INLINE static int iround(double v)
220 if(v < double(-Limit)) return -Limit;
221 if(v > double( Limit)) return Limit;
222 return agg::iround(v);
226 //------------------------------------------------------------------mul_one
227 template<unsigned Shift> struct mul_one
229 AGG_INLINE static unsigned mul(unsigned a, unsigned b)
231 unsigned q = a * b + (1 << (Shift-1));
232 return (q + (q >> Shift)) >> Shift;
236 //-------------------------------------------------------------------------
237 typedef unsigned char cover_type; //----cover_type
238 enum cover_scale_e
240 cover_shift = 8, //----cover_shift
241 cover_size = 1 << cover_shift, //----cover_size
242 cover_mask = cover_size - 1, //----cover_mask
243 cover_none = 0, //----cover_none
244 cover_full = cover_mask //----cover_full
247 //----------------------------------------------------poly_subpixel_scale_e
248 // These constants determine the subpixel accuracy, to be more precise,
249 // the number of bits of the fractional part of the coordinates.
250 // The possible coordinate capacity in bits can be calculated by formula:
251 // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
252 // 8-bits fractional part the capacity is 24 bits.
253 enum poly_subpixel_scale_e
255 poly_subpixel_shift = 8, //----poly_subpixel_shift
256 poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
257 poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask
260 //----------------------------------------------------------filling_rule_e
261 enum filling_rule_e
263 fill_non_zero,
264 fill_even_odd
267 //-----------------------------------------------------------------------pi
268 const double pi = 3.14159265358979323846;
270 //------------------------------------------------------------------deg2rad
271 inline double deg2rad(double deg)
273 return deg * pi / 180.0;
276 //------------------------------------------------------------------rad2deg
277 inline double rad2deg(double rad)
279 return rad * 180.0 / pi;
282 //----------------------------------------------------------------rect_base
283 template<class T> struct rect_base
285 typedef T value_type;
286 typedef rect_base<T> self_type;
287 T x1, y1, x2, y2;
289 rect_base() {}
290 rect_base(T x1_, T y1_, T x2_, T y2_) :
291 x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
293 void init(T x1_, T y1_, T x2_, T y2_)
295 x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_;
298 const self_type& normalize()
300 T t;
301 if(x1 > x2) { t = x1; x1 = x2; x2 = t; }
302 if(y1 > y2) { t = y1; y1 = y2; y2 = t; }
303 return *this;
306 bool clip(const self_type& r)
308 if(x2 > r.x2) x2 = r.x2;
309 if(y2 > r.y2) y2 = r.y2;
310 if(x1 < r.x1) x1 = r.x1;
311 if(y1 < r.y1) y1 = r.y1;
312 return x1 <= x2 && y1 <= y2;
315 bool is_valid() const
317 return x1 <= x2 && y1 <= y2;
320 bool hit_test(T x, T y) const
322 return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
325 bool overlaps(const self_type& r) const
327 return !(r.x1 > x2 || r.x2 < x1
328 || r.y1 > y2 || r.y2 < y1);
332 //-----------------------------------------------------intersect_rectangles
333 template<class Rect>
334 inline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
336 Rect r = r1;
338 // First process x2,y2 because the other order
339 // results in Internal Compiler Error under
340 // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in
341 // case of "Maximize Speed" optimization option.
342 //-----------------
343 if(r.x2 > r2.x2) r.x2 = r2.x2;
344 if(r.y2 > r2.y2) r.y2 = r2.y2;
345 if(r.x1 < r2.x1) r.x1 = r2.x1;
346 if(r.y1 < r2.y1) r.y1 = r2.y1;
347 return r;
351 //---------------------------------------------------------unite_rectangles
352 template<class Rect>
353 inline Rect unite_rectangles(const Rect& r1, const Rect& r2)
355 Rect r = r1;
356 if(r.x2 < r2.x2) r.x2 = r2.x2;
357 if(r.y2 < r2.y2) r.y2 = r2.y2;
358 if(r.x1 > r2.x1) r.x1 = r2.x1;
359 if(r.y1 > r2.y1) r.y1 = r2.y1;
360 return r;
363 typedef rect_base<int> rect_i; //----rect_i
364 typedef rect_base<float> rect_f; //----rect_f
365 typedef rect_base<double> rect_d; //----rect_d
367 //---------------------------------------------------------path_commands_e
368 enum path_commands_e
370 path_cmd_stop = 0, //----path_cmd_stop
371 path_cmd_move_to = 1, //----path_cmd_move_to
372 path_cmd_line_to = 2, //----path_cmd_line_to
373 path_cmd_curve3 = 3, //----path_cmd_curve3
374 path_cmd_curve4 = 4, //----path_cmd_curve4
375 path_cmd_curveN = 5, //----path_cmd_curveN
376 path_cmd_catrom = 6, //----path_cmd_catrom
377 path_cmd_ubspline = 7, //----path_cmd_ubspline
378 path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
379 path_cmd_mask = 0x0F //----path_cmd_mask
382 //------------------------------------------------------------path_flags_e
383 enum path_flags_e
385 path_flags_none = 0, //----path_flags_none
386 path_flags_ccw = 0x10, //----path_flags_ccw
387 path_flags_cw = 0x20, //----path_flags_cw
388 path_flags_close = 0x40, //----path_flags_close
389 path_flags_mask = 0xF0 //----path_flags_mask
392 //---------------------------------------------------------------is_vertex
393 inline bool is_vertex(unsigned c)
395 return c >= path_cmd_move_to && c < path_cmd_end_poly;
398 //--------------------------------------------------------------is_drawing
399 inline bool is_drawing(unsigned c)
401 return c >= path_cmd_line_to && c < path_cmd_end_poly;
404 //-----------------------------------------------------------------is_stop
405 inline bool is_stop(unsigned c)
407 return c == path_cmd_stop;
410 //--------------------------------------------------------------is_move_to
411 inline bool is_move_to(unsigned c)
413 return c == path_cmd_move_to;
416 //--------------------------------------------------------------is_line_to
417 inline bool is_line_to(unsigned c)
419 return c == path_cmd_line_to;
422 //----------------------------------------------------------------is_curve
423 inline bool is_curve(unsigned c)
425 return c == path_cmd_curve3 || c == path_cmd_curve4;
428 //---------------------------------------------------------------is_curve3
429 inline bool is_curve3(unsigned c)
431 return c == path_cmd_curve3;
434 //---------------------------------------------------------------is_curve4
435 inline bool is_curve4(unsigned c)
437 return c == path_cmd_curve4;
440 //-------------------------------------------------------------is_end_poly
441 inline bool is_end_poly(unsigned c)
443 return (c & path_cmd_mask) == path_cmd_end_poly;
446 //----------------------------------------------------------------is_close
447 inline bool is_close(unsigned c)
449 return (c & ~(path_flags_cw | path_flags_ccw)) ==
450 (path_cmd_end_poly | path_flags_close);
453 //------------------------------------------------------------is_next_poly
454 inline bool is_next_poly(unsigned c)
456 return is_stop(c) || is_move_to(c) || is_end_poly(c);
459 //-------------------------------------------------------------------is_cw
460 inline bool is_cw(unsigned c)
462 return (c & path_flags_cw) != 0;
465 //------------------------------------------------------------------is_ccw
466 inline bool is_ccw(unsigned c)
468 return (c & path_flags_ccw) != 0;
471 //-------------------------------------------------------------is_oriented
472 inline bool is_oriented(unsigned c)
474 return (c & (path_flags_cw | path_flags_ccw)) != 0;
477 //---------------------------------------------------------------is_closed
478 inline bool is_closed(unsigned c)
480 return (c & path_flags_close) != 0;
483 //----------------------------------------------------------get_close_flag
484 inline unsigned get_close_flag(unsigned c)
486 return c & path_flags_close;
489 //-------------------------------------------------------clear_orientation
490 inline unsigned clear_orientation(unsigned c)
492 return c & ~(path_flags_cw | path_flags_ccw);
495 //---------------------------------------------------------get_orientation
496 inline unsigned get_orientation(unsigned c)
498 return c & (path_flags_cw | path_flags_ccw);
501 //---------------------------------------------------------set_orientation
502 inline unsigned set_orientation(unsigned c, unsigned o)
504 return clear_orientation(c) | o;
507 //--------------------------------------------------------------point_base
508 template<class T> struct point_base
510 typedef T value_type;
511 T x,y;
512 point_base() {}
513 point_base(T x_, T y_) : x(x_), y(y_) {}
515 typedef point_base<int> point_i; //-----point_i
516 typedef point_base<float> point_f; //-----point_f
517 typedef point_base<double> point_d; //-----point_d
519 //-------------------------------------------------------------vertex_base
520 template<class T> struct vertex_base
522 typedef T value_type;
523 T x,y;
524 unsigned cmd;
525 vertex_base() {}
526 vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
528 typedef vertex_base<int> vertex_i; //-----vertex_i
529 typedef vertex_base<float> vertex_f; //-----vertex_f
530 typedef vertex_base<double> vertex_d; //-----vertex_d
532 //----------------------------------------------------------------row_info
533 template<class T> struct row_info
535 int x1, x2;
536 T* ptr;
537 row_info() {}
538 row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
541 //----------------------------------------------------------const_row_info
542 template<class T> struct const_row_info
544 int x1, x2;
545 const T* ptr;
546 const_row_info() {}
547 const_row_info(int x1_, int x2_, const T* ptr_) :
548 x1(x1_), x2(x2_), ptr(ptr_) {}
551 //------------------------------------------------------------is_equal_eps
552 template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
554 return fabs(v1 - v2) <= double(epsilon);
559 #endif