agg_basics.h 17 KB

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