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_BLEND on B_RGBA32.
6 *
7 */
8
9#ifndef DRAWING_MODE_BLEND_H
10#define DRAWING_MODE_BLEND_H
11
12#include "DrawingMode.h"
13
14// BLEND_BLEND
15#define BLEND_BLEND(d, r, g, b, a) \
16{ \
17	pixel32 _p; \
18	_p.data32 = *(uint32*)d; \
19	uint8 bt = (_p.data8[0] + (b)) >> 1; \
20	uint8 gt = (_p.data8[1] + (g)) >> 1; \
21	uint8 rt = (_p.data8[2] + (r)) >> 1; \
22	BLEND(d, rt, gt, bt, a); \
23}
24
25// ASSIGN_BLEND
26#define ASSIGN_BLEND(d, r, g, b) \
27{ \
28	pixel32 _p; \
29	_p.data32 = *(uint32*)d; \
30	d[0] = (_p.data8[0] + (b)) >> 1; \
31	d[1] = (_p.data8[1] + (g)) >> 1; \
32	d[2] = (_p.data8[2] + (r)) >> 1; \
33	d[3] = 255; \
34}
35
36// blend_pixel_blend
37void
38blend_pixel_blend(int x, int y, const color_type& c, uint8 cover,
39				  agg_buffer* buffer, const PatternHandler* pattern)
40{
41	uint8* p = buffer->row_ptr(y) + (x << 2);
42	rgb_color color = pattern->ColorAt(x, y);
43	if (cover == 255) {
44		ASSIGN_BLEND(p, color.red, color.green, color.blue);
45	} else {
46		BLEND_BLEND(p, color.red, color.green, color.blue, cover);
47	}
48}
49
50// blend_hline_blend
51void
52blend_hline_blend(int x, int y, unsigned len,
53				  const color_type& c, uint8 cover,
54				  agg_buffer* buffer, const PatternHandler* pattern)
55{
56	uint8* p = buffer->row_ptr(y) + (x << 2);
57	if (cover == 255) {
58		do {
59			rgb_color color = pattern->ColorAt(x, y);
60
61			ASSIGN_BLEND(p, color.red, color.green, color.blue);
62
63			p += 4;
64			x++;
65		} while(--len);
66	} else {
67		do {
68			rgb_color color = pattern->ColorAt(x, y);
69
70			BLEND_BLEND(p, color.red, color.green, color.blue, cover);
71
72			x++;
73			p += 4;
74		} while(--len);
75	}
76}
77
78// blend_solid_hspan_blend
79void
80blend_solid_hspan_blend(int x, int y, unsigned len,
81						const color_type& c, const uint8* covers,
82						agg_buffer* buffer, const PatternHandler* pattern)
83{
84	uint8* p = buffer->row_ptr(y) + (x << 2);
85	do {
86		rgb_color color = pattern->ColorAt(x, y);
87		if (*covers) {
88			if (*covers == 255) {
89				ASSIGN_BLEND(p, color.red, color.green, color.blue);
90			} else {
91				BLEND_BLEND(p, color.red, color.green, color.blue, *covers);
92			}
93		}
94		covers++;
95		p += 4;
96		x++;
97	} while(--len);
98}
99
100
101
102// blend_solid_vspan_blend
103void
104blend_solid_vspan_blend(int x, int y, unsigned len,
105						const color_type& c, const uint8* covers,
106						agg_buffer* buffer, const PatternHandler* pattern)
107{
108	uint8* p = buffer->row_ptr(y) + (x << 2);
109	do {
110		rgb_color color = pattern->ColorAt(x, y);
111		if (*covers) {
112			if (*covers == 255) {
113				ASSIGN_BLEND(p, color.red, color.green, color.blue);
114			} else {
115				BLEND_BLEND(p, color.red, color.green, color.blue, *covers);
116			}
117		}
118		covers++;
119		p += buffer->stride();
120		y++;
121	} while(--len);
122}
123
124
125// blend_color_hspan_blend
126void
127blend_color_hspan_blend(int x, int y, unsigned len,
128						const color_type* colors,
129						const uint8* covers, uint8 cover,
130						agg_buffer* buffer, const PatternHandler* pattern)
131{
132	uint8* p = buffer->row_ptr(y) + (x << 2);
133	if (covers) {
134		// non-solid opacity
135		do {
136//			if (*covers) {
137if (*covers && (colors->a & 0xff)) {
138				if (*covers == 255) {
139					ASSIGN_BLEND(p, colors->r, colors->g, colors->b);
140				} else {
141					BLEND_BLEND(p, colors->r, colors->g, colors->b, *covers);
142				}
143			}
144			covers++;
145			p += 4;
146			++colors;
147		} while(--len);
148	} else {
149		// solid full opcacity
150		if (cover == 255) {
151			do {
152if (colors->a & 0xff) {
153				ASSIGN_BLEND(p, colors->r, colors->g, colors->b);
154}
155				p += 4;
156				++colors;
157			} while(--len);
158		// solid partial opacity
159		} else if (cover) {
160			do {
161				BLEND_BLEND(p, colors->r, colors->g, colors->b, cover);
162				p += 4;
163				++colors;
164			} while(--len);
165		}
166	}
167}
168
169#endif // DRAWING_MODE_BLEND_H
170
171