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