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_INVERT on B_RGBA32. 6 * 7 */ 8 9 #ifndef DRAWING_MODE_INVERT_H 10 #define DRAWING_MODE_INVERT_H 11 12 #include "DrawingMode.h" 13 14 // BLEND_INVERT 15 #define BLEND_INVERT(d, a) \ 16 { \ 17 pixel32 _p; \ 18 _p.data32 = *(uint32*)d; \ 19 BLEND(d, 255 - _p.data8[2], 255 - _p.data8[1], 255 - _p.data8[0], a); \ 20 } 21 22 // ASSIGN_INVERT 23 #define ASSIGN_INVERT(d) \ 24 { \ 25 pixel32 _p; \ 26 _p.data32 = *(uint32*)d; \ 27 d[0] = 255 - _p.data8[0]; \ 28 d[1] = 255 - _p.data8[1]; \ 29 d[2] = 255 - _p.data8[2]; \ 30 d[3] = 255; \ 31 } 32 33 // blend_pixel_invert 34 void 35 blend_pixel_invert(int x, int y, const color_type& c, uint8 cover, 36 agg_buffer* buffer, const PatternHandler* pattern) 37 { 38 if (pattern->IsHighColor(x, y)) { 39 uint8* p = buffer->row_ptr(y) + (x << 2); 40 if (cover == 255) { 41 ASSIGN_INVERT(p); 42 } else { 43 BLEND_INVERT(p, cover); 44 } 45 } 46 } 47 48 // blend_hline_invert 49 void 50 blend_hline_invert(int x, int y, unsigned len, 51 const color_type& c, uint8 cover, 52 agg_buffer* buffer, const PatternHandler* pattern) 53 { 54 uint8* p = buffer->row_ptr(y) + (x << 2); 55 if(cover == 255) { 56 do { 57 if (pattern->IsHighColor(x, y)) { 58 ASSIGN_INVERT(p); 59 } 60 x++; 61 p += 4; 62 } while(--len); 63 } else { 64 do { 65 if (pattern->IsHighColor(x, y)) { 66 BLEND_INVERT(p, cover); 67 } 68 x++; 69 p += 4; 70 } while(--len); 71 } 72 } 73 74 // blend_solid_hspan_invert 75 void 76 blend_solid_hspan_invert(int x, int y, unsigned len, 77 const color_type& c, const uint8* covers, 78 agg_buffer* buffer, const PatternHandler* pattern) 79 { 80 uint8* p = buffer->row_ptr(y) + (x << 2); 81 do { 82 if (pattern->IsHighColor(x, y)) { 83 if (*covers) { 84 if (*covers == 255) { 85 ASSIGN_INVERT(p); 86 } else { 87 BLEND_INVERT(p, *covers); 88 } 89 } 90 } 91 covers++; 92 p += 4; 93 x++; 94 } while(--len); 95 } 96 97 98 99 // blend_solid_vspan_invert 100 void 101 blend_solid_vspan_invert(int x, int y, unsigned len, 102 const color_type& c, const uint8* covers, 103 agg_buffer* buffer, const PatternHandler* pattern) 104 { 105 uint8* p = buffer->row_ptr(y) + (x << 2); 106 do { 107 if (pattern->IsHighColor(x, y)) { 108 if (*covers) { 109 if (*covers == 255) { 110 ASSIGN_INVERT(p); 111 } else { 112 BLEND_INVERT(p, *covers); 113 } 114 } 115 } 116 covers++; 117 p += buffer->stride(); 118 y++; 119 } while(--len); 120 } 121 122 123 // blend_color_hspan_invert 124 void 125 blend_color_hspan_invert(int x, int y, unsigned len, 126 const color_type* colors, 127 const uint8* covers, uint8 cover, 128 agg_buffer* buffer, const PatternHandler* pattern) 129 { 130 // TODO: does the R5 app_server check for the 131 // appearance of the high color in the source bitmap? 132 uint8* p = buffer->row_ptr(y) + (x << 2); 133 if (covers) { 134 // non-solid opacity 135 do { 136 if (*covers && colors->a > 0) { 137 if (*covers == 255) { 138 ASSIGN_INVERT(p); 139 } else { 140 BLEND_INVERT(p, *covers); 141 } 142 } 143 covers++; 144 p += 4; 145 ++colors; 146 } while(--len); 147 } else { 148 // solid full opcacity 149 if (cover == 255) { 150 do { 151 if (colors->a > 0) { 152 ASSIGN_INVERT(p); 153 } 154 p += 4; 155 ++colors; 156 } while(--len); 157 // solid partial opacity 158 } else if (cover) { 159 do { 160 if (colors->a > 0) { 161 BLEND_INVERT(p, cover); 162 } 163 p += 4; 164 ++colors; 165 } while(--len); 166 } 167 } 168 } 169 170 #endif // DRAWING_MODE_INVERT_H 171 172