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_SELECT on B_RGBA32. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_SELECT_H 10 #define DRAWING_MODE_SELECT_H 11 12 #include "DrawingMode.h" 13 14 // BLEND_SELECT 15 #define BLEND_SELECT(d1, d2, d3, da, s1, s2, s3, a) \ 16 { \ 17 BLEND(d1, d2, d3, da, s1, s2, s3, a); \ 18 } 19 20 // ASSIGN_SELECT 21 #define ASSIGN_SELECT(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 DrawingModeSelect : public DrawingMode { 32 public: 33 // constructor 34 DrawingModeSelect() 35 : DrawingMode() 36 { 37 } 38 39 // compare 40 inline bool compare(uint8* p, 41 const rgb_color& high, 42 const rgb_color& low, rgb_color* result) 43 { 44 if (p[Order::R] == high.red && 45 p[Order::G] == high.green && 46 p[Order::B] == high.blue) { 47 result->red = low.red; 48 result->green = low.green; 49 result->blue = low.blue; 50 return true; 51 } else if (p[Order::R] == low.red && 52 p[Order::G] == low.green && 53 p[Order::B] == low.blue) { 54 result->red = high.red; 55 result->green = high.green; 56 result->blue = high.blue; 57 return true; 58 } 59 return false; 60 } 61 62 63 // blend_pixel 64 virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) 65 { 66 if (fPatternHandler->IsHighColor(x, y)) { 67 uint8* p = fBuffer->row(y) + (x << 2); 68 rgb_color high = fPatternHandler->HighColor().GetColor32(); 69 rgb_color low = fPatternHandler->LowColor().GetColor32(); 70 rgb_color color; 71 if (compare(p, high, low, &color)) { 72 if (cover == 255) { 73 ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 74 color.red, color.green, color.blue); 75 } else { 76 BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 77 color.red, color.green, color.blue, cover); 78 } 79 } 80 } 81 } 82 83 // blend_hline 84 virtual void blend_hline(int x, int y, unsigned len, 85 const color_type& c, uint8 cover) 86 { 87 uint8* p = fBuffer->row(y) + (x << 2); 88 rgb_color high = fPatternHandler->HighColor().GetColor32(); 89 rgb_color low = fPatternHandler->LowColor().GetColor32(); 90 rgb_color color; 91 if (cover == 255) { 92 do { 93 if (fPatternHandler->IsHighColor(x, y) 94 && compare(p, high, low, &color)) 95 ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 96 color.red, color.green, color.blue); 97 x++; 98 p += 4; 99 } while(--len); 100 } else { 101 do { 102 if (fPatternHandler->IsHighColor(x, y) 103 && compare(p, high, low, &color)) { 104 BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 105 color.red, color.green, color.blue, cover); 106 } 107 x++; 108 p += 4; 109 } while(--len); 110 } 111 } 112 113 // blend_vline 114 virtual void blend_vline(int x, int y, unsigned len, 115 const color_type& c, uint8 cover) 116 { 117 printf("DrawingModeSelect::blend_vline()\n"); 118 } 119 120 // blend_solid_hspan 121 virtual void blend_solid_hspan(int x, int y, unsigned len, 122 const color_type& c, const uint8* covers) 123 { 124 uint8* p = fBuffer->row(y) + (x << 2); 125 rgb_color high = fPatternHandler->HighColor().GetColor32(); 126 rgb_color low = fPatternHandler->LowColor().GetColor32(); 127 rgb_color color; 128 do { 129 if (fPatternHandler->IsHighColor(x, y)) { 130 if (*covers && compare(p, high, low, &color)) { 131 if (*covers == 255) { 132 ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 133 color.red, color.green, color.blue); 134 } else { 135 BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 136 color.red, color.green, color.blue, *covers); 137 } 138 } 139 } 140 covers++; 141 p += 4; 142 x++; 143 } while(--len); 144 } 145 146 147 148 // blend_solid_vspan 149 virtual void blend_solid_vspan(int x, int y, unsigned len, 150 const color_type& c, const uint8* covers) 151 { 152 uint8* p = fBuffer->row(y) + (x << 2); 153 rgb_color high = fPatternHandler->HighColor().GetColor32(); 154 rgb_color low = fPatternHandler->LowColor().GetColor32(); 155 rgb_color color; 156 do { 157 if (fPatternHandler->IsHighColor(x, y)) { 158 if (*covers && compare(p, high, low, &color)) { 159 if (*covers == 255) { 160 ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 161 color.red, color.green, color.blue); 162 } else { 163 BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 164 color.red, color.green, color.blue, *covers); 165 } 166 } 167 } 168 covers++; 169 p += fBuffer->stride(); 170 y++; 171 } while(--len); 172 } 173 174 175 // blend_color_hspan 176 virtual void blend_color_hspan(int x, int y, unsigned len, 177 const color_type* colors, 178 const uint8* covers, 179 uint8 cover) 180 { 181 uint8* p = fBuffer->row(y) + (x << 2); 182 rgb_color high = fPatternHandler->HighColor().GetColor32(); 183 rgb_color low = fPatternHandler->LowColor().GetColor32(); 184 rgb_color color; 185 if (covers) { 186 // non-solid opacity 187 do { 188 if (*covers && compare(p, high, low, &color)) { 189 if (*covers == 255) { 190 ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 191 color.red, color.green, color.blue); 192 } else { 193 BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 194 color.red, color.green, color.blue, *covers); 195 } 196 } 197 covers++; 198 p += 4; 199 ++colors; 200 } while(--len); 201 } else { 202 // solid full opcacity 203 if (cover == 255) { 204 do { 205 if (compare(p, high, low, &color)) { 206 ASSIGN_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 207 color.red, color.green, color.blue); 208 } 209 p += 4; 210 ++colors; 211 } while(--len); 212 // solid partial opacity 213 } else if (cover) { 214 do { 215 if (compare(p, high, low, &color)) { 216 BLEND_SELECT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 217 color.red, color.green, color.blue, *covers); 218 } 219 p += 4; 220 ++colors; 221 } while(--len); 222 } 223 } 224 } 225 226 227 // blend_color_vspan 228 virtual void blend_color_vspan(int x, int y, unsigned len, 229 const color_type* colors, 230 const uint8* covers, 231 uint8 cover) 232 { 233 printf("DrawingModeSelect::blend_color_vspan()\n"); 234 } 235 236 }; 237 238 typedef DrawingModeSelect<agg::order_rgba32> DrawingModeRGBA32Select; 239 typedef DrawingModeSelect<agg::order_argb32> DrawingModeARGB32Select; 240 typedef DrawingModeSelect<agg::order_abgr32> DrawingModeABGR32Select; 241 typedef DrawingModeSelect<agg::order_bgra32> DrawingModeBGRA32Select; 242 243 #endif // DRAWING_MODE_SELECT_H 244 245