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