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_ERASE on B_RGBA32. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_ERASE_H 10 #define DRAWING_MODE_ERASE_H 11 12 #include "DrawingMode.h" 13 14 // BLEND_ERASE 15 #define BLEND_ERASE(d1, d2, d3, da, s1, s2, s3, a) \ 16 { \ 17 BLEND(d1, d2, d3, da, s1, s2, s3, a); \ 18 } 19 20 // ASSIGN_ERASE 21 #define ASSIGN_ERASE(d1, d2, d3, da, s1, s2, s3) \ 22 { \ 23 (d1) = (s1); \ 24 (d2) = (s2); \ 25 (d3) = (s3); \ 26 (da) = 255; \ 27 } 28 29 30 template<class Order> 31 class DrawingModeErase : public DrawingMode { 32 public: 33 // constructor 34 DrawingModeErase() 35 : DrawingMode() 36 { 37 } 38 39 // blend_pixel 40 virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) 41 { 42 if (fPatternHandler->IsHighColor(x, y)) { 43 uint8* p = fBuffer->row(y) + (x << 2); 44 rgb_color color = fPatternHandler->LowColor().GetColor32(); 45 if (cover == 255) { 46 ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 47 color.red, color.green, color.blue); 48 } else { 49 BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 50 color.red, color.green, color.blue, cover); 51 } 52 } 53 } 54 55 // blend_hline 56 virtual void blend_hline(int x, int y, unsigned len, 57 const color_type& c, uint8 cover) 58 { 59 if (cover == 255) { 60 rgb_color color = fPatternHandler->LowColor().GetColor32(); 61 uint32 v; 62 uint8* p8 = (uint8*)&v; 63 p8[Order::R] = (uint8)color.red; 64 p8[Order::G] = (uint8)color.green; 65 p8[Order::B] = (uint8)color.blue; 66 p8[Order::A] = 255; 67 uint32* p32 = (uint32*)(fBuffer->row(y)) + x; 68 do { 69 if (fPatternHandler->IsHighColor(x, y)) 70 *p32 = v; 71 p32++; 72 x++; 73 } while(--len); 74 } else { 75 uint8* p = fBuffer->row(y) + (x << 2); 76 rgb_color color = fPatternHandler->LowColor().GetColor32(); 77 do { 78 if (fPatternHandler->IsHighColor(x, y)) { 79 BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 80 color.red, color.green, color.blue, cover); 81 } 82 x++; 83 p += 4; 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("DrawingModeErase::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 rgb_color color = fPatternHandler->LowColor().GetColor32(); 101 do { 102 if (fPatternHandler->IsHighColor(x, y)) { 103 if (*covers) { 104 if(*covers == 255) { 105 ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 106 color.red, color.green, color.blue); 107 } else { 108 BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 109 color.red, color.green, color.blue, *covers); 110 } 111 } 112 } 113 covers++; 114 p += 4; 115 x++; 116 } while(--len); 117 } 118 119 120 121 // blend_solid_vspan 122 virtual void blend_solid_vspan(int x, int y, unsigned len, 123 const color_type& c, const uint8* covers) 124 { 125 uint8* p = fBuffer->row(y) + (x << 2); 126 rgb_color color = fPatternHandler->LowColor().GetColor32(); 127 do { 128 if (fPatternHandler->IsHighColor(x, y)) { 129 if (*covers) { 130 if (*covers == 255) { 131 ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 132 color.red, color.green, color.blue); 133 } else { 134 BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 135 color.red, color.green, color.blue, *covers); 136 } 137 } 138 } 139 covers++; 140 p += fBuffer->stride(); 141 y++; 142 } while(--len); 143 } 144 145 146 // blend_color_hspan 147 virtual void blend_color_hspan(int x, int y, unsigned len, 148 const color_type* colors, 149 const uint8* covers, 150 uint8 cover) 151 { 152 // TODO: compare this with BView 153 uint8* p = fBuffer->row(y) + (x << 2); 154 if (covers) { 155 // non-solid opacity 156 do { 157 if(*covers) { 158 if(*covers == 255) { 159 ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 160 colors->r, colors->g, colors->b); 161 } else { 162 BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 163 colors->r, colors->g, colors->b, *covers); 164 } 165 } 166 covers++; 167 p += 4; 168 ++colors; 169 } while(--len); 170 } else { 171 // solid full opcacity 172 if (cover == 255) { 173 do { 174 ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 175 colors->r, colors->g, colors->b); 176 p += 4; 177 ++colors; 178 } while(--len); 179 // solid partial opacity 180 } else if (cover) { 181 do { 182 BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 183 colors->r, colors->g, colors->b, cover); 184 p += 4; 185 ++colors; 186 } while(--len); 187 } 188 } 189 } 190 191 192 // blend_color_vspan 193 virtual void blend_color_vspan(int x, int y, unsigned len, 194 const color_type* colors, 195 const uint8* covers, 196 uint8 cover) 197 { 198 printf("DrawingModeErase::blend_color_vspan()\n"); 199 } 200 201 }; 202 203 typedef DrawingModeErase<agg::order_rgba32> DrawingModeRGBA32Erase; 204 typedef DrawingModeErase<agg::order_argb32> DrawingModeARGB32Erase; 205 typedef DrawingModeErase<agg::order_abgr32> DrawingModeABGR32Erase; 206 typedef DrawingModeErase<agg::order_bgra32> DrawingModeBGRA32Erase; 207 208 #endif // DRAWING_MODE_ERASE_H 209 210