| |
| //---------------------------------------------------------------------------- |
| // 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 |