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
31void
32blend_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
47void
48blend_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
94void
95blend_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
120void
121blend_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
145void
146blend_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