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_OVER on B_RGBA32.
6 *
7 */
8
9 #ifndef DRAWING_MODE_OVER_H
10 #define DRAWING_MODE_OVER_H
11
12 #include "DrawingMode.h"
13
14 // BLEND_OVER
15 #define BLEND_OVER(d, r, g, b, a) \
16 { \
17 BLEND(d, r, g, b, a) \
18 }
19
20 // ASSIGN_OVER
21 #define ASSIGN_OVER(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_over
30 void
blend_pixel_over(int x,int y,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)31 blend_pixel_over(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->HighColor();
37 if (cover == 255) {
38 ASSIGN_OVER(p, color.red, color.green, color.blue);
39 } else {
40 BLEND_OVER(p, color.red, color.green, color.blue, cover);
41 }
42 }
43 }
44
45 // blend_hline_over
46 void
blend_hline_over(int x,int y,unsigned len,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)47 blend_hline_over(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->HighColor();
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->HighColor();
69 do {
70 if (pattern->IsHighColor(x, y)) {
71 BLEND_OVER(p, color.red, color.green, color.blue, cover);
72 }
73 x++;
74 p += 4;
75 } while(--len);
76 }
77 }
78
79 // blend_solid_hspan_over
80 void
blend_solid_hspan_over(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)81 blend_solid_hspan_over(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->HighColor();
87 do {
88 if (pattern->IsHighColor(x, y)) {
89 if (*covers) {
90 if (*covers == 255) {
91 ASSIGN_OVER(p, color.red, color.green, color.blue);
92 } else {
93 BLEND_OVER(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_over
106 void
blend_solid_vspan_over(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)107 blend_solid_vspan_over(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->HighColor();
113 do {
114 if (pattern->IsHighColor(x, y)) {
115 if (*covers) {
116 if (*covers == 255) {
117 ASSIGN_OVER(p, color.red, color.green, color.blue);
118 } else {
119 BLEND_OVER(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_over
131 void
blend_color_hspan_over(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_over(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_OVER(p, colors->r, colors->g, colors->b);
144 } else {
145 BLEND_OVER(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_OVER(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_OVER(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_OVER_H
176
177