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