xref: /haiku/src/servers/app/drawing/Painter/agg_scanline_u_subpix.h (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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 
18 namespace 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