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(y) + (x << 2); 42 rgb_color color = pattern->R5ColorAt(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(y) + (x << 2); 57 if (cover == 255) { 58 do { 59 rgb_color color = pattern->R5ColorAt(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->R5ColorAt(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(y) + (x << 2); 85 do { 86 rgb_color color = pattern->R5ColorAt(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(y) + (x << 2); 109 do { 110 rgb_color color = pattern->R5ColorAt(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(y) + (x << 2); 133 if (covers) { 134 // non-solid opacity 135 do { 136 if (*covers) { 137 if (*covers == 255) { 138 ASSIGN_BLEND(p, colors->r, colors->g, colors->b); 139 } else { 140 BLEND_BLEND(p, colors->r, colors->g, colors->b, *covers); 141 } 142 } 143 covers++; 144 p += 4; 145 ++colors; 146 } while(--len); 147 } else { 148 // solid full opcacity 149 if (cover == 255) { 150 do { 151 ASSIGN_BLEND(p, colors->r, colors->g, colors->b); 152 p += 4; 153 ++colors; 154 } while(--len); 155 // solid partial opacity 156 } else if (cover) { 157 do { 158 BLEND_BLEND(p, colors->r, colors->g, colors->b, cover); 159 p += 4; 160 ++colors; 161 } while(--len); 162 } 163 } 164 } 165 166 #endif // DRAWING_MODE_BLEND_H 167 168