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