agg_scanline_p.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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. // Class scanline_p - a general purpose scanline container with packed spans.
  17. //
  18. //----------------------------------------------------------------------------
  19. //
  20. // Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
  21. // Liberty Technology Systems, Inc., visit http://lib-sys.com
  22. //
  23. // Liberty Technology Systems, Inc. is the provider of
  24. // PostScript and PDF technology for software developers.
  25. //
  26. //----------------------------------------------------------------------------
  27. #ifndef AGG_SCANLINE_P_INCLUDED
  28. #define AGG_SCANLINE_P_INCLUDED
  29. #include "agg_array.h"
  30. namespace agg
  31. {
  32. //=============================================================scanline_p8
  33. //
  34. // This is a general purpose scaline container which supports the interface
  35. // used in the rasterizer::render(). See description of scanline_u8
  36. // for details.
  37. //
  38. //------------------------------------------------------------------------
  39. class scanline_p8
  40. {
  41. public:
  42. typedef scanline_p8 self_type;
  43. typedef int8u cover_type;
  44. typedef int16 coord_type;
  45. //--------------------------------------------------------------------
  46. struct span
  47. {
  48. coord_type x;
  49. coord_type len; // If negative, it's a solid span, covers is valid
  50. const cover_type* covers;
  51. };
  52. typedef span* iterator;
  53. typedef const span* const_iterator;
  54. scanline_p8() :
  55. m_last_x(0x7FFFFFF0),
  56. m_covers(),
  57. m_cover_ptr(0),
  58. m_spans(),
  59. m_cur_span(0)
  60. {
  61. }
  62. //--------------------------------------------------------------------
  63. void reset(int min_x, int max_x)
  64. {
  65. unsigned max_len = max_x - min_x + 3;
  66. if(max_len > m_spans.size())
  67. {
  68. m_spans.resize(max_len);
  69. m_covers.resize(max_len);
  70. }
  71. m_last_x = 0x7FFFFFF0;
  72. m_cover_ptr = &m_covers[0];
  73. m_cur_span = &m_spans[0];
  74. m_cur_span->len = 0;
  75. }
  76. //--------------------------------------------------------------------
  77. void add_cell(int x, unsigned cover)
  78. {
  79. *m_cover_ptr = (cover_type)cover;
  80. if(x == m_last_x+1 && m_cur_span->len > 0)
  81. {
  82. m_cur_span->len++;
  83. }
  84. else
  85. {
  86. m_cur_span++;
  87. m_cur_span->covers = m_cover_ptr;
  88. m_cur_span->x = (int16)x;
  89. m_cur_span->len = 1;
  90. }
  91. m_last_x = x;
  92. m_cover_ptr++;
  93. }
  94. //--------------------------------------------------------------------
  95. void add_cells(int x, unsigned len, const cover_type* covers)
  96. {
  97. memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
  98. if(x == m_last_x+1 && m_cur_span->len > 0)
  99. {
  100. m_cur_span->len += (int16)len;
  101. }
  102. else
  103. {
  104. m_cur_span++;
  105. m_cur_span->covers = m_cover_ptr;
  106. m_cur_span->x = (int16)x;
  107. m_cur_span->len = (int16)len;
  108. }
  109. m_cover_ptr += len;
  110. m_last_x = x + len - 1;
  111. }
  112. //--------------------------------------------------------------------
  113. void add_span(int x, unsigned len, unsigned cover)
  114. {
  115. if(x == m_last_x+1 &&
  116. m_cur_span->len < 0 &&
  117. cover == *m_cur_span->covers)
  118. {
  119. m_cur_span->len -= (int16)len;
  120. }
  121. else
  122. {
  123. *m_cover_ptr = (cover_type)cover;
  124. m_cur_span++;
  125. m_cur_span->covers = m_cover_ptr++;
  126. m_cur_span->x = (int16)x;
  127. m_cur_span->len = (int16)(-int(len));
  128. }
  129. m_last_x = x + len - 1;
  130. }
  131. //--------------------------------------------------------------------
  132. void finalize(int y)
  133. {
  134. m_y = y;
  135. }
  136. //--------------------------------------------------------------------
  137. void reset_spans()
  138. {
  139. m_last_x = 0x7FFFFFF0;
  140. m_cover_ptr = &m_covers[0];
  141. m_cur_span = &m_spans[0];
  142. m_cur_span->len = 0;
  143. }
  144. //--------------------------------------------------------------------
  145. int y() const { return m_y; }
  146. unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
  147. const_iterator begin() const { return &m_spans[1]; }
  148. private:
  149. scanline_p8(const self_type&);
  150. const self_type& operator = (const self_type&);
  151. int m_last_x;
  152. int m_y;
  153. pod_array<cover_type> m_covers;
  154. cover_type* m_cover_ptr;
  155. pod_array<span> m_spans;
  156. span* m_cur_span;
  157. };
  158. //==========================================================scanline32_p8
  159. class scanline32_p8
  160. {
  161. public:
  162. typedef scanline32_p8 self_type;
  163. typedef int8u cover_type;
  164. typedef int32 coord_type;
  165. struct span
  166. {
  167. span() {}
  168. span(coord_type x_, coord_type len_, const cover_type* covers_) :
  169. x(x_), len(len_), covers(covers_) {}
  170. coord_type x;
  171. coord_type len; // If negative, it's a solid span, covers is valid
  172. const cover_type* covers;
  173. };
  174. typedef pod_bvector<span, 4> span_array_type;
  175. //--------------------------------------------------------------------
  176. class const_iterator
  177. {
  178. public:
  179. const_iterator(const span_array_type& spans) :
  180. m_spans(spans),
  181. m_span_idx(0)
  182. {}
  183. const span& operator*() const { return m_spans[m_span_idx]; }
  184. const span* operator->() const { return &m_spans[m_span_idx]; }
  185. void operator ++ () { ++m_span_idx; }
  186. private:
  187. const span_array_type& m_spans;
  188. unsigned m_span_idx;
  189. };
  190. //--------------------------------------------------------------------
  191. scanline32_p8() :
  192. m_max_len(0),
  193. m_last_x(0x7FFFFFF0),
  194. m_covers(),
  195. m_cover_ptr(0)
  196. {
  197. }
  198. //--------------------------------------------------------------------
  199. void reset(int min_x, int max_x)
  200. {
  201. unsigned max_len = max_x - min_x + 3;
  202. if(max_len > m_covers.size())
  203. {
  204. m_covers.resize(max_len);
  205. }
  206. m_last_x = 0x7FFFFFF0;
  207. m_cover_ptr = &m_covers[0];
  208. m_spans.remove_all();
  209. }
  210. //--------------------------------------------------------------------
  211. void add_cell(int x, unsigned cover)
  212. {
  213. *m_cover_ptr = cover_type(cover);
  214. if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
  215. {
  216. m_spans.last().len++;
  217. }
  218. else
  219. {
  220. m_spans.add(span(coord_type(x), 1, m_cover_ptr));
  221. }
  222. m_last_x = x;
  223. m_cover_ptr++;
  224. }
  225. //--------------------------------------------------------------------
  226. void add_cells(int x, unsigned len, const cover_type* covers)
  227. {
  228. memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
  229. if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
  230. {
  231. m_spans.last().len += coord_type(len);
  232. }
  233. else
  234. {
  235. m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
  236. }
  237. m_cover_ptr += len;
  238. m_last_x = x + len - 1;
  239. }
  240. //--------------------------------------------------------------------
  241. void add_span(int x, unsigned len, unsigned cover)
  242. {
  243. if(x == m_last_x+1 &&
  244. m_spans.size() &&
  245. m_spans.last().len < 0 &&
  246. cover == *m_spans.last().covers)
  247. {
  248. m_spans.last().len -= coord_type(len);
  249. }
  250. else
  251. {
  252. *m_cover_ptr = cover_type(cover);
  253. m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
  254. }
  255. m_last_x = x + len - 1;
  256. }
  257. //--------------------------------------------------------------------
  258. void finalize(int y)
  259. {
  260. m_y = y;
  261. }
  262. //--------------------------------------------------------------------
  263. void reset_spans()
  264. {
  265. m_last_x = 0x7FFFFFF0;
  266. m_cover_ptr = &m_covers[0];
  267. m_spans.remove_all();
  268. }
  269. //--------------------------------------------------------------------
  270. int y() const { return m_y; }
  271. unsigned num_spans() const { return m_spans.size(); }
  272. const_iterator begin() const { return const_iterator(m_spans); }
  273. private:
  274. scanline32_p8(const self_type&);
  275. const self_type& operator = (const self_type&);
  276. unsigned m_max_len;
  277. int m_last_x;
  278. int m_y;
  279. pod_array<cover_type> m_covers;
  280. cover_type* m_cover_ptr;
  281. span_array_type m_spans;
  282. };
  283. }
  284. #endif