1/*
2 * Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 *
5 * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
6 *
7 *
8 * Class scanline_u8_subpix, a slightly modified version of
9 * scanline_u8 customized to store 3 covers per pixel
10 *
11 */
12
13#ifndef AGG_SCANLINE_U_SUBPIX_INCLUDED
14#define AGG_SCANLINE_U_SUBPIX_INCLUDED
15
16#include <agg_array.h>
17
18namespace agg
19{
20	//======================================================scanline_u8_subpix
21	//------------------------------------------------------------------------
22	class scanline_u8_subpix
23	{
24	public:
25		typedef scanline_u8_subpix self_type;
26		typedef int8u		cover_type;
27		typedef int16		coord_type;
28
29		//--------------------------------------------------------------------
30		struct span
31		{
32			coord_type	x;
33			coord_type	len;
34			cover_type* covers;
35		};
36
37		typedef span* iterator;
38		typedef const span* const_iterator;
39
40		//--------------------------------------------------------------------
41		scanline_u8_subpix() :
42			m_min_x(0),
43			m_last_x(0x7FFFFFF0),
44			m_cur_span(0)
45		{}
46
47		//--------------------------------------------------------------------
48		void reset(int min_x, int max_x)
49		{
50			unsigned max_len = 3*(max_x - min_x + 2);
51			if(max_len > m_spans.size())
52			{
53				m_spans.resize(max_len);
54				m_covers.resize(max_len);
55			}
56			m_last_x   = 0x7FFFFFF0;
57			m_min_x	   = min_x;
58			m_cur_span = &m_spans[0];
59		}
60
61		//--------------------------------------------------------------------
62		void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
63		{
64			x -= m_min_x;
65			m_covers[3 * x] = (cover_type)cover1;
66			m_covers[3 * x + 1] = (cover_type)cover2;
67			m_covers[3 * x + 2] = (cover_type)cover3;
68			if(x == m_last_x + 1)
69			{
70				m_cur_span->len += 3;
71			}
72			else
73			{
74				m_cur_span++;
75				m_cur_span->x	   = (coord_type)(x + m_min_x);
76				m_cur_span->len	   = 3;
77				m_cur_span->covers = &m_covers[3 * x];
78			}
79			m_last_x = x;
80		}
81
82		//--------------------------------------------------------------------
83		void add_span(int x, unsigned len, unsigned cover)
84		{
85			x -= m_min_x;
86			memset(&m_covers[3 * x], cover, 3 * len);
87			if(x == m_last_x+1)
88			{
89				m_cur_span->len += 3 * (coord_type)len;
90			}
91			else
92			{
93				m_cur_span++;
94				m_cur_span->x	   = (coord_type)(x + m_min_x);
95				m_cur_span->len	   = 3 * (coord_type)len;
96				m_cur_span->covers = &m_covers[3 * x];
97			}
98			m_last_x = x + len - 1;
99		}
100
101		//--------------------------------------------------------------------
102		void finalize(int y)
103		{
104			m_y = y;
105		}
106
107		//--------------------------------------------------------------------
108		void reset_spans()
109		{
110			m_last_x	= 0x7FFFFFF0;
111			m_cur_span	= &m_spans[0];
112		}
113
114		//--------------------------------------------------------------------
115		int		 y()		   const { return m_y; }
116		unsigned num_spans()   const { return unsigned(m_cur_span - &m_spans[0]); }
117		const_iterator begin() const { return &m_spans[1]; }
118		iterator	   begin()		 { return &m_spans[1]; }
119
120	private:
121		scanline_u8_subpix(const self_type&);
122		const self_type& operator = (const self_type&);
123
124	private:
125		int					  m_min_x;
126		int					  m_last_x;
127		int					  m_y;
128		pod_array<cover_type> m_covers;
129		pod_array<span>		  m_spans;
130		span*				  m_cur_span;
131	};
132
133}
134
135#endif
136
137