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_ALPHA in "Constant Overlay" mode on B_RGBA32. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_ALPHA_CO_H 10 #define DRAWING_MODE_ALPHA_CO_H 11 12 #include "DrawingMode.h" 13 14 // BLEND_ALPHA_CO 15 #define BLEND_ALPHA_CO(d, r, g, b, a) \ 16 { \ 17 BLEND16(d, r, g, b, a); \ 18 } 19 20 // ASSIGN_ALPHA_CO 21 #define ASSIGN_ALPHA_CO(d, r, g, b) \ 22 { \ 23 d[0] = (b); \ 24 d[1] = (g); \ 25 d[2] = (r); \ 26 d[3] = 255; \ 27 } 28 29 // blend_pixel_alpha_co 30 void 31 blend_pixel_alpha_co(int x, int y, const color_type& c, uint8 cover, 32 agg_buffer* buffer, const PatternHandler* pattern) 33 { 34 uint8* p = buffer->row_ptr(y) + (x << 2); 35 rgb_color color = pattern->ColorAt(x, y); 36 uint16 alpha = pattern->HighColor().alpha * cover; 37 if (alpha == 255 * 255) { 38 ASSIGN_ALPHA_CO(p, color.red, color.green, color.blue); 39 } else { 40 BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha); 41 } 42 } 43 44 // blend_hline_alpha_co 45 void 46 blend_hline_alpha_co(int x, int y, unsigned len, 47 const color_type& c, uint8 cover, 48 agg_buffer* buffer, const PatternHandler* pattern) 49 { 50 rgb_color color = pattern->HighColor(); 51 uint16 alpha = color.alpha * cover; 52 if (alpha == 255*255) { 53 // cache the low and high color as 32bit values 54 // high color 55 uint32 vh; 56 uint8* p8 = (uint8*)&vh; 57 p8[0] = color.blue; 58 p8[1] = color.green; 59 p8[2] = color.red; 60 p8[3] = 255; 61 // low color 62 color = pattern->LowColor(); 63 uint32 vl; 64 p8 = (uint8*)&vl; 65 p8[0] = color.blue; 66 p8[1] = color.green; 67 p8[2] = color.red; 68 p8[3] = 255; 69 // row offset as 32bit pointer 70 uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; 71 do { 72 if (pattern->IsHighColor(x, y)) 73 *p32 = vh; 74 else 75 *p32 = vl; 76 p32++; 77 x++; 78 } while(--len); 79 } else { 80 uint8* p = buffer->row_ptr(y) + (x << 2); 81 do { 82 rgb_color color = pattern->ColorAt(x, y); 83 BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha); 84 x++; 85 p += 4; 86 } while(--len); 87 } 88 } 89 90 // blend_solid_hspan_alpha_co 91 void 92 blend_solid_hspan_alpha_co(int x, int y, unsigned len, 93 const color_type& c, const uint8* covers, 94 agg_buffer* buffer, const PatternHandler* pattern) 95 { 96 uint8* p = buffer->row_ptr(y) + (x << 2); 97 uint8 hAlpha = pattern->HighColor().alpha; 98 do { 99 rgb_color color = pattern->ColorAt(x, y); 100 uint16 alpha = hAlpha * *covers; 101 if (alpha) { 102 if (alpha == 255 * 255) { 103 ASSIGN_ALPHA_CO(p, color.red, color.green, color.blue); 104 } else { 105 BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha); 106 } 107 } 108 covers++; 109 p += 4; 110 x++; 111 } while(--len); 112 } 113 114 115 116 // blend_solid_vspan_alpha_co 117 void 118 blend_solid_vspan_alpha_co(int x, int y, unsigned len, 119 const color_type& c, const uint8* covers, 120 agg_buffer* buffer, const PatternHandler* pattern) 121 { 122 uint8* p = buffer->row_ptr(y) + (x << 2); 123 uint8 hAlpha = pattern->HighColor().alpha; 124 do { 125 rgb_color color = pattern->ColorAt(x, y); 126 uint16 alpha = hAlpha * *covers; 127 if (alpha) { 128 if (alpha == 255 * 255) { 129 ASSIGN_ALPHA_CO(p, color.red, color.green, color.blue); 130 } else { 131 BLEND_ALPHA_CO(p, color.red, color.green, color.blue, alpha); 132 } 133 } 134 covers++; 135 p += buffer->stride(); 136 y++; 137 } while(--len); 138 } 139 140 141 // blend_color_hspan_alpha_co 142 void 143 blend_color_hspan_alpha_co(int x, int y, unsigned len, 144 const color_type* colors, 145 const uint8* covers, uint8 cover, 146 agg_buffer* buffer, const PatternHandler* pattern) 147 { 148 uint8* p = buffer->row_ptr(y) + (x << 2); 149 uint8 hAlpha = pattern->HighColor().alpha; 150 if (covers) { 151 // non-solid opacity 152 do { 153 uint16 alpha = hAlpha * colors->a * *covers / 255; 154 if (alpha) { 155 if (alpha == 255*255) { 156 ASSIGN_ALPHA_CO(p, colors->r, colors->g, colors->b); 157 } else { 158 BLEND_ALPHA_CO(p, colors->r, colors->g, colors->b, alpha); 159 } 160 } 161 covers++; 162 p += 4; 163 ++colors; 164 } while(--len); 165 } else { 166 // solid full opcacity 167 uint16 alpha = hAlpha * colors->a * cover / 255; 168 if (alpha == 255 * 255) { 169 do { 170 ASSIGN_ALPHA_CO(p, colors->r, colors->g, colors->b); 171 p += 4; 172 ++colors; 173 } while(--len); 174 // solid partial opacity 175 } else if (alpha) { 176 do { 177 BLEND_ALPHA_CO(p, colors->r, colors->g, colors->b, alpha); 178 p += 4; 179 ++colors; 180 } while(--len); 181 } 182 } 183 } 184 185 #endif // DRAWING_MODE_ALPHA_CO_H 186 187