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