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