00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef AGG_SCANLINE_U_INCLUDED
00017 #define AGG_SCANLINE_U_INCLUDED
00018
00019 #include <string.h>
00020 #include "agg_basics.h"
00021
00022 namespace agg
00023 {
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 template<class T> class scanline_u
00103 {
00104 public:
00105 typedef T cover_type;
00106
00107
00108 struct span
00109 {
00110 int16 x;
00111 int16 len;
00112 cover_type* covers;
00113 };
00114
00115 typedef span* iterator;
00116 typedef const span* const_iterator;
00117
00118
00119 ~scanline_u();
00120 scanline_u();
00121
00122 void reset(int min_x, int max_x);
00123 void add_cell(int x, unsigned cover);
00124 void add_cells(int x, unsigned len, const T* covers);
00125 void add_span(int x, unsigned len, unsigned cover);
00126 void finalize(int y) { m_y = y; }
00127 void reset_spans();
00128
00129 int y() const { return m_y; }
00130 unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
00131 const_iterator begin() const { return m_spans + 1; }
00132 iterator begin() { return m_spans + 1; }
00133
00134 private:
00135 scanline_u<T>(const scanline_u<T>&);
00136 const scanline_u<T>& operator = (const scanline_u<T>&);
00137
00138 private:
00139 int m_min_x;
00140 unsigned m_max_len;
00141 int m_last_x;
00142 int m_y;
00143 cover_type* m_covers;
00144 span* m_spans;
00145 span* m_cur_span;
00146 };
00147
00148
00149
00150
00151 template<class T> scanline_u<T>::~scanline_u()
00152 {
00153 delete [] m_spans;
00154 delete [] m_covers;
00155 }
00156
00157
00158
00159 template<class T> scanline_u<T>::scanline_u() :
00160 m_min_x(0),
00161 m_max_len(0),
00162 m_last_x(0x7FFFFFF0),
00163 m_covers(0),
00164 m_spans(0),
00165 m_cur_span(0)
00166 {
00167 }
00168
00169
00170
00171 template<class T> void scanline_u<T>::reset(int min_x, int max_x)
00172 {
00173 unsigned max_len = max_x - min_x + 2;
00174 if(max_len > m_max_len)
00175 {
00176 delete [] m_spans;
00177 delete [] m_covers;
00178 m_covers = new cover_type [max_len];
00179 m_spans = new span [max_len];
00180 m_max_len = max_len;
00181 }
00182 m_last_x = 0x7FFFFFF0;
00183 m_min_x = min_x;
00184 m_cur_span = m_spans;
00185 }
00186
00187
00188
00189 template<class T> inline void scanline_u<T>::reset_spans()
00190 {
00191 m_last_x = 0x7FFFFFF0;
00192 m_cur_span = m_spans;
00193 }
00194
00195
00196
00197 template<class T> inline void scanline_u<T>::add_cell(int x, unsigned cover)
00198 {
00199 x -= m_min_x;
00200 m_covers[x] = (unsigned char)cover;
00201 if(x == m_last_x+1)
00202 {
00203 m_cur_span->len++;
00204 }
00205 else
00206 {
00207 m_cur_span++;
00208 m_cur_span->x = (int16)(x + m_min_x);
00209 m_cur_span->len = 1;
00210 m_cur_span->covers = m_covers + x;
00211 }
00212 m_last_x = x;
00213 }
00214
00215
00216
00217 template<class T> void scanline_u<T>::add_cells(int x, unsigned len, const T* covers)
00218 {
00219 x -= m_min_x;
00220 memcpy(m_covers + x, covers, len * sizeof(T));
00221 if(x == m_last_x+1)
00222 {
00223 m_cur_span->len += (int16)len;
00224 }
00225 else
00226 {
00227 m_cur_span++;
00228 m_cur_span->x = (int16)(x + m_min_x);
00229 m_cur_span->len = (int16)len;
00230 m_cur_span->covers = m_covers + x;
00231 }
00232 m_last_x = x + len - 1;
00233 }
00234
00235
00236
00237 template<class T> void scanline_u<T>::add_span(int x, unsigned len, unsigned cover)
00238 {
00239 x -= m_min_x;
00240 memset(m_covers + x, cover, len);
00241 if(x == m_last_x+1)
00242 {
00243 m_cur_span->len += (int16)len;
00244 }
00245 else
00246 {
00247 m_cur_span++;
00248 m_cur_span->x = (int16)(x + m_min_x);
00249 m_cur_span->len = (int16)len;
00250 m_cur_span->covers = m_covers + x;
00251 }
00252 m_last_x = x + len - 1;
00253 }
00254
00255
00256
00257 typedef scanline_u<int8u> scanline_u8;
00258
00259
00260 typedef scanline_u<int16u> scanline_u16;
00261
00262
00263 typedef scanline_u<int32u> scanline_u32;
00264
00265
00266
00267
00268
00269
00270
00271 template<class AlphaMask, class CoverT>
00272 class scanline_am : public scanline_u<CoverT>
00273 {
00274 public:
00275 typedef AlphaMask alpha_mask_type;
00276 typedef CoverT cover_type;
00277 typedef scanline_u<CoverT> scanline_type;
00278
00279 scanline_am() : scanline_type(), m_alpha_mask(0) {}
00280 scanline_am(const AlphaMask& am) : scanline_type(), m_alpha_mask(&am) {}
00281
00282
00283 void finalize(int span_y)
00284 {
00285 scanline_u<CoverT>::finalize(span_y);
00286 if(m_alpha_mask)
00287 {
00288 typename scanline_type::iterator span = scanline_type::begin();
00289 unsigned count = scanline_type::num_spans();
00290 do
00291 {
00292 m_alpha_mask->combine_hspan(span->x,
00293 scanline_type::y(),
00294 span->covers,
00295 span->len);
00296 ++span;
00297 }
00298 while(--count);
00299 }
00300 }
00301
00302 private:
00303 const AlphaMask* m_alpha_mask;
00304 };
00305
00306
00307
00308 template<class AlphaMask>
00309 class scanline_u8_am : public scanline_am<AlphaMask, int8u>
00310 {
00311 public:
00312 typedef AlphaMask alpha_mask_type;
00313 typedef int8u cover_type;
00314 typedef scanline_am<alpha_mask_type, cover_type> self_type;
00315
00316 scanline_u8_am() : self_type() {}
00317 scanline_u8_am(const AlphaMask& am) : self_type(am) {}
00318 };
00319
00320 }
00321
00322 #endif
00323