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