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