xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeInvert.h (revision c0fe8a07c960b06325099bb14ee09a6267c35e8e)
1*c0fe8a07SStephan Aßmus // DrawingModeInvert.h
2*c0fe8a07SStephan Aßmus 
3*c0fe8a07SStephan Aßmus #ifndef DRAWING_MODE_INVERT_H
4*c0fe8a07SStephan Aßmus #define DRAWING_MODE_INVERT_H
5*c0fe8a07SStephan Aßmus 
6*c0fe8a07SStephan Aßmus #include "DrawingMode.h"
7*c0fe8a07SStephan Aßmus 
8*c0fe8a07SStephan Aßmus // BLEND_INVERT
9*c0fe8a07SStephan Aßmus #define BLEND_INVERT(d1, d2, d3, da, a) \
10*c0fe8a07SStephan Aßmus { \
11*c0fe8a07SStephan Aßmus 	BLEND(d1, d2, d3, da, 255 - d1, 255 - d2, 255 - d3, a); \
12*c0fe8a07SStephan Aßmus }
13*c0fe8a07SStephan Aßmus 
14*c0fe8a07SStephan Aßmus // ASSIGN_INVERT
15*c0fe8a07SStephan Aßmus #define ASSIGN_INVERT(d1, d2, d3, da) \
16*c0fe8a07SStephan Aßmus { \
17*c0fe8a07SStephan Aßmus 	(d1) = 255 - (d1); \
18*c0fe8a07SStephan Aßmus 	(d2) = 255 - (d2); \
19*c0fe8a07SStephan Aßmus 	(d3) = 255 - (d3); \
20*c0fe8a07SStephan Aßmus 	(da) = 255; \
21*c0fe8a07SStephan Aßmus }
22*c0fe8a07SStephan Aßmus 
23*c0fe8a07SStephan Aßmus 
24*c0fe8a07SStephan Aßmus template<class Order>
25*c0fe8a07SStephan Aßmus class DrawingModeInvert : public DrawingMode {
26*c0fe8a07SStephan Aßmus  public:
27*c0fe8a07SStephan Aßmus 	// constructor
28*c0fe8a07SStephan Aßmus 	DrawingModeInvert()
29*c0fe8a07SStephan Aßmus 		: DrawingMode()
30*c0fe8a07SStephan Aßmus 	{
31*c0fe8a07SStephan Aßmus 	}
32*c0fe8a07SStephan Aßmus 
33*c0fe8a07SStephan Aßmus 	// blend_pixel
34*c0fe8a07SStephan Aßmus 	virtual	void blend_pixel(int x, int y, const color_type& c, uint8 cover)
35*c0fe8a07SStephan Aßmus 	{
36*c0fe8a07SStephan Aßmus 		if (fPatternHandler->IsHighColor(x, y)) {
37*c0fe8a07SStephan Aßmus 			uint8* p = fBuffer->row(y) + (x << 2);
38*c0fe8a07SStephan Aßmus 			if (cover == 255) {
39*c0fe8a07SStephan Aßmus 				ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
40*c0fe8a07SStephan Aßmus 			} else {
41*c0fe8a07SStephan Aßmus 				BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], cover);
42*c0fe8a07SStephan Aßmus 			}
43*c0fe8a07SStephan Aßmus 		}
44*c0fe8a07SStephan Aßmus 	}
45*c0fe8a07SStephan Aßmus 
46*c0fe8a07SStephan Aßmus 	// blend_hline
47*c0fe8a07SStephan Aßmus 	virtual	void blend_hline(int x, int y, unsigned len,
48*c0fe8a07SStephan Aßmus 							 const color_type& c, uint8 cover)
49*c0fe8a07SStephan Aßmus 	{
50*c0fe8a07SStephan Aßmus 		uint8* p = fBuffer->row(y) + (x << 2);
51*c0fe8a07SStephan Aßmus 		if(cover == 255) {
52*c0fe8a07SStephan Aßmus 			do {
53*c0fe8a07SStephan Aßmus 				if (fPatternHandler->IsHighColor(x, y)) {
54*c0fe8a07SStephan Aßmus 					ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
55*c0fe8a07SStephan Aßmus 				}
56*c0fe8a07SStephan Aßmus 				x++;
57*c0fe8a07SStephan Aßmus 				p += 4;
58*c0fe8a07SStephan Aßmus 			} while(--len);
59*c0fe8a07SStephan Aßmus 		} else {
60*c0fe8a07SStephan Aßmus 			do {
61*c0fe8a07SStephan Aßmus 				if (fPatternHandler->IsHighColor(x, y)) {
62*c0fe8a07SStephan Aßmus 					BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], cover);
63*c0fe8a07SStephan Aßmus 				}
64*c0fe8a07SStephan Aßmus 				x++;
65*c0fe8a07SStephan Aßmus 				p += 4;
66*c0fe8a07SStephan Aßmus 			} while(--len);
67*c0fe8a07SStephan Aßmus 		}
68*c0fe8a07SStephan Aßmus 	}
69*c0fe8a07SStephan Aßmus 
70*c0fe8a07SStephan Aßmus 	// blend_vline
71*c0fe8a07SStephan Aßmus 	virtual	void blend_vline(int x, int y, unsigned len,
72*c0fe8a07SStephan Aßmus 							 const color_type& c, uint8 cover)
73*c0fe8a07SStephan Aßmus 	{
74*c0fe8a07SStephan Aßmus printf("DrawingModeInvert::blend_vline()\n");
75*c0fe8a07SStephan Aßmus 	}
76*c0fe8a07SStephan Aßmus 
77*c0fe8a07SStephan Aßmus 	// blend_solid_hspan
78*c0fe8a07SStephan Aßmus 	virtual	void blend_solid_hspan(int x, int y, unsigned len,
79*c0fe8a07SStephan Aßmus 								   const color_type& c, const uint8* covers)
80*c0fe8a07SStephan Aßmus 	{
81*c0fe8a07SStephan Aßmus 		uint8* p = fBuffer->row(y) + (x << 2);
82*c0fe8a07SStephan Aßmus 		do {
83*c0fe8a07SStephan Aßmus 			if (fPatternHandler->IsHighColor(x, y)) {
84*c0fe8a07SStephan Aßmus 				if (*covers) {
85*c0fe8a07SStephan Aßmus 					if (*covers == 255) {
86*c0fe8a07SStephan Aßmus 						ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
87*c0fe8a07SStephan Aßmus 					} else {
88*c0fe8a07SStephan Aßmus 						BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], *covers);
89*c0fe8a07SStephan Aßmus 					}
90*c0fe8a07SStephan Aßmus 				}
91*c0fe8a07SStephan Aßmus 			}
92*c0fe8a07SStephan Aßmus 			covers++;
93*c0fe8a07SStephan Aßmus 			p += 4;
94*c0fe8a07SStephan Aßmus 			x++;
95*c0fe8a07SStephan Aßmus 		} while(--len);
96*c0fe8a07SStephan Aßmus 	}
97*c0fe8a07SStephan Aßmus 
98*c0fe8a07SStephan Aßmus 
99*c0fe8a07SStephan Aßmus 
100*c0fe8a07SStephan Aßmus 	// blend_solid_vspan
101*c0fe8a07SStephan Aßmus 	virtual	void blend_solid_vspan(int x, int y, unsigned len,
102*c0fe8a07SStephan Aßmus 								   const color_type& c, const uint8* covers)
103*c0fe8a07SStephan Aßmus 	{
104*c0fe8a07SStephan Aßmus 		uint8* p = fBuffer->row(y) + (x << 2);
105*c0fe8a07SStephan Aßmus 		do {
106*c0fe8a07SStephan Aßmus 			if (fPatternHandler->IsHighColor(x, y)) {
107*c0fe8a07SStephan Aßmus 				if (*covers) {
108*c0fe8a07SStephan Aßmus 					if (*covers == 255) {
109*c0fe8a07SStephan Aßmus 						ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
110*c0fe8a07SStephan Aßmus 					} else {
111*c0fe8a07SStephan Aßmus 						BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], *covers);
112*c0fe8a07SStephan Aßmus 					}
113*c0fe8a07SStephan Aßmus 				}
114*c0fe8a07SStephan Aßmus 			}
115*c0fe8a07SStephan Aßmus 			covers++;
116*c0fe8a07SStephan Aßmus 			p += fBuffer->stride();
117*c0fe8a07SStephan Aßmus 			y++;
118*c0fe8a07SStephan Aßmus 		} while(--len);
119*c0fe8a07SStephan Aßmus 	}
120*c0fe8a07SStephan Aßmus 
121*c0fe8a07SStephan Aßmus 
122*c0fe8a07SStephan Aßmus 	// blend_color_hspan
123*c0fe8a07SStephan Aßmus 	virtual	void blend_color_hspan(int x, int y, unsigned len,
124*c0fe8a07SStephan Aßmus 								   const color_type* colors,
125*c0fe8a07SStephan Aßmus 								   const uint8* covers,
126*c0fe8a07SStephan Aßmus 								   uint8 cover)
127*c0fe8a07SStephan Aßmus 	{
128*c0fe8a07SStephan Aßmus 		// TODO: does the R5 app_server check for the
129*c0fe8a07SStephan Aßmus 		// appearance of the high color in the source bitmap?
130*c0fe8a07SStephan Aßmus 		uint8* p = fBuffer->row(y) + (x << 2);
131*c0fe8a07SStephan Aßmus 		if (covers) {
132*c0fe8a07SStephan Aßmus 			// non-solid opacity
133*c0fe8a07SStephan Aßmus 			do {
134*c0fe8a07SStephan Aßmus 				if (*covers) {
135*c0fe8a07SStephan Aßmus 					if (*covers == 255) {
136*c0fe8a07SStephan Aßmus 						ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
137*c0fe8a07SStephan Aßmus 					} else {
138*c0fe8a07SStephan Aßmus 						BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], *covers);
139*c0fe8a07SStephan Aßmus 					}
140*c0fe8a07SStephan Aßmus 				}
141*c0fe8a07SStephan Aßmus 				covers++;
142*c0fe8a07SStephan Aßmus 				p += 4;
143*c0fe8a07SStephan Aßmus //					++colors;
144*c0fe8a07SStephan Aßmus 			} while(--len);
145*c0fe8a07SStephan Aßmus 		} else {
146*c0fe8a07SStephan Aßmus 			// solid full opcacity
147*c0fe8a07SStephan Aßmus 			if (cover == 255) {
148*c0fe8a07SStephan Aßmus 				do {
149*c0fe8a07SStephan Aßmus 					ASSIGN_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
150*c0fe8a07SStephan Aßmus 					p += 4;
151*c0fe8a07SStephan Aßmus //						++colors;
152*c0fe8a07SStephan Aßmus 				} while(--len);
153*c0fe8a07SStephan Aßmus 			// solid partial opacity
154*c0fe8a07SStephan Aßmus 			} else if (cover) {
155*c0fe8a07SStephan Aßmus 				do {
156*c0fe8a07SStephan Aßmus 					BLEND_INVERT(p[Order::R], p[Order::G], p[Order::B], p[Order::A], cover);
157*c0fe8a07SStephan Aßmus 					p += 4;
158*c0fe8a07SStephan Aßmus //						++colors;
159*c0fe8a07SStephan Aßmus 				} while(--len);
160*c0fe8a07SStephan Aßmus 			}
161*c0fe8a07SStephan Aßmus 		}
162*c0fe8a07SStephan Aßmus 	}
163*c0fe8a07SStephan Aßmus 
164*c0fe8a07SStephan Aßmus 
165*c0fe8a07SStephan Aßmus 	// blend_color_vspan
166*c0fe8a07SStephan Aßmus 	virtual	void blend_color_vspan(int x, int y, unsigned len,
167*c0fe8a07SStephan Aßmus 								   const color_type* colors,
168*c0fe8a07SStephan Aßmus 								   const uint8* covers,
169*c0fe8a07SStephan Aßmus 								   uint8 cover)
170*c0fe8a07SStephan Aßmus 	{
171*c0fe8a07SStephan Aßmus printf("DrawingModeInvert::blend_color_vspan()\n");
172*c0fe8a07SStephan Aßmus 	}
173*c0fe8a07SStephan Aßmus 
174*c0fe8a07SStephan Aßmus };
175*c0fe8a07SStephan Aßmus 
176*c0fe8a07SStephan Aßmus typedef DrawingModeInvert<agg::order_rgba32> DrawingModeRGBA32Invert;
177*c0fe8a07SStephan Aßmus typedef DrawingModeInvert<agg::order_argb32> DrawingModeARGB32Invert;
178*c0fe8a07SStephan Aßmus typedef DrawingModeInvert<agg::order_abgr32> DrawingModeABGR32Invert;
179*c0fe8a07SStephan Aßmus typedef DrawingModeInvert<agg::order_bgra32> DrawingModeBGRA32Invert;
180*c0fe8a07SStephan Aßmus 
181*c0fe8a07SStephan Aßmus #endif // DRAWING_MODE_INVERT_H
182*c0fe8a07SStephan Aßmus 
183