139241fe2SDarkWyrm //---------------------------------------------------------------------------- 2e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4 3e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 439241fe2SDarkWyrm // 539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software 639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies. 739241fe2SDarkWyrm // This software is provided "as is" without express or implied 839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose. 939241fe2SDarkWyrm // 1039241fe2SDarkWyrm //---------------------------------------------------------------------------- 1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com 1239241fe2SDarkWyrm // mcseemagg@yahoo.com 1339241fe2SDarkWyrm // http://www.antigrain.com 1439241fe2SDarkWyrm //---------------------------------------------------------------------------- 15e39da397SStephan Aßmus // 16e39da397SStephan Aßmus // Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by 17e39da397SStephan Aßmus // Liberty Technology Systems, Inc., visit http://lib-sys.com 18e39da397SStephan Aßmus // 19e39da397SStephan Aßmus // Liberty Technology Systems, Inc. is the provider of 20e39da397SStephan Aßmus // PostScript and PDF technology for software developers. 21e39da397SStephan Aßmus // 22e39da397SStephan Aßmus //---------------------------------------------------------------------------- 2339241fe2SDarkWyrm 2439241fe2SDarkWyrm #ifndef AGG_SCANLINE_U_INCLUDED 2539241fe2SDarkWyrm #define AGG_SCANLINE_U_INCLUDED 2639241fe2SDarkWyrm 27e39da397SStephan Aßmus #include "agg_array.h" 2839241fe2SDarkWyrm 2939241fe2SDarkWyrm namespace agg 3039241fe2SDarkWyrm { 31e39da397SStephan Aßmus //=============================================================scanline_u8 3239241fe2SDarkWyrm // 3339241fe2SDarkWyrm // Unpacked scanline container class 3439241fe2SDarkWyrm // 35e39da397SStephan Aßmus // This class is used to transfer data from a scanline rasterizer 3639241fe2SDarkWyrm // to the rendering buffer. It's organized very simple. The class stores 3739241fe2SDarkWyrm // information of horizontal spans to render it into a pixel-map buffer. 3839241fe2SDarkWyrm // Each span has staring X, length, and an array of bytes that determine the 3939241fe2SDarkWyrm // cover-values for each pixel. 4039241fe2SDarkWyrm // Before using this class you should know the minimal and maximal pixel 4139241fe2SDarkWyrm // coordinates of your scanline. The protocol of using is: 4239241fe2SDarkWyrm // 1. reset(min_x, max_x) 4339241fe2SDarkWyrm // 2. add_cell() / add_span() - accumulate scanline. 4439241fe2SDarkWyrm // When forming one scanline the next X coordinate must be always greater 4539241fe2SDarkWyrm // than the last stored one, i.e. it works only with ordered coordinates. 4639241fe2SDarkWyrm // 3. Call finalize(y) and render the scanline. 4739241fe2SDarkWyrm // 3. Call reset_spans() to prepare for the new scanline. 4839241fe2SDarkWyrm // 4939241fe2SDarkWyrm // 4. Rendering: 5039241fe2SDarkWyrm // 5139241fe2SDarkWyrm // Scanline provides an iterator class that allows you to extract 5239241fe2SDarkWyrm // the spans and the cover values for each pixel. Be aware that clipping 5339241fe2SDarkWyrm // has not been done yet, so you should perform it yourself. 5439241fe2SDarkWyrm // Use scanline_u8::iterator to render spans: 5539241fe2SDarkWyrm //------------------------------------------------------------------------- 5639241fe2SDarkWyrm // 5739241fe2SDarkWyrm // int y = sl.y(); // Y-coordinate of the scanline 5839241fe2SDarkWyrm // 5939241fe2SDarkWyrm // ************************************ 6039241fe2SDarkWyrm // ...Perform vertical clipping here... 6139241fe2SDarkWyrm // ************************************ 6239241fe2SDarkWyrm // 6339241fe2SDarkWyrm // scanline_u8::const_iterator span = sl.begin(); 6439241fe2SDarkWyrm // 6539241fe2SDarkWyrm // unsigned char* row = m_rbuf->row(y); // The the address of the beginning 6639241fe2SDarkWyrm // // of the current row 6739241fe2SDarkWyrm // 6839241fe2SDarkWyrm // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that 6939241fe2SDarkWyrm // // num_spans is always greater than 0. 7039241fe2SDarkWyrm // 7139241fe2SDarkWyrm // do 7239241fe2SDarkWyrm // { 7339241fe2SDarkWyrm // const scanline_u8::cover_type* covers = 7439241fe2SDarkWyrm // span->covers; // The array of the cover values 7539241fe2SDarkWyrm // 7639241fe2SDarkWyrm // int num_pix = span->len; // Number of pixels of the span. 7739241fe2SDarkWyrm // // Always greater than 0, still it's 7839241fe2SDarkWyrm // // better to use "int" instead of 7939241fe2SDarkWyrm // // "unsigned" because it's more 8039241fe2SDarkWyrm // // convenient for clipping 8139241fe2SDarkWyrm // int x = span->x; 8239241fe2SDarkWyrm // 8339241fe2SDarkWyrm // ************************************** 8439241fe2SDarkWyrm // ...Perform horizontal clipping here... 8539241fe2SDarkWyrm // ...you have x, covers, and pix_count.. 8639241fe2SDarkWyrm // ************************************** 8739241fe2SDarkWyrm // 8839241fe2SDarkWyrm // unsigned char* dst = row + x; // Calculate the start address of the row. 8939241fe2SDarkWyrm // // In this case we assume a simple 9039241fe2SDarkWyrm // // grayscale image 1-byte per pixel. 9139241fe2SDarkWyrm // do 9239241fe2SDarkWyrm // { 9339241fe2SDarkWyrm // *dst++ = *covers++; // Hypotetical rendering. 9439241fe2SDarkWyrm // } 9539241fe2SDarkWyrm // while(--num_pix); 9639241fe2SDarkWyrm // 9739241fe2SDarkWyrm // ++span; 9839241fe2SDarkWyrm // } 9939241fe2SDarkWyrm // while(--num_spans); // num_spans cannot be 0, so this loop is quite safe 10039241fe2SDarkWyrm //------------------------------------------------------------------------ 10139241fe2SDarkWyrm // 10239241fe2SDarkWyrm // The question is: why should we accumulate the whole scanline when we 10339241fe2SDarkWyrm // could render just separate spans when they're ready? 104e39da397SStephan Aßmus // That's because using the scanline is generally faster. When is consists 10539241fe2SDarkWyrm // of more than one span the conditions for the processor cash system 10639241fe2SDarkWyrm // are better, because switching between two different areas of memory 107e39da397SStephan Aßmus // (that can be very large) occurs less frequently. 10839241fe2SDarkWyrm //------------------------------------------------------------------------ 109e39da397SStephan Aßmus class scanline_u8 11039241fe2SDarkWyrm { 11139241fe2SDarkWyrm public: 112e39da397SStephan Aßmus typedef scanline_u8 self_type; 113e39da397SStephan Aßmus typedef int8u cover_type; 114e39da397SStephan Aßmus typedef int16 coord_type; 11539241fe2SDarkWyrm 11639241fe2SDarkWyrm //-------------------------------------------------------------------- 11739241fe2SDarkWyrm struct span 11839241fe2SDarkWyrm { 119e39da397SStephan Aßmus coord_type x; 120e39da397SStephan Aßmus coord_type len; 12139241fe2SDarkWyrm cover_type* covers; 12239241fe2SDarkWyrm }; 12339241fe2SDarkWyrm 12439241fe2SDarkWyrm typedef span* iterator; 12539241fe2SDarkWyrm typedef const span* const_iterator; 12639241fe2SDarkWyrm 12739241fe2SDarkWyrm //-------------------------------------------------------------------- scanline_u8()128e39da397SStephan Aßmus scanline_u8() : 12939241fe2SDarkWyrm m_min_x(0), 13039241fe2SDarkWyrm m_last_x(0x7FFFFFF0), 13139241fe2SDarkWyrm m_cur_span(0) 132e39da397SStephan Aßmus {} 13339241fe2SDarkWyrm 134e39da397SStephan Aßmus //-------------------------------------------------------------------- reset(int min_x,int max_x)135e39da397SStephan Aßmus void reset(int min_x, int max_x) 13639241fe2SDarkWyrm { 13739241fe2SDarkWyrm unsigned max_len = max_x - min_x + 2; 138e39da397SStephan Aßmus if(max_len > m_spans.size()) 13939241fe2SDarkWyrm { 140e39da397SStephan Aßmus m_spans.resize(max_len); 141e39da397SStephan Aßmus m_covers.resize(max_len); 14239241fe2SDarkWyrm } 14339241fe2SDarkWyrm m_last_x = 0x7FFFFFF0; 14439241fe2SDarkWyrm m_min_x = min_x; 145e39da397SStephan Aßmus m_cur_span = &m_spans[0]; 14639241fe2SDarkWyrm } 14739241fe2SDarkWyrm 148e39da397SStephan Aßmus //-------------------------------------------------------------------- add_cell(int x,unsigned cover)149e39da397SStephan Aßmus void add_cell(int x, unsigned cover) 15039241fe2SDarkWyrm { 15139241fe2SDarkWyrm x -= m_min_x; 152e39da397SStephan Aßmus m_covers[x] = (cover_type)cover; 15339241fe2SDarkWyrm if(x == m_last_x+1) 15439241fe2SDarkWyrm { 15539241fe2SDarkWyrm m_cur_span->len++; 15639241fe2SDarkWyrm } 15739241fe2SDarkWyrm else 15839241fe2SDarkWyrm { 15939241fe2SDarkWyrm m_cur_span++; 160e39da397SStephan Aßmus m_cur_span->x = (coord_type)(x + m_min_x); 16139241fe2SDarkWyrm m_cur_span->len = 1; 162e39da397SStephan Aßmus m_cur_span->covers = &m_covers[x]; 16339241fe2SDarkWyrm } 16439241fe2SDarkWyrm m_last_x = x; 16539241fe2SDarkWyrm } 16639241fe2SDarkWyrm 167e39da397SStephan Aßmus //-------------------------------------------------------------------- add_cells(int x,unsigned len,const cover_type * covers)168e39da397SStephan Aßmus void add_cells(int x, unsigned len, const cover_type* covers) 16939241fe2SDarkWyrm { 17039241fe2SDarkWyrm x -= m_min_x; 171e39da397SStephan Aßmus memcpy(&m_covers[x], covers, len * sizeof(cover_type)); 17239241fe2SDarkWyrm if(x == m_last_x+1) 17339241fe2SDarkWyrm { 174e39da397SStephan Aßmus m_cur_span->len += (coord_type)len; 17539241fe2SDarkWyrm } 17639241fe2SDarkWyrm else 17739241fe2SDarkWyrm { 17839241fe2SDarkWyrm m_cur_span++; 179e39da397SStephan Aßmus m_cur_span->x = (coord_type)(x + m_min_x); 180e39da397SStephan Aßmus m_cur_span->len = (coord_type)len; 181e39da397SStephan Aßmus m_cur_span->covers = &m_covers[x]; 18239241fe2SDarkWyrm } 18339241fe2SDarkWyrm m_last_x = x + len - 1; 18439241fe2SDarkWyrm } 18539241fe2SDarkWyrm 186e39da397SStephan Aßmus //-------------------------------------------------------------------- add_span(int x,unsigned len,unsigned cover)187e39da397SStephan Aßmus void add_span(int x, unsigned len, unsigned cover) 18839241fe2SDarkWyrm { 18939241fe2SDarkWyrm x -= m_min_x; 190e39da397SStephan Aßmus memset(&m_covers[x], cover, len); 19139241fe2SDarkWyrm if(x == m_last_x+1) 19239241fe2SDarkWyrm { 193e39da397SStephan Aßmus m_cur_span->len += (coord_type)len; 19439241fe2SDarkWyrm } 19539241fe2SDarkWyrm else 19639241fe2SDarkWyrm { 19739241fe2SDarkWyrm m_cur_span++; 198e39da397SStephan Aßmus m_cur_span->x = (coord_type)(x + m_min_x); 199e39da397SStephan Aßmus m_cur_span->len = (coord_type)len; 200e39da397SStephan Aßmus m_cur_span->covers = &m_covers[x]; 20139241fe2SDarkWyrm } 20239241fe2SDarkWyrm m_last_x = x + len - 1; 20339241fe2SDarkWyrm } 20439241fe2SDarkWyrm 205e39da397SStephan Aßmus //-------------------------------------------------------------------- finalize(int y)206e39da397SStephan Aßmus void finalize(int y) 207e39da397SStephan Aßmus { 208e39da397SStephan Aßmus m_y = y; 209e39da397SStephan Aßmus } 21039241fe2SDarkWyrm 211e39da397SStephan Aßmus //-------------------------------------------------------------------- reset_spans()212e39da397SStephan Aßmus void reset_spans() 213e39da397SStephan Aßmus { 214e39da397SStephan Aßmus m_last_x = 0x7FFFFFF0; 215e39da397SStephan Aßmus m_cur_span = &m_spans[0]; 216e39da397SStephan Aßmus } 21739241fe2SDarkWyrm 218e39da397SStephan Aßmus //-------------------------------------------------------------------- y()219e39da397SStephan Aßmus int y() const { return m_y; } num_spans()220e39da397SStephan Aßmus unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } begin()221e39da397SStephan Aßmus const_iterator begin() const { return &m_spans[1]; } begin()222e39da397SStephan Aßmus iterator begin() { return &m_spans[1]; } 22339241fe2SDarkWyrm 224e39da397SStephan Aßmus private: 225e39da397SStephan Aßmus scanline_u8(const self_type&); 226e39da397SStephan Aßmus const self_type& operator = (const self_type&); 227e39da397SStephan Aßmus 228e39da397SStephan Aßmus private: 229e39da397SStephan Aßmus int m_min_x; 230e39da397SStephan Aßmus int m_last_x; 231e39da397SStephan Aßmus int m_y; 232e39da397SStephan Aßmus pod_array<cover_type> m_covers; 233e39da397SStephan Aßmus pod_array<span> m_spans; 234e39da397SStephan Aßmus span* m_cur_span; 235e39da397SStephan Aßmus }; 23639241fe2SDarkWyrm 23739241fe2SDarkWyrm 238e39da397SStephan Aßmus 239e39da397SStephan Aßmus 240e39da397SStephan Aßmus //==========================================================scanline_u8_am 24139241fe2SDarkWyrm // 24239241fe2SDarkWyrm // The scanline container with alpha-masking 24339241fe2SDarkWyrm // 24439241fe2SDarkWyrm //------------------------------------------------------------------------ 245e39da397SStephan Aßmus template<class AlphaMask> 246e39da397SStephan Aßmus class scanline_u8_am : public scanline_u8 24739241fe2SDarkWyrm { 24839241fe2SDarkWyrm public: 249e39da397SStephan Aßmus typedef scanline_u8 base_type; 25039241fe2SDarkWyrm typedef AlphaMask alpha_mask_type; 251e39da397SStephan Aßmus typedef base_type::cover_type cover_type; 252e39da397SStephan Aßmus typedef base_type::coord_type coord_type; 25339241fe2SDarkWyrm scanline_u8_am()254e39da397SStephan Aßmus scanline_u8_am() : base_type(), m_alpha_mask(0) {} scanline_u8_am(AlphaMask & am)255*8cc5325aSAlexander von Gluck IV scanline_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} 25639241fe2SDarkWyrm 25739241fe2SDarkWyrm //-------------------------------------------------------------------- finalize(int span_y)25839241fe2SDarkWyrm void finalize(int span_y) 25939241fe2SDarkWyrm { 260e39da397SStephan Aßmus base_type::finalize(span_y); 26139241fe2SDarkWyrm if(m_alpha_mask) 26239241fe2SDarkWyrm { 263e39da397SStephan Aßmus typename base_type::iterator span = base_type::begin(); 264e39da397SStephan Aßmus unsigned count = base_type::num_spans(); 26539241fe2SDarkWyrm do 26639241fe2SDarkWyrm { 26739241fe2SDarkWyrm m_alpha_mask->combine_hspan(span->x, 268e39da397SStephan Aßmus base_type::y(), 26939241fe2SDarkWyrm span->covers, 27039241fe2SDarkWyrm span->len); 27139241fe2SDarkWyrm ++span; 27239241fe2SDarkWyrm } 27339241fe2SDarkWyrm while(--count); 27439241fe2SDarkWyrm } 27539241fe2SDarkWyrm } 27639241fe2SDarkWyrm 27739241fe2SDarkWyrm private: 278*8cc5325aSAlexander von Gluck IV AlphaMask* m_alpha_mask; 27939241fe2SDarkWyrm }; 28039241fe2SDarkWyrm 28139241fe2SDarkWyrm 282e39da397SStephan Aßmus 283e39da397SStephan Aßmus 284e39da397SStephan Aßmus //===========================================================scanline32_u8 285e39da397SStephan Aßmus class scanline32_u8 28639241fe2SDarkWyrm { 28739241fe2SDarkWyrm public: 288e39da397SStephan Aßmus typedef scanline32_u8 self_type; 28939241fe2SDarkWyrm typedef int8u cover_type; 290e39da397SStephan Aßmus typedef int32 coord_type; 29139241fe2SDarkWyrm 292e39da397SStephan Aßmus //-------------------------------------------------------------------- 293e39da397SStephan Aßmus struct span 294e39da397SStephan Aßmus { spanspan295e39da397SStephan Aßmus span() {} spanspan296e39da397SStephan Aßmus span(coord_type x_, coord_type len_, cover_type* covers_) : 297e39da397SStephan Aßmus x(x_), len(len_), covers(covers_) {} 298e39da397SStephan Aßmus 299e39da397SStephan Aßmus coord_type x; 300e39da397SStephan Aßmus coord_type len; 301e39da397SStephan Aßmus cover_type* covers; 30239241fe2SDarkWyrm }; 30339241fe2SDarkWyrm 304e39da397SStephan Aßmus typedef pod_bvector<span, 4> span_array_type; 305e39da397SStephan Aßmus 306e39da397SStephan Aßmus //-------------------------------------------------------------------- 307e39da397SStephan Aßmus class const_iterator 308e39da397SStephan Aßmus { 309e39da397SStephan Aßmus public: const_iterator(const span_array_type & spans)310e39da397SStephan Aßmus const_iterator(const span_array_type& spans) : 311e39da397SStephan Aßmus m_spans(spans), 312e39da397SStephan Aßmus m_span_idx(0) 313e39da397SStephan Aßmus {} 314e39da397SStephan Aßmus 315e39da397SStephan Aßmus const span& operator*() const { return m_spans[m_span_idx]; } 316e39da397SStephan Aßmus const span* operator->() const { return &m_spans[m_span_idx]; } 317e39da397SStephan Aßmus 318e39da397SStephan Aßmus void operator ++ () { ++m_span_idx; } 319e39da397SStephan Aßmus 320e39da397SStephan Aßmus private: 321e39da397SStephan Aßmus const span_array_type& m_spans; 322e39da397SStephan Aßmus unsigned m_span_idx; 323e39da397SStephan Aßmus }; 324e39da397SStephan Aßmus 325e39da397SStephan Aßmus //-------------------------------------------------------------------- 326e39da397SStephan Aßmus class iterator 327e39da397SStephan Aßmus { 328e39da397SStephan Aßmus public: iterator(span_array_type & spans)329e39da397SStephan Aßmus iterator(span_array_type& spans) : 330e39da397SStephan Aßmus m_spans(spans), 331e39da397SStephan Aßmus m_span_idx(0) 332e39da397SStephan Aßmus {} 333e39da397SStephan Aßmus 334e39da397SStephan Aßmus span& operator*() { return m_spans[m_span_idx]; } 335e39da397SStephan Aßmus span* operator->() { return &m_spans[m_span_idx]; } 336e39da397SStephan Aßmus 337e39da397SStephan Aßmus void operator ++ () { ++m_span_idx; } 338e39da397SStephan Aßmus 339e39da397SStephan Aßmus private: 340e39da397SStephan Aßmus span_array_type& m_spans; 341e39da397SStephan Aßmus unsigned m_span_idx; 342e39da397SStephan Aßmus }; 343e39da397SStephan Aßmus 344e39da397SStephan Aßmus 345e39da397SStephan Aßmus 346e39da397SStephan Aßmus //-------------------------------------------------------------------- scanline32_u8()347e39da397SStephan Aßmus scanline32_u8() : 348e39da397SStephan Aßmus m_min_x(0), 349e39da397SStephan Aßmus m_last_x(0x7FFFFFF0), 350e39da397SStephan Aßmus m_covers() 351e39da397SStephan Aßmus {} 352e39da397SStephan Aßmus 353e39da397SStephan Aßmus //-------------------------------------------------------------------- reset(int min_x,int max_x)354e39da397SStephan Aßmus void reset(int min_x, int max_x) 355e39da397SStephan Aßmus { 356e39da397SStephan Aßmus unsigned max_len = max_x - min_x + 2; 357e39da397SStephan Aßmus if(max_len > m_covers.size()) 358e39da397SStephan Aßmus { 359e39da397SStephan Aßmus m_covers.resize(max_len); 360e39da397SStephan Aßmus } 361e39da397SStephan Aßmus m_last_x = 0x7FFFFFF0; 362e39da397SStephan Aßmus m_min_x = min_x; 363e39da397SStephan Aßmus m_spans.remove_all(); 364e39da397SStephan Aßmus } 365e39da397SStephan Aßmus 366e39da397SStephan Aßmus //-------------------------------------------------------------------- add_cell(int x,unsigned cover)367e39da397SStephan Aßmus void add_cell(int x, unsigned cover) 368e39da397SStephan Aßmus { 369e39da397SStephan Aßmus x -= m_min_x; 370e39da397SStephan Aßmus m_covers[x] = cover_type(cover); 371e39da397SStephan Aßmus if(x == m_last_x+1) 372e39da397SStephan Aßmus { 373e39da397SStephan Aßmus m_spans.last().len++; 374e39da397SStephan Aßmus } 375e39da397SStephan Aßmus else 376e39da397SStephan Aßmus { 377e39da397SStephan Aßmus m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x])); 378e39da397SStephan Aßmus } 379e39da397SStephan Aßmus m_last_x = x; 380e39da397SStephan Aßmus } 381e39da397SStephan Aßmus 382e39da397SStephan Aßmus //-------------------------------------------------------------------- add_cells(int x,unsigned len,const cover_type * covers)383e39da397SStephan Aßmus void add_cells(int x, unsigned len, const cover_type* covers) 384e39da397SStephan Aßmus { 385e39da397SStephan Aßmus x -= m_min_x; 386e39da397SStephan Aßmus memcpy(&m_covers[x], covers, len * sizeof(cover_type)); 387e39da397SStephan Aßmus if(x == m_last_x+1) 388e39da397SStephan Aßmus { 389e39da397SStephan Aßmus m_spans.last().len += coord_type(len); 390e39da397SStephan Aßmus } 391e39da397SStephan Aßmus else 392e39da397SStephan Aßmus { 393e39da397SStephan Aßmus m_spans.add(span(coord_type(x + m_min_x), 394e39da397SStephan Aßmus coord_type(len), 395e39da397SStephan Aßmus &m_covers[x])); 396e39da397SStephan Aßmus } 397e39da397SStephan Aßmus m_last_x = x + len - 1; 398e39da397SStephan Aßmus } 399e39da397SStephan Aßmus 400e39da397SStephan Aßmus //-------------------------------------------------------------------- add_span(int x,unsigned len,unsigned cover)401e39da397SStephan Aßmus void add_span(int x, unsigned len, unsigned cover) 402e39da397SStephan Aßmus { 403e39da397SStephan Aßmus x -= m_min_x; 404e39da397SStephan Aßmus memset(&m_covers[x], cover, len); 405e39da397SStephan Aßmus if(x == m_last_x+1) 406e39da397SStephan Aßmus { 407e39da397SStephan Aßmus m_spans.last().len += coord_type(len); 408e39da397SStephan Aßmus } 409e39da397SStephan Aßmus else 410e39da397SStephan Aßmus { 411e39da397SStephan Aßmus m_spans.add(span(coord_type(x + m_min_x), 412e39da397SStephan Aßmus coord_type(len), 413e39da397SStephan Aßmus &m_covers[x])); 414e39da397SStephan Aßmus } 415e39da397SStephan Aßmus m_last_x = x + len - 1; 416e39da397SStephan Aßmus } 417e39da397SStephan Aßmus 418e39da397SStephan Aßmus //-------------------------------------------------------------------- finalize(int y)419e39da397SStephan Aßmus void finalize(int y) 420e39da397SStephan Aßmus { 421e39da397SStephan Aßmus m_y = y; 422e39da397SStephan Aßmus } 423e39da397SStephan Aßmus 424e39da397SStephan Aßmus //-------------------------------------------------------------------- reset_spans()425e39da397SStephan Aßmus void reset_spans() 426e39da397SStephan Aßmus { 427e39da397SStephan Aßmus m_last_x = 0x7FFFFFF0; 428e39da397SStephan Aßmus m_spans.remove_all(); 429e39da397SStephan Aßmus } 430e39da397SStephan Aßmus 431e39da397SStephan Aßmus //-------------------------------------------------------------------- y()432e39da397SStephan Aßmus int y() const { return m_y; } num_spans()433e39da397SStephan Aßmus unsigned num_spans() const { return m_spans.size(); } begin()434e39da397SStephan Aßmus const_iterator begin() const { return const_iterator(m_spans); } begin()435e39da397SStephan Aßmus iterator begin() { return iterator(m_spans); } 436e39da397SStephan Aßmus 437e39da397SStephan Aßmus private: 438e39da397SStephan Aßmus scanline32_u8(const self_type&); 439e39da397SStephan Aßmus const self_type& operator = (const self_type&); 440e39da397SStephan Aßmus 441e39da397SStephan Aßmus private: 442e39da397SStephan Aßmus int m_min_x; 443e39da397SStephan Aßmus int m_last_x; 444e39da397SStephan Aßmus int m_y; 445e39da397SStephan Aßmus pod_array<cover_type> m_covers; 446e39da397SStephan Aßmus span_array_type m_spans; 447e39da397SStephan Aßmus }; 448e39da397SStephan Aßmus 449e39da397SStephan Aßmus 450e39da397SStephan Aßmus 451e39da397SStephan Aßmus 452e39da397SStephan Aßmus //========================================================scanline32_u8_am 453e39da397SStephan Aßmus // 454e39da397SStephan Aßmus // The scanline container with alpha-masking 455e39da397SStephan Aßmus // 456e39da397SStephan Aßmus //------------------------------------------------------------------------ 457e39da397SStephan Aßmus template<class AlphaMask> 458e39da397SStephan Aßmus class scanline32_u8_am : public scanline32_u8 459e39da397SStephan Aßmus { 460e39da397SStephan Aßmus public: 46158916d4aSMurai Takashi typedef scanline32_u8 base_type; 462e39da397SStephan Aßmus typedef AlphaMask alpha_mask_type; 463e39da397SStephan Aßmus typedef base_type::cover_type cover_type; 464e39da397SStephan Aßmus typedef base_type::coord_type coord_type; 465e39da397SStephan Aßmus 466e39da397SStephan Aßmus scanline32_u8_am()467*8cc5325aSAlexander von Gluck IV scanline32_u8_am() : base_type(), m_alpha_mask(0) {} scanline32_u8_am(AlphaMask & am)468*8cc5325aSAlexander von Gluck IV scanline32_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} 469e39da397SStephan Aßmus 470e39da397SStephan Aßmus //-------------------------------------------------------------------- finalize(int span_y)471e39da397SStephan Aßmus void finalize(int span_y) 472e39da397SStephan Aßmus { 473*8cc5325aSAlexander von Gluck IV base_type::finalize(span_y); 474e39da397SStephan Aßmus if(m_alpha_mask) 475e39da397SStephan Aßmus { 476*8cc5325aSAlexander von Gluck IV typename base_type::iterator span = base_type::begin(); 477*8cc5325aSAlexander von Gluck IV unsigned count = base_type::num_spans(); 478e39da397SStephan Aßmus do 479e39da397SStephan Aßmus { 480e39da397SStephan Aßmus m_alpha_mask->combine_hspan(span->x, 481*8cc5325aSAlexander von Gluck IV base_type::y(), 482e39da397SStephan Aßmus span->covers, 483e39da397SStephan Aßmus span->len); 484e39da397SStephan Aßmus ++span; 485e39da397SStephan Aßmus } 486e39da397SStephan Aßmus while(--count); 487e39da397SStephan Aßmus } 488e39da397SStephan Aßmus } 489e39da397SStephan Aßmus 490e39da397SStephan Aßmus private: 491*8cc5325aSAlexander von Gluck IV AlphaMask* m_alpha_mask; 492e39da397SStephan Aßmus }; 493e39da397SStephan Aßmus 494e39da397SStephan Aßmus 495e39da397SStephan Aßmus 49639241fe2SDarkWyrm } 49739241fe2SDarkWyrm 49839241fe2SDarkWyrm #endif 49939241fe2SDarkWyrm 500