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_MAX on B_RGBA32.
6 *
7 */
8
9#ifndef DRAWING_MODE_MAX_H
10#define DRAWING_MODE_MAX_H
11
12#include "DrawingMode.h"
13
14
15// BLEND_MAX
16#define BLEND_MAX(d, r, g, b, a) \
17{ \
18	pixel32 _p; \
19	_p.data32 = *(uint32*)d; \
20	if (brightness_for((r), (g), (b)) \
21		> brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \
22		BLEND(d, (r), (g), (b), a); \
23	} \
24}
25
26// ASSIGN_MAX
27#define ASSIGN_MAX(d, r, g, b) \
28{ \
29	pixel32 _p; \
30	_p.data32 = *(uint32*)d; \
31	if (brightness_for((r), (g), (b)) \
32		> brightness_for(_p.data8[2], _p.data8[1], _p.data8[0])) { \
33		d[0] = (b); \
34		d[1] = (g); \
35		d[2] = (r); \
36		d[3] = 255; \
37	} \
38}
39
40
41// blend_pixel_max
42void
43blend_pixel_max(int x, int y, const color_type& c, uint8 cover,
44				agg_buffer* buffer, const PatternHandler* pattern)
45{
46	uint8* p = buffer->row_ptr(y) + (x << 2);
47	rgb_color color = pattern->ColorAt(x, y);
48	if (cover == 255) {
49		ASSIGN_MAX(p, color.red, color.green, color.blue);
50	} else {
51		BLEND_MAX(p, color.red, color.green, color.blue, cover);
52	}
53}
54
55// blend_hline_max
56void
57blend_hline_max(int x, int y, unsigned len,
58				const color_type& c, uint8 cover,
59				agg_buffer* buffer, const PatternHandler* pattern)
60{
61	uint8* p = buffer->row_ptr(y) + (x << 2);
62	if (cover == 255) {
63		do {
64			rgb_color color = pattern->ColorAt(x, y);
65
66			ASSIGN_MAX(p, color.red, color.green, color.blue);
67
68			p += 4;
69			x++;
70		} while(--len);
71	} else {
72		do {
73			rgb_color color = pattern->ColorAt(x, y);
74
75			BLEND_MAX(p, color.red, color.green, color.blue, cover);
76
77			x++;
78			p += 4;
79		} while(--len);
80	}
81}
82
83// blend_solid_hspan_max
84void
85blend_solid_hspan_max(int x, int y, unsigned len,
86					  const color_type& c, const uint8* covers,
87					  agg_buffer* buffer, const PatternHandler* pattern)
88{
89	uint8* p = buffer->row_ptr(y) + (x << 2);
90	do {
91		rgb_color color = pattern->ColorAt(x, y);
92		if (*covers) {
93			if (*covers == 255) {
94				ASSIGN_MAX(p, color.red, color.green, color.blue);
95			} else {
96				BLEND_MAX(p, color.red, color.green, color.blue, *covers);
97			}
98		}
99		covers++;
100		p += 4;
101		x++;
102	} while(--len);
103}
104
105
106
107// blend_solid_vspan_max
108void
109blend_solid_vspan_max(int x, int y, unsigned len,
110					  const color_type& c, const uint8* covers,
111					  agg_buffer* buffer, const PatternHandler* pattern)
112{
113	uint8* p = buffer->row_ptr(y) + (x << 2);
114	do {
115		rgb_color color = pattern->ColorAt(x, y);
116		if (*covers) {
117			if (*covers == 255) {
118				ASSIGN_MAX(p, color.red, color.green, color.blue);
119			} else {
120				BLEND_MAX(p, color.red, color.green, color.blue, *covers);
121			}
122		}
123		covers++;
124		p += buffer->stride();
125		y++;
126	} while(--len);
127}
128
129
130// blend_color_hspan_max
131void
132blend_color_hspan_max(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_MAX(p, colors->r, colors->g, colors->b);
144				} else {
145					BLEND_MAX(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_MAX(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_MAX(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_MAX_H
176
177