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#include "PixelFormat.h"
15
16#include <stdio.h>
17
18#include "DrawingModeAdd.h"
19#include "DrawingModeAlphaCC.h"
20#include "DrawingModeAlphaCO.h"
21#include "DrawingModeAlphaCOSolid.h"
22#include "DrawingModeAlphaPC.h"
23#include "DrawingModeAlphaPO.h"
24#include "DrawingModeAlphaPOSolid.h"
25#include "DrawingModeBlend.h"
26#include "DrawingModeCopy.h"
27#include "DrawingModeCopySolid.h"
28#include "DrawingModeCopyText.h"
29#include "DrawingModeErase.h"
30#include "DrawingModeInvert.h"
31#include "DrawingModeMin.h"
32#include "DrawingModeMax.h"
33#include "DrawingModeOver.h"
34#include "DrawingModeOverSolid.h"
35#include "DrawingModeSelect.h"
36#include "DrawingModeSubtract.h"
37
38#include "DrawingModeAddSUBPIX.h"
39#include "DrawingModeAlphaCCSUBPIX.h"
40#include "DrawingModeAlphaCOSUBPIX.h"
41#include "DrawingModeAlphaCOSolidSUBPIX.h"
42#include "DrawingModeAlphaPCSUBPIX.h"
43#include "DrawingModeAlphaPOSUBPIX.h"
44#include "DrawingModeAlphaPOSolidSUBPIX.h"
45#include "DrawingModeBlendSUBPIX.h"
46#include "DrawingModeCopySUBPIX.h"
47#include "DrawingModeCopySolidSUBPIX.h"
48#include "DrawingModeCopyTextSUBPIX.h"
49#include "DrawingModeEraseSUBPIX.h"
50#include "DrawingModeInvertSUBPIX.h"
51#include "DrawingModeMinSUBPIX.h"
52#include "DrawingModeMaxSUBPIX.h"
53#include "DrawingModeOverSUBPIX.h"
54#include "DrawingModeOverSolidSUBPIX.h"
55#include "DrawingModeSelectSUBPIX.h"
56#include "DrawingModeSubtractSUBPIX.h"
57
58#include "PatternHandler.h"
59
60// blend_pixel_empty
61void
62blend_pixel_empty(int x, int y, const color_type& c, uint8 cover,
63				  agg_buffer* buffer, const PatternHandler* pattern)
64{
65	printf("blend_pixel_empty()\n");
66}
67
68// blend_hline_empty
69void
70blend_hline_empty(int x, int y, unsigned len,
71				  const color_type& c, uint8 cover,
72				  agg_buffer* buffer, const PatternHandler* pattern)
73{
74	printf("blend_hline_empty()\n");
75}
76
77// blend_vline_empty
78void
79blend_vline_empty(int x, int y, unsigned len,
80				  const color_type& c, uint8 cover,
81				  agg_buffer* buffer, const PatternHandler* pattern)
82{
83	printf("blend_vline_empty()\n");
84}
85
86// blend_solid_hspan_empty
87void
88blend_solid_hspan_empty(int x, int y, unsigned len,
89						const color_type& c, const uint8* covers,
90						agg_buffer* buffer, const PatternHandler* pattern)
91{
92	printf("blend_solid_hspan_empty()\n");
93}
94
95// blend_solid_hspan_subpix_empty
96void
97blend_solid_hspan_empty_subpix(int x, int y, unsigned len,
98						const color_type& c, const uint8* covers,
99						agg_buffer* buffer, const PatternHandler* pattern)
100{
101	printf("blend_solid_hspan_empty_subpix()\n");
102}
103
104// blend_solid_vspan_empty
105void
106blend_solid_vspan_empty(int x, int y,
107						unsigned len, const color_type& c,
108						const uint8* covers,
109						agg_buffer* buffer, const PatternHandler* pattern)
110{
111	printf("blend_solid_vspan_empty()\n");
112}
113
114// blend_color_hspan_empty
115void
116blend_color_hspan_empty(int x, int y, unsigned len,
117						const color_type* colors,
118						const uint8* covers, uint8 cover,
119						agg_buffer* buffer, const PatternHandler* pattern)
120{
121	printf("blend_color_hspan_empty()\n");
122}
123
124// blend_color_vspan_empty
125void
126blend_color_vspan_empty(int x, int y, unsigned len,
127						const color_type* colors,
128						const uint8* covers, uint8 cover,
129						agg_buffer* buffer, const PatternHandler* pattern)
130{
131	printf("blend_color_vspan_empty()\n");
132}
133
134// #pragma mark -
135
136// constructor
137PixelFormat::PixelFormat(agg::rendering_buffer& rb,
138						 const PatternHandler* handler)
139	: fBuffer(&rb),
140	  fPatternHandler(handler),
141	  fUsesOpCopyForText(false),
142
143	  fBlendPixel(blend_pixel_empty),
144	  fBlendHLine(blend_hline_empty),
145	  fBlendVLine(blend_vline_empty),
146	  fBlendSolidHSpan(blend_solid_hspan_empty),
147	  fBlendSolidHSpanSubpix(blend_solid_hspan_empty_subpix),
148	  fBlendSolidVSpan(blend_solid_vspan_empty),
149	  fBlendColorHSpan(blend_color_hspan_empty),
150	  fBlendColorVSpan(blend_color_vspan_empty)
151{
152}
153
154// destructor
155PixelFormat::~PixelFormat()
156{
157}
158
159// SetDrawingMode
160void
161PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
162							alpha_function alphaFncMode, bool text)
163{
164	fUsesOpCopyForText = false;
165	switch (mode) {
166		// these drawing modes discard source pixels
167		// which have the current low color
168		case B_OP_OVER:
169			if (fPatternHandler->IsSolid()) {
170				fBlendPixel = blend_pixel_over_solid;
171				fBlendHLine = blend_hline_over_solid;
172				fBlendSolidHSpan = blend_solid_hspan_over_solid;
173				fBlendSolidVSpan = blend_solid_vspan_over_solid;
174				fBlendSolidHSpanSubpix = blend_solid_hspan_over_solid_subpix;
175			} else {
176				fBlendPixel = blend_pixel_over;
177				fBlendHLine = blend_hline_over;
178				fBlendSolidHSpanSubpix = blend_solid_hspan_over_subpix;
179				fBlendSolidHSpan = blend_solid_hspan_over;
180				fBlendSolidVSpan = blend_solid_vspan_over;
181			}
182			fBlendColorHSpan = blend_color_hspan_over;
183			break;
184		case B_OP_ERASE:
185			fBlendPixel = blend_pixel_erase;
186			fBlendHLine = blend_hline_erase;
187			fBlendSolidHSpanSubpix = blend_solid_hspan_erase_subpix;
188			fBlendSolidHSpan = blend_solid_hspan_erase;
189			fBlendSolidVSpan = blend_solid_vspan_erase;
190			fBlendColorHSpan = blend_color_hspan_erase;
191			break;
192		case B_OP_INVERT:
193			fBlendPixel = blend_pixel_invert;
194			fBlendHLine = blend_hline_invert;
195			fBlendSolidHSpanSubpix = blend_solid_hspan_invert_subpix;
196			fBlendSolidHSpan = blend_solid_hspan_invert;
197			fBlendSolidVSpan = blend_solid_vspan_invert;
198			fBlendColorHSpan = blend_color_hspan_invert;
199			break;
200		case B_OP_SELECT:
201			fBlendPixel = blend_pixel_select;
202			fBlendHLine = blend_hline_select;
203			fBlendSolidHSpanSubpix = blend_solid_hspan_select_subpix;
204			fBlendSolidHSpan = blend_solid_hspan_select;
205			fBlendSolidVSpan = blend_solid_vspan_select;
206			fBlendColorHSpan = blend_color_hspan_select;
207			break;
208
209		// in these drawing modes, the current high
210		// and low color are treated equally
211		case B_OP_COPY:
212			if (text) {
213				fBlendPixel = blend_pixel_copy_text;
214				fBlendHLine = blend_hline_copy_text;
215				fBlendSolidHSpanSubpix = blend_solid_hspan_copy_text_subpix;
216				fBlendSolidHSpan = blend_solid_hspan_copy_text;
217				fBlendSolidVSpan = blend_solid_vspan_copy_text;
218				fBlendColorHSpan = blend_color_hspan_copy_text;
219				// set the special flag so that Painter
220				// knows if an update is needed even though
221				// "nothing changed"
222				fUsesOpCopyForText = true;
223			} else if (fPatternHandler->IsSolid()) {
224				fBlendPixel = blend_pixel_copy_solid;
225				fBlendHLine = blend_hline_copy_solid;
226				fBlendSolidHSpanSubpix = blend_solid_hspan_copy_solid_subpix;
227				fBlendSolidHSpan = blend_solid_hspan_copy_solid;
228				fBlendSolidVSpan = blend_solid_vspan_copy_solid;
229				fBlendColorHSpan = blend_color_hspan_copy_solid;
230			} else {
231				fBlendPixel = blend_pixel_copy;
232				fBlendHLine = blend_hline_copy;
233				fBlendSolidHSpanSubpix = blend_solid_hspan_copy_subpix;
234				fBlendSolidHSpan = blend_solid_hspan_copy;
235				fBlendSolidVSpan = blend_solid_vspan_copy;
236				fBlendColorHSpan = blend_color_hspan_copy;
237			}
238			break;
239		case B_OP_ADD:
240			fBlendPixel = blend_pixel_add;
241			fBlendHLine = blend_hline_add;
242			fBlendSolidHSpanSubpix = blend_solid_hspan_add_subpix;
243			fBlendSolidHSpan = blend_solid_hspan_add;
244			fBlendSolidVSpan = blend_solid_vspan_add;
245			fBlendColorHSpan = blend_color_hspan_add;
246			break;
247		case B_OP_SUBTRACT:
248			fBlendPixel = blend_pixel_subtract;
249			fBlendHLine = blend_hline_subtract;
250			fBlendSolidHSpanSubpix = blend_solid_hspan_subtract_subpix;
251			fBlendSolidHSpan = blend_solid_hspan_subtract;
252			fBlendSolidVSpan = blend_solid_vspan_subtract;
253			fBlendColorHSpan = blend_color_hspan_subtract;
254			break;
255		case B_OP_BLEND:
256			fBlendPixel = blend_pixel_blend;
257			fBlendHLine = blend_hline_blend;
258			fBlendSolidHSpanSubpix = blend_solid_hspan_blend_subpix;
259			fBlendSolidHSpan = blend_solid_hspan_blend;
260			fBlendSolidVSpan = blend_solid_vspan_blend;
261			fBlendColorHSpan = blend_color_hspan_blend;
262			break;
263		case B_OP_MIN:
264			fBlendPixel = blend_pixel_min;
265			fBlendHLine = blend_hline_min;
266			fBlendSolidHSpanSubpix = blend_solid_hspan_min_subpix;
267			fBlendSolidHSpan = blend_solid_hspan_min;
268			fBlendSolidVSpan = blend_solid_vspan_min;
269			fBlendColorHSpan = blend_color_hspan_min;
270			break;
271		case B_OP_MAX:
272			fBlendPixel = blend_pixel_max;
273			fBlendHLine = blend_hline_max;
274			fBlendSolidHSpanSubpix = blend_solid_hspan_max_subpix;
275			fBlendSolidHSpan = blend_solid_hspan_max;
276			fBlendSolidVSpan = blend_solid_vspan_max;
277			fBlendColorHSpan = blend_color_hspan_max;
278			break;
279
280		// this drawing mode is the only one considering
281		// alpha at all. In B_CONSTANT_ALPHA, the alpha
282		// value from the current high color is used for
283		// all computations. In B_PIXEL_ALPHA, the alpha
284		// is considered at every source pixel.
285		// To simplify the implementation, four separate
286		// DrawingMode classes are used to cover the
287		// four possible combinations of alpha enabled drawing.
288		case B_OP_ALPHA:
289			if (alphaSrcMode == B_CONSTANT_ALPHA) {
290				if (alphaFncMode == B_ALPHA_OVERLAY) {
291					if (fPatternHandler->IsSolid()) {
292						fBlendPixel = blend_pixel_alpha_co_solid;
293						fBlendHLine = blend_hline_alpha_co_solid;
294						fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_co_solid_subpix;
295						fBlendSolidHSpan = blend_solid_hspan_alpha_co_solid;
296						fBlendSolidVSpan = blend_solid_vspan_alpha_co_solid;
297					} else {
298						fBlendPixel = blend_pixel_alpha_co;
299						fBlendHLine = blend_hline_alpha_co;
300						fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_co_subpix;
301						fBlendSolidHSpan = blend_solid_hspan_alpha_co;
302						fBlendSolidVSpan = blend_solid_vspan_alpha_co;
303					}
304					fBlendColorHSpan = blend_color_hspan_alpha_co;
305				} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
306					fBlendPixel = blend_pixel_alpha_cc;
307					fBlendHLine = blend_hline_alpha_cc;
308					fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_cc_subpix;
309					fBlendSolidHSpan = blend_solid_hspan_alpha_cc;
310					fBlendSolidVSpan = blend_solid_vspan_alpha_cc;
311					fBlendColorHSpan = blend_color_hspan_alpha_cc;
312				}
313			} else if (alphaSrcMode == B_PIXEL_ALPHA){
314				if (alphaFncMode == B_ALPHA_OVERLAY) {
315					if (fPatternHandler->IsSolid()) {
316						fBlendPixel = blend_pixel_alpha_po_solid;
317						fBlendHLine = blend_hline_alpha_po_solid;
318						fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_po_solid_subpix;
319						fBlendSolidHSpan = blend_solid_hspan_alpha_po_solid;
320						fBlendSolidVSpan = blend_solid_vspan_alpha_po_solid;
321					} else {
322						fBlendPixel = blend_pixel_alpha_po;
323						fBlendHLine = blend_hline_alpha_po;
324						fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_po_subpix;
325						fBlendSolidHSpan = blend_solid_hspan_alpha_po;
326						fBlendSolidVSpan = blend_solid_vspan_alpha_po;
327					}
328					fBlendColorHSpan = blend_color_hspan_alpha_po;
329				} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
330					fBlendPixel = blend_pixel_alpha_pc;
331					fBlendHLine = blend_hline_alpha_pc;
332					fBlendSolidHSpanSubpix = blend_solid_hspan_alpha_pc_subpix;
333					fBlendSolidHSpan = blend_solid_hspan_alpha_pc;
334					fBlendSolidVSpan = blend_solid_vspan_alpha_pc;
335					fBlendColorHSpan = blend_color_hspan_alpha_pc;
336				}
337			}
338			break;
339
340		default:
341fprintf(stderr, "PixelFormat::SetDrawingMode() - drawing_mode not implemented\n");
342//			return fDrawingModeBGRA32Copy;
343			break;
344	}
345}
346