1 /* 2 * Copyright 2005, Stephan Aßmus <superstippi@gmx.de>. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * DrawingMode implementing B_OP_SUBTRACT on B_RGBA32. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_SUBTRACT_H 10 #define DRAWING_MODE_SUBTRACT_H 11 12 #include <SupportDefs.h> 13 14 #include "DrawingMode.h" 15 #include "PatternHandler.h" 16 17 // BLEND_SUBTRACT 18 #define BLEND_SUBTRACT(d1, d2, d3, da, s1, s2, s3, a) \ 19 { \ 20 uint8 t1 = max_c(0, (d1) - (s1)); \ 21 uint8 t2 = max_c(0, (d2) - (s2)); \ 22 uint8 t3 = max_c(0, (d3) - (s3)); \ 23 BLEND(d1, d2, d3, da, t1, t2, t3, a); \ 24 } 25 26 // ASSIGN_SUBTRACT 27 #define ASSIGN_SUBTRACT(d1, d2, d3, da, s1, s2, s3) \ 28 { \ 29 (d1) = max_c(0, (d1) - (s1)); \ 30 (d2) = max_c(0, (d2) - (s2)); \ 31 (d3) = max_c(0, (d3) - (s3)); \ 32 (da) = 255; \ 33 } 34 35 36 template<class Order> 37 class DrawingModeSubtract : public DrawingMode { 38 public: 39 // constructor 40 DrawingModeSubtract() 41 : DrawingMode() 42 { 43 } 44 45 // blend_pixel 46 virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) 47 { 48 uint8* p = fBuffer->row(y) + (x << 2); 49 rgb_color color = fPatternHandler->R5ColorAt(x, y); 50 if (cover == 255) { 51 ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 52 color.red, color.green, color.blue); 53 } else { 54 BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 55 color.red, color.green, color.blue, cover); 56 } 57 } 58 59 // blend_hline 60 virtual void blend_hline(int x, int y, unsigned len, 61 const color_type& c, uint8 cover) 62 { 63 uint8* p = fBuffer->row(y) + (x << 2); 64 if (cover == 255) { 65 do { 66 rgb_color color = fPatternHandler->R5ColorAt(x, y); 67 68 ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 69 color.red, color.green, color.blue); 70 71 p += 4; 72 x++; 73 } while(--len); 74 } else { 75 do { 76 rgb_color color = fPatternHandler->R5ColorAt(x, y); 77 78 BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 79 color.red, color.green, color.blue, cover); 80 81 x++; 82 p += 4; 83 } 84 while(--len); 85 } 86 } 87 88 // blend_vline 89 virtual void blend_vline(int x, int y, unsigned len, 90 const color_type& c, uint8 cover) 91 { 92 printf("DrawingModeSubtract::blend_vline()\n"); 93 } 94 95 // blend_solid_hspan 96 virtual void blend_solid_hspan(int x, int y, unsigned len, 97 const color_type& c, const uint8* covers) 98 { 99 uint8* p = fBuffer->row(y) + (x << 2); 100 do { 101 rgb_color color = fPatternHandler->R5ColorAt(x, y); 102 if (*covers) { 103 if (*covers == 255) { 104 ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 105 color.red, color.green, color.blue); 106 } else { 107 BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 108 color.red, color.green, color.blue, *covers); 109 } 110 } 111 covers++; 112 p += 4; 113 x++; 114 } while(--len); 115 } 116 117 118 119 // blend_solid_vspan 120 virtual void blend_solid_vspan(int x, int y, unsigned len, 121 const color_type& c, const uint8* covers) 122 { 123 uint8* p = fBuffer->row(y) + (x << 2); 124 do { 125 rgb_color color = fPatternHandler->R5ColorAt(x, y); 126 if (*covers) { 127 if (*covers == 255) { 128 ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 129 color.red, color.green, color.blue); 130 } else { 131 BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 132 color.red, color.green, color.blue, *covers); 133 } 134 } 135 covers++; 136 p += fBuffer->stride(); 137 y++; 138 } while(--len); 139 } 140 141 142 // blend_color_hspan 143 virtual void blend_color_hspan(int x, int y, unsigned len, 144 const color_type* colors, 145 const uint8* covers, 146 uint8 cover) 147 { 148 uint8* p = fBuffer->row(y) + (x << 2); 149 if (covers) { 150 // non-solid opacity 151 do { 152 if (*covers) { 153 if (*covers == 255) { 154 ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 155 colors->r, colors->g, colors->b); 156 } else { 157 BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 158 colors->r, colors->g, colors->b, *covers); 159 } 160 } 161 covers++; 162 p += 4; 163 ++colors; 164 } while(--len); 165 } else { 166 // solid full opcacity 167 if (cover == 255) { 168 do { 169 ASSIGN_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 170 colors->r, colors->g, colors->b); 171 p += 4; 172 ++colors; 173 } while(--len); 174 // solid partial opacity 175 } else if (cover) { 176 do { 177 BLEND_SUBTRACT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 178 colors->r, colors->g, colors->b, cover); 179 p += 4; 180 ++colors; 181 } while(--len); 182 } 183 } 184 } 185 186 187 // blend_color_vspan 188 virtual void blend_color_vspan(int x, int y, unsigned len, 189 const color_type* colors, 190 const uint8* covers, 191 uint8 cover) 192 { 193 printf("DrawingModeSubtract::blend_color_vspan()\n"); 194 } 195 196 }; 197 198 typedef DrawingModeSubtract<agg::order_rgba32> DrawingModeRGBA32Subtract; 199 typedef DrawingModeSubtract<agg::order_argb32> DrawingModeARGB32Subtract; 200 typedef DrawingModeSubtract<agg::order_abgr32> DrawingModeABGR32Subtract; 201 typedef DrawingModeSubtract<agg::order_bgra32> DrawingModeBGRA32Subtract; 202 203 #endif // DRAWING_MODE_SUBTRACT_H 204 205