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