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_PO_H 10 #define DRAWING_MODE_ALPHA_PO_H 11 12 #include "DrawingMode.h" 13 14 // BLEND_ALPHA_PO 15 #define BLEND_ALPHA_PO(d1, d2, d3, da, s1, s2, s3, a) \ 16 { \ 17 BLEND16(d1, d2, d3, da, s1, s2, s3, a); \ 18 } 19 20 // ASSIGN_ALPHA_PO 21 #define ASSIGN_ALPHA_PO(d1, d2, d3, da, s1, s2, s3) \ 22 { \ 23 (d1) = (s1); \ 24 (d2) = (s2); \ 25 (d3) = (s3); \ 26 (da) = 255; \ 27 } 28 29 30 template<class Order> 31 class DrawingModeAlphaPO : public DrawingMode { 32 public: 33 // constructor 34 DrawingModeAlphaPO() 35 : DrawingMode() 36 { 37 } 38 39 // blend_pixel 40 virtual void blend_pixel(int x, int y, const color_type& c, uint8 cover) 41 { 42 uint8* p = fBuffer->row(y) + (x << 2); 43 rgb_color color = fPatternHandler->R5ColorAt(x, y); 44 uint16 alpha = color.alpha * cover; 45 if (alpha == 255*255) { 46 ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 47 color.red, color.green, color.blue); 48 } else { 49 BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 50 color.red, color.green, color.blue, alpha); 51 } 52 } 53 54 // blend_hline 55 virtual void blend_hline(int x, int y, unsigned len, 56 const color_type& c, uint8 cover) 57 { 58 uint8* p = fBuffer->row(y) + (x << 2); 59 do { 60 rgb_color color = fPatternHandler->R5ColorAt(x, y); 61 uint16 alpha = color.alpha * cover; 62 if (alpha) { 63 if (alpha == 255) { 64 ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 65 color.red, color.green, color.blue); 66 } else { 67 BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 68 color.red, color.green, color.blue, alpha); 69 } 70 } 71 x++; 72 p += 4; 73 } while(--len); 74 } 75 76 // blend_vline 77 virtual void blend_vline(int x, int y, unsigned len, 78 const color_type& c, uint8 cover) 79 { 80 printf("DrawingModeAlphaPO::blend_vline()\n"); 81 } 82 83 // blend_solid_hspan 84 virtual void blend_solid_hspan(int x, int y, unsigned len, 85 const color_type& c, const uint8* covers) 86 { 87 uint8* p = fBuffer->row(y) + (x << 2); 88 do { 89 rgb_color color = fPatternHandler->R5ColorAt(x, y); 90 uint16 alpha = color.alpha * *covers; 91 if (alpha) { 92 if(alpha == 255*255) { 93 ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 94 color.red, color.green, color.blue); 95 } else { 96 BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 97 color.red, color.green, color.blue, alpha); 98 } 99 } 100 covers++; 101 p += 4; 102 x++; 103 } while(--len); 104 } 105 106 107 108 // blend_solid_vspan 109 virtual void blend_solid_vspan(int x, int y, unsigned len, 110 const color_type& c, const uint8* covers) 111 { 112 uint8* p = fBuffer->row(y) + (x << 2); 113 do { 114 rgb_color color = fPatternHandler->R5ColorAt(x, y); 115 uint16 alpha = color.alpha * *covers; 116 if (alpha) { 117 if (alpha == 255*255) { 118 ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 119 color.red, color.green, color.blue); 120 } else { 121 BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 122 color.red, color.green, color.blue, alpha); 123 } 124 } 125 covers++; 126 p += fBuffer->stride(); 127 y++; 128 } while(--len); 129 } 130 131 132 // blend_color_hspan 133 virtual void blend_color_hspan(int x, int y, unsigned len, 134 const color_type* colors, 135 const uint8* covers, 136 uint8 cover) 137 { 138 uint8* p = fBuffer->row(y) + (x << 2); 139 if (covers) { 140 // non-solid opacity 141 do { 142 uint16 alpha = colors->a * *covers; 143 if (alpha) { 144 if (alpha == 255*255) { 145 ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 146 colors->r, colors->g, colors->b); 147 } else { 148 BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 149 colors->r, colors->g, colors->b, alpha); 150 } 151 } 152 covers++; 153 p += 4; 154 ++colors; 155 } while(--len); 156 } else { 157 // solid full opcacity 158 uint16 alpha = colors->a * cover; 159 if (alpha == 255*255) { 160 do { 161 ASSIGN_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 162 colors->r, colors->g, colors->b); 163 p += 4; 164 ++colors; 165 } while(--len); 166 // solid partial opacity 167 } else if (alpha) { 168 do { 169 BLEND_ALPHA_PO(p[Order::R], p[Order::G], p[Order::B], p[Order::A], 170 colors->r, colors->g, colors->b, alpha); 171 p += 4; 172 ++colors; 173 } while(--len); 174 } 175 } 176 } 177 178 179 // blend_color_vspan 180 virtual void blend_color_vspan(int x, int y, unsigned len, 181 const color_type* colors, 182 const uint8* covers, 183 uint8 cover) 184 { 185 printf("DrawingModeAlphaPO::blend_color_vspan()\n"); 186 } 187 188 }; 189 190 typedef DrawingModeAlphaPO<agg::order_rgba32> DrawingModeRGBA32AlphaPO; 191 typedef DrawingModeAlphaPO<agg::order_argb32> DrawingModeARGB32AlphaPO; 192 typedef DrawingModeAlphaPO<agg::order_abgr32> DrawingModeABGR32AlphaPO; 193 typedef DrawingModeAlphaPO<agg::order_bgra32> DrawingModeBGRA32AlphaPO; 194 195 #endif // DRAWING_MODE_ALPHA_PO_H 196 197