xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h (revision 25a7b01d15612846f332751841da3579db313082)
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
blend_pixel_invert(int x,int y,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)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
blend_hline_invert(int x,int y,unsigned len,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)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
blend_solid_hspan_invert(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)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
blend_solid_vspan_invert(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)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
blend_color_hspan_invert(int x,int y,unsigned len,const color_type * colors,const uint8 * covers,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)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