xref: /haiku/src/tests/servers/app/gradients/main.cpp (revision bf57c148f7787f0df15980976997c6dfb70ee067)
1 /*
2  * Copyright 2014 Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Authors:
6  * Adrien Destugues <pulkomandy@pulkomandy.tk>
7  */
8 
9 
10 #include <algorithm>
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include <Application.h>
15 #include <GradientLinear.h>
16 #include <GradientRadial.h>
17 #include <LayoutBuilder.h>
18 #include <List.h>
19 #include <Message.h>
20 #include <Picture.h>
21 #include <PopUpMenu.h>
22 #include <Roster.h>
23 #include <ScrollView.h>
24 #include <String.h>
25 #include <StringView.h>
26 #include <View.h>
27 #include <Window.h>
28 
29 #include "harness.h"
30 
31 
32 static const char* kAppSignature = "application/x-vnd.Haiku-Gradients";
33 
34 
35 // #pragma mark - Test1
36 
37 
38 class RadialGradientTest : public Test {
39 public:
40 	RadialGradientTest()
41 		:
42 		Test("Radial Gradient")
43 	{
44 	}
45 
46 	virtual void Draw(BView* view, BRect updateRect)
47 	{
48 		// Draws two radial gradients with the same stops and different radiis,
49 		// and their enclosing circles. The gradients and circles should have
50 		// the same size.
51 		BGradientRadial g1(100, 100, 50);
52 		BGradientRadial g2(300, 100, 100);
53 
54 		g1.AddColor(make_color(0,0,0,255), 0);
55 		g1.AddColor(make_color(255,255,255,255), 255);
56 
57 		g2.AddColor(make_color(0,0,0,255), 0);
58 		g2.AddColor(make_color(255,255,255,255), 255);
59 
60 		BRect r1(0, 0, 200, 200);
61 		BRect r2(200, 0, 400, 200);
62 		view->FillRect(r1, g1);
63 		view->FillRect(r2, g2);
64 
65 		r1.InsetBy(50, 50);
66 		view->StrokeEllipse(r1);
67 		view->StrokeEllipse(r2);
68 	}
69 };
70 
71 
72 // Test for https://dev.haiku-os.org/ticket/2946
73 // Gradients with an alpha channel are not drawn properly
74 class AlphaGradientTest : public Test {
75 public:
76 	AlphaGradientTest()
77 		:
78 		Test("Alpha gradients")
79 	{
80 	}
81 
82 	virtual void Draw(BView* view, BRect updateRect)
83 	{
84 		view->SetDrawingMode(B_OP_ALPHA);
85 
86 		// These draw as almost transparent
87 
88 		// Radial gradient
89 		BPoint center(50, 50);
90 		float radius = 50.0;
91 		BGradientRadial g(center, radius);
92 		g.AddColor((rgb_color){ 255, 0, 0, 255 }, 0.0);
93 		g.AddColor((rgb_color){ 0, 255, 0, 0 }, 255.0);
94 		view->FillEllipse(center, radius, radius, g);
95 
96 		// Linear gradient - Horizontal
97 		BPoint from(100, 0);
98 		BPoint to(200, 0);
99 		BGradientLinear l(from, to);
100 		l.AddColor((rgb_color){ 255, 0, 0, 0 }, 0.0);
101 		l.AddColor((rgb_color){ 0, 255, 0, 255 }, 255.0);
102 		view->FillRect(BRect(100, 0, 200, 100), l);
103 
104 		// Linear gradient - Vertical
105 		// (this uses a different code path in app_server)
106 		BPoint top(0, 0);
107 		BPoint bot(0, 100);
108 		BGradientLinear v(top, bot);
109 		v.AddColor((rgb_color){ 255, 0, 0, 0 }, 0.0);
110 		v.AddColor((rgb_color){ 0, 255, 0, 255 }, 255.0);
111 		view->FillRect(BRect(200, 0, 300, 100), v);
112 
113 		// These draw as opaque or almost opaque
114 
115 		view->SetOrigin(BPoint(0, 100));
116 
117 		// Radial gradient
118 		BGradientRadial go(center, radius);
119 		go.AddColor((rgb_color){ 255, 0, 0, 0 }, 0.0);
120 		go.AddColor((rgb_color){ 0, 255, 0, 255 }, 255.0);
121 		view->FillEllipse(center, radius, radius, go);
122 
123 		// Linear gradient - Horizontal
124 		BGradientLinear lo(from, to);
125 		lo.AddColor((rgb_color){ 255, 0, 0, 255 }, 0.0);
126 		lo.AddColor((rgb_color){ 0, 255, 0, 0 }, 255.0);
127 		view->FillRect(BRect(100, 0, 200, 100), lo);
128 
129 		// Linear gradient - Vertical
130 		// (this uses a different code path in app_server)
131 		BGradientLinear vo(top, bot);
132 		vo.AddColor((rgb_color){ 255, 0, 0, 255 }, 0.0);
133 		vo.AddColor((rgb_color){ 0, 255, 0, 0 }, 255.0);
134 		view->FillRect(BRect(200, 0, 300, 100), vo);
135 
136 		// Finally, do the same using ClipToPicture. This forces using an
137 		// unpacked scanline rasterizer, and it works.
138 		view->SetOrigin(BPoint(0, 0));
139 
140 		view->SetDrawingMode(B_OP_COPY);
141 
142 		BPicture picture;
143 		view->BeginPicture(&picture);
144 		view->SetHighColor(make_color(0,0,0,255));
145 		view->FillRect(BRect(0, 200, 300, 300));
146 		view->EndPicture();
147 		view->ClipToPicture(&picture);
148 
149 		view->SetOrigin(BPoint(0, 200));
150 
151 		view->SetDrawingMode(B_OP_ALPHA);
152 
153 		view->FillEllipse(center, radius, radius, g);
154 		view->FillRect(BRect(100, 0, 200, 100), l);
155 		view->FillRect(BRect(200, 0, 300, 100), v);
156 	}
157 };
158 
159 
160 // Test for https://dev.haiku-os.org/ticket/2945
161 // Gradients with no stop at offset 0 or 255 draw random colors
162 class OutOfBoundsGradientTest : public Test {
163 public:
164 	OutOfBoundsGradientTest()
165 		:
166 		Test("Out of bounds gradients")
167 	{
168 	}
169 
170 	virtual void Draw(BView* view, BRect updateRect)
171 	{
172 		{
173 			// Linear gradient - Vertical
174 			BPoint from(275, 10);
175 			BPoint to(275, 138);
176 			BGradientLinear l(from, to);
177 			l.AddColor((rgb_color){ 255, 0, 0, 255 }, 100.0);
178 			l.AddColor((rgb_color){ 255, 255, 0, 255 }, 156.0);
179 			view->FillRect(BRect(275, 10, 2*265, 265), l);
180 		}
181 
182 		{
183 			// Linear gradient - Horizontal
184 			BPoint from(10, 10);
185 			BPoint to(138, 10);
186 			BGradientLinear l(from, to);
187 			l.AddColor((rgb_color){ 255, 0, 0, 255 }, 100.0);
188 			l.AddColor((rgb_color){ 255, 255, 0, 255 }, 156.0);
189 			view->FillRect(BRect(10, 10, 265, 265), l);
190 		}
191 	}
192 };
193 
194 
195 // #pragma mark -
196 
197 
198 int
199 main(int argc, char** argv)
200 {
201 	BApplication app(kAppSignature);
202 
203 	TestWindow* window = new TestWindow("Gradient tests");
204 
205 	window->AddTest(new RadialGradientTest());
206 	window->AddTest(new AlphaGradientTest());
207 	window->AddTest(new OutOfBoundsGradientTest());
208 
209 	window->SetToTest(0);
210 	window->Show();
211 
212 	app.Run();
213 	return 0;
214 }
215