xref: /haiku/src/tests/servers/app/drawing_modes/DrawingModes.cpp (revision 97bd6fe8d425790dc9a22384e4447bae564507de)
1 #include <Application.h>
2 #include <Bitmap.h>
3 #include <View.h>
4 #include <Window.h>
5 #include <stdio.h>
6 #include <string.h>
7 
8 //#define DUMP_BLENDING_RESULTS
9 #ifdef DUMP_BLENDING_RESULTS
10 #include <BitmapStream.h>
11 #include <File.h>
12 #include <TranslatorRoster.h>
13 #include <String.h>
14 #endif
15 
16 uint32 kBitmapBits[] = {
17 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
18 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
19 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
20 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
21 	0x00777477, 0x00777477, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
22 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
23 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
24 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
25 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
26 	0x00777477, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00111111,
27 	0x00777777, 0x00000000, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
28 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
29 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
30 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
31 	0x00777477, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00111111,
32 	0x00777777, 0x00444444, 0x00000000, 0x00000000, 0x00777477, 0x00777477,
33 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
34 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
35 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
36 	0x00777477, 0x00000000, 0x00000000, 0x00bb0000, 0x00ffffff, 0x00000000,
37 	0x00444444, 0x00777777, 0x00111111, 0x00000000, 0x00000000, 0x00000000,
38 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
39 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
40 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
41 	0x00777477, 0x00777477, 0x00000000, 0x00bb0000, 0x00ee0000, 0x00ee0000,
42 	0x00ff0000, 0x00ffffff, 0x00ee0000, 0x00111111, 0x00000000, 0x00000000,
43 	0x00000000, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
44 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
45 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
46 	0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00bb0000, 0x00ee0000,
47 	0x00ee0000, 0x00ff0000, 0x00ffffff, 0x00ee0000, 0x00ee0000, 0x00ee0000,
48 	0x00000000, 0x00000000, 0x00000000, 0x00777477, 0x00777477, 0x00777477,
49 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
50 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
51 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00bb0000,
52 	0x00ee0000, 0x00ee0000, 0x00ff0000, 0x00ffffff, 0x00ee0000, 0x00ee0000,
53 	0x00ee0000, 0x00cc0000, 0x00000000, 0x00000000, 0x00000000, 0x00777477,
54 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
55 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
56 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000,
57 	0x00bb0000, 0x00ee0000, 0x00ee0000, 0x00ff0000, 0x00ffffff, 0x00ee0000,
58 	0x00ee0000, 0x00ee0000, 0x00cc0000, 0x00990000, 0x00990000, 0x00000000,
59 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
60 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
61 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
62 	0x00777477, 0x00000000, 0x00ee0000, 0x00ee0000, 0x00ee0000, 0x00ffffff,
63 	0x00ee0000, 0x00ff0000, 0x00cc0000, 0x00cc0000, 0x00990000, 0x00bb0000,
64 	0x00880000, 0x00000000, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
65 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
66 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
67 	0x00777477, 0x00777477, 0x00000000, 0x00ee0000, 0x00ee0000, 0x00ee0000,
68 	0x00ffffff, 0x00ee0000, 0x00ff0000, 0x00cc0000, 0x00cc0000, 0x00990000,
69 	0x00bb0000, 0x00880000, 0x00000000, 0x00777477, 0x00777477, 0x00777477,
70 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
71 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
72 	0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00ee0000, 0x00ee0000,
73 	0x00ee0000, 0x00ffffff, 0x00ee0000, 0x00ff0000, 0x00cc0000, 0x00cc0000,
74 	0x00990000, 0x00bb0000, 0x00880000, 0x00990000, 0x00000000, 0x00777477,
75 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
76 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
77 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00ee0000,
78 	0x00ee0000, 0x00ee0000, 0x00ffffff, 0x00ee0000, 0x00ff0000, 0x00cc0000,
79 	0x00cc0000, 0x00990000, 0x00bb0000, 0x00880000, 0x00990000, 0x00000000,
80 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
81 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
82 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
83 	0x00000000, 0x00ee0000, 0x00ff0000, 0x00ffffff, 0x00ee0000, 0x00ee0000,
84 	0x00ee0000, 0x00cc0000, 0x00990000, 0x00bb0000, 0x00880000, 0x00880000,
85 	0x00000000, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
86 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
87 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
88 	0x00777477, 0x00000000, 0x00ee0000, 0x00ee0000, 0x00ffffff, 0x00ee0000,
89 	0x00ff0000, 0x00cc0000, 0x00cc0000, 0x00990000, 0x00bb0000, 0x00880000,
90 	0x00990000, 0x00000000, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
91 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
92 	0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00000000, 0x00000000,
93 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ee0000, 0x00ffffff,
94 	0x00ee0000, 0x00ff0000, 0x00cc0000, 0x00cc0000, 0x00990000, 0x00bb0000,
95 	0x00880000, 0x00000000, 0x00000000, 0x00777477, 0x00777477, 0x00777477,
96 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
97 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00ff6666,
98 	0x00ff6666, 0x00ff6666, 0x00ff6666, 0x00880000, 0x00000000, 0x00ee0000,
99 	0x00ff6666, 0x00000000, 0x00ee0000, 0x00ee0000, 0x00bb0000, 0x00bb0000,
100 	0x00bb0000, 0x00880000, 0x00000000, 0x00777477, 0x00777477, 0x00777477,
101 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
102 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000,
103 	0x00ee0000, 0x00ff0000, 0x00ee0000, 0x00880000, 0x00990000, 0x00000000,
104 	0x00ee0000, 0x00ff6666, 0x00880000, 0x00000000, 0x00cc0000, 0x00990000,
105 	0x00bb0000, 0x00880000, 0x00990000, 0x00000000, 0x00777477, 0x00777477,
106 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
107 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
108 	0x00000000, 0x00ee0000, 0x00ff0000, 0x00ee0000, 0x00880000, 0x00990000,
109 	0x00000000, 0x00ee0000, 0x00ff6666, 0x00880000, 0x00000000, 0x00990000,
110 	0x00880000, 0x00880000, 0x00990000, 0x00000000, 0x00000000, 0x00777477,
111 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
112 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
113 	0x00777477, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
114 	0x00000000, 0x00000000, 0x00000000, 0x00ff6666, 0x00880000, 0x00000000,
115 	0x00990000, 0x00880000, 0x00880000, 0x00000000, 0x00000000, 0x00777477,
116 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
117 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
118 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
119 	0x00777477, 0x00777477, 0x00000000, 0x00444444, 0x00ff6666, 0x00880000,
120 	0x00000000, 0x00990000, 0x00880000, 0x00880000, 0x00000000, 0x00ee0000,
121 	0x00000000, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
122 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777777, 0x00777777,
123 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477,
124 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00ff6666,
125 	0x00880000, 0x00000000, 0x00000000, 0x00000000, 0x00990000, 0x00000000,
126 	0x00880000, 0x00ee0000, 0x00000000, 0x00777477, 0x00777477, 0x00777477,
127 	0x00777477, 0x00777477, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
128 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
129 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00000000,
130 	0x00ff9900, 0x00000000, 0x00000000, 0x00000000, 0x00444444, 0x00000000,
131 	0x00000000, 0x00880000, 0x00990000, 0x00ee0000, 0x00000000, 0x00777477,
132 	0x00777477, 0x00777477, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
133 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
134 	0x00777777, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000,
135 	0x00ff9900, 0x00ff9900, 0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00000000,
136 	0x00444444, 0x00000000, 0x00000000, 0x00880000, 0x00ff0000, 0x00ee0000,
137 	0x00000000, 0x00777477, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
138 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
139 	0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477, 0x00777477,
140 	0x00000000, 0x00ff9900, 0x00ff9900, 0x00ffff00, 0x00ffff00, 0x00ffff00,
141 	0x00ff9900, 0x00000000, 0x00000000, 0x00777477, 0x00000000, 0x00ee0000,
142 	0x00ff0000, 0x00880000, 0x00000000, 0x00777477, 0x00777777, 0x00777777,
143 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
144 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477,
145 	0x00777477, 0x00777477, 0x00000000, 0x00ff9900, 0x00ff9900, 0x00ffff00,
146 	0x00ffff00, 0x00ff9900, 0x00000000, 0x00777777, 0x00777777, 0x00777777,
147 	0x00000000, 0x00ee0000, 0x00990000, 0x00000000, 0x00777777, 0x00777777,
148 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
149 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477,
150 	0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00ff9900, 0x00ff9900,
151 	0x00ffff00, 0x00ff9900, 0x00ff9900, 0x00ff9900, 0x00000000, 0x00777777,
152 	0x00777777, 0x00777777, 0x00000000, 0x00880000, 0x00000000, 0x00777777,
153 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
154 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477,
155 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000,
156 	0x00ff9900, 0x00ffff00, 0x00ff9900, 0x00ff9900, 0x00ff9900, 0x00000000,
157 	0x00777477, 0x00777477, 0x00777477, 0x00777777, 0x00000000, 0x00000000,
158 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
159 	0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477, 0x00777477,
160 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
161 	0x00000000, 0x00ff9900, 0x00ffff00, 0x00ff9900, 0x00ff9900, 0x00000000,
162 	0x00000000, 0x00777477, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
163 	0x00000000, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
164 	0x00777777, 0x00777777, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
165 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
166 	0x00777477, 0x00777477, 0x00000000, 0x00ffff00, 0x00ff9900, 0x00000000,
167 	0x00000000, 0x00777477, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
168 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
169 	0x00777777, 0x00777777, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
170 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
171 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00000000, 0x00000000,
172 	0x00000000, 0x00777477, 0x00777477, 0x00777777, 0x00777777, 0x00777777,
173 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
174 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477,
175 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
176 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
177 	0x00777477, 0x00777477, 0x00777477, 0x00777777, 0x00777777, 0x00777777,
178 	0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777777, 0x00777477,
179 	0x00777477, 0x00777477, 0x00777777, 0x00777777, 0x00777777, 0x00777777,
180 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
181 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
182 	0x00777477, 0x00777477, 0x00777477, 0x00777777, 0x00777777, 0x00777777,
183 	0x00777777, 0x00777777, 0x00777777, 0x00777477, 0x00777477, 0x00777477,
184 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777777, 0x00777777,
185 	0x00777777, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
186 	0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477, 0x00777477,
187 	0x00777477, 0x00777477, 0x00777477, 0x00777477
188 };
189 
190 class DrawingModeView : public BView {
191 public:
192 							DrawingModeView(BRect frame);
193 virtual						~DrawingModeView();
194 
195 virtual	void				Draw(BRect updateRect);
196 
197 private:
198 		BBitmap *			fBitmap;
199 		BBitmap *			fTriangleLeft;
200 		BBitmap *			fTriangleRight;
201 };
202 
203 
204 class DrawingModeWindow : public BWindow {
205 public:
206 							DrawingModeWindow(BRect frame);
207 
208 private:
209 		DrawingModeView *	fView;
210 };
211 
212 
213 class DrawingModeApp : public BApplication {
214 public:
215 							DrawingModeApp();
216 
217 private:
218 		DrawingModeWindow *	fWindow;
219 };
220 
221 
DrawingModeApp()222 DrawingModeApp::DrawingModeApp()
223 	:	BApplication("application/x.vnd-Haiku.DrawingModeTest")
224 {
225 	fWindow = new DrawingModeWindow(BRect(200, 200, 760, 800));
226 	fWindow->Show();
227 }
228 
229 
DrawingModeWindow(BRect frame)230 DrawingModeWindow::DrawingModeWindow(BRect frame)
231 	:	BWindow(frame, "Drawing Modes Test", B_TITLED_WINDOW,
232 			B_QUIT_ON_WINDOW_CLOSE)
233 {
234 	fView = new DrawingModeView(frame.OffsetToSelf(0, 0));
235 	AddChild(fView);
236 	fView->SetViewColor(255, 203, 0);
237 	fView->SetDrawingMode(B_OP_OVER);
238 }
239 
240 
DrawingModeView(BRect frame)241 DrawingModeView::DrawingModeView(BRect frame)
242 	:	BView(frame, "DrawingModeView", B_FOLLOW_ALL, B_WILL_DRAW),
243 		fBitmap(NULL)
244 {
245 	fBitmap = new BBitmap(BRect(0, 0, 31, 31), B_RGB32);
246 	memcpy(fBitmap->Bits(), kBitmapBits, fBitmap->BitsLength());
247 
248 	uint32 triangleLeftBits[32 * 32] = { 0 };
249 	uint32 triangleRightBits[32 * 32] = { 0 };
250 	for(int y = 0; y < 32; ++y) {
251 		for(int x = 0; x < 32; ++x) {
252 			if(x < 32 - y) {
253 				triangleLeftBits[y * 32 + x] = 0xffff0000;
254 			}
255 			if(x >= y) {
256 				triangleRightBits[y * 32 + x] = 0xff0000ff;
257 			}
258 		}
259 	}
260 
261 	fTriangleLeft = new BBitmap(BRect(0, 0, 31, 31), B_RGBA32);
262 	memcpy(fTriangleLeft->Bits(), triangleLeftBits,
263 		fTriangleLeft->BitsLength());
264 	fTriangleRight = new BBitmap(BRect(0, 0, 31, 31), B_RGBA32);
265 	memcpy(fTriangleRight->Bits(), triangleRightBits,
266 		fTriangleRight->BitsLength());
267 }
268 
269 
~DrawingModeView()270 DrawingModeView::~DrawingModeView()
271 {
272 	delete fBitmap;
273 	delete fTriangleLeft;
274 	delete fTriangleRight;
275 }
276 
277 
278 void
Draw(BRect updateRect)279 DrawingModeView::Draw(BRect updateRect)
280 {
281 	SetDrawingMode(B_OP_COPY);
282 	SetLowColor(ViewColor());
283 	FillRect(Bounds(), B_SOLID_LOW);
284 
285 	SetLowColor(255, 0, 0);
286 	SetHighColor(0, 0, 255);
287 
288 	BRect bitmapBounds = fBitmap->Bounds();
289 	int32 imageHeight = bitmapBounds.IntegerHeight() + 10;
290 	int32 imageWidth = bitmapBounds.IntegerWidth() + 10;
291 	BRect triangleBounds = fTriangleLeft->Bounds();
292 	int32 triangleHeight = triangleBounds.IntegerHeight() + 10;
293 	int32 triangleWidth = triangleBounds.IntegerWidth() + 10;
294 
295 #define MODE(m) { m, #m }
296 
297 	struct {
298 		drawing_mode mode;
299 		const char *name;
300 	} drawingModes[] = {
301 		MODE(B_OP_COPY),
302 		MODE(B_OP_OVER),
303 		MODE(B_OP_ERASE),
304 		MODE(B_OP_INVERT),
305 		MODE(B_OP_SELECT),
306 		MODE(B_OP_ADD),
307 		MODE(B_OP_SUBTRACT),
308 		MODE(B_OP_BLEND),
309 		MODE(B_OP_MIN),
310 		MODE(B_OP_MAX)
311 	};
312 
313 	struct {
314 		alpha_function mode;
315 		const char *name;
316 	} blendingModes[] = {
317 		MODE(B_ALPHA_COMPOSITE_SOURCE_OVER),
318 		MODE(B_ALPHA_COMPOSITE_SOURCE_IN),
319 		MODE(B_ALPHA_COMPOSITE_SOURCE_OUT),
320 		MODE(B_ALPHA_COMPOSITE_SOURCE_ATOP),
321 		MODE(B_ALPHA_COMPOSITE_DESTINATION_OVER),
322 		MODE(B_ALPHA_COMPOSITE_DESTINATION_IN),
323 		MODE(B_ALPHA_COMPOSITE_DESTINATION_OUT),
324 		MODE(B_ALPHA_COMPOSITE_DESTINATION_ATOP),
325 		MODE(B_ALPHA_COMPOSITE_XOR),
326 		MODE(B_ALPHA_COMPOSITE_CLEAR),
327 		MODE(B_ALPHA_COMPOSITE_DIFFERENCE),
328 		MODE(B_ALPHA_COMPOSITE_LIGHTEN),
329 		MODE(B_ALPHA_COMPOSITE_DARKEN)
330 	};
331 
332 	int32 modeCount = sizeof(drawingModes) / sizeof(drawingModes[0]);
333 	for (int32 i = 0; i < modeCount; i++) {
334 		if (drawingModes[i].mode == B_OP_SELECT) {
335 			// make the background contain the low and high color to see
336 			// actual effect of B_OP_SELECT
337 			SetDrawingMode(B_OP_COPY);
338 			FillRect(BRect(0, imageHeight * i, imageWidth * 2 - 10,
339 				imageHeight * i + bitmapBounds.Height() / 2), B_SOLID_LOW);
340 			FillRect(BRect(0, imageHeight * i  + bitmapBounds.Height() / 2,
341 				imageWidth * 2 - 10, imageHeight * i + bitmapBounds.Height()),
342 				B_SOLID_HIGH);
343 		} else if (drawingModes[i].mode == B_OP_MAX
344 			|| drawingModes[i].mode == B_OP_MIN) {
345 			// need a darker/lighter color as a background otherwise nothing
346 			// will be selected from the source
347 			SetDrawingMode(B_OP_COPY);
348 			SetHighColor(255, 255, 255);
349 			FillRect(BRect(0, imageHeight * i, imageWidth * 2 - 10,
350 				imageHeight * i + bitmapBounds.Height() / 3), B_SOLID_HIGH);
351 			SetHighColor(128, 128, 128);
352 			FillRect(BRect(0, imageHeight * i  + bitmapBounds.Height() / 3,
353 				imageWidth * 2 - 10, imageHeight * i + bitmapBounds.Height()),
354 				B_SOLID_HIGH);
355 			SetHighColor(0, 0, 0);
356 			FillRect(BRect(0, imageHeight * i  + bitmapBounds.Height() / 3 * 2,
357 				imageWidth * 2 - 10, imageHeight * i + bitmapBounds.Height()),
358 				B_SOLID_HIGH);
359 			SetHighColor(0, 0, 255);
360 		}
361 
362 		SetDrawingMode(drawingModes[i].mode);
363 		DrawBitmap(fBitmap, BPoint(0, imageHeight * i));
364 		FillRect(bitmapBounds.OffsetToCopy(imageWidth,
365 			imageHeight * i), B_MIXED_COLORS);
366 
367 		SetDrawingMode(B_OP_OVER);
368 		DrawString(drawingModes[i].name, BPoint(imageWidth * 2,
369 			imageHeight * i + 20));
370 	}
371 
372 #ifdef DUMP_BLENDING_RESULTS
373 	BTranslatorRoster* roster = BTranslatorRoster::Default();
374 	if (roster == NULL)
375 		abort();
376 
377 	translator_id* outId;
378 	int32 outCount;
379 	translation_format pngFormat;
380 	roster->GetAllTranslators(&outId, &outCount);
381 	for(int32 i = 0; i < outCount; ++i) {
382 		const translation_format* formats;
383 		int32 formatCount;
384 		roster->GetOutputFormats(outId[i], &formats, &formatCount);
385 		for(int32 j = 0; j < formatCount; ++j) {
386 			if(strcmp(formats[j].MIME, "image/png") == 0) {
387 				pngFormat = formats[j];
388 			}
389 		}
390 	}
391 
392 	status_t r = B_OK;
393 	{
394 		BFile file("DESTINATION.png",
395 			B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
396 		BBitmapStream stream(fTriangleLeft);
397 		r = roster->Translate(&stream, NULL, NULL, &file, pngFormat.type);
398 		if(r != B_OK)
399 			fprintf(stderr, "Failed to save PNG file for destination\n");
400 		stream.DetachBitmap(&fTriangleLeft);
401 	}
402 	{
403 		BFile file("SOURCE.png", B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
404 		BBitmapStream stream(fTriangleRight);
405 		r = roster->Translate(&stream, NULL, NULL, &file, pngFormat.type);
406 		if(r != B_OK)
407 			fprintf(stderr, "Failed to save PNG file for source\n");
408 		stream.DetachBitmap(&fTriangleRight);
409 	}
410 #endif
411 
412 	modeCount = sizeof(blendingModes) / sizeof(blendingModes[0]);
413 	const int columnOffset = 180;
414 	BView *blitter = new BView(BRect(0, 0, 31, 31),
415 		"blitter", B_FOLLOW_ALL, B_WILL_DRAW);
416 	BBitmap *resultBitmap = new BBitmap(BRect(0, 0, 31, 31),
417 		B_RGBA32, true, false);
418 	resultBitmap->AddChild(blitter);
419 	for (int32 i = 0; i < modeCount; i++) {
420 		resultBitmap->Lock();
421 		blitter->SetDrawingMode(B_OP_COPY);
422 		blitter->SetHighColor(0, 0, 0, 0);
423 		blitter->FillRect(resultBitmap->Bounds());
424 		blitter->DrawBitmap(fTriangleLeft, B_ORIGIN);
425 		blitter->SetDrawingMode(B_OP_ALPHA);
426 		blitter->SetBlendingMode(B_PIXEL_ALPHA, blendingModes[i].mode);
427 		blitter->DrawBitmap(fTriangleRight, B_ORIGIN);
428 		resultBitmap->Unlock();
429 
430 #ifdef DUMP_BLENDING_RESULTS
431 		BBitmapStream stream(resultBitmap);
432 		BString fileName(blendingModes[i].name);
433 		BFile file(fileName.Append(".png"),
434 			B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
435 
436 		r = roster->Translate(&stream, NULL, NULL, &file, pngFormat.type);
437 		if(r != B_OK) {
438 			fprintf(stderr, "Failed to save PNG file for %s\n",
439 				blendingModes[i].name);
440 		}
441 
442 		stream.DetachBitmap(&resultBitmap);
443 #endif
444 
445 		SetDrawingMode(B_OP_ALPHA);
446 		SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
447 		DrawBitmap(resultBitmap, BPoint(columnOffset, triangleHeight * i));
448 
449 		SetDrawingMode(B_OP_OVER);
450 		DrawString(blendingModes[i].name, BPoint(columnOffset + triangleWidth,
451 			triangleHeight * i + 20));
452 	}
453 	resultBitmap->Lock();
454 	resultBitmap->RemoveChild(blitter);
455 	delete resultBitmap;
456 	delete blitter;
457 }
458 
459 
460 int
main(int argc,const char * argv[])461 main(int argc, const char *argv[])
462 {
463 	DrawingModeApp *app = new DrawingModeApp();
464 	app->Run();
465 	delete app;
466 	return 0;
467 }
468