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