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_OVER on B_RGBA32. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_OVER_H 10 #define DRAWING_MODE_OVER_H 11 12 #include "DrawingMode.h" 13 14 // BLEND_OVER 15 #define BLEND_OVER(d, r, g, b, a) \ 16 { \ 17 BLEND(d, r, g, b, a) \ 18 } 19 20 // ASSIGN_OVER 21 #define ASSIGN_OVER(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_over 30 void 31 blend_pixel_over(int x, int y, const color_type& c, uint8 cover, 32 agg_buffer* buffer, const PatternHandler* pattern) 33 { 34 if (pattern->IsHighColor(x, y)) { 35 uint8* p = buffer->row_ptr(y) + (x << 2); 36 rgb_color color = pattern->HighColor(); 37 if (cover == 255) { 38 ASSIGN_OVER(p, color.red, color.green, color.blue); 39 } else { 40 BLEND_OVER(p, color.red, color.green, color.blue, cover); 41 } 42 } 43 } 44 45 // blend_hline_over 46 void 47 blend_hline_over(int x, int y, unsigned len, 48 const color_type& c, uint8 cover, 49 agg_buffer* buffer, const PatternHandler* pattern) 50 { 51 if (cover == 255) { 52 rgb_color color = pattern->HighColor(); 53 uint32 v; 54 uint8* p8 = (uint8*)&v; 55 p8[0] = (uint8)color.blue; 56 p8[1] = (uint8)color.green; 57 p8[2] = (uint8)color.red; 58 p8[3] = 255; 59 uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x; 60 do { 61 if (pattern->IsHighColor(x, y)) 62 *p32 = v; 63 p32++; 64 x++; 65 } while(--len); 66 } else { 67 uint8* p = buffer->row_ptr(y) + (x << 2); 68 rgb_color color = pattern->HighColor(); 69 do { 70 if (pattern->IsHighColor(x, y)) { 71 BLEND_OVER(p, color.red, color.green, color.blue, cover); 72 } 73 x++; 74 p += 4; 75 } while(--len); 76 } 77 } 78 79 // blend_solid_hspan_over 80 void 81 blend_solid_hspan_over(int x, int y, unsigned len, 82 const color_type& c, const uint8* covers, 83 agg_buffer* buffer, const PatternHandler* pattern) 84 { 85 uint8* p = buffer->row_ptr(y) + (x << 2); 86 rgb_color color = pattern->HighColor(); 87 do { 88 if (pattern->IsHighColor(x, y)) { 89 if (*covers) { 90 if (*covers == 255) { 91 ASSIGN_OVER(p, color.red, color.green, color.blue); 92 } else { 93 BLEND_OVER(p, color.red, color.green, color.blue, *covers); 94 } 95 } 96 } 97 covers++; 98 p += 4; 99 x++; 100 } while(--len); 101 } 102 103 104 105 // blend_solid_vspan_over 106 void 107 blend_solid_vspan_over(int x, int y, unsigned len, 108 const color_type& c, const uint8* covers, 109 agg_buffer* buffer, const PatternHandler* pattern) 110 { 111 uint8* p = buffer->row_ptr(y) + (x << 2); 112 rgb_color color = pattern->HighColor(); 113 do { 114 if (pattern->IsHighColor(x, y)) { 115 if (*covers) { 116 if (*covers == 255) { 117 ASSIGN_OVER(p, color.red, color.green, color.blue); 118 } else { 119 BLEND_OVER(p, color.red, color.green, color.blue, *covers); 120 } 121 } 122 } 123 covers++; 124 p += buffer->stride(); 125 y++; 126 } while(--len); 127 } 128 129 130 // blend_color_hspan_over 131 void 132 blend_color_hspan_over(int x, int y, unsigned len, 133 const color_type* colors, 134 const uint8* covers, uint8 cover, 135 agg_buffer* buffer, const PatternHandler* pattern) 136 { 137 uint8* p = buffer->row_ptr(y) + (x << 2); 138 if (covers) { 139 // non-solid opacity 140 do { 141 if (*covers && colors->a > 0) { 142 if (*covers == 255) { 143 ASSIGN_OVER(p, colors->r, colors->g, colors->b); 144 } else { 145 BLEND_OVER(p, colors->r, colors->g, colors->b, *covers); 146 } 147 } 148 covers++; 149 p += 4; 150 ++colors; 151 } while(--len); 152 } else { 153 // solid full opcacity 154 if (cover == 255) { 155 do { 156 if (colors->a > 0) { 157 ASSIGN_OVER(p, colors->r, colors->g, colors->b); 158 } 159 p += 4; 160 ++colors; 161 } while(--len); 162 // solid partial opacity 163 } else if (cover) { 164 do { 165 if (colors->a > 0) { 166 BLEND_OVER(p, colors->r, colors->g, colors->b, cover); 167 } 168 p += 4; 169 ++colors; 170 } while(--len); 171 } 172 } 173 } 174 175 #endif // DRAWING_MODE_OVER_H 176 177