Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 // 00025 // Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by 00026 // Liberty Technology Systems, Inc., visit http://lib-sys.com 00027 // 00028 // Liberty Technology Systems, Inc. is the provider of 00029 // PostScript and PDF technology for software developers. 00030 // 00031 //---------------------------------------------------------------------------- 00032 #ifndef AGG_SCANLINE_P_INCLUDED 00033 #define AGG_SCANLINE_P_INCLUDED 00034 00035 #include "agg_array.h" 00036 00037 namespace agg 00038 { 00039 00040 //=============================================================scanline_p8 00041 // 00042 // This is a general purpose scaline container which supports the interface 00043 // used in the rasterizer::render(). See description of scanline_u8 00044 // for details. 00045 // 00046 //------------------------------------------------------------------------ 00047 class scanline_p8 00048 { 00049 public: 00050 typedef scanline_p8 self_type; 00051 typedef int8u cover_type; 00052 typedef int16 coord_type; 00053 00054 //-------------------------------------------------------------------- 00055 struct span 00056 { 00057 coord_type x; 00058 coord_type len; // If negative, it's a solid span, covers is valid 00059 const cover_type* covers; 00060 }; 00061 00062 typedef span* iterator; 00063 typedef const span* const_iterator; 00064 00065 scanline_p8() : 00066 m_last_x(0x7FFFFFF0), 00067 m_covers(), 00068 m_cover_ptr(0), 00069 m_spans(), 00070 m_cur_span(0) 00071 { 00072 } 00073 00074 //-------------------------------------------------------------------- 00075 void reset(int min_x, int max_x) 00076 { 00077 unsigned max_len = max_x - min_x + 3; 00078 if(max_len > m_spans.size()) 00079 { 00080 m_spans.resize(max_len); 00081 m_covers.resize(max_len); 00082 } 00083 m_last_x = 0x7FFFFFF0; 00084 m_cover_ptr = &m_covers[0]; 00085 m_cur_span = &m_spans[0]; 00086 m_cur_span->len = 0; 00087 } 00088 00089 //-------------------------------------------------------------------- 00090 void add_cell(int x, unsigned cover) 00091 { 00092 *m_cover_ptr = (cover_type)cover; 00093 if(x == m_last_x+1 && m_cur_span->len > 0) 00094 { 00095 m_cur_span->len++; 00096 } 00097 else 00098 { 00099 m_cur_span++; 00100 m_cur_span->covers = m_cover_ptr; 00101 m_cur_span->x = (int16)x; 00102 m_cur_span->len = 1; 00103 } 00104 m_last_x = x; 00105 m_cover_ptr++; 00106 } 00107 00108 //-------------------------------------------------------------------- 00109 void add_cells(int x, unsigned len, const cover_type* covers) 00110 { 00111 memcpy(m_cover_ptr, covers, len * sizeof(cover_type)); 00112 if(x == m_last_x+1 && m_cur_span->len > 0) 00113 { 00114 m_cur_span->len += (int16)len; 00115 } 00116 else 00117 { 00118 m_cur_span++; 00119 m_cur_span->covers = m_cover_ptr; 00120 m_cur_span->x = (int16)x; 00121 m_cur_span->len = (int16)len; 00122 } 00123 m_cover_ptr += len; 00124 m_last_x = x + len - 1; 00125 } 00126 00127 //-------------------------------------------------------------------- 00128 void add_span(int x, unsigned len, unsigned cover) 00129 { 00130 if(x == m_last_x+1 && 00131 m_cur_span->len < 0 && 00132 cover == *m_cur_span->covers) 00133 { 00134 m_cur_span->len -= (int16)len; 00135 } 00136 else 00137 { 00138 *m_cover_ptr = (cover_type)cover; 00139 m_cur_span++; 00140 m_cur_span->covers = m_cover_ptr++; 00141 m_cur_span->x = (int16)x; 00142 m_cur_span->len = (int16)(-int(len)); 00143 } 00144 m_last_x = x + len - 1; 00145 } 00146 00147 //-------------------------------------------------------------------- 00148 void finalize(int y) 00149 { 00150 m_y = y; 00151 } 00152 00153 //-------------------------------------------------------------------- 00154 void reset_spans() 00155 { 00156 m_last_x = 0x7FFFFFF0; 00157 m_cover_ptr = &m_covers[0]; 00158 m_cur_span = &m_spans[0]; 00159 m_cur_span->len = 0; 00160 } 00161 00162 //-------------------------------------------------------------------- 00163 int y() const { return m_y; } 00164 unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } 00165 const_iterator begin() const { return &m_spans[1]; } 00166 00167 private: 00168 scanline_p8(const self_type&); 00169 const self_type& operator = (const self_type&); 00170 00171 int m_last_x; 00172 int m_y; 00173 pod_array<cover_type> m_covers; 00174 cover_type* m_cover_ptr; 00175 pod_array<span> m_spans; 00176 span* m_cur_span; 00177 }; 00178 00179 00180 00181 00182 00183 00184 00185 00186 //==========================================================scanline32_p8 00187 class scanline32_p8 00188 { 00189 public: 00190 typedef scanline32_p8 self_type; 00191 typedef int8u cover_type; 00192 typedef int32 coord_type; 00193 00194 struct span 00195 { 00196 span() {} 00197 span(coord_type x_, coord_type len_, const cover_type* covers_) : 00198 x(x_), len(len_), covers(covers_) {} 00199 00200 coord_type x; 00201 coord_type len; // If negative, it's a solid span, covers is valid 00202 const cover_type* covers; 00203 }; 00204 typedef pod_bvector<span, 4> span_array_type; 00205 00206 00207 //-------------------------------------------------------------------- 00208 class const_iterator 00209 { 00210 public: 00211 const_iterator(const span_array_type& spans) : 00212 m_spans(spans), 00213 m_span_idx(0) 00214 {} 00215 00216 const span& operator*() const { return m_spans[m_span_idx]; } 00217 const span* operator->() const { return &m_spans[m_span_idx]; } 00218 00219 void operator ++ () { ++m_span_idx; } 00220 00221 private: 00222 const span_array_type& m_spans; 00223 unsigned m_span_idx; 00224 }; 00225 00226 //-------------------------------------------------------------------- 00227 scanline32_p8() : 00228 m_max_len(0), 00229 m_last_x(0x7FFFFFF0), 00230 m_covers(), 00231 m_cover_ptr(0) 00232 { 00233 } 00234 00235 //-------------------------------------------------------------------- 00236 void reset(int min_x, int max_x) 00237 { 00238 unsigned max_len = max_x - min_x + 3; 00239 if(max_len > m_covers.size()) 00240 { 00241 m_covers.resize(max_len); 00242 } 00243 m_last_x = 0x7FFFFFF0; 00244 m_cover_ptr = &m_covers[0]; 00245 m_spans.remove_all(); 00246 } 00247 00248 //-------------------------------------------------------------------- 00249 void add_cell(int x, unsigned cover) 00250 { 00251 *m_cover_ptr = cover_type(cover); 00252 if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0) 00253 { 00254 m_spans.last().len++; 00255 } 00256 else 00257 { 00258 m_spans.add(span(coord_type(x), 1, m_cover_ptr)); 00259 } 00260 m_last_x = x; 00261 m_cover_ptr++; 00262 } 00263 00264 //-------------------------------------------------------------------- 00265 void add_cells(int x, unsigned len, const cover_type* covers) 00266 { 00267 memcpy(m_cover_ptr, covers, len * sizeof(cover_type)); 00268 if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0) 00269 { 00270 m_spans.last().len += coord_type(len); 00271 } 00272 else 00273 { 00274 m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr)); 00275 } 00276 m_cover_ptr += len; 00277 m_last_x = x + len - 1; 00278 } 00279 00280 //-------------------------------------------------------------------- 00281 void add_span(int x, unsigned len, unsigned cover) 00282 { 00283 if(x == m_last_x+1 && 00284 m_spans.size() && 00285 m_spans.last().len < 0 && 00286 cover == *m_spans.last().covers) 00287 { 00288 m_spans.last().len -= coord_type(len); 00289 } 00290 else 00291 { 00292 *m_cover_ptr = cover_type(cover); 00293 m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++)); 00294 } 00295 m_last_x = x + len - 1; 00296 } 00297 00298 //-------------------------------------------------------------------- 00299 void finalize(int y) 00300 { 00301 m_y = y; 00302 } 00303 00304 //-------------------------------------------------------------------- 00305 void reset_spans() 00306 { 00307 m_last_x = 0x7FFFFFF0; 00308 m_cover_ptr = &m_covers[0]; 00309 m_spans.remove_all(); 00310 } 00311 00312 //-------------------------------------------------------------------- 00313 int y() const { return m_y; } 00314 unsigned num_spans() const { return m_spans.size(); } 00315 const_iterator begin() const { return const_iterator(m_spans); } 00316 00317 private: 00318 scanline32_p8(const self_type&); 00319 const self_type& operator = (const self_type&); 00320 00321 unsigned m_max_len; 00322 int m_last_x; 00323 int m_y; 00324 pod_array<cover_type> m_covers; 00325 cover_type* m_cover_ptr; 00326 span_array_type m_spans; 00327 }; 00328 00329 00330 } 00331 00332 00333 #endif 00334