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