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