|  |  | 
|  | //---------------------------------------------------------------------------- | 
|  | // Anti-Grain Geometry - Version 2.3 | 
|  | // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) | 
|  | // | 
|  | // Permission to copy, use, modify, sell and distribute this software | 
|  | // is granted provided this copyright notice appears in all copies. | 
|  | // This software is provided "as is" without express or implied | 
|  | // warranty, and with no claim as to its suitability for any purpose. | 
|  | // | 
|  | //---------------------------------------------------------------------------- | 
|  | // Contact: mcseem@antigrain.com | 
|  | //          mcseemagg@yahoo.com | 
|  | //          http://www.antigrain.com | 
|  | //---------------------------------------------------------------------------- | 
|  | // | 
|  | // Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by | 
|  | // Liberty Technology Systems, Inc., visit http://lib-sys.com | 
|  | // | 
|  | // Liberty Technology Systems, Inc. is the provider of | 
|  | // PostScript and PDF technology for software developers. | 
|  | // | 
|  | //---------------------------------------------------------------------------- | 
|  | #ifndef AGG_SCANLINE_U_INCLUDED | 
|  | #define AGG_SCANLINE_U_INCLUDED | 
|  | #include "agg_array.h" | 
|  | namespace agg | 
|  | { | 
|  | template<class CoverT> class scanline_u | 
|  | { | 
|  | public: | 
|  | typedef scanline_u<CoverT> self_type; | 
|  | typedef CoverT cover_type; | 
|  | typedef int16  coord_type; | 
|  | struct span  { | 
|  | coord_type  x; | 
|  | coord_type  len; | 
|  | cover_type* covers; | 
|  | }; | 
|  | typedef span* iterator; | 
|  | typedef const span* const_iterator; | 
|  | ~scanline_u() | 
|  | { | 
|  | FX_Free(m_spans); | 
|  | FX_Free(m_covers); | 
|  | } | 
|  | scanline_u() : | 
|  | m_min_x(0), | 
|  | m_max_len(0), | 
|  | m_last_x(0x7FFFFFF0), | 
|  | m_covers(0), | 
|  | m_spans(0), | 
|  | m_cur_span(0) | 
|  | {} | 
|  | void reset(int min_x, int max_x) | 
|  | { | 
|  | unsigned max_len = max_x - min_x + 2; | 
|  | if(max_len > m_max_len) { | 
|  | FX_Free(m_spans); | 
|  | FX_Free(m_covers); | 
|  | m_covers  = FX_Alloc( cover_type , max_len); | 
|  | m_spans   = FX_Alloc( span       , max_len); | 
|  | m_max_len = max_len; | 
|  | } | 
|  | m_last_x        = 0x7FFFFFF0; | 
|  | m_min_x         = min_x; | 
|  | m_cur_span      = m_spans; | 
|  | } | 
|  | void add_cell(int x, unsigned cover) | 
|  | { | 
|  | x -= m_min_x; | 
|  | m_covers[x] = (cover_type)cover; | 
|  | if(x == m_last_x + 1) { | 
|  | m_cur_span->len++; | 
|  | } else { | 
|  | m_cur_span++; | 
|  | m_cur_span->x      = (coord_type)(x + m_min_x); | 
|  | m_cur_span->len    = 1; | 
|  | m_cur_span->covers = m_covers + x; | 
|  | } | 
|  | m_last_x = x; | 
|  | } | 
|  | void add_cells(int x, unsigned len, const CoverT* covers) | 
|  | { | 
|  | x -= m_min_x; | 
|  | memcpy(m_covers + x, covers, len * sizeof(CoverT)); | 
|  | if(x == m_last_x + 1) { | 
|  | m_cur_span->len += (coord_type)len; | 
|  | } else { | 
|  | m_cur_span++; | 
|  | m_cur_span->x      = (coord_type)(x + m_min_x); | 
|  | m_cur_span->len    = (coord_type)len; | 
|  | m_cur_span->covers = m_covers + x; | 
|  | } | 
|  | m_last_x = x + len - 1; | 
|  | } | 
|  | void add_span(int x, unsigned len, unsigned cover) | 
|  | { | 
|  | x -= m_min_x; | 
|  | memset(m_covers + x, cover, len); | 
|  | if(x == m_last_x + 1) { | 
|  | m_cur_span->len += (coord_type)len; | 
|  | } else { | 
|  | m_cur_span++; | 
|  | m_cur_span->x      = (coord_type)(x + m_min_x); | 
|  | m_cur_span->len    = (coord_type)len; | 
|  | m_cur_span->covers = m_covers + x; | 
|  | } | 
|  | m_last_x = x + len - 1; | 
|  | } | 
|  | void finalize(int y) | 
|  | { | 
|  | m_y = y; | 
|  | } | 
|  | void reset_spans() | 
|  | { | 
|  | m_last_x    = 0x7FFFFFF0; | 
|  | m_cur_span  = m_spans; | 
|  | } | 
|  | int      y()           const | 
|  | { | 
|  | return m_y; | 
|  | } | 
|  | unsigned num_spans()   const | 
|  | { | 
|  | return unsigned(m_cur_span - m_spans); | 
|  | } | 
|  | const_iterator begin() const | 
|  | { | 
|  | return m_spans + 1; | 
|  | } | 
|  | iterator       begin() | 
|  | { | 
|  | return m_spans + 1; | 
|  | } | 
|  | private: | 
|  | scanline_u(const self_type&); | 
|  | const self_type& operator = (const self_type&); | 
|  | private: | 
|  | int           m_min_x; | 
|  | unsigned      m_max_len; | 
|  | int           m_last_x; | 
|  | int           m_y; | 
|  | cover_type*   m_covers; | 
|  | span*         m_spans; | 
|  | span*         m_cur_span; | 
|  | }; | 
|  | typedef scanline_u<int8u> scanline_u8; | 
|  | } | 
|  | #endif |