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