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