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