xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeAlphaPCSolid.h (revision 97dfeb96704e5dbc5bec32ad7b21379d0125e031)
1 /*
2  * Copyright 2005, Stephan Aßmus <superstippi@gmx.de>
3  * Copyright 2015, Julian Harnath <julian.harnath@rwth-aachen.de>
4  * All rights reserved. Distributed under the terms of the MIT License.
5  *
6  * DrawingMode implementing B_OP_ALPHA in "Pixel Composite" mode on B_RGBA32.
7  *
8  */
9 
10 #ifndef DRAWING_MODE_ALPHA_PC_SOLID_H
11 #define DRAWING_MODE_ALPHA_PC_SOLID_H
12 
13 #include "DrawingMode.h"
14 
15 
16 #define BLEND_ALPHA_PC(d, r, g, b, a) \
17 { \
18 	BLEND_COMPOSITE16(d, r, g, b, a); \
19 }
20 
21 
22 #define ASSIGN_ALPHA_PC(d, r, g, b) \
23 { \
24 	d[0] = (b); \
25 	d[1] = (g); \
26 	d[2] = (r); \
27 	d[3] = 255; \
28 }
29 
30 
31 void
32 blend_pixel_alpha_pc_solid(int x, int y, const color_type& color, uint8 cover,
33 					 agg_buffer* buffer, const PatternHandler*)
34 {
35 	uint8* p = buffer->row_ptr(y) + (x << 2);
36 	uint16 alpha = color.a * cover;
37 	if (alpha == 255 * 255) {
38 		ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
39 	} else {
40 		BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
41 	}
42 }
43 
44 
45 void
46 blend_hline_alpha_pc_solid(int x, int y, unsigned len,
47 					 const color_type& color, uint8 cover,
48 					 agg_buffer* buffer, const PatternHandler*)
49 {
50 	uint8* p = buffer->row_ptr(y) + (x << 2);
51 	uint16 alpha = color.a * cover;
52 	if (alpha == 0)
53 		return;
54 
55 	if (alpha == 255 * 255) {
56 		do {
57 			ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
58 			p += 4;
59 		} while(--len);
60 		return;
61 	}
62 
63 	do {
64 		BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
65 		p += 4;
66 	} while(--len);
67 }
68 
69 
70 void
71 blend_solid_hspan_alpha_pc_solid(int x, int y, unsigned len,
72 						   const color_type& color, const uint8* covers,
73 						   agg_buffer* buffer, const PatternHandler*)
74 {
75 	uint8* p = buffer->row_ptr(y) + (x << 2);
76 	do {
77 		uint16 alpha = color.a * *covers;
78 		if (alpha) {
79 			if(alpha == 255 * 255) {
80 				ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
81 			} else {
82 				BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
83 			}
84 		}
85 		covers++;
86 		p += 4;
87 	} while(--len);
88 }
89 
90 
91 void
92 blend_solid_vspan_alpha_pc_solid(int x, int y, unsigned len,
93 						   const color_type& color, const uint8* covers,
94 						   agg_buffer* buffer, const PatternHandler*)
95 {
96 	uint8* p = buffer->row_ptr(y) + (x << 2);
97 	do {
98 		uint16 alpha = color.a * *covers;
99 		if (alpha) {
100 			if (alpha == 255 * 255) {
101 				ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
102 			} else {
103 				BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
104 			}
105 		}
106 		covers++;
107 		p += buffer->stride();
108 	} while(--len);
109 }
110 
111 
112 void
113 blend_color_hspan_alpha_pc_solid(int x, int y, unsigned len,
114 						   const color_type* colors,
115 						   const uint8* covers, uint8 cover,
116 						   agg_buffer* buffer, const PatternHandler*)
117 {
118 	uint8* p = buffer->row_ptr(y) + (x << 2);
119 	if (covers) {
120 		// non-solid opacity
121 		do {
122 			uint16 alpha = colors->a * *covers;
123 			if (alpha) {
124 				if (alpha == 255 * 255) {
125 					ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
126 				} else {
127 					BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
128 				}
129 			}
130 			covers++;
131 			p += 4;
132 			++colors;
133 		} while(--len);
134 	} else {
135 		// solid full opcacity
136 		uint16 alpha = colors->a * cover;
137 		if (alpha == 255 * 255) {
138 			do {
139 				ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
140 				p += 4;
141 				++colors;
142 			} while(--len);
143 		// solid partial opacity
144 		} else if (alpha) {
145 			do {
146 				BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
147 				p += 4;
148 				++colors;
149 			} while(--len);
150 		}
151 	}
152 }
153 
154 
155 #endif // DRAWING_MODE_ALPHA_PC_SOLID_H
156