xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/PixelFormat.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 /*
2  * Copyright 2005, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Copyright 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
6  *
7  * A class implementing the AGG "pixel format" interface which maintains
8  * a PatternHandler and pointers to blending functions implementing the
9  * different BeOS "drawing_modes".
10  *
11  */
12 
13 #include "PixelFormat.h"
14 
15 #include <stdio.h>
16 
17 #include "DrawingModeAdd.h"
18 #include "DrawingModeAlphaCC.h"
19 #include "DrawingModeAlphaCO.h"
20 #include "DrawingModeAlphaCOSolid.h"
21 #include "DrawingModeAlphaPC.h"
22 #include "DrawingModeAlphaPO.h"
23 #include "DrawingModeAlphaPOSolid.h"
24 #include "DrawingModeBlend.h"
25 #include "DrawingModeCopy.h"
26 #include "DrawingModeCopySolid.h"
27 #include "DrawingModeCopyText.h"
28 #include "DrawingModeErase.h"
29 #include "DrawingModeInvert.h"
30 #include "DrawingModeMin.h"
31 #include "DrawingModeMax.h"
32 #include "DrawingModeOver.h"
33 #include "DrawingModeOverSolid.h"
34 #include "DrawingModeSelect.h"
35 #include "DrawingModeSubtract.h"
36 
37 #include "PatternHandler.h"
38 
39 // blend_pixel_empty
40 void
41 blend_pixel_empty(int x, int y, const color_type& c, uint8 cover,
42 				  agg_buffer* buffer, const PatternHandler* pattern)
43 {
44 	printf("blend_pixel_empty()\n");
45 }
46 
47 // blend_hline_empty
48 void
49 blend_hline_empty(int x, int y, unsigned len,
50 				  const color_type& c, uint8 cover,
51 				  agg_buffer* buffer, const PatternHandler* pattern)
52 {
53 	printf("blend_hline_empty()\n");
54 }
55 
56 // blend_vline_empty
57 void
58 blend_vline_empty(int x, int y, unsigned len,
59 				  const color_type& c, uint8 cover,
60 				  agg_buffer* buffer, const PatternHandler* pattern)
61 {
62 	printf("blend_vline_empty()\n");
63 }
64 
65 // blend_solid_hspan_empty
66 void
67 blend_solid_hspan_empty(int x, int y, unsigned len,
68 						const color_type& c, const uint8* covers,
69 						agg_buffer* buffer, const PatternHandler* pattern)
70 {
71 	printf("blend_solid_hspan_empty()\n");
72 }
73 
74 // blend_solid_vspan_empty
75 void
76 blend_solid_vspan_empty(int x, int y,
77 						unsigned len, const color_type& c,
78 						const uint8* covers,
79 						agg_buffer* buffer, const PatternHandler* pattern)
80 {
81 	printf("blend_solid_vspan_empty()\n");
82 }
83 
84 // blend_color_hspan_empty
85 void
86 blend_color_hspan_empty(int x, int y, unsigned len,
87 						const color_type* colors,
88 						const uint8* covers, uint8 cover,
89 						agg_buffer* buffer, const PatternHandler* pattern)
90 {
91 	printf("blend_color_hspan_empty()\n");
92 }
93 
94 // blend_color_vspan_empty
95 void
96 blend_color_vspan_empty(int x, int y, unsigned len,
97 						const color_type* colors,
98 						const uint8* covers, uint8 cover,
99 						agg_buffer* buffer, const PatternHandler* pattern)
100 {
101 	printf("blend_color_vspan_empty()\n");
102 }
103 
104 // #pragma mark -
105 
106 // constructor
107 PixelFormat::PixelFormat(agg::rendering_buffer& rb,
108 						 const PatternHandler* handler)
109 	: fBuffer(&rb),
110 	  fPatternHandler(handler),
111 	  fUsesOpCopyForText(false),
112 
113 	  fBlendPixel(blend_pixel_empty),
114 	  fBlendHLine(blend_hline_empty),
115 	  fBlendVLine(blend_vline_empty),
116 	  fBlendSolidHSpan(blend_solid_hspan_empty),
117 	  fBlendSolidVSpan(blend_solid_vspan_empty),
118 	  fBlendColorHSpan(blend_color_hspan_empty),
119 	  fBlendColorVSpan(blend_color_vspan_empty)
120 {
121 }
122 
123 // destructor
124 PixelFormat::~PixelFormat()
125 {
126 }
127 
128 // SetDrawingMode
129 void
130 PixelFormat::SetDrawingMode(drawing_mode mode, source_alpha alphaSrcMode,
131 							alpha_function alphaFncMode, bool text)
132 {
133 	fUsesOpCopyForText = false;
134 	switch (mode) {
135 		// these drawing modes discard source pixels
136 		// which have the current low color
137 		case B_OP_OVER:
138 			if (fPatternHandler->IsSolid()) {
139 				fBlendPixel = blend_pixel_over;
140 				fBlendHLine = blend_hline_over;
141 				fBlendSolidHSpan = blend_solid_hspan_over;
142 				fBlendSolidVSpan = blend_solid_vspan_over;
143 				fBlendColorHSpan = blend_color_hspan_over;
144 			} else {
145 				fBlendPixel = blend_pixel_over_solid;
146 				fBlendHLine = blend_hline_over_solid;
147 				fBlendSolidHSpan = blend_solid_hspan_over_solid;
148 				fBlendSolidVSpan = blend_solid_vspan_over_solid;
149 				fBlendColorHSpan = blend_color_hspan_over_solid;
150 			}
151 			break;
152 		case B_OP_ERASE:
153 			fBlendPixel = blend_pixel_erase;
154 			fBlendHLine = blend_hline_erase;
155 			fBlendSolidHSpan = blend_solid_hspan_erase;
156 			fBlendSolidVSpan = blend_solid_vspan_erase;
157 			fBlendColorHSpan = blend_color_hspan_erase;
158 			break;
159 		case B_OP_INVERT:
160 			fBlendPixel = blend_pixel_invert;
161 			fBlendHLine = blend_hline_invert;
162 			fBlendSolidHSpan = blend_solid_hspan_invert;
163 			fBlendSolidVSpan = blend_solid_vspan_invert;
164 			fBlendColorHSpan = blend_color_hspan_invert;
165 			break;
166 		case B_OP_SELECT:
167 			fBlendPixel = blend_pixel_select;
168 			fBlendHLine = blend_hline_select;
169 			fBlendSolidHSpan = blend_solid_hspan_select;
170 			fBlendSolidVSpan = blend_solid_vspan_select;
171 			fBlendColorHSpan = blend_color_hspan_select;
172 			break;
173 
174 		// in these drawing modes, the current high
175 		// and low color are treated equally
176 		case B_OP_COPY:
177 			if (text) {
178 				fBlendPixel = blend_pixel_copy_text;
179 				fBlendHLine = blend_hline_copy_text;
180 				fBlendSolidHSpan = blend_solid_hspan_copy_text;
181 				fBlendSolidVSpan = blend_solid_vspan_copy_text;
182 				fBlendColorHSpan = blend_color_hspan_copy_text;
183 				// set the special flag so that Painter
184 				// knows if an update is needed even though
185 				// "nothing changed"
186 				fUsesOpCopyForText = true;
187 			} else if (fPatternHandler->IsSolid()) {
188 				fBlendPixel = blend_pixel_copy_solid;
189 				fBlendHLine = blend_hline_copy_solid;
190 				fBlendSolidHSpan = blend_solid_hspan_copy_solid;
191 				fBlendSolidVSpan = blend_solid_vspan_copy_solid;
192 				fBlendColorHSpan = blend_color_hspan_copy_solid;
193 			} else {
194 				fBlendPixel = blend_pixel_copy;
195 				fBlendHLine = blend_hline_copy;
196 				fBlendSolidHSpan = blend_solid_hspan_copy;
197 				fBlendSolidVSpan = blend_solid_vspan_copy;
198 				fBlendColorHSpan = blend_color_hspan_copy;
199 			}
200 			break;
201 		case B_OP_ADD:
202 			fBlendPixel = blend_pixel_add;
203 			fBlendHLine = blend_hline_add;
204 			fBlendSolidHSpan = blend_solid_hspan_add;
205 			fBlendSolidVSpan = blend_solid_vspan_add;
206 			fBlendColorHSpan = blend_color_hspan_add;
207 			break;
208 		case B_OP_SUBTRACT:
209 			fBlendPixel = blend_pixel_subtract;
210 			fBlendHLine = blend_hline_subtract;
211 			fBlendSolidHSpan = blend_solid_hspan_subtract;
212 			fBlendSolidVSpan = blend_solid_vspan_subtract;
213 			fBlendColorHSpan = blend_color_hspan_subtract;
214 			break;
215 		case B_OP_BLEND:
216 			fBlendPixel = blend_pixel_blend;
217 			fBlendHLine = blend_hline_blend;
218 			fBlendSolidHSpan = blend_solid_hspan_blend;
219 			fBlendSolidVSpan = blend_solid_vspan_blend;
220 			fBlendColorHSpan = blend_color_hspan_blend;
221 			break;
222 		case B_OP_MIN:
223 			fBlendPixel = blend_pixel_min;
224 			fBlendHLine = blend_hline_min;
225 			fBlendSolidHSpan = blend_solid_hspan_min;
226 			fBlendSolidVSpan = blend_solid_vspan_min;
227 			fBlendColorHSpan = blend_color_hspan_min;
228 			break;
229 		case B_OP_MAX:
230 			fBlendPixel = blend_pixel_max;
231 			fBlendHLine = blend_hline_max;
232 			fBlendSolidHSpan = blend_solid_hspan_max;
233 			fBlendSolidVSpan = blend_solid_vspan_max;
234 			fBlendColorHSpan = blend_color_hspan_max;
235 			break;
236 
237 		// this drawing mode is the only one considering
238 		// alpha at all. In B_CONSTANT_ALPHA, the alpha
239 		// value from the current high color is used for
240 		// all computations. In B_PIXEL_ALPHA, the alpha
241 		// is considered at every source pixel.
242 		// To simplify the implementation, four separate
243 		// DrawingMode classes are used to cover the
244 		// four possible combinations of alpha enabled drawing.
245 		case B_OP_ALPHA:
246 			if (alphaSrcMode == B_CONSTANT_ALPHA) {
247 				if (alphaFncMode == B_ALPHA_OVERLAY) {
248 					if (fPatternHandler->IsSolid()) {
249 						fBlendPixel = blend_pixel_alpha_co_solid;
250 						fBlendHLine = blend_hline_alpha_co_solid;
251 						fBlendSolidHSpan = blend_solid_hspan_alpha_co_solid;
252 						fBlendSolidVSpan = blend_solid_vspan_alpha_co_solid;
253 					} else {
254 						fBlendPixel = blend_pixel_alpha_co;
255 						fBlendHLine = blend_hline_alpha_co;
256 						fBlendSolidHSpan = blend_solid_hspan_alpha_co;
257 						fBlendSolidVSpan = blend_solid_vspan_alpha_co;
258 					}
259 					fBlendColorHSpan = blend_color_hspan_alpha_co;
260 				} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
261 					fBlendPixel = blend_pixel_alpha_cc;
262 					fBlendHLine = blend_hline_alpha_cc;
263 					fBlendSolidHSpan = blend_solid_hspan_alpha_cc;
264 					fBlendSolidVSpan = blend_solid_vspan_alpha_cc;
265 					fBlendColorHSpan = blend_color_hspan_alpha_cc;
266 				}
267 			} else if (alphaSrcMode == B_PIXEL_ALPHA){
268 				if (alphaFncMode == B_ALPHA_OVERLAY) {
269 					if (fPatternHandler->IsSolid()) {
270 						fBlendPixel = blend_pixel_alpha_po_solid;
271 						fBlendHLine = blend_hline_alpha_po_solid;
272 						fBlendSolidHSpan = blend_solid_hspan_alpha_po_solid;
273 						fBlendSolidVSpan = blend_solid_vspan_alpha_po_solid;
274 					} else {
275 						fBlendPixel = blend_pixel_alpha_po;
276 						fBlendHLine = blend_hline_alpha_po;
277 						fBlendSolidHSpan = blend_solid_hspan_alpha_po;
278 						fBlendSolidVSpan = blend_solid_vspan_alpha_po;
279 					}
280 					fBlendColorHSpan = blend_color_hspan_alpha_po;
281 				} else if (alphaFncMode == B_ALPHA_COMPOSITE) {
282 					fBlendPixel = blend_pixel_alpha_pc;
283 					fBlendHLine = blend_hline_alpha_pc;
284 					fBlendSolidHSpan = blend_solid_hspan_alpha_pc;
285 					fBlendSolidVSpan = blend_solid_vspan_alpha_pc;
286 					fBlendColorHSpan = blend_color_hspan_alpha_pc;
287 				}
288 			}
289 			break;
290 
291 		default:
292 fprintf(stderr, "PixelFormat::SetDrawingMode() - drawing_mode not implemented\n");
293 //			return fDrawingModeBGRA32Copy;
294 			break;
295 	}
296 }
297