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