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