1/*
2 * Copyright 2005, Stephan A��mus <superstippi@gmx.de>.
3 * Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>
4 * All rights reserved. Distributed under the terms of the MIT License.
5 *
6 * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
7 *
8 * A class implementing the AGG "pixel format" interface which maintains
9 * a PatternHandler and pointers to blending functions implementing the
10 * different BeOS "drawing_modes".
11 *
12 */
13
14#ifndef PIXEL_FORMAT_H
15#define PIXEL_FORMAT_H
16
17#include <agg_basics.h>
18#include <agg_color_rgba.h>
19#include <agg_rendering_buffer.h>
20#include <agg_pixfmt_rgba.h>
21
22#include <GraphicsDefs.h>
23
24#include "AggCompOpAdapter.h"
25
26class PatternHandler;
27
28class PixelFormat {
29 public:
30	typedef agg::rgba8						color_type;
31	typedef agg::rendering_buffer			agg_buffer;
32	typedef agg::rendering_buffer::row_data	row_data;
33	typedef agg::order_bgra					order_type;
34
35	typedef agg::comp_op_rgba_src_in<color_type, order_type>	comp_src_in;
36	typedef agg::comp_op_rgba_src_out<color_type, order_type>	comp_src_out;
37	typedef agg::comp_op_rgba_src_atop<color_type, order_type>	comp_src_atop;
38	typedef agg::comp_op_rgba_dst_over<color_type, order_type>	comp_dst_over;
39	typedef agg::comp_op_rgba_dst_in<color_type, order_type>	comp_dst_in;
40	typedef agg::comp_op_rgba_dst_out<color_type, order_type>	comp_dst_out;
41	typedef agg::comp_op_rgba_dst_atop<color_type, order_type>	comp_dst_atop;
42	typedef agg::comp_op_rgba_xor<color_type, order_type>		comp_xor;
43	typedef agg::comp_op_rgba_clear<color_type, order_type>		comp_clear;
44	typedef agg::comp_op_rgba_difference<color_type, order_type>
45		comp_difference;
46	typedef agg::comp_op_rgba_lighten<color_type, order_type>	comp_lighten;
47	typedef agg::comp_op_rgba_darken<color_type, order_type>	comp_darken;
48
49	typedef AggCompOpAdapter<comp_src_in, agg_buffer>		alpha_src_in;
50	typedef AggCompOpAdapter<comp_src_out, agg_buffer>		alpha_src_out;
51	typedef AggCompOpAdapter<comp_src_atop, agg_buffer>		alpha_src_atop;
52	typedef AggCompOpAdapter<comp_dst_over, agg_buffer>		alpha_dst_over;
53	typedef AggCompOpAdapter<comp_dst_in, agg_buffer>		alpha_dst_in;
54	typedef AggCompOpAdapter<comp_dst_out, agg_buffer>		alpha_dst_out;
55	typedef AggCompOpAdapter<comp_dst_atop, agg_buffer>		alpha_dst_atop;
56	typedef AggCompOpAdapter<comp_xor, agg_buffer>			alpha_xor;
57	typedef AggCompOpAdapter<comp_clear, agg_buffer>		alpha_clear;
58	typedef AggCompOpAdapter<comp_difference, agg_buffer>	alpha_difference;
59	typedef AggCompOpAdapter<comp_lighten, agg_buffer>		alpha_lighten;
60	typedef AggCompOpAdapter<comp_darken, agg_buffer>		alpha_darken;
61
62	enum base_scale_e
63	{
64		base_shift = color_type::base_shift,
65		base_scale = color_type::base_scale,
66		base_mask  = color_type::base_mask,
67		pix_width  = 4,
68	};
69
70	typedef void (*blend_pixel_f)(int x, int y, const color_type& c,
71								  uint8 cover,
72								  agg_buffer* buffer,
73								  const PatternHandler* pattern);
74
75	typedef void (*blend_line)(int x, int y, unsigned len,
76							   const color_type& c, uint8 cover,
77							   agg_buffer* buffer,
78							   const PatternHandler* pattern);
79
80	typedef void (*blend_solid_span)(int x, int y, unsigned len,
81									 const color_type& c,
82									 const uint8* covers,
83									 agg_buffer* buffer,
84									 const PatternHandler* pattern);
85
86	typedef void (*blend_color_span)(int x, int y, unsigned len,
87									 const color_type* colors,
88									 const uint8* covers,
89									 uint8 cover,
90									 agg_buffer* buffer,
91									 const PatternHandler* pattern);
92
93			// PixelFormat class
94								PixelFormat(agg::rendering_buffer& buffer,
95											const PatternHandler* handler);
96
97								~PixelFormat();
98
99
100			void				SetDrawingMode(drawing_mode mode,
101											   source_alpha alphaSrcMode,
102											   alpha_function alphaFncMode);
103
104			// AGG "pixel format" interface
105	inline	unsigned			width() const
106									{ return fBuffer->width(); }
107	inline	unsigned			height() const
108									{ return fBuffer->height(); }
109	inline	int					stride() const
110									{ return fBuffer->stride(); }
111
112	inline	uint8*				row_ptr(int y)
113									{ return fBuffer->row_ptr(y); }
114	inline	const uint8*		row_ptr(int y) const
115									{ return fBuffer->row_ptr(y); }
116	inline	row_data			row(int y) const
117									{ return fBuffer->row(y); }
118
119	inline	uint8*				pix_ptr(int x, int y);
120	inline	const uint8*		pix_ptr(int x, int y) const;
121
122	inline	static	void		make_pix(uint8* p, const color_type& c);
123//	inline	color_type			pixel(int x, int y) const;
124
125	inline	void				blend_pixel(int x, int y,
126											const color_type& c,
127											uint8 cover);
128
129
130	inline	void				blend_hline(int x, int y,
131											unsigned len,
132											const color_type& c,
133											uint8 cover);
134
135	inline	void				blend_vline(int x, int y,
136											unsigned len,
137											const color_type& c,
138											uint8 cover);
139
140	inline	void				blend_solid_hspan(int x, int y,
141												  unsigned len,
142												  const color_type& c,
143												  const uint8* covers);
144
145	inline	void				blend_solid_hspan_subpix(int x, int y,
146												  unsigned len,
147												  const color_type& c,
148												  const uint8* covers);
149
150	inline	void				blend_solid_vspan(int x, int y,
151												  unsigned len,
152												  const color_type& c,
153												  const uint8* covers);
154
155	inline	void				blend_color_hspan(int x, int y,
156												  unsigned len,
157												  const color_type* colors,
158												  const uint8* covers,
159												  uint8 cover);
160
161	inline	void				blend_color_vspan(int x, int y,
162												  unsigned len,
163												  const color_type* colors,
164												  const uint8* covers,
165												  uint8 cover);
166
167 private:
168	agg::rendering_buffer*		fBuffer;
169	const PatternHandler*		fPatternHandler;
170
171	blend_pixel_f				fBlendPixel;
172	blend_line					fBlendHLine;
173	blend_line					fBlendVLine;
174	blend_solid_span			fBlendSolidHSpan;
175	blend_solid_span            fBlendSolidHSpanSubpix;
176	blend_solid_span			fBlendSolidVSpan;
177	blend_color_span			fBlendColorHSpan;
178	blend_color_span			fBlendColorVSpan;
179
180	template<typename T>
181	void SetAggCompOpAdapter()
182	{
183		fBlendPixel = T::blend_pixel;
184		fBlendHLine = T::blend_hline;
185		fBlendSolidHSpanSubpix = T::blend_solid_hspan_subpix;
186		fBlendSolidHSpan = T::blend_solid_hspan;
187		fBlendSolidVSpan = T::blend_solid_vspan;
188		fBlendColorHSpan = T::blend_color_hspan;
189	}
190};
191
192// inlined functions
193
194// pix_ptr
195inline uint8*
196PixelFormat::pix_ptr(int x, int y)
197{
198	return fBuffer->row_ptr(y) + x * pix_width;
199}
200
201// pix_ptr
202inline const uint8*
203PixelFormat::pix_ptr(int x, int y) const
204{
205	return fBuffer->row_ptr(y) + x * pix_width;
206}
207
208// make_pix
209inline void
210PixelFormat::make_pix(uint8* p, const color_type& c)
211{
212	p[0] = c.b;
213	p[1] = c.g;
214	p[2] = c.r;
215	p[3] = c.a;
216}
217
218//// pixel
219//inline color_type
220//PixelFormat::pixel(int x, int y) const
221//{
222//	const uint8* p = (const uint8*)fBuffer->row_ptr(y);
223//	if (p) {
224//		p += x << 2;
225//		return color_type(p[2], p[1], p[0], p[3]);
226//	}
227//	return color_type::no_color();
228//}
229
230// blend_pixel
231inline void
232PixelFormat::blend_pixel(int x, int y, const color_type& c, uint8 cover)
233{
234	fBlendPixel(x, y, c, cover, fBuffer, fPatternHandler);
235}
236
237// blend_hline
238inline void
239PixelFormat::blend_hline(int x, int y, unsigned len,
240						 const color_type& c, uint8 cover)
241{
242	fBlendHLine(x, y, len, c, cover, fBuffer, fPatternHandler);
243}
244
245// blend_vline
246inline void
247PixelFormat::blend_vline(int x, int y, unsigned len,
248						 const color_type& c, uint8 cover)
249{
250	fBlendVLine(x, y, len, c, cover, fBuffer, fPatternHandler);
251}
252
253// blend_solid_hspan
254inline void
255PixelFormat::blend_solid_hspan(int x, int y, unsigned len,
256							   const color_type& c, const uint8* covers)
257{
258	fBlendSolidHSpan(x, y, len, c, covers, fBuffer, fPatternHandler);
259}
260
261// blend_solid_hspan_subpix
262inline void
263PixelFormat::blend_solid_hspan_subpix(int x, int y, unsigned len,
264							   const color_type& c, const uint8* covers)
265{
266	fBlendSolidHSpanSubpix(x, y, len, c, covers, fBuffer, fPatternHandler);
267}
268
269// blend_solid_vspan
270inline void
271PixelFormat::blend_solid_vspan(int x, int y, unsigned len,
272							   const color_type& c, const uint8* covers)
273{
274	fBlendSolidVSpan(x, y, len, c, covers, fBuffer, fPatternHandler);
275}
276
277// blend_color_hspan
278inline void
279PixelFormat::blend_color_hspan(int x, int y, unsigned len,
280							   const color_type* colors,
281							   const uint8* covers,
282							   uint8 cover)
283{
284	fBlendColorHSpan(x, y, len, colors, covers, cover,
285					 fBuffer, fPatternHandler);
286}
287
288// blend_color_vspan
289inline void
290PixelFormat::blend_color_vspan(int x, int y, unsigned len,
291							   const color_type* colors,
292							   const uint8* covers,
293							   uint8 cover)
294{
295	fBlendColorVSpan(x, y, len, colors, covers, cover,
296					 fBuffer, fPatternHandler);
297}
298
299#endif // PIXEL_FORMAT_H
300
301