xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPO.h (revision a3e794ae459fec76826407f8ba8c94cd3535f128)
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_ALPHA in "Pixel Overlay" mode on B_RGBA32.
6  *
7  */
8 
9 #ifndef DRAWING_MODE_ALPHA_PO_H
10 #define DRAWING_MODE_ALPHA_PO_H
11 
12 #include "DrawingMode.h"
13 
14 // BLEND_ALPHA_PO
15 #define BLEND_ALPHA_PO(d, r, g, b, a) \
16 { \
17 	BLEND16(d, r, g, b, a); \
18 }
19 
20 // ASSIGN_ALPHA_PO
21 #define ASSIGN_ALPHA_PO(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_alpha_po
30 void
31 blend_pixel_alpha_po(int x, int y, const color_type& c, uint8 cover,
32 					 agg_buffer* buffer, const PatternHandler* pattern)
33 {
34 	uint8* p = buffer->row_ptr(y) + (x << 2);
35 	rgb_color color = pattern->ColorAt(x, y);
36 	uint16 alpha = color.alpha * cover;
37 	if (alpha == 255 * 255) {
38 		ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
39 	} else {
40 		BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
41 	}
42 }
43 
44 // blend_hline_alpha_po
45 void
46 blend_hline_alpha_po(int x, int y, unsigned len,
47 					 const color_type& c, uint8 cover,
48 					 agg_buffer* buffer, const PatternHandler* pattern)
49 {
50 	uint8* p = buffer->row_ptr(y) + (x << 2);
51 	do {
52 		rgb_color color = pattern->ColorAt(x, y);
53 		uint16 alpha = color.alpha * cover;
54 		if (alpha) {
55 			if (alpha == 255) {
56 				ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
57 			} else {
58 				BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
59 			}
60 		}
61 		x++;
62 		p += 4;
63 	} while(--len);
64 }
65 
66 // blend_solid_hspan_alpha_po
67 void
68 blend_solid_hspan_alpha_po(int x, int y, unsigned len,
69 						   const color_type& c, const uint8* covers,
70 						   agg_buffer* buffer, const PatternHandler* pattern)
71 {
72 	uint8* p = buffer->row_ptr(y) + (x << 2);
73 	do {
74 		rgb_color color = pattern->ColorAt(x, y);
75 		uint16 alpha = color.alpha * *covers;
76 		if (alpha) {
77 			if(alpha == 255 * 255) {
78 				ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
79 			} else {
80 				BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
81 			}
82 		}
83 		covers++;
84 		p += 4;
85 		x++;
86 	} while(--len);
87 }
88 
89 
90 
91 // blend_solid_vspan_alpha_po
92 void
93 blend_solid_vspan_alpha_po(int x, int y, unsigned len,
94 						   const color_type& c, const uint8* covers,
95 						   agg_buffer* buffer, const PatternHandler* pattern)
96 {
97 	uint8* p = buffer->row_ptr(y) + (x << 2);
98 	do {
99 		rgb_color color = pattern->ColorAt(x, y);
100 		uint16 alpha = color.alpha * *covers;
101 		if (alpha) {
102 			if (alpha == 255 * 255) {
103 				ASSIGN_ALPHA_PO(p, color.red, color.green, color.blue);
104 			} else {
105 				BLEND_ALPHA_PO(p, color.red, color.green, color.blue, alpha);
106 			}
107 		}
108 		covers++;
109 		p += buffer->stride();
110 		y++;
111 	} while(--len);
112 }
113 
114 
115 // blend_color_hspan_alpha_po
116 void
117 blend_color_hspan_alpha_po(int x, int y, unsigned len,
118 						   const color_type* colors,
119 						   const uint8* covers, uint8 cover,
120 						   agg_buffer* buffer, const PatternHandler* pattern)
121 {
122 	uint8* p = buffer->row_ptr(y) + (x << 2);
123 	if (covers) {
124 		// non-solid opacity
125 		do {
126 			uint16 alpha = colors->a * *covers;
127 			if (alpha) {
128 				if (alpha == 255 * 255) {
129 					ASSIGN_ALPHA_PO(p, colors->r, colors->g, colors->b);
130 				} else {
131 					BLEND_ALPHA_PO(p, colors->r, colors->g, colors->b, alpha);
132 				}
133 			}
134 			covers++;
135 			p += 4;
136 			++colors;
137 		} while(--len);
138 	} else {
139 		// solid full opcacity
140 		uint16 alpha = colors->a * cover;
141 		if (alpha == 255 * 255) {
142 			do {
143 				ASSIGN_ALPHA_PO(p, colors->r, colors->g, colors->b);
144 				p += 4;
145 				++colors;
146 			} while(--len);
147 		// solid partial opacity
148 		} else if (alpha) {
149 			do {
150 				BLEND_ALPHA_PO(p, colors->r, colors->g, colors->b, alpha);
151 				p += 4;
152 				++colors;
153 			} while(--len);
154 		}
155 	}
156 }
157 
158 #endif // DRAWING_MODE_ALPHA_PO_H
159 
160