xref: /haiku/src/servers/app/drawing/Painter/drawing_modes/DrawingModeMax.h (revision 61ed28ee13e6bcf41a9c39c834c1a238881214bd)
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
42 void
blend_pixel_max(int x,int y,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)43 blend_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
56 void
blend_hline_max(int x,int y,unsigned len,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)57 blend_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
84 void
blend_solid_hspan_max(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)85 blend_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
108 void
blend_solid_vspan_max(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)109 blend_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
131 void
blend_color_hspan_max(int x,int y,unsigned len,const color_type * colors,const uint8 * covers,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)132 blend_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