xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
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_ERASE on B_RGBA32.
6  *
7  */
8 
9 #ifndef DRAWING_MODE_ERASE_H
10 #define DRAWING_MODE_ERASE_H
11 
12 #include "DrawingMode.h"
13 
14 // BLEND_ERASE
15 #define BLEND_ERASE(d1, d2, d3, da, s1, s2, s3, a) \
16 { \
17 	BLEND(d1, d2, d3, da, s1, s2, s3, a); \
18 }
19 
20 // ASSIGN_ERASE
21 #define ASSIGN_ERASE(d1, d2, d3, da, s1, s2, s3) \
22 { \
23 	(d1) = (s1); \
24 	(d2) = (s2); \
25 	(d3) = (s3); \
26 	(da) = 255; \
27 }
28 
29 
30 template<class Order>
31 class DrawingModeErase : public DrawingMode {
32  public:
33 	// constructor
34 	DrawingModeErase()
35 		: DrawingMode()
36 	{
37 	}
38 
39 	// blend_pixel
40 	virtual	void blend_pixel(int x, int y, const color_type& c, uint8 cover)
41 	{
42 		if (fPatternHandler->IsHighColor(x, y)) {
43 			uint8* p = fBuffer->row(y) + (x << 2);
44 			rgb_color color = fPatternHandler->LowColor().GetColor32();
45 			if (cover == 255) {
46 				ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
47 							 color.red, color.green, color.blue);
48 			} else {
49 				BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
50 							color.red, color.green, color.blue, cover);
51 			}
52 		}
53 	}
54 
55 	// blend_hline
56 	virtual	void blend_hline(int x, int y, unsigned len,
57 							 const color_type& c, uint8 cover)
58 	{
59 		if (cover == 255) {
60 			rgb_color color = fPatternHandler->LowColor().GetColor32();
61 			uint32 v;
62 			uint8* p8 = (uint8*)&v;
63 			p8[Order::R] = (uint8)color.red;
64 			p8[Order::G] = (uint8)color.green;
65 			p8[Order::B] = (uint8)color.blue;
66 			p8[Order::A] = 255;
67 			uint32* p32 = (uint32*)(fBuffer->row(y)) + x;
68 			do {
69 				if (fPatternHandler->IsHighColor(x, y))
70 					*p32 = v;
71 				p32++;
72 				x++;
73 			} while(--len);
74 		} else {
75 			uint8* p = fBuffer->row(y) + (x << 2);
76 			rgb_color color = fPatternHandler->LowColor().GetColor32();
77 			do {
78 				if (fPatternHandler->IsHighColor(x, y)) {
79 					BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
80 								color.red, color.green, color.blue, cover);
81 				}
82 				x++;
83 				p += 4;
84 			} while(--len);
85 		}
86 	}
87 
88 	// blend_vline
89 	virtual	void blend_vline(int x, int y, unsigned len,
90 							 const color_type& c, uint8 cover)
91 	{
92 printf("DrawingModeErase::blend_vline()\n");
93 	}
94 
95 	// blend_solid_hspan
96 	virtual	void blend_solid_hspan(int x, int y, unsigned len,
97 								   const color_type& c, const uint8* covers)
98 	{
99 		uint8* p = fBuffer->row(y) + (x << 2);
100 		rgb_color color = fPatternHandler->LowColor().GetColor32();
101 		do {
102 			if (fPatternHandler->IsHighColor(x, y)) {
103 				if (*covers) {
104 					if(*covers == 255) {
105 						ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
106 									 color.red, color.green, color.blue);
107 					} else {
108 						BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
109 									color.red, color.green, color.blue, *covers);
110 					}
111 				}
112 			}
113 			covers++;
114 			p += 4;
115 			x++;
116 		} while(--len);
117 	}
118 
119 
120 
121 	// blend_solid_vspan
122 	virtual	void blend_solid_vspan(int x, int y, unsigned len,
123 								   const color_type& c, const uint8* covers)
124 	{
125 		uint8* p = fBuffer->row(y) + (x << 2);
126 		rgb_color color = fPatternHandler->LowColor().GetColor32();
127 		do {
128 			if (fPatternHandler->IsHighColor(x, y)) {
129 				if (*covers) {
130 					if (*covers == 255) {
131 						ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
132 									 color.red, color.green, color.blue);
133 					} else {
134 						BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
135 									color.red, color.green, color.blue, *covers);
136 					}
137 				}
138 			}
139 			covers++;
140 			p += fBuffer->stride();
141 			y++;
142 		} while(--len);
143 	}
144 
145 
146 	// blend_color_hspan
147 	virtual	void blend_color_hspan(int x, int y, unsigned len,
148 								   const color_type* colors,
149 								   const uint8* covers,
150 								   uint8 cover)
151 	{
152 		// TODO: compare this with BView
153 		uint8* p = fBuffer->row(y) + (x << 2);
154 		if (covers) {
155 			// non-solid opacity
156 			do {
157 				if(*covers) {
158 					if(*covers == 255) {
159 						ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
160 									 colors->r, colors->g, colors->b);
161 					} else {
162 						BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
163 									colors->r, colors->g, colors->b, *covers);
164 					}
165 				}
166 				covers++;
167 				p += 4;
168 				++colors;
169 			} while(--len);
170 		} else {
171 			// solid full opcacity
172 			if (cover == 255) {
173 				do {
174 					ASSIGN_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
175 								 colors->r, colors->g, colors->b);
176 					p += 4;
177 					++colors;
178 				} while(--len);
179 			// solid partial opacity
180 			} else if (cover) {
181 				do {
182 					BLEND_ERASE(p[Order::R], p[Order::G], p[Order::B], p[Order::A],
183 								colors->r, colors->g, colors->b, cover);
184 					p += 4;
185 					++colors;
186 				} while(--len);
187 			}
188 		}
189 	}
190 
191 
192 	// blend_color_vspan
193 	virtual	void blend_color_vspan(int x, int y, unsigned len,
194 								   const color_type* colors,
195 								   const uint8* covers,
196 								   uint8 cover)
197 	{
198 printf("DrawingModeErase::blend_color_vspan()\n");
199 	}
200 
201 };
202 
203 typedef DrawingModeErase<agg::order_rgba32> DrawingModeRGBA32Erase;
204 typedef DrawingModeErase<agg::order_argb32> DrawingModeARGB32Erase;
205 typedef DrawingModeErase<agg::order_abgr32> DrawingModeABGR32Erase;
206 typedef DrawingModeErase<agg::order_bgra32> DrawingModeBGRA32Erase;
207 
208 #endif // DRAWING_MODE_ERASE_H
209 
210