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