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(d, r, g, b, a) \ 16 { \ 17 BLEND(d, r, g, b, a); \ 18 } 19 20 // ASSIGN_SELECT 21 #define ASSIGN_SELECT(d, r, g, b) \ 22 { \ 23 d[0] = (b); \ 24 d[1] = (g); \ 25 d[2] = (r); \ 26 d[3] = 255; \ 27 } 28 29 // compare 30 inline bool 31 compare(uint8* p, const rgb_color& high, const rgb_color& low, rgb_color* result) 32 { 33 pixel32 _p; 34 _p.data32 = *(uint32*)p; 35 if (_p.data8[2] == high.red && 36 _p.data8[1] == high.green && 37 _p.data8[0] == high.blue) { 38 result->red = low.red; 39 result->green = low.green; 40 result->blue = low.blue; 41 return true; 42 } else if (_p.data8[2] == low.red && 43 _p.data8[1] == low.green && 44 _p.data8[0] == low.blue) { 45 result->red = high.red; 46 result->green = high.green; 47 result->blue = high.blue; 48 return true; 49 } 50 return false; 51 } 52 53 // blend_pixel_select 54 void 55 blend_pixel_select(int x, int y, const color_type& c, uint8 cover, 56 agg_buffer* buffer, const PatternHandler* pattern) 57 { 58 if (pattern->IsHighColor(x, y)) { 59 uint8* p = buffer->row_ptr(y) + (x << 2); 60 rgb_color high = pattern->HighColor().GetColor32(); 61 rgb_color low = pattern->LowColor().GetColor32(); 62 rgb_color color; 63 if (compare(p, high, low, &color)) { 64 if (cover == 255) { 65 ASSIGN_SELECT(p, color.red, color.green, color.blue); 66 } else { 67 BLEND_SELECT(p, color.red, color.green, color.blue, cover); 68 } 69 } 70 } 71 } 72 73 // blend_hline_select 74 void 75 blend_hline_select(int x, int y, unsigned len, 76 const color_type& c, uint8 cover, 77 agg_buffer* buffer, const PatternHandler* pattern) 78 { 79 uint8* p = buffer->row_ptr(y) + (x << 2); 80 rgb_color high = pattern->HighColor().GetColor32(); 81 rgb_color low = pattern->LowColor().GetColor32(); 82 rgb_color color; 83 if (cover == 255) { 84 do { 85 if (pattern->IsHighColor(x, y) 86 && compare(p, high, low, &color)) 87 ASSIGN_SELECT(p, color.red, color.green, color.blue); 88 x++; 89 p += 4; 90 } while(--len); 91 } else { 92 do { 93 if (pattern->IsHighColor(x, y) 94 && compare(p, high, low, &color)) { 95 BLEND_SELECT(p, color.red, color.green, color.blue, cover); 96 } 97 x++; 98 p += 4; 99 } while(--len); 100 } 101 } 102 103 // blend_solid_hspan_select 104 void 105 blend_solid_hspan_select(int x, int y, unsigned len, 106 const color_type& c, const uint8* covers, 107 agg_buffer* buffer, const PatternHandler* pattern) 108 { 109 uint8* p = buffer->row_ptr(y) + (x << 2); 110 rgb_color high = pattern->HighColor().GetColor32(); 111 rgb_color low = pattern->LowColor().GetColor32(); 112 rgb_color color; 113 do { 114 if (pattern->IsHighColor(x, y)) { 115 if (*covers && compare(p, high, low, &color)) { 116 if (*covers == 255) { 117 ASSIGN_SELECT(p, color.red, color.green, color.blue); 118 } else { 119 BLEND_SELECT(p, color.red, color.green, color.blue, *covers); 120 } 121 } 122 } 123 covers++; 124 p += 4; 125 x++; 126 } while(--len); 127 } 128 129 130 131 // blend_solid_vspan_select 132 void 133 blend_solid_vspan_select(int x, int y, unsigned len, 134 const color_type& c, const uint8* covers, 135 agg_buffer* buffer, const PatternHandler* pattern) 136 { 137 uint8* p = buffer->row_ptr(y) + (x << 2); 138 rgb_color high = pattern->HighColor().GetColor32(); 139 rgb_color low = pattern->LowColor().GetColor32(); 140 rgb_color color; 141 do { 142 if (pattern->IsHighColor(x, y)) { 143 if (*covers && compare(p, high, low, &color)) { 144 if (*covers == 255) { 145 ASSIGN_SELECT(p, color.red, color.green, color.blue); 146 } else { 147 BLEND_SELECT(p, color.red, color.green, color.blue, *covers); 148 } 149 } 150 } 151 covers++; 152 p += buffer->stride(); 153 y++; 154 } while(--len); 155 } 156 157 158 // blend_color_hspan_select 159 void 160 blend_color_hspan_select(int x, int y, unsigned len, 161 const color_type* colors, 162 const uint8* covers, uint8 cover, 163 agg_buffer* buffer, const PatternHandler* pattern) 164 { 165 uint8* p = buffer->row_ptr(y) + (x << 2); 166 rgb_color high = pattern->HighColor().GetColor32(); 167 rgb_color low = pattern->LowColor().GetColor32(); 168 rgb_color color; 169 if (covers) { 170 // non-solid opacity 171 do { 172 if (*covers && compare(p, high, low, &color)) { 173 if (*covers == 255) { 174 ASSIGN_SELECT(p, color.red, color.green, color.blue); 175 } else { 176 BLEND_SELECT(p, color.red, color.green, color.blue, *covers); 177 } 178 } 179 covers++; 180 p += 4; 181 ++colors; 182 } while(--len); 183 } else { 184 // solid full opcacity 185 if (cover == 255) { 186 do { 187 if (compare(p, high, low, &color)) { 188 ASSIGN_SELECT(p, color.red, color.green, color.blue); 189 } 190 p += 4; 191 ++colors; 192 } while(--len); 193 // solid partial opacity 194 } else if (cover) { 195 do { 196 if (compare(p, high, low, &color)) { 197 BLEND_SELECT(p, color.red, color.green, color.blue, *covers); 198 } 199 p += 4; 200 ++colors; 201 } while(--len); 202 } 203 } 204 } 205 206 #endif // DRAWING_MODE_SELECT_H 207 208