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