1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.2 3 // Copyright (C) 2002-2004 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_bin - binary scanline. 17 // 18 //---------------------------------------------------------------------------- 19 #ifndef AGG_SCANLINE_BIN_INCLUDED 20 #define AGG_SCANLINE_BIN_INCLUDED 21 22 #include "agg_basics.h" 23 24 namespace agg 25 { 26 27 //=============================================================scanline_bin 28 // 29 // This is binary scaline container which supports the interface 30 // used in the rasterizer::render(). See description of agg_scanline_u8 31 // for details. 32 // 33 // Rendering: 34 //------------------------------------------------------------------------- 35 // 36 // int y = sl.y(); 37 // 38 // ************************************ 39 // ...Perform vertical clipping here... 40 // ************************************ 41 // 42 // unsigned num_spans = sl.num_spans(); 43 // const agg::scanline_bin::span* cur_span = sl.spans(); 44 // 45 // do 46 // { 47 // x = cur_span->x; 48 // len = cur_span->len; 49 // 50 // ************************************** 51 // ...Perform horizontal clipping here... 52 // ************************************** 53 // 54 // hor_line(x, y, len) 55 // ++cur_span; 56 // } 57 // while(--num_spans); 58 // 59 //------------------------------------------------------------------------ 60 class scanline_bin 61 { 62 public: 63 struct span 64 { 65 int16 x; 66 int16 len; 67 }; 68 69 typedef const span* const_iterator; 70 71 ~scanline_bin() 72 { 73 delete [] m_spans; 74 } 75 76 scanline_bin() : 77 m_max_len(0), 78 m_last_x(0x7FFF), 79 m_spans(0), 80 m_cur_span(0) 81 { 82 } 83 84 void reset(int min_x, int max_x); 85 void add_cell(int x, unsigned); 86 void add_cells(int x, unsigned len, const void*); 87 void add_span(int x, unsigned len, unsigned); 88 void finalize(int y) { m_y = y; } 89 void reset_spans(); 90 91 int y() const { return m_y; } 92 unsigned num_spans() const { return unsigned(m_cur_span - m_spans); } 93 const_iterator begin() const { return m_spans + 1; } 94 95 private: 96 scanline_bin(const scanline_bin&); 97 const scanline_bin operator = (const scanline_bin&); 98 99 unsigned m_max_len; 100 int m_last_x; 101 int m_y; 102 span* m_spans; 103 span* m_cur_span; 104 }; 105 106 107 //------------------------------------------------------------------------ 108 inline void scanline_bin::reset(int min_x, int max_x) 109 { 110 unsigned max_len = max_x - min_x + 3; 111 if(max_len > m_max_len) 112 { 113 delete [] m_spans; 114 m_spans = new span [max_len]; 115 m_max_len = max_len; 116 } 117 m_last_x = 0x7FFF; 118 m_cur_span = m_spans; 119 } 120 121 122 //------------------------------------------------------------------------ 123 inline void scanline_bin::reset_spans() 124 { 125 m_last_x = 0x7FFF; 126 m_cur_span = m_spans; 127 } 128 129 130 //------------------------------------------------------------------------ 131 inline void scanline_bin::add_cell(int x, unsigned) 132 { 133 if(x == m_last_x+1) 134 { 135 m_cur_span->len++; 136 } 137 else 138 { 139 ++m_cur_span; 140 m_cur_span->x = (int16)x; 141 m_cur_span->len = 1; 142 } 143 m_last_x = x; 144 } 145 146 147 //------------------------------------------------------------------------ 148 inline void scanline_bin::add_span(int x, unsigned len, unsigned) 149 { 150 if(x == m_last_x+1) 151 { 152 m_cur_span->len = (int16)(m_cur_span->len + len); 153 } 154 else 155 { 156 ++m_cur_span; 157 m_cur_span->x = (int16)x; 158 m_cur_span->len = (int16)len; 159 } 160 m_last_x = x + len - 1; 161 } 162 163 //------------------------------------------------------------------------ 164 inline void scanline_bin::add_cells(int x, unsigned len, const void*) 165 { 166 add_span(x, len, 0); 167 } 168 } 169 170 171 #endif 172