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