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_INVERT on B_RGBA32.
6 *
7 */
8
9 #ifndef DRAWING_MODE_INVERT_H
10 #define DRAWING_MODE_INVERT_H
11
12 #include "DrawingMode.h"
13
14 // BLEND_INVERT
15 #define BLEND_INVERT(d, a) \
16 { \
17 pixel32 _p; \
18 _p.data32 = *(uint32*)d; \
19 BLEND(d, 255 - _p.data8[2], 255 - _p.data8[1], 255 - _p.data8[0], a); \
20 (void)_p; \
21 }
22
23 // ASSIGN_INVERT
24 #define ASSIGN_INVERT(d) \
25 { \
26 pixel32 _p; \
27 _p.data32 = *(uint32*)d; \
28 d[0] = 255 - _p.data8[0]; \
29 d[1] = 255 - _p.data8[1]; \
30 d[2] = 255 - _p.data8[2]; \
31 d[3] = 255; \
32 }
33
34 // blend_pixel_invert
35 void
blend_pixel_invert(int x,int y,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)36 blend_pixel_invert(int x, int y, const color_type& c, uint8 cover,
37 agg_buffer* buffer, const PatternHandler* pattern)
38 {
39 if (pattern->IsHighColor(x, y)) {
40 uint8* p = buffer->row_ptr(y) + (x << 2);
41 if (cover == 255) {
42 ASSIGN_INVERT(p);
43 } else {
44 BLEND_INVERT(p, cover);
45 }
46 }
47 }
48
49 // blend_hline_invert
50 void
blend_hline_invert(int x,int y,unsigned len,const color_type & c,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)51 blend_hline_invert(int x, int y, unsigned len,
52 const color_type& c, uint8 cover,
53 agg_buffer* buffer, const PatternHandler* pattern)
54 {
55 uint8* p = buffer->row_ptr(y) + (x << 2);
56 if(cover == 255) {
57 do {
58 if (pattern->IsHighColor(x, y)) {
59 ASSIGN_INVERT(p);
60 }
61 x++;
62 p += 4;
63 } while(--len);
64 } else {
65 do {
66 if (pattern->IsHighColor(x, y)) {
67 BLEND_INVERT(p, cover);
68 }
69 x++;
70 p += 4;
71 } while(--len);
72 }
73 }
74
75 // blend_solid_hspan_invert
76 void
blend_solid_hspan_invert(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)77 blend_solid_hspan_invert(int x, int y, unsigned len,
78 const color_type& c, const uint8* covers,
79 agg_buffer* buffer, const PatternHandler* pattern)
80 {
81 uint8* p = buffer->row_ptr(y) + (x << 2);
82 do {
83 if (pattern->IsHighColor(x, y)) {
84 if (*covers) {
85 if (*covers == 255) {
86 ASSIGN_INVERT(p);
87 } else {
88 BLEND_INVERT(p, *covers);
89 }
90 }
91 }
92 covers++;
93 p += 4;
94 x++;
95 } while(--len);
96 }
97
98
99
100 // blend_solid_vspan_invert
101 void
blend_solid_vspan_invert(int x,int y,unsigned len,const color_type & c,const uint8 * covers,agg_buffer * buffer,const PatternHandler * pattern)102 blend_solid_vspan_invert(int x, int y, unsigned len,
103 const color_type& c, const uint8* covers,
104 agg_buffer* buffer, const PatternHandler* pattern)
105 {
106 uint8* p = buffer->row_ptr(y) + (x << 2);
107 do {
108 if (pattern->IsHighColor(x, y)) {
109 if (*covers) {
110 if (*covers == 255) {
111 ASSIGN_INVERT(p);
112 } else {
113 BLEND_INVERT(p, *covers);
114 }
115 }
116 }
117 covers++;
118 p += buffer->stride();
119 y++;
120 } while(--len);
121 }
122
123
124 // blend_color_hspan_invert
125 void
blend_color_hspan_invert(int x,int y,unsigned len,const color_type * colors,const uint8 * covers,uint8 cover,agg_buffer * buffer,const PatternHandler * pattern)126 blend_color_hspan_invert(int x, int y, unsigned len,
127 const color_type* colors,
128 const uint8* covers, uint8 cover,
129 agg_buffer* buffer, const PatternHandler* pattern)
130 {
131 // TODO: does the R5 app_server check for the
132 // appearance of the high color in the source bitmap?
133 uint8* p = buffer->row_ptr(y) + (x << 2);
134 if (covers) {
135 // non-solid opacity
136 do {
137 if (*covers && colors->a > 0) {
138 if (*covers == 255) {
139 ASSIGN_INVERT(p);
140 } else {
141 BLEND_INVERT(p, *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 > 0) {
153 ASSIGN_INVERT(p);
154 }
155 p += 4;
156 ++colors;
157 } while(--len);
158 // solid partial opacity
159 } else if (cover) {
160 do {
161 if (colors->a > 0) {
162 BLEND_INVERT(p, cover);
163 }
164 p += 4;
165 ++colors;
166 } while(--len);
167 }
168 }
169 }
170
171 #endif // DRAWING_MODE_INVERT_H
172
173