xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeErase.h (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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(d, r, g, b, a) \
16 { \
17 	BLEND(d, r, g, b, a); \
18 }
19 
20 // ASSIGN_ERASE
21 #define ASSIGN_ERASE(d, r, g, b) \
22 { \
23 	d[0] = (b); \
24 	d[1] = (g); \
25 	d[2] = (r); \
26 	d[3] = 255; \
27 }
28 
29 // blend_pixel_erase
30 void
31 blend_pixel_erase(int x, int y, const color_type& c, uint8 cover,
32 				  agg_buffer* buffer, const PatternHandler* pattern)
33 {
34 	if (pattern->IsHighColor(x, y)) {
35 		uint8* p = buffer->row_ptr(y) + (x << 2);
36 		rgb_color color = pattern->LowColor();
37 		if (cover == 255) {
38 			ASSIGN_ERASE(p, color.red, color.green, color.blue);
39 		} else {
40 			BLEND_ERASE(p, color.red, color.green, color.blue, cover);
41 		}
42 	}
43 }
44 
45 // blend_hline_erase
46 void
47 blend_hline_erase(int x, int y, unsigned len,
48 						 const color_type& c, uint8 cover,
49 						 agg_buffer* buffer, const PatternHandler* pattern)
50 {
51 	if (cover == 255) {
52 		rgb_color color = pattern->LowColor();
53 		uint32 v;
54 		uint8* p8 = (uint8*)&v;
55 		p8[0] = (uint8)color.blue;
56 		p8[1] = (uint8)color.green;
57 		p8[2] = (uint8)color.red;
58 		p8[3] = 255;
59 		uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
60 		do {
61 			if (pattern->IsHighColor(x, y))
62 				*p32 = v;
63 			p32++;
64 			x++;
65 		} while(--len);
66 	} else {
67 		uint8* p = buffer->row_ptr(y) + (x << 2);
68 		rgb_color color = pattern->LowColor();
69 		do {
70 			if (pattern->IsHighColor(x, y)) {
71 				BLEND_ERASE(p, color.red, color.green, color.blue, cover);
72 			}
73 			x++;
74 			p += 4;
75 		} while(--len);
76 	}
77 }
78 
79 // blend_solid_hspan_erase
80 void
81 blend_solid_hspan_erase(int x, int y, unsigned len,
82 						const color_type& c, const uint8* covers,
83 						agg_buffer* buffer, const PatternHandler* pattern)
84 {
85 	uint8* p = buffer->row_ptr(y) + (x << 2);
86 	rgb_color color = pattern->LowColor();
87 	do {
88 		if (pattern->IsHighColor(x, y)) {
89 			if (*covers) {
90 				if(*covers == 255) {
91 					ASSIGN_ERASE(p, color.red, color.green, color.blue);
92 				} else {
93 					BLEND_ERASE(p, color.red, color.green, color.blue, *covers);
94 				}
95 			}
96 		}
97 		covers++;
98 		p += 4;
99 		x++;
100 	} while(--len);
101 }
102 
103 
104 
105 // blend_solid_vspan_erase
106 void
107 blend_solid_vspan_erase(int x, int y, unsigned len,
108 						const color_type& c, const uint8* covers,
109 						agg_buffer* buffer, const PatternHandler* pattern)
110 {
111 	uint8* p = buffer->row_ptr(y) + (x << 2);
112 	rgb_color color = pattern->LowColor();
113 	do {
114 		if (pattern->IsHighColor(x, y)) {
115 			if (*covers) {
116 				if (*covers == 255) {
117 					ASSIGN_ERASE(p, color.red, color.green, color.blue);
118 				} else {
119 					BLEND_ERASE(p, color.red, color.green, color.blue, *covers);
120 				}
121 			}
122 		}
123 		covers++;
124 		p += buffer->stride();
125 		y++;
126 	} while(--len);
127 }
128 
129 
130 // blend_color_hspan_erase
131 void
132 blend_color_hspan_erase(int x, int y, unsigned len,
133 						const color_type* colors,
134 						const uint8* covers, uint8 cover,
135 						agg_buffer* buffer, const PatternHandler* pattern)
136 {
137 	uint8* p = buffer->row_ptr(y) + (x << 2);
138 	rgb_color lowColor = pattern->LowColor();
139 	if (covers) {
140 		// non-solid opacity
141 		do {
142 			if (*covers && colors->a > 0) {
143 				if (*covers == 255) {
144 					ASSIGN_ERASE(p, lowColor.red, lowColor.green,
145 						lowColor.blue);
146 				} else {
147 					BLEND_ERASE(p, lowColor.red, lowColor.green, lowColor.blue,
148 						*covers);
149 				}
150 			}
151 			covers++;
152 			p += 4;
153 			++colors;
154 		} while(--len);
155 	} else {
156 		// solid full opcacity
157 		if (cover == 255) {
158 			do {
159 				if (colors->a > 0) {
160 					ASSIGN_ERASE(p, lowColor.red, lowColor.green,
161 						lowColor.blue);
162 				}
163 				p += 4;
164 				++colors;
165 			} while(--len);
166 		// solid partial opacity
167 		} else if (cover) {
168 			do {
169 				if (colors->a > 0) {
170 					BLEND_ERASE(p, lowColor.red, lowColor.green, lowColor.blue,
171 						cover);
172 				}
173 				p += 4;
174 				++colors;
175 			} while(--len);
176 		}
177 	}
178 }
179 
180 #endif // DRAWING_MODE_ERASE_H
181 
182