xref: /haiku/src/servers/app/drawing/Painter/agg_scanline_p_subpix.h (revision 59e13a3f06eedbc797f797da71c6810634b22cd4)
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_p8_subpix_avrg_filtering, a slightly modified version of
9  * scanline_p8 customized to store 3 covers per pixel
10  *
11  */
12 
13 #ifndef AGG_SCANLINE_P_SUBPIX_INCLUDED
14 #define AGG_SCANLINE_P_SUBPIX_INCLUDED
15 
16 #include "agg_array.h"
17 
18 namespace agg
19 {
20 
21 	//======================================================scanline_p8_subpix
22 	//
23 	// This is a general purpose scaline container which supports the interface
24 	// used in the rasterizer::render(). See description of scanline_u8
25 	// for details.
26 	//
27 	//------------------------------------------------------------------------
28 	class scanline_p8_subpix
29 	{
30 	public:
31 		typedef scanline_p8_subpix	self_type;
32 		typedef int8u				cover_type;
33 		typedef int16				coord_type;
34 
35 		//--------------------------------------------------------------------
36 		struct span
37 		{
38 			coord_type		  x;
39 			coord_type		  len; // If negative, it's a solid span, covers is valid
40 			const cover_type* covers;
41 		};
42 
43 		typedef span* iterator;
44 		typedef const span* const_iterator;
45 
scanline_p8_subpix()46 		scanline_p8_subpix() :
47 			m_last_x(0x7FFFFFF0),
48 			m_covers(),
49 			m_cover_ptr(0),
50 			m_spans(),
51 			m_cur_span(0)
52 		{
53 		}
54 
55 		//--------------------------------------------------------------------
reset(int min_x,int max_x)56 		void reset(int min_x, int max_x)
57 		{
58 			unsigned max_len = 3*(max_x - min_x + 3);
59 			if(max_len > m_spans.size())
60 			{
61 				m_spans.resize(max_len);
62 				m_covers.resize(max_len);
63 			}
64 			m_last_x	= 0x7FFFFFF0;
65 			m_cover_ptr = &m_covers[0];
66 			m_cur_span	= &m_spans[0];
67 			m_cur_span->len = 0;
68 		}
69 
70 		//--------------------------------------------------------------------
add_cell(int x,unsigned cover1,unsigned cover2,unsigned cover3)71 		void add_cell(int x, unsigned cover1, unsigned cover2, unsigned cover3)
72 		{
73 			m_cover_ptr[0] = (cover_type)cover1;
74 			m_cover_ptr[1] = (cover_type)cover2;
75 			m_cover_ptr[2] = (cover_type)cover3;
76 			if(x == m_last_x+1 && m_cur_span->len > 0)
77 			{
78 				m_cur_span->len += 3;
79 			}
80 			else
81 			{
82 				m_cur_span++;
83 				m_cur_span->covers = m_cover_ptr;
84 				m_cur_span->x = (int16)x;
85 				m_cur_span->len = 3;
86 			}
87 			m_last_x = x;
88 			m_cover_ptr += 3;
89 		}
90 
91 		//--------------------------------------------------------------------
add_cells(int x,unsigned len,const cover_type * covers)92 		void add_cells(int x, unsigned len, const cover_type* covers)
93 		{
94 			memcpy(m_cover_ptr, covers, 3 * len * sizeof(cover_type));
95 			if(x == m_last_x+1 && m_cur_span->len > 0)
96 			{
97 				m_cur_span->len += 3 * (int16)len;
98 			}
99 			else
100 			{
101 				m_cur_span++;
102 				m_cur_span->covers = m_cover_ptr;
103 				m_cur_span->x = (int16)x;
104 				m_cur_span->len = 3 * (int16)len;
105 			}
106 			m_cover_ptr += 3 * len;
107 			m_last_x = x + len - 1;
108 		}
109 
110 		//--------------------------------------------------------------------
add_span(int x,unsigned len,unsigned cover)111 		void add_span(int x, unsigned len, unsigned cover)
112 		{
113 			if(x == m_last_x+1 &&
114 			   m_cur_span->len < 0 &&
115 			   cover == *m_cur_span->covers)
116 			{
117 				m_cur_span->len -= 3 * (int16)len;
118 			}
119 			else
120 			{
121 				*m_cover_ptr = (cover_type)cover;
122 				m_cur_span++;
123 				m_cur_span->covers = m_cover_ptr;
124 				m_cover_ptr += 3;
125 				m_cur_span->x	   = (int16)x;
126 				m_cur_span->len	   = 3 * (int16)(-int(len));
127 			}
128 			m_last_x = x + len - 1;
129 		}
130 
131 		//--------------------------------------------------------------------
finalize(int y)132 		void finalize(int y)
133 		{
134 			m_y = y;
135 		}
136 
137 		//--------------------------------------------------------------------
reset_spans()138 		void reset_spans()
139 		{
140 			m_last_x	= 0x7FFFFFF0;
141 			m_cover_ptr = &m_covers[0];
142 			m_cur_span	= &m_spans[0];
143 			m_cur_span->len = 0;
144 		}
145 
146 		//--------------------------------------------------------------------
y()147 		int			   y()		   const { return m_y; }
num_spans()148 		unsigned	   num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
begin()149 		const_iterator begin()	   const { return &m_spans[1]; }
150 
151 	private:
152 		scanline_p8_subpix(const self_type&);
153 		const self_type& operator = (const self_type&);
154 
155 		int					  m_last_x;
156 		int					  m_y;
157 		pod_array<cover_type> m_covers;
158 		cover_type*			  m_cover_ptr;
159 		pod_array<span>		  m_spans;
160 		span*				  m_cur_span;
161 	};
162 
163 }
164 
165 
166 #endif
167 
168