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 61 void 62 blend_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 69 void 70 blend_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 78 void 79 blend_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 87 void 88 blend_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 96 void 97 blend_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 105 void 106 blend_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 115 void 116 blend_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 125 void 126 blend_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 137 PixelFormat::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 155 PixelFormat::~PixelFormat() 156 { 157 } 158 159 // SetDrawingMode 160 void 161 PixelFormat::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: 341 fprintf(stderr, "PixelFormat::SetDrawingMode() - drawing_mode not implemented\n"); 342 // return fDrawingModeBGRA32Copy; 343 break; 344 } 345 } 346