1/*
2 * Copyright 2005, Stephan Aßmus <superstippi@gmx.de>
3 * Copyright 2015, Julian Harnath <julian.harnath@rwth-aachen.de>
4 * All rights reserved. Distributed under the terms of the MIT License.
5 *
6 * DrawingMode implementing B_OP_ALPHA in "Pixel Composite" mode on B_RGBA32.
7 *
8 */
9
10#ifndef DRAWING_MODE_ALPHA_PC_SOLID_H
11#define DRAWING_MODE_ALPHA_PC_SOLID_H
12
13#include "DrawingMode.h"
14
15
16#define BLEND_ALPHA_PC(d, r, g, b, a) \
17{ \
18	BLEND_COMPOSITE16(d, r, g, b, a); \
19}
20
21
22#define ASSIGN_ALPHA_PC(d, r, g, b) \
23{ \
24	d[0] = (b); \
25	d[1] = (g); \
26	d[2] = (r); \
27	d[3] = 255; \
28}
29
30
31void
32blend_pixel_alpha_pc_solid(int x, int y, const color_type& color, uint8 cover,
33					 agg_buffer* buffer, const PatternHandler*)
34{
35	uint8* p = buffer->row_ptr(y) + (x << 2);
36	uint16 alpha = color.a * cover;
37	if (alpha == 255 * 255) {
38		ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
39	} else {
40		BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
41	}
42}
43
44
45void
46blend_hline_alpha_pc_solid(int x, int y, unsigned len,
47					 const color_type& color, uint8 cover,
48					 agg_buffer* buffer, const PatternHandler*)
49{
50	uint8* p = buffer->row_ptr(y) + (x << 2);
51	uint16 alpha = color.a * cover;
52	if (alpha == 0)
53		return;
54
55	if (alpha == 255 * 255) {
56		do {
57			ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
58			p += 4;
59		} while(--len);
60		return;
61	}
62
63	do {
64		BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
65		p += 4;
66	} while(--len);
67}
68
69
70void
71blend_solid_hspan_alpha_pc_solid(int x, int y, unsigned len,
72						   const color_type& color, const uint8* covers,
73						   agg_buffer* buffer, const PatternHandler*)
74{
75	uint8* p = buffer->row_ptr(y) + (x << 2);
76	do {
77		uint16 alpha = color.a * *covers;
78		if (alpha) {
79			if(alpha == 255 * 255) {
80				ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
81			} else {
82				BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
83			}
84		}
85		covers++;
86		p += 4;
87	} while(--len);
88}
89
90
91void
92blend_solid_vspan_alpha_pc_solid(int x, int y, unsigned len,
93						   const color_type& color, const uint8* covers,
94						   agg_buffer* buffer, const PatternHandler*)
95{
96	uint8* p = buffer->row_ptr(y) + (x << 2);
97	do {
98		uint16 alpha = color.a * *covers;
99		if (alpha) {
100			if (alpha == 255 * 255) {
101				ASSIGN_ALPHA_PC(p, color.r, color.g, color.b);
102			} else {
103				BLEND_ALPHA_PC(p, color.r, color.g, color.b, alpha);
104			}
105		}
106		covers++;
107		p += buffer->stride();
108	} while(--len);
109}
110
111
112void
113blend_color_hspan_alpha_pc_solid(int x, int y, unsigned len,
114						   const color_type* colors,
115						   const uint8* covers, uint8 cover,
116						   agg_buffer* buffer, const PatternHandler*)
117{
118	uint8* p = buffer->row_ptr(y) + (x << 2);
119	if (covers) {
120		// non-solid opacity
121		do {
122			uint16 alpha = colors->a * *covers;
123			if (alpha) {
124				if (alpha == 255 * 255) {
125					ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
126				} else {
127					BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
128				}
129			}
130			covers++;
131			p += 4;
132			++colors;
133		} while(--len);
134	} else {
135		// solid full opcacity
136		uint16 alpha = colors->a * cover;
137		if (alpha == 255 * 255) {
138			do {
139				ASSIGN_ALPHA_PC(p, colors->r, colors->g, colors->b);
140				p += 4;
141				++colors;
142			} while(--len);
143		// solid partial opacity
144		} else if (alpha) {
145			do {
146				BLEND_ALPHA_PC(p, colors->r, colors->g, colors->b, alpha);
147				p += 4;
148				++colors;
149			} while(--len);
150		}
151	}
152}
153
154
155#endif // DRAWING_MODE_ALPHA_PC_SOLID_H
156