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(d, r, g, b, a) \ 19 { \ 20 pixel32 _p; \ 21 _p.data32 = *(uint32*)d; \ 22 uint8 rt = max_c(0, _p.data8[2] - (r)); \ 23 uint8 gt = max_c(0, _p.data8[1] - (g)); \ 24 uint8 bt = max_c(0, _p.data8[0] - (b)); \ 25 BLEND(d, rt, gt, bt, a); \ 26 } 27 28 // ASSIGN_SUBTRACT 29 #define ASSIGN_SUBTRACT(d, r, g, b) \ 30 { \ 31 pixel32 _p; \ 32 _p.data32 = *(uint32*)d; \ 33 d[0] = max_c(0, _p.data8[0] - (b)); \ 34 d[1] = max_c(0, _p.data8[1] - (g)); \ 35 d[2] = max_c(0, _p.data8[2] - (r)); \ 36 } 37 38 39 // blend_pixel_subtract 40 void 41 blend_pixel_subtract(int x, int y, const color_type& c, uint8 cover, 42 agg_buffer* buffer, const PatternHandler* pattern) 43 { 44 uint8* p = buffer->row(y) + (x << 2); 45 rgb_color color = pattern->R5ColorAt(x, y); 46 if (cover == 255) { 47 ASSIGN_SUBTRACT(p, color.red, color.green, color.blue); 48 } else { 49 BLEND_SUBTRACT(p, color.red, color.green, color.blue, cover); 50 } 51 } 52 53 // blend_hline_subtract 54 void 55 blend_hline_subtract(int x, int y, unsigned len, 56 const color_type& c, uint8 cover, 57 agg_buffer* buffer, const PatternHandler* pattern) 58 { 59 uint8* p = buffer->row(y) + (x << 2); 60 if (cover == 255) { 61 do { 62 rgb_color color = pattern->R5ColorAt(x, y); 63 64 ASSIGN_SUBTRACT(p, color.red, color.green, color.blue); 65 66 p += 4; 67 x++; 68 } while(--len); 69 } else { 70 do { 71 rgb_color color = pattern->R5ColorAt(x, y); 72 73 BLEND_SUBTRACT(p, color.red, color.green, color.blue, cover); 74 75 x++; 76 p += 4; 77 } while(--len); 78 } 79 } 80 81 // blend_solid_hspan_subtract 82 void 83 blend_solid_hspan_subtract(int x, int y, unsigned len, 84 const color_type& c, const uint8* covers, 85 agg_buffer* buffer, const PatternHandler* pattern) 86 { 87 uint8* p = buffer->row(y) + (x << 2); 88 do { 89 rgb_color color = pattern->R5ColorAt(x, y); 90 if (*covers) { 91 if (*covers == 255) { 92 ASSIGN_SUBTRACT(p, color.red, color.green, color.blue); 93 } else { 94 BLEND_SUBTRACT(p, color.red, color.green, color.blue, *covers); 95 } 96 } 97 covers++; 98 p += 4; 99 x++; 100 } while(--len); 101 } 102 103 104 105 // blend_solid_vspan_subtract 106 void 107 blend_solid_vspan_subtract(int x, int y, unsigned len, 108 const color_type& c, const uint8* covers, 109 agg_buffer* buffer, const PatternHandler* pattern) 110 { 111 uint8* p = buffer->row(y) + (x << 2); 112 do { 113 rgb_color color = pattern->R5ColorAt(x, y); 114 if (*covers) { 115 if (*covers == 255) { 116 ASSIGN_SUBTRACT(p, color.red, color.green, color.blue); 117 } else { 118 BLEND_SUBTRACT(p, color.red, color.green, color.blue, *covers); 119 } 120 } 121 covers++; 122 p += buffer->stride(); 123 y++; 124 } while(--len); 125 } 126 127 128 // blend_color_hspan_subtract 129 void 130 blend_color_hspan_subtract(int x, int y, unsigned len, 131 const color_type* colors, 132 const uint8* covers, uint8 cover, 133 agg_buffer* buffer, const PatternHandler* pattern) 134 { 135 uint8* p = buffer->row(y) + (x << 2); 136 if (covers) { 137 // non-solid opacity 138 do { 139 if (*covers) { 140 if (*covers == 255) { 141 ASSIGN_SUBTRACT(p, colors->r, colors->g, colors->b); 142 } else { 143 BLEND_SUBTRACT(p, colors->r, colors->g, colors->b, *covers); 144 } 145 } 146 covers++; 147 p += 4; 148 ++colors; 149 } while(--len); 150 } else { 151 // solid full opcacity 152 if (cover == 255) { 153 do { 154 ASSIGN_SUBTRACT(p, colors->r, colors->g, colors->b); 155 p += 4; 156 ++colors; 157 } while(--len); 158 // solid partial opacity 159 } else if (cover) { 160 do { 161 BLEND_SUBTRACT(p, colors->r, colors->g, colors->b, cover); 162 p += 4; 163 ++colors; 164 } while(--len); 165 } 166 } 167 } 168 169 #endif // DRAWING_MODE_SUBTRACT_H 170 171