1
2//----------------------------------------------------------------------------
3// Anti-Grain Geometry - Version 2.3
4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5//
6// Permission to copy, use, modify, sell and distribute this software
7// is granted provided this copyright notice appears in all copies.
8// This software is provided "as is" without express or implied
9// warranty, and with no claim as to its suitability for any purpose.
10//
11//----------------------------------------------------------------------------
12// Contact: mcseem@antigrain.com
13//          mcseemagg@yahoo.com
14//          http://www.antigrain.com
15//----------------------------------------------------------------------------
16//
17// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
18// Liberty Technology Systems, Inc., visit http://lib-sys.com
19//
20// Liberty Technology Systems, Inc. is the provider of
21// PostScript and PDF technology for software developers.
22//
23//----------------------------------------------------------------------------
24#ifndef AGG_SCANLINE_U_INCLUDED
25#define AGG_SCANLINE_U_INCLUDED
26#include "agg_array.h"
27namespace agg
28{
29template<class CoverT> class scanline_u : public CFX_Object
30{
31public:
32    typedef scanline_u<CoverT> self_type;
33    typedef CoverT cover_type;
34    typedef int16  coord_type;
35    struct span : public CFX_Object {
36        coord_type  x;
37        coord_type  len;
38        cover_type* covers;
39    };
40    typedef span* iterator;
41    typedef const span* const_iterator;
42    ~scanline_u()
43    {
44        FX_Free(m_spans);
45        FX_Free(m_covers);
46    }
47    scanline_u() :
48        m_min_x(0),
49        m_max_len(0),
50        m_last_x(0x7FFFFFF0),
51        m_covers(0),
52        m_spans(0),
53        m_cur_span(0)
54    {}
55    void reset(int min_x, int max_x)
56    {
57        unsigned max_len = max_x - min_x + 2;
58        if(max_len > m_max_len) {
59            FX_Free(m_spans);
60            FX_Free(m_covers);
61            m_covers  = FX_Alloc( cover_type , max_len);
62            m_spans   = FX_Alloc( span       , max_len);
63            m_max_len = max_len;
64        }
65        m_last_x        = 0x7FFFFFF0;
66        m_min_x         = min_x;
67        m_cur_span      = m_spans;
68    }
69    void add_cell(int x, unsigned cover)
70    {
71        x -= m_min_x;
72        m_covers[x] = (cover_type)cover;
73        if(x == m_last_x + 1) {
74            m_cur_span->len++;
75        } else {
76            m_cur_span++;
77            m_cur_span->x      = (coord_type)(x + m_min_x);
78            m_cur_span->len    = 1;
79            m_cur_span->covers = m_covers + x;
80        }
81        m_last_x = x;
82    }
83    void add_cells(int x, unsigned len, const CoverT* covers)
84    {
85        x -= m_min_x;
86        FXSYS_memcpy(m_covers + x, covers, len * sizeof(CoverT));
87        if(x == m_last_x + 1) {
88            m_cur_span->len += (coord_type)len;
89        } else {
90            m_cur_span++;
91            m_cur_span->x      = (coord_type)(x + m_min_x);
92            m_cur_span->len    = (coord_type)len;
93            m_cur_span->covers = m_covers + x;
94        }
95        m_last_x = x + len - 1;
96    }
97    void add_span(int x, unsigned len, unsigned cover)
98    {
99        x -= m_min_x;
100        FXSYS_memset8(m_covers + x, cover, len);
101        if(x == m_last_x + 1) {
102            m_cur_span->len += (coord_type)len;
103        } else {
104            m_cur_span++;
105            m_cur_span->x      = (coord_type)(x + m_min_x);
106            m_cur_span->len    = (coord_type)len;
107            m_cur_span->covers = m_covers + x;
108        }
109        m_last_x = x + len - 1;
110    }
111    void finalize(int y)
112    {
113        m_y = y;
114    }
115    void reset_spans()
116    {
117        m_last_x    = 0x7FFFFFF0;
118        m_cur_span  = m_spans;
119    }
120    int      y()           const
121    {
122        return m_y;
123    }
124    unsigned num_spans()   const
125    {
126        return unsigned(m_cur_span - m_spans);
127    }
128    const_iterator begin() const
129    {
130        return m_spans + 1;
131    }
132    iterator       begin()
133    {
134        return m_spans + 1;
135    }
136private:
137    scanline_u(const self_type&);
138    const self_type& operator = (const self_type&);
139private:
140    int           m_min_x;
141    unsigned      m_max_len;
142    int           m_last_x;
143    int           m_y;
144    cover_type*   m_covers;
145    span*         m_spans;
146    span*         m_cur_span;
147};
148typedef scanline_u<int8u> scanline_u8;
149}
150#endif
151