1//----------------------------------------------------------------------------
2// Anti-Grain Geometry - Version 2.4
3// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4//
5// Permission to copy, use, modify, sell and distribute this software
6// is granted provided this copyright notice appears in all copies.
7// This software is provided "as is" without express or implied
8// warranty, and with no claim as to its suitability for any purpose.
9//
10//----------------------------------------------------------------------------
11// Contact: mcseem@antigrain.com
12//          mcseemagg@yahoo.com
13//          http://www.antigrain.com
14//----------------------------------------------------------------------------
15//
16// Class scanline_bin - binary scanline.
17//
18//----------------------------------------------------------------------------
19//
20// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by
21// Liberty Technology Systems, Inc., visit http://lib-sys.com
22//
23// Liberty Technology Systems, Inc. is the provider of
24// PostScript and PDF technology for software developers.
25//
26//----------------------------------------------------------------------------
27
28#ifndef AGG_SCANLINE_BIN_INCLUDED
29#define AGG_SCANLINE_BIN_INCLUDED
30
31#include "agg_array.h"
32
33namespace agg
34{
35
36    //=============================================================scanline_bin
37    //
38    // This is binary scaline container which supports the interface
39    // used in the rasterizer::render(). See description of agg_scanline_u8
40    // for details.
41    //
42    //------------------------------------------------------------------------
43    class scanline_bin
44    {
45    public:
46        typedef int32 coord_type;
47
48        struct span
49        {
50            int16 x;
51            int16 len;
52        };
53
54        typedef const span* const_iterator;
55
56        //--------------------------------------------------------------------
57        scanline_bin() :
58            m_last_x(0x7FFFFFF0),
59            m_spans(),
60            m_cur_span(0)
61        {
62        }
63
64        //--------------------------------------------------------------------
65        void reset(int min_x, int max_x)
66        {
67            unsigned max_len = max_x - min_x + 3;
68            if(max_len > m_spans.size())
69            {
70                m_spans.resize(max_len);
71            }
72            m_last_x   = 0x7FFFFFF0;
73            m_cur_span = &m_spans[0];
74        }
75
76        //--------------------------------------------------------------------
77        void add_cell(int x, unsigned)
78        {
79            if(x == m_last_x+1)
80            {
81                m_cur_span->len++;
82            }
83            else
84            {
85                ++m_cur_span;
86                m_cur_span->x = (int16)x;
87                m_cur_span->len = 1;
88            }
89            m_last_x = x;
90        }
91
92        //--------------------------------------------------------------------
93        void add_span(int x, unsigned len, unsigned)
94        {
95            if(x == m_last_x+1)
96            {
97                m_cur_span->len = (int16)(m_cur_span->len + len);
98            }
99            else
100            {
101                ++m_cur_span;
102                m_cur_span->x = (int16)x;
103                m_cur_span->len = (int16)len;
104            }
105            m_last_x = x + len - 1;
106        }
107
108        //--------------------------------------------------------------------
109        void add_cells(int x, unsigned len, const void*)
110        {
111            add_span(x, len, 0);
112        }
113
114        //--------------------------------------------------------------------
115        void finalize(int y)
116        {
117            m_y = y;
118        }
119
120        //--------------------------------------------------------------------
121        void reset_spans()
122        {
123            m_last_x    = 0x7FFFFFF0;
124            m_cur_span  = &m_spans[0];
125        }
126
127        //--------------------------------------------------------------------
128        int            y()         const { return m_y; }
129        unsigned       num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
130        const_iterator begin()     const { return &m_spans[1]; }
131
132    private:
133        scanline_bin(const scanline_bin&);
134        const scanline_bin operator = (const scanline_bin&);
135
136        int             m_last_x;
137        int             m_y;
138        pod_array<span> m_spans;
139        span*           m_cur_span;
140    };
141
142
143
144
145
146
147    //===========================================================scanline32_bin
148    class scanline32_bin
149    {
150    public:
151        typedef int32 coord_type;
152
153        //--------------------------------------------------------------------
154        struct span
155        {
156            span() {}
157            span(coord_type x_, coord_type len_) : x(x_), len(len_) {}
158
159            coord_type x;
160            coord_type len;
161        };
162        typedef pod_bvector<span, 4> span_array_type;
163
164
165        //--------------------------------------------------------------------
166        class const_iterator
167        {
168        public:
169            const_iterator(const span_array_type& spans) :
170                m_spans(spans),
171                m_span_idx(0)
172            {}
173
174            const span& operator*()  const { return m_spans[m_span_idx];  }
175            const span* operator->() const { return &m_spans[m_span_idx]; }
176
177            void operator ++ () { ++m_span_idx; }
178
179        private:
180            const span_array_type& m_spans;
181            unsigned               m_span_idx;
182        };
183
184
185        //--------------------------------------------------------------------
186        scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {}
187
188        //--------------------------------------------------------------------
189        void reset(int min_x, int max_x)
190        {
191            m_last_x = 0x7FFFFFF0;
192            m_spans.remove_all();
193        }
194
195        //--------------------------------------------------------------------
196        void add_cell(int x, unsigned)
197        {
198            if(x == m_last_x+1)
199            {
200                m_spans.last().len++;
201            }
202            else
203            {
204                m_spans.add(span(coord_type(x), 1));
205            }
206            m_last_x = x;
207        }
208
209        //--------------------------------------------------------------------
210        void add_span(int x, unsigned len, unsigned)
211        {
212            if(x == m_last_x+1)
213            {
214                m_spans.last().len += coord_type(len);
215            }
216            else
217            {
218                m_spans.add(span(coord_type(x), coord_type(len)));
219            }
220            m_last_x = x + len - 1;
221        }
222
223        //--------------------------------------------------------------------
224        void add_cells(int x, unsigned len, const void*)
225        {
226            add_span(x, len, 0);
227        }
228
229        //--------------------------------------------------------------------
230        void finalize(int y)
231        {
232            m_y = y;
233        }
234
235        //--------------------------------------------------------------------
236        void reset_spans()
237        {
238            m_last_x = 0x7FFFFFF0;
239            m_spans.remove_all();
240        }
241
242        //--------------------------------------------------------------------
243        int            y()         const { return m_y; }
244        unsigned       num_spans() const { return m_spans.size(); }
245        const_iterator begin()     const { return const_iterator(m_spans); }
246
247    private:
248        scanline32_bin(const scanline32_bin&);
249        const scanline32_bin operator = (const scanline32_bin&);
250
251        unsigned        m_max_len;
252        int             m_last_x;
253        int             m_y;
254        span_array_type m_spans;
255    };
256
257
258
259
260
261}
262
263
264#endif
265