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 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 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 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 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 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 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 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 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 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 153 PixelFormat::~PixelFormat() 154 { 155 } 156 157 // SetDrawingMode 158 void 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