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_ERASE on B_RGBA32.
6 *
7 */
8
9#ifndef DRAWING_MODE_ERASE_H
10#define DRAWING_MODE_ERASE_H
11
12#include "DrawingMode.h"
13
14// BLEND_ERASE
15#define BLEND_ERASE(d, r, g, b, a) \
16{ \
17	BLEND(d, r, g, b, a); \
18}
19
20// ASSIGN_ERASE
21#define ASSIGN_ERASE(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_erase
30void
31blend_pixel_erase(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->LowColor();
37		if (cover == 255) {
38			ASSIGN_ERASE(p, color.red, color.green, color.blue);
39		} else {
40			BLEND_ERASE(p, color.red, color.green, color.blue, cover);
41		}
42	}
43}
44
45// blend_hline_erase
46void
47blend_hline_erase(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->LowColor();
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->LowColor();
69		do {
70			if (pattern->IsHighColor(x, y)) {
71				BLEND_ERASE(p, color.red, color.green, color.blue, cover);
72			}
73			x++;
74			p += 4;
75		} while(--len);
76	}
77}
78
79// blend_solid_hspan_erase
80void
81blend_solid_hspan_erase(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->LowColor();
87	do {
88		if (pattern->IsHighColor(x, y)) {
89			if (*covers) {
90				if(*covers == 255) {
91					ASSIGN_ERASE(p, color.red, color.green, color.blue);
92				} else {
93					BLEND_ERASE(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_erase
106void
107blend_solid_vspan_erase(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->LowColor();
113	do {
114		if (pattern->IsHighColor(x, y)) {
115			if (*covers) {
116				if (*covers == 255) {
117					ASSIGN_ERASE(p, color.red, color.green, color.blue);
118				} else {
119					BLEND_ERASE(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_erase
131void
132blend_color_hspan_erase(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	rgb_color lowColor = pattern->LowColor();
139	if (covers) {
140		// non-solid opacity
141		do {
142			if (*covers && colors->a > 0) {
143				if (*covers == 255) {
144					ASSIGN_ERASE(p, lowColor.red, lowColor.green,
145						lowColor.blue);
146				} else {
147					BLEND_ERASE(p, lowColor.red, lowColor.green, lowColor.blue,
148						*covers);
149				}
150			}
151			covers++;
152			p += 4;
153			++colors;
154		} while(--len);
155	} else {
156		// solid full opcacity
157		if (cover == 255) {
158			do {
159				if (colors->a > 0) {
160					ASSIGN_ERASE(p, lowColor.red, lowColor.green,
161						lowColor.blue);
162				}
163				p += 4;
164				++colors;
165			} while(--len);
166		// solid partial opacity
167		} else if (cover) {
168			do {
169				if (colors->a > 0) {
170					BLEND_ERASE(p, lowColor.red, lowColor.green, lowColor.blue,
171						cover);
172				}
173				p += 4;
174				++colors;
175			} while(--len);
176		}
177	}
178}
179
180#endif // DRAWING_MODE_ERASE_H
181
182