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