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