xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeCopy.h (revision 9e25244c5e9051f6cd333820d6332397361abd6c)
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_COPY on B_RGBA32.
6  *
7  */
8 
9 #ifndef DRAWING_MODE_COPY_H
10 #define DRAWING_MODE_COPY_H
11 
12 #include "DrawingMode.h"
13 
14 // BLEND_COPY
15 #define BLEND_COPY(d, r2, g2, b2, a, r1, g1, b1) \
16 { \
17 	BLEND_FROM(d, r1, g1, b1, r2, g2, b2, a); \
18 }
19 
20 // ASSIGN_COPY
21 #define ASSIGN_COPY(d, r, g, b, a) \
22 { \
23 	d[0] = (b); \
24 	d[1] = (g); \
25 	d[2] = (r); \
26 	d[3] = (a); \
27 }
28 
29 
30 // blend_pixel_copy
31 void
32 blend_pixel_copy(int x, int y, const color_type& c, uint8 cover,
33 				 agg_buffer* buffer, const PatternHandler* pattern)
34 {
35 	uint8* p = buffer->row_ptr(y) + (x << 2);
36 	rgb_color color = pattern->ColorAt(x, y);
37 	if (cover == 255) {
38 		ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
39 	} else if (cover != 0) {
40 		rgb_color l = pattern->LowColor();
41 		BLEND_COPY(p, color.red, color.green, color.blue, cover,
42 				   l.red, l.green, l.blue);
43 	}
44 }
45 
46 // blend_hline_copy
47 void
48 blend_hline_copy(int x, int y, unsigned len,
49 						 const color_type& c, uint8 cover,
50 						 agg_buffer* buffer, const PatternHandler* pattern)
51 {
52 	if (cover == 255) {
53 		// cache the low and high color as 32bit values
54 		// high color
55 		rgb_color color = pattern->HighColor();
56 		uint32 vh;
57 		uint8* p8 = (uint8*)&vh;
58 		p8[0] = (uint8)color.blue;
59 		p8[1] = (uint8)color.green;
60 		p8[2] = (uint8)color.red;
61 		p8[3] = 255;
62 		// low color
63 		color = pattern->LowColor();
64 		uint32 vl;
65 		p8 = (uint8*)&vl;
66 		p8[0] = (uint8)color.blue;
67 		p8[1] = (uint8)color.green;
68 		p8[2] = (uint8)color.red;
69 		p8[3] = 255;
70 		// row offset as 32bit pointer
71 		uint32* p32 = (uint32*)(buffer->row_ptr(y)) + x;
72 		do {
73 			if (pattern->IsHighColor(x, y))
74 				*p32 = vh;
75 			else
76 				*p32 = vl;
77 			p32++;
78 			x++;
79 		} while(--len);
80 	} else  if (cover != 0) {
81 		uint8* p = buffer->row_ptr(y) + (x << 2);
82 		rgb_color l = pattern->LowColor();
83 		do {
84 			rgb_color color = pattern->ColorAt(x, y);
85 			BLEND_COPY(p, color.red, color.green, color.blue, cover,
86 					   l.red, l.green, l.blue);
87 			x++;
88 			p += 4;
89 		} while(--len);
90 	}
91 }
92 
93 // blend_solid_hspan_copy
94 void
95 blend_solid_hspan_copy(int x, int y, unsigned len,
96 				  const color_type& c, const uint8* covers,
97 				  agg_buffer* buffer, const PatternHandler* pattern)
98 {
99 	uint8* p = buffer->row_ptr(y) + (x << 2);
100 	rgb_color l = pattern->LowColor();
101 	do {
102 		rgb_color color = pattern->ColorAt(x, y);
103 		if (*covers) {
104 			if (*covers == 255) {
105 				ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
106 			} else if (*covers != 0) {
107 				BLEND_COPY(p, color.red, color.green, color.blue, *covers,
108 						   l.red, l.green, l.blue);
109 			}
110 		}
111 		covers++;
112 		p += 4;
113 		x++;
114 	} while(--len);
115 }
116 
117 
118 
119 // blend_solid_vspan_copy
120 void
121 blend_solid_vspan_copy(int x, int y, unsigned len,
122 					   const color_type& c, const uint8* covers,
123 					   agg_buffer* buffer, const PatternHandler* pattern)
124 {
125 	uint8* p = buffer->row_ptr(y) + (x << 2);
126 	rgb_color l = pattern->LowColor();
127 	do {
128 		rgb_color color = pattern->ColorAt(x, y);
129 		if (*covers) {
130 			if (*covers == 255) {
131 				ASSIGN_COPY(p, color.red, color.green, color.blue, color.alpha);
132 			} else if (*covers != 0) {
133 				BLEND_COPY(p, color.red, color.green, color.blue, *covers,
134 						   l.red, l.green, l.blue);
135 			}
136 		}
137 		covers++;
138 		p += buffer->stride();
139 		y++;
140 	} while(--len);
141 }
142 
143 
144 // blend_color_hspan_copy
145 void
146 blend_color_hspan_copy(int x, int y, unsigned len, const color_type* colors,
147 					   const uint8* covers, uint8 cover,
148 					   agg_buffer* buffer, const PatternHandler* pattern)
149 {
150 	uint8* p = buffer->row_ptr(y) + (x << 2);
151 	rgb_color l = pattern->LowColor();
152 	if (covers) {
153 		// non-solid opacity
154 		do {
155 			if(*covers) {
156 				if(*covers == 255) {
157 					ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
158 				} else if (*covers != 0) {
159 					BLEND_COPY(p, colors->r, colors->g, colors->b, *covers,
160 							   l.red, l.green, l.blue);
161 				}
162 			}
163 			covers++;
164 			p += 4;
165 			++colors;
166 		} while(--len);
167 	} else {
168 		// solid full opcacity
169 		if (cover == 255) {
170 			do {
171 				ASSIGN_COPY(p, colors->r, colors->g, colors->b, colors->a);
172 				p += 4;
173 				++colors;
174 			} while(--len);
175 		// solid partial opacity
176 		} else if (cover != 0) {
177 			do {
178 				BLEND_COPY(p, colors->r, colors->g, colors->b, cover,
179 						   l.red, l.green, l.blue);
180 				p += 4;
181 				++colors;
182 			} while(--len);
183 		}
184 	}
185 }
186 
187 #endif // DRAWING_MODE_COPY_H
188 
189