xref: /haiku/headers/libs/agg/agg_scanline_bin.h (revision 95bac3fda53a4cb21880712d7b43f8c21db32a2e)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.2
3 // Copyright (C) 2002-2004 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 #ifndef AGG_SCANLINE_BIN_INCLUDED
20 #define AGG_SCANLINE_BIN_INCLUDED
21 
22 #include "agg_basics.h"
23 
24 namespace agg
25 {
26 
27     //=============================================================scanline_bin
28     //
29     // This is binary scaline container which supports the interface
30     // used in the rasterizer::render(). See description of agg_scanline_u8
31     // for details.
32     //
33     // Rendering:
34     //-------------------------------------------------------------------------
35     //
36     //  int y = sl.y();
37     //
38     // ************************************
39     // ...Perform vertical clipping here...
40     // ************************************
41     //
42     //  unsigned num_spans = sl.num_spans();
43     //  const agg::scanline_bin::span* cur_span = sl.spans();
44     //
45     //  do
46     //  {
47     //      x = cur_span->x;
48     //      len = cur_span->len;
49     //
50     //      **************************************
51     //      ...Perform horizontal clipping here...
52     //      **************************************
53     //
54     //      hor_line(x, y, len)
55     //      ++cur_span;
56     //  }
57     //  while(--num_spans);
58     //
59     //------------------------------------------------------------------------
60     class scanline_bin
61     {
62     public:
63         struct span
64         {
65             int16 x;
66             int16 len;
67         };
68 
69         typedef const span* const_iterator;
70 
71         ~scanline_bin()
72         {
73             delete [] m_spans;
74         }
75 
76         scanline_bin() :
77             m_max_len(0),
78             m_last_x(0x7FFF),
79             m_spans(0),
80             m_cur_span(0)
81         {
82         }
83 
84         void reset(int min_x, int max_x);
85         void add_cell(int x, unsigned);
86         void add_cells(int x, unsigned len, const void*);
87         void add_span(int x, unsigned len, unsigned);
88         void finalize(int y) { m_y = y; }
89         void reset_spans();
90 
91         int            y()         const { return m_y; }
92         unsigned       num_spans() const { return unsigned(m_cur_span - m_spans); }
93         const_iterator begin()     const { return m_spans + 1; }
94 
95     private:
96         scanline_bin(const scanline_bin&);
97         const scanline_bin operator = (const scanline_bin&);
98 
99         unsigned  m_max_len;
100         int       m_last_x;
101         int       m_y;
102         span*     m_spans;
103         span*     m_cur_span;
104     };
105 
106 
107     //------------------------------------------------------------------------
108     inline void scanline_bin::reset(int min_x, int max_x)
109     {
110         unsigned max_len = max_x - min_x + 3;
111         if(max_len > m_max_len)
112         {
113             delete [] m_spans;
114             m_spans   = new span [max_len];
115             m_max_len = max_len;
116         }
117         m_last_x    = 0x7FFF;
118         m_cur_span  = m_spans;
119     }
120 
121 
122     //------------------------------------------------------------------------
123     inline void scanline_bin::reset_spans()
124     {
125         m_last_x    = 0x7FFF;
126         m_cur_span  = m_spans;
127     }
128 
129 
130     //------------------------------------------------------------------------
131     inline void scanline_bin::add_cell(int x, unsigned)
132     {
133         if(x == m_last_x+1)
134         {
135             m_cur_span->len++;
136         }
137         else
138         {
139             ++m_cur_span;
140             m_cur_span->x = (int16)x;
141             m_cur_span->len = 1;
142         }
143         m_last_x = x;
144     }
145 
146 
147     //------------------------------------------------------------------------
148     inline void scanline_bin::add_span(int x, unsigned len, unsigned)
149     {
150         if(x == m_last_x+1)
151         {
152             m_cur_span->len = (int16)(m_cur_span->len + len);
153         }
154         else
155         {
156             ++m_cur_span;
157             m_cur_span->x = (int16)x;
158             m_cur_span->len = (int16)len;
159         }
160         m_last_x = x + len - 1;
161     }
162 
163     //------------------------------------------------------------------------
164     inline void scanline_bin::add_cells(int x, unsigned len, const void*)
165     {
166         add_span(x, len, 0);
167     }
168 }
169 
170 
171 #endif
172