1 /*
2 * Copyright 2007, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Michael Pfeiffer
7 */
8
9 #include "PictureTestCases.h"
10
11 #include <GradientLinear.h>
12 #include <GradientRadial.h>
13 #include <GradientRadialFocus.h>
14 #include <GradientDiamond.h>
15 #include <GradientConic.h>
16
17 #include <stdio.h>
18
19 static const rgb_color kBlack = {0, 0, 0};
20 static const rgb_color kWhite = {255, 255, 255};
21 static const rgb_color kRed = {255, 0, 0};
22 static const rgb_color kGreen = {0, 255, 0};
23 static const rgb_color kBlue = {0, 0, 255};
24
centerPoint(BRect rect)25 static BPoint centerPoint(BRect rect)
26 {
27 int x = (int)(rect.left + rect.IntegerWidth() / 2);
28 int y = (int)(rect.top + rect.IntegerHeight() / 2);
29 return BPoint(x, y);
30 }
31
testNoOp(BView * view,BRect frame)32 static void testNoOp(BView *view, BRect frame)
33 {
34 // no op
35 }
36
testDrawChar(BView * view,BRect frame)37 static void testDrawChar(BView *view, BRect frame)
38 {
39 view->MovePenTo(frame.left, frame.bottom - 5);
40 view->DrawChar('A');
41
42 view->DrawChar('B', BPoint(frame.left + 20, frame.bottom - 5));
43 }
44
testDrawString(BView * view,BRect frame)45 static void testDrawString(BView *view, BRect frame)
46 {
47 BFont font;
48 view->GetFont(&font);
49 font_height height;
50 font.GetHeight(&height);
51 float baseline = frame.bottom - height.descent;
52 // draw base line
53 view->SetHighColor(kGreen);
54 view->StrokeLine(BPoint(frame.left, baseline - 1), BPoint(frame.right, baseline -1));
55
56 view->SetHighColor(kBlack);
57 view->DrawString("Haiku [ÖÜÄöüä]", BPoint(frame.left, baseline));
58 }
59
testDrawStringWithLength(BView * view,BRect frame)60 static void testDrawStringWithLength(BView *view, BRect frame)
61 {
62 BFont font;
63 view->GetFont(&font);
64 font_height height;
65 font.GetHeight(&height);
66 float baseline = frame.bottom - height.descent;
67 // draw base line
68 view->SetHighColor(kGreen);
69 view->StrokeLine(BPoint(frame.left, baseline - 1), BPoint(frame.right, baseline -1));
70
71 view->SetHighColor(kBlack);
72 view->DrawString("Haiku [ÖÜÄöüä]", 13, BPoint(frame.left, baseline));
73 }
74
75
testDrawStringWithOffsets(BView * view,BRect frame)76 static void testDrawStringWithOffsets(BView* view, BRect frame)
77 {
78 BFont font;
79 view->GetFont(&font);
80 font_height height;
81 font.GetHeight(&height);
82 float baseline = frame.bottom - height.descent;
83 // draw base line
84 view->SetHighColor(kGreen);
85 view->StrokeLine(BPoint(frame.left, baseline - 1), BPoint(frame.right, baseline -1));
86
87 view->SetHighColor(kBlack);
88 BPoint point(frame.left, baseline);
89 BPoint pointArray[] = {
90 point,
91 point,
92 point,
93 point,
94 point
95 };
96
97 for (size_t i = 1; i < (sizeof(pointArray) / sizeof(pointArray[0])); i++)
98 pointArray[i] = pointArray[i - 1] + BPoint(10, 0);
99
100 view->DrawString("Haiku", pointArray, sizeof(pointArray) / sizeof(pointArray[0]));
101 }
102
103
testDrawStringWithoutPosition(BView * view,BRect frame)104 static void testDrawStringWithoutPosition(BView* view, BRect frame)
105 {
106 BFont font;
107 view->GetFont(&font);
108 font_height height;
109 font.GetHeight(&height);
110 float baseline = frame.bottom - height.descent;
111 // draw base line
112 view->SetHighColor(kGreen);
113 view->StrokeLine(BPoint(frame.left, baseline - 1), BPoint(frame.right, baseline -1));
114
115 view->SetHighColor(kBlack);
116 view->MovePenTo(BPoint(frame.left, baseline));
117 view->DrawString("H");
118 view->DrawString("a");
119 view->DrawString("i");
120 view->DrawString("k");
121 view->DrawString("u");
122 }
123
124
testFillArc(BView * view,BRect frame)125 static void testFillArc(BView *view, BRect frame)
126 {
127 frame.InsetBy(2, 2);
128 view->FillArc(frame, 45, 180);
129 }
130
testStrokeArc(BView * view,BRect frame)131 static void testStrokeArc(BView *view, BRect frame)
132 {
133 frame.InsetBy(2, 2);
134 view->StrokeArc(frame, 45, 180);
135 }
136
testFillBezier(BView * view,BRect frame)137 static void testFillBezier(BView *view, BRect frame)
138 {
139 frame.InsetBy(2, 2);
140 BPoint points[4];
141 points[0] = BPoint(frame.left, frame.bottom);
142 points[1] = BPoint(frame.left, frame.top);
143 points[1] = BPoint(frame.left, frame.top);
144 points[3] = BPoint(frame.right, frame.top);
145 view->FillBezier(points);
146 }
147
testStrokeBezier(BView * view,BRect frame)148 static void testStrokeBezier(BView *view, BRect frame)
149 {
150 frame.InsetBy(2, 2);
151 BPoint points[4];
152 points[0] = BPoint(frame.left, frame.bottom);
153 points[1] = BPoint(frame.left, frame.top);
154 points[1] = BPoint(frame.left, frame.top);
155 points[3] = BPoint(frame.right, frame.top);
156 view->StrokeBezier(points);
157 }
158
testFillEllipse(BView * view,BRect frame)159 static void testFillEllipse(BView *view, BRect frame)
160 {
161 frame.InsetBy(2, 2);
162 view->FillEllipse(frame);
163
164 view->SetHighColor(kRed);
165 float r = frame.Width() / 3;
166 float s = frame.Height() / 4;
167 view->FillEllipse(centerPoint(frame), r, s);
168 }
169
testStrokeEllipse(BView * view,BRect frame)170 static void testStrokeEllipse(BView *view, BRect frame)
171 {
172 frame.InsetBy(2, 2);
173 view->StrokeEllipse(frame);
174
175 view->SetHighColor(kRed);
176 float r = frame.Width() / 3;
177 float s = frame.Height() / 4;
178 view->StrokeEllipse(centerPoint(frame), r, s);
179 }
180
testFillPolygon(BView * view,BRect frame)181 static void testFillPolygon(BView *view, BRect frame)
182 {
183 frame.InsetBy(2, 2);
184
185 BPoint points[4];
186 points[0] = BPoint(frame.left, frame.top);
187 points[1] = BPoint(frame.right, frame.bottom);
188 points[2] = BPoint(frame.right, frame.top);
189 points[3] = BPoint(frame.left, frame.bottom);
190
191 view->FillPolygon(points, 4);
192 }
193
testStrokePolygon(BView * view,BRect frame)194 static void testStrokePolygon(BView *view, BRect frame)
195 {
196 frame.InsetBy(2, 2);
197
198 BPoint points[4];
199 points[0] = BPoint(frame.left, frame.top);
200 points[1] = BPoint(frame.right, frame.bottom);
201 points[2] = BPoint(frame.right, frame.top);
202 points[3] = BPoint(frame.left, frame.bottom);
203
204 view->StrokePolygon(points, 4);
205 }
206
testFillRect(BView * view,BRect frame)207 static void testFillRect(BView *view, BRect frame)
208 {
209 frame.InsetBy(2, 2);
210 view->FillRect(frame);
211 }
212
testFillRectGradientLinear(BView * view,BRect frame)213 static void testFillRectGradientLinear(BView* view, BRect frame)
214 {
215 BGradientLinear gradient(0, 0, frame.right, frame.bottom);
216 gradient.AddColor(kRed, 0);
217 gradient.AddColor(kBlue, 255);
218 frame.InsetBy(2, 2);
219 view->FillRect(frame, gradient);
220 }
221
testFillRectGradientRadial(BView * view,BRect frame)222 static void testFillRectGradientRadial(BView* view, BRect frame)
223 {
224 BGradientRadial gradient(10, 10, 10);
225 gradient.AddColor(kRed, 0);
226 gradient.AddColor(kBlue, 255);
227 frame.InsetBy(2, 2);
228 view->FillRect(frame, gradient);
229 }
230
testFillRectGradientRadialFocus(BView * view,BRect frame)231 static void testFillRectGradientRadialFocus(BView* view, BRect frame)
232 {
233 BGradientRadialFocus gradient(0, 0, 10, 10, 5);
234 gradient.AddColor(kRed, 0);
235 gradient.AddColor(kBlue, 255);
236 frame.InsetBy(2, 2);
237 view->FillRect(frame, gradient);
238 }
239
testFillRectGradientDiamond(BView * view,BRect frame)240 static void testFillRectGradientDiamond(BView* view, BRect frame)
241 {
242 BGradientDiamond gradient(0, 10);
243 gradient.AddColor(kRed, 0);
244 gradient.AddColor(kBlue, 255);
245 frame.InsetBy(2, 2);
246 view->FillRect(frame, gradient);
247 }
248
testFillRectGradientConic(BView * view,BRect frame)249 static void testFillRectGradientConic(BView* view, BRect frame)
250 {
251 BGradientConic gradient(0, 0, 10);
252 gradient.AddColor(kRed, 0);
253 gradient.AddColor(kBlue, 255);
254 frame.InsetBy(2, 2);
255 view->FillRect(frame, gradient);
256 }
257
testStrokeRect(BView * view,BRect frame)258 static void testStrokeRect(BView *view, BRect frame)
259 {
260 frame.InsetBy(2, 2);
261 view->StrokeRect(frame);
262 }
263
testFillRegion(BView * view,BRect frame)264 static void testFillRegion(BView *view, BRect frame)
265 {
266 frame.InsetBy(2, 2);
267 BRegion region(frame);
268 frame.InsetBy(10, 10);
269 region.Exclude(frame);
270 view->FillRegion(®ion);
271 }
272
testFillRegionGradientLinear(BView * view,BRect frame)273 static void testFillRegionGradientLinear(BView* view, BRect frame)
274 {
275 BGradientLinear gradient(0, 0, frame.right, frame.bottom);
276 gradient.AddColor(kRed, 0);
277 gradient.AddColor(kBlue, 255);
278 frame.InsetBy(2, 2);
279 BRegion region(frame);
280 frame.InsetBy(10, 10);
281 region.Exclude(frame);
282 view->FillRegion(®ion, gradient);
283 }
284
testFillRegionGradientRadial(BView * view,BRect frame)285 static void testFillRegionGradientRadial(BView* view, BRect frame)
286 {
287 BGradientRadial gradient(10, 10, 10);
288 gradient.AddColor(kRed, 0);
289 gradient.AddColor(kBlue, 255);
290 frame.InsetBy(2, 2);
291 BRegion region(frame);
292 frame.InsetBy(10, 10);
293 region.Exclude(frame);
294 view->FillRegion(®ion, gradient);
295 }
296
testFillRegionGradientRadialFocus(BView * view,BRect frame)297 static void testFillRegionGradientRadialFocus(BView* view, BRect frame)
298 {
299 BGradientRadialFocus gradient(0, 0, 10, 10, 5);
300 gradient.AddColor(kRed, 0);
301 gradient.AddColor(kBlue, 255);
302 frame.InsetBy(2, 2);
303 BRegion region(frame);
304 frame.InsetBy(10, 10);
305 region.Exclude(frame);
306 view->FillRegion(®ion, gradient);
307 }
308
testFillRegionGradientDiamond(BView * view,BRect frame)309 static void testFillRegionGradientDiamond(BView* view, BRect frame)
310 {
311 BGradientDiamond gradient(0, 10);
312 gradient.AddColor(kRed, 0);
313 gradient.AddColor(kBlue, 255);
314 frame.InsetBy(2, 2);
315 BRegion region(frame);
316 frame.InsetBy(10, 10);
317 region.Exclude(frame);
318 view->FillRegion(®ion, gradient);
319 }
320
testFillRegionGradientConic(BView * view,BRect frame)321 static void testFillRegionGradientConic(BView* view, BRect frame)
322 {
323 BGradientConic gradient(0, 0, 10);
324 gradient.AddColor(kRed, 0);
325 gradient.AddColor(kBlue, 255);
326 frame.InsetBy(2, 2);
327 BRegion region(frame);
328 frame.InsetBy(10, 10);
329 region.Exclude(frame);
330 view->FillRegion(®ion, gradient);
331 }
332
testFillRoundRect(BView * view,BRect frame)333 static void testFillRoundRect(BView *view, BRect frame)
334 {
335 frame.InsetBy(2, 2);
336 view->FillRoundRect(frame, 5, 3);
337 }
338
testFillRoundRectGradientLinear(BView * view,BRect frame)339 static void testFillRoundRectGradientLinear(BView* view, BRect frame)
340 {
341 BGradientLinear gradient(0, 0, frame.right, frame.bottom);
342 gradient.AddColor(kRed, 0);
343 gradient.AddColor(kBlue, 255);
344 frame.InsetBy(2, 2);
345 view->FillRoundRect(frame, 5, 3, gradient);
346 }
347
testFillRoundRectGradientRadial(BView * view,BRect frame)348 static void testFillRoundRectGradientRadial(BView* view, BRect frame)
349 {
350 BGradientRadial gradient(10, 10, 10);
351 gradient.AddColor(kRed, 0);
352 gradient.AddColor(kBlue, 255);
353 frame.InsetBy(2, 2);
354 view->FillRoundRect(frame, 5, 3, gradient);
355 }
356
testFillRoundRectGradientRadialFocus(BView * view,BRect frame)357 static void testFillRoundRectGradientRadialFocus(BView* view, BRect frame)
358 {
359 BGradientRadialFocus gradient(0, 0, 10, 10, 5);
360 gradient.AddColor(kRed, 0);
361 gradient.AddColor(kBlue, 255);
362 view->FillRoundRect(frame, 5, 3, gradient);
363 }
364
testFillRoundRectGradientDiamond(BView * view,BRect frame)365 static void testFillRoundRectGradientDiamond(BView* view, BRect frame)
366 {
367 BGradientDiamond gradient(0, 10);
368 gradient.AddColor(kRed, 0);
369 gradient.AddColor(kBlue, 255);
370 frame.InsetBy(2, 2);
371 view->FillRoundRect(frame, 5, 3, gradient);
372 }
373
testFillRoundRectGradientConic(BView * view,BRect frame)374 static void testFillRoundRectGradientConic(BView* view, BRect frame)
375 {
376 BGradientConic gradient(0, 0, 10);
377 gradient.AddColor(kRed, 0);
378 gradient.AddColor(kBlue, 255);
379 frame.InsetBy(2, 2);
380 view->FillRoundRect(frame, 5, 3, gradient);
381 }
382
testStrokeRoundRect(BView * view,BRect frame)383 static void testStrokeRoundRect(BView *view, BRect frame)
384 {
385 frame.InsetBy(2, 2);
386 view->StrokeRoundRect(frame, 5, 3);
387 }
388
testFillTriangle(BView * view,BRect frame)389 static void testFillTriangle(BView *view, BRect frame)
390 {
391 frame.InsetBy(2, 2);
392 BPoint points[3];
393 points[0] = BPoint(frame.left, frame.bottom);
394 points[1] = BPoint(centerPoint(frame).x, frame.top);
395 points[2] = BPoint(frame.right, frame.bottom);
396 view->FillTriangle(points[0], points[1], points[2]);
397 }
398
testFillTriangleGradientLinear(BView * view,BRect frame)399 static void testFillTriangleGradientLinear(BView* view, BRect frame)
400 {
401 BGradientLinear gradient(0, 0, frame.right, frame.bottom);
402 gradient.AddColor(kRed, 0);
403 gradient.AddColor(kBlue, 255);
404 frame.InsetBy(2, 2);
405 BPoint points[3];
406 points[0] = BPoint(frame.left, frame.bottom);
407 points[1] = BPoint(centerPoint(frame).x, frame.top);
408 points[2] = BPoint(frame.right, frame.bottom);
409 view->FillTriangle(points[0], points[1], points[2], gradient);
410 }
411
testFillTriangleGradientRadial(BView * view,BRect frame)412 static void testFillTriangleGradientRadial(BView* view, BRect frame)
413 {
414 BGradientRadial gradient(10, 10, 10);
415 gradient.AddColor(kRed, 0);
416 gradient.AddColor(kBlue, 255);
417 frame.InsetBy(2, 2);
418 BPoint points[3];
419 points[0] = BPoint(frame.left, frame.bottom);
420 points[1] = BPoint(centerPoint(frame).x, frame.top);
421 points[2] = BPoint(frame.right, frame.bottom);
422 view->FillTriangle(points[0], points[1], points[2], gradient);
423 }
424
testFillTriangleGradientRadialFocus(BView * view,BRect frame)425 static void testFillTriangleGradientRadialFocus(BView* view, BRect frame)
426 {
427 BGradientRadialFocus gradient(0, 0, 10, 10, 5);
428 gradient.AddColor(kRed, 0);
429 gradient.AddColor(kBlue, 255);
430 frame.InsetBy(2, 2);
431 BPoint points[3];
432 points[0] = BPoint(frame.left, frame.bottom);
433 points[1] = BPoint(centerPoint(frame).x, frame.top);
434 points[2] = BPoint(frame.right, frame.bottom);
435 view->FillTriangle(points[0], points[1], points[2], gradient);
436 }
437
testFillTriangleGradientDiamond(BView * view,BRect frame)438 static void testFillTriangleGradientDiamond(BView* view, BRect frame)
439 {
440 BGradientDiamond gradient(0, 10);
441 gradient.AddColor(kRed, 0);
442 gradient.AddColor(kBlue, 255);
443 frame.InsetBy(2, 2);
444 BPoint points[3];
445 points[0] = BPoint(frame.left, frame.bottom);
446 points[1] = BPoint(centerPoint(frame).x, frame.top);
447 points[2] = BPoint(frame.right, frame.bottom);
448 view->FillTriangle(points[0], points[1], points[2], gradient);
449 }
450
testFillTriangleGradientConic(BView * view,BRect frame)451 static void testFillTriangleGradientConic(BView* view, BRect frame)
452 {
453 BGradientConic gradient(0, 0, 10);
454 gradient.AddColor(kRed, 0);
455 gradient.AddColor(kBlue, 255);
456 frame.InsetBy(2, 2);
457 BPoint points[3];
458 points[0] = BPoint(frame.left, frame.bottom);
459 points[1] = BPoint(centerPoint(frame).x, frame.top);
460 points[2] = BPoint(frame.right, frame.bottom);
461 view->FillTriangle(points[0], points[1], points[2], gradient);
462 }
463
testStrokeTriangle(BView * view,BRect frame)464 static void testStrokeTriangle(BView *view, BRect frame)
465 {
466 frame.InsetBy(2, 2);
467 BPoint points[3];
468 points[0] = BPoint(frame.left, frame.bottom);
469 points[1] = BPoint(centerPoint(frame).x, frame.top);
470 points[2] = BPoint(frame.right, frame.bottom);
471 view->StrokeTriangle(points[0], points[1], points[2]);
472 }
473
testStrokeLine(BView * view,BRect frame)474 static void testStrokeLine(BView *view, BRect frame)
475 {
476 frame.InsetBy(2, 2);
477 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
478
479 frame.top += 2;
480 frame.bottom -= 2;
481 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.bottom));
482
483 frame.bottom += 2;;
484 frame.top = frame.bottom;
485 view->StrokeLine(BPoint(frame.right, frame.top), BPoint(frame.left, frame.top));
486 }
487
testFillShape(BView * view,BRect frame)488 static void testFillShape(BView *view, BRect frame)
489 {
490 frame.InsetBy(2, 2);
491 BShape shape;
492 shape.MoveTo(BPoint(frame.left, frame.bottom));
493 shape.LineTo(BPoint(frame.right, frame.top));
494 shape.LineTo(BPoint(frame.left, frame.top));
495 shape.LineTo(BPoint(frame.right, frame.bottom));
496 view->FillShape(&shape);
497 }
498
testStrokeShape(BView * view,BRect frame)499 static void testStrokeShape(BView *view, BRect frame)
500 {
501 frame.InsetBy(2, 2);
502 BShape shape;
503 shape.MoveTo(BPoint(frame.left, frame.bottom));
504 shape.LineTo(BPoint(frame.right, frame.top));
505 shape.LineTo(BPoint(frame.left, frame.top));
506 shape.LineTo(BPoint(frame.right, frame.bottom));
507 view->StrokeShape(&shape);
508 }
509
testRecordPicture(BView * view,BRect frame)510 static void testRecordPicture(BView *view, BRect frame)
511 {
512 BPicture *picture = new BPicture();
513 view->BeginPicture(picture);
514 view->FillRect(frame);
515 view->EndPicture();
516 delete picture;
517 }
518
testRecordAndPlayPicture(BView * view,BRect frame)519 static void testRecordAndPlayPicture(BView *view, BRect frame)
520 {
521 BPicture *picture = new BPicture();
522 view->BeginPicture(picture);
523 frame.InsetBy(2, 2);
524 view->FillRect(frame);
525 view->EndPicture();
526 view->DrawPicture(picture);
527 delete picture;
528 }
529
testRecordAndPlayPictureWithOffset(BView * view,BRect frame)530 static void testRecordAndPlayPictureWithOffset(BView *view, BRect frame)
531 {
532 BPicture *picture = new BPicture();
533 view->BeginPicture(picture);
534 frame.InsetBy(frame.Width() / 4, frame.Height() / 4);
535 frame.OffsetTo(0, 0);
536 view->FillRect(frame);
537 view->EndPicture();
538
539 view->DrawPicture(picture, BPoint(10, 10));
540 // color of picture should not change
541 view->SetLowColor(kGreen);
542 view->SetLowColor(kRed);
543 view->DrawPicture(picture, BPoint(0, 0));
544 delete picture;
545 }
546
testAppendToPicture(BView * view,BRect frame)547 static void testAppendToPicture(BView *view, BRect frame)
548 {
549 frame.InsetBy(2, 2);
550 view->BeginPicture(new BPicture());
551 view->FillRect(frame);
552 BPicture* picture = view->EndPicture();
553 if (picture == NULL)
554 return;
555
556 frame.InsetBy(2, 2);
557 view->AppendToPicture(picture);
558 view->SetHighColor(kRed);
559 view->FillRect(frame);
560 if (view->EndPicture() != picture)
561 return;
562
563 view->DrawPicture(picture);
564 delete picture;
565 }
566
testDrawScaledPicture(BView * view,BRect frame)567 static void testDrawScaledPicture(BView* view, BRect frame)
568 {
569 view->BeginPicture(new BPicture());
570 view->FillRect(BRect(0, 0, 15, 15));
571 BPicture* picture = view->EndPicture();
572
573 // first unscaled at left, top
574 view->DrawPicture(picture, BPoint(2, 2));
575
576 // draw scaled at middle top
577 view->SetScale(0.5);
578 // the drawing offset must be scaled too!
579 view->DrawPicture(picture, BPoint(frame.Width(), 4));
580
581 delete picture;
582 }
583
testLineArray(BView * view,BRect frame)584 static void testLineArray(BView *view, BRect frame)
585 {
586 frame.InsetBy(2, 2);
587 view->BeginLineArray(3);
588 view->AddLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top), kBlack);
589
590 frame.top += 2;
591 frame.bottom -= 2;
592 view->AddLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.bottom), kRed);
593
594 frame.bottom += 2;;
595 frame.top = frame.bottom;
596 view->AddLine(BPoint(frame.right, frame.top), BPoint(frame.left, frame.top), kGreen);
597
598 view->EndLineArray();
599 }
600
testInvertRect(BView * view,BRect frame)601 static void testInvertRect(BView *view, BRect frame)
602 {
603 frame.InsetBy(2, 2);
604 view->InvertRect(frame);
605 }
606
testInvertRectSetDrawingMode(BView * view,BRect frame)607 static void testInvertRectSetDrawingMode(BView *view, BRect frame)
608 {
609 view->SetDrawingMode(B_OP_ALPHA);
610 view->SetHighColor(128, 128, 128, 128);
611 frame.InsetBy(2, 2);
612 view->InvertRect(frame);
613 frame.InsetBy(10, 10);
614 view->FillRect(frame, B_SOLID_HIGH);
615 }
616
isBorder(int32 x,int32 y,int32 width,int32 height)617 static bool isBorder(int32 x, int32 y, int32 width, int32 height) {
618 return x == 0 || y == 0 || x == width - 1 || y == height - 1;
619 }
620
fillBitmap(BBitmap & bitmap)621 static void fillBitmap(BBitmap &bitmap) {
622 int32 height = bitmap.Bounds().IntegerHeight()+1;
623 int32 width = bitmap.Bounds().IntegerWidth()+1;
624 for (int32 y = 0; y < height; y ++) {
625 for (int32 x = 0; x < width; x ++) {
626 char *pixel = (char*)bitmap.Bits();
627 pixel += bitmap.BytesPerRow() * y + 4 * x;
628 if (isBorder(x, y, width, height)) {
629 // fill with green
630 pixel[0] = 255;
631 pixel[1] = 0;
632 pixel[2] = 255;
633 pixel[3] = 0;
634 } else {
635 // fill with blue
636 pixel[0] = 255;
637 pixel[1] = 0;
638 pixel[2] = 0;
639 pixel[3] = 255;
640 }
641 }
642 }
643 }
644
testDrawBitmap(BView * view,BRect frame)645 static void testDrawBitmap(BView *view, BRect frame) {
646 BBitmap bitmap(frame, B_RGBA32);
647 fillBitmap(bitmap);
648 view->DrawBitmap(&bitmap, BPoint(0, 0));
649 }
650
testDrawBitmapAtPoint(BView * view,BRect frame)651 static void testDrawBitmapAtPoint(BView *view, BRect frame) {
652 frame.InsetBy(2, 2);
653
654 BRect bounds(frame);
655 bounds.OffsetTo(0, 0);
656 bounds.right /= 2;
657 bounds.bottom /= 2;
658
659 BBitmap bitmap(bounds, B_RGBA32);
660 fillBitmap(bitmap);
661 view->DrawBitmap(&bitmap, centerPoint(frame));
662 }
663
testDrawBitmapAtRect(BView * view,BRect frame)664 static void testDrawBitmapAtRect(BView *view, BRect frame) {
665 BRect bounds(frame);
666 BBitmap bitmap(bounds, B_RGBA32);
667 fillBitmap(bitmap);
668 frame.InsetBy(2, 2);
669 view->DrawBitmap(&bitmap, frame);
670 }
671
testDrawLargeBitmap(BView * view,BRect frame)672 static void testDrawLargeBitmap(BView *view, BRect frame) {
673 BRect bounds(frame);
674 bounds.OffsetTo(0, 0);
675 bounds.right *= 4;
676 bounds.bottom *= 4;
677 BBitmap bitmap(bounds, B_RGBA32);
678 fillBitmap(bitmap);
679 frame.InsetBy(2, 2);
680 view->DrawBitmap(&bitmap, frame);
681 }
682
testConstrainClippingRegion(BView * view,BRect frame)683 static void testConstrainClippingRegion(BView *view, BRect frame)
684 {
685 frame.InsetBy(2, 2);
686 // draw background
687 view->SetHighColor(kRed);
688 view->FillRect(frame);
689
690 frame.InsetBy(1, 1);
691 BRegion region(frame);
692 BRect r(frame);
693 r.InsetBy(r.IntegerWidth() / 4, r.IntegerHeight() / 4);
694 region.Exclude(r);
695 view->ConstrainClippingRegion(®ion);
696
697 frame.InsetBy(-1, -1);
698 view->SetHighColor(kBlack);
699 view->FillRect(frame);
700 // a filled black rectangle with a red one pixel border
701 // and inside a red rectangle should be drawn.
702 }
703
testClipToPicture(BView * view,BRect frame)704 static void testClipToPicture(BView *view, BRect frame)
705 {
706 frame.InsetBy(2, 2);
707 view->BeginPicture(new BPicture());
708 view->FillEllipse(frame);
709 BPicture *picture = view->EndPicture();
710 if (picture == NULL)
711 return;
712
713 view->ClipToPicture(picture);
714 delete picture;
715
716 view->FillRect(frame);
717 // black ellipse should be drawn
718 }
719
testClipToInversePicture(BView * view,BRect frame)720 static void testClipToInversePicture(BView *view, BRect frame)
721 {
722 frame.InsetBy(2, 2);
723
724 view->BeginPicture(new BPicture());
725 view->FillEllipse(frame);
726 BPicture *picture = view->EndPicture();
727 if (picture == NULL)
728 return;
729
730 view->ClipToInversePicture(picture);
731 delete picture;
732
733 view->FillRect(frame);
734 // white ellipse inside a black rectangle
735 }
736
testSetPenSize(BView * view,BRect frame)737 static void testSetPenSize(BView *view, BRect frame)
738 {
739 frame.InsetBy(8, 2);
740 float x = centerPoint(frame).x;
741
742 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
743
744 frame.OffsetBy(0, 5);
745 view->SetPenSize(1);
746 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
747 view->SetPenSize(0);
748 view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
749
750 frame.OffsetBy(0, 5);
751 view->SetPenSize(1);
752 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
753 view->SetPenSize(2);
754 view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
755
756 frame.OffsetBy(0, 5);
757 view->SetPenSize(1);
758 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
759 view->SetPenSize(3);
760 view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
761
762 frame.OffsetBy(0, 5);
763 view->SetPenSize(1);
764 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
765 view->SetPenSize(4);
766 view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
767 }
768
testSetPenSize2(BView * view,BRect frame)769 static void testSetPenSize2(BView *view, BRect frame)
770 {
771 // test if pen size is scaled too
772 frame.InsetBy(2, 2);
773 frame.OffsetBy(0, 5);
774 view->SetPenSize(4);
775 view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
776 view->SetScale(0.5);
777 view->StrokeLine(BPoint(frame.left + 2, frame.bottom), BPoint(frame.right + 2, frame.bottom));
778
779 // black line from left to right, 4 pixel size
780 // below black line with half the length of the first one
781 // and 2 pixel size
782 }
783
testPattern(BView * view,BRect frame)784 static void testPattern(BView *view, BRect frame)
785 {
786 frame.InsetBy(2, 2);
787 int x = frame.IntegerWidth() / 3;
788 frame.right = frame.left + x - 2;
789 // -2 for an empty pixel row between
790 // filled rectangles
791
792 view->SetLowColor(kGreen);
793 view->SetHighColor(kRed);
794
795 view->FillRect(frame, B_SOLID_HIGH);
796
797 frame.OffsetBy(x, 0);
798 view->FillRect(frame, B_MIXED_COLORS);
799
800 frame.OffsetBy(x, 0);
801 view->FillRect(frame, B_SOLID_LOW);
802 }
803
testSetOrigin(BView * view,BRect frame)804 static void testSetOrigin(BView *view, BRect frame)
805 {
806 BPoint origin = view->Origin();
807 BPoint center = centerPoint(frame);
808 view->SetOrigin(center);
809
810 BRect r(0, 0, center.x, center.y);
811 view->SetHighColor(kBlue);
812 view->FillRect(r);
813
814 view->SetOrigin(origin);
815 view->SetHighColor(kRed);
816 view->FillRect(r);
817
818 // red rectangle in left, top corner
819 // blue rectangle in right, bottom corner
820 // the red rectangle overwrites the
821 // top, left pixel of the blue rectangle
822 }
823
testSetOrigin2(BView * view,BRect frame)824 static void testSetOrigin2(BView *view, BRect frame)
825 {
826 BPoint center = centerPoint(frame);
827 BRect r(0, 0, center.x, center.y);
828 view->SetOrigin(center);
829 view->PushState();
830 view->SetOrigin(BPoint(-center.x, 0));
831 view->FillRect(r);
832 view->PopState();
833 // black rectangle in left, bottom corner
834 }
835
testSetScale(BView * view,BRect frame)836 static void testSetScale(BView *view, BRect frame)
837 {
838 view->SetScale(0.5);
839 view->FillRect(frame);
840 // black rectangle in left, top corner
841 }
842
testSetScale2(BView * view,BRect frame)843 static void testSetScale2(BView *view, BRect frame)
844 {
845 view->SetScale(0.5);
846 view->PushState();
847 view->SetScale(0.5);
848 view->FillRect(frame);
849 view->PopState();
850 // black rectangle in left, top corner
851 // with half the size of the rectangle
852 // from test testSetScaling
853 }
854
testSetScale3(BView * view,BRect frame)855 static void testSetScale3(BView *view, BRect frame)
856 {
857 view->SetScale(0.5);
858 view->PushState();
859 // if the second scale value differs slightly
860 // the bug under BeOS R5 in testSetScale2
861 // does not occur
862 view->SetScale(0.5000001);
863 view->FillRect(frame);
864 view->PopState();
865 // black rectangle in left, top corner
866 // with half the size of the rectangle
867 // from test testSetScaling
868 }
869
testSetOriginAndScale(BView * view,BRect frame)870 static void testSetOriginAndScale(BView *view, BRect frame)
871 {
872 frame.InsetBy(2, 2);
873 BPoint center = centerPoint(frame);
874
875 BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
876 view->SetOrigin(center);
877 view->FillRect(r);
878
879 view->SetScale(0.5);
880 view->SetHighColor(kRed);
881 view->FillRect(r);
882 }
883
testSetOriginAndScale2(BView * view,BRect frame)884 static void testSetOriginAndScale2(BView *view, BRect frame)
885 {
886 frame.InsetBy(2, 2);
887 BPoint center = centerPoint(frame);
888
889 BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
890 view->SetOrigin(center);
891 view->FillRect(r);
892
893 view->SetScale(0.5);
894 view->SetHighColor(kRed);
895 view->FillRect(r);
896
897 view->SetOrigin(0, 0);
898 view->SetHighColor(kGreen);
899 view->FillRect(r);
900 }
901
testSetOriginAndScale3(BView * view,BRect frame)902 static void testSetOriginAndScale3(BView *view, BRect frame)
903 {
904 frame.InsetBy(2, 2);
905 BPoint center = centerPoint(frame);
906
907 BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
908 view->SetOrigin(center);
909 view->FillRect(r);
910
911 view->SetScale(0.5);
912 view->SetHighColor(kRed);
913 view->FillRect(r);
914
915 view->SetScale(0.25);
916 view->SetHighColor(kGreen);
917 view->FillRect(r);
918 }
919
testSetOriginAndScale4(BView * view,BRect frame)920 static void testSetOriginAndScale4(BView *view, BRect frame)
921 {
922 frame.InsetBy(2, 2);
923 BPoint center = centerPoint(frame);
924
925 BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
926 view->SetOrigin(center);
927 view->FillRect(r);
928
929 view->SetScale(0.5);
930 view->SetHighColor(kRed);
931 view->FillRect(r);
932
933 view->PushState();
934 //
935 view->SetOrigin(center.x+1, center.y);
936 // +1 to work around BeOS bug
937 // where setting the origin has no
938 // effect if it is the same as
939 // the previous value althou
940 // it is from the "outer" coordinate
941 // system
942 view->SetHighColor(kGreen);
943 view->FillRect(r);
944 view->PopState();
945 }
946
testSetOriginAndScale5(BView * view,BRect frame)947 static void testSetOriginAndScale5(BView *view, BRect frame)
948 {
949 frame.InsetBy(2, 2);
950 BPoint center = centerPoint(frame);
951
952 BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
953 view->SetOrigin(center);
954 view->FillRect(r);
955
956 view->SetScale(0.5);
957 view->SetHighColor(kRed);
958 view->FillRect(r);
959
960 view->PushState();
961 view->SetScale(0.75);
962 view->SetHighColor(kGreen);
963 view->FillRect(r);
964 view->PopState();
965 }
966
testSetFontSize(BView * view,BRect frame)967 static void testSetFontSize(BView *view, BRect frame)
968 {
969 frame.InsetBy(2, 2);
970 int size = frame.IntegerHeight() / 3;
971
972 frame.OffsetBy(0, size);
973 view->MovePenTo(BPoint(frame.left, frame.top));
974 view->SetFontSize(size);
975 view->DrawString("Haiku");
976
977 size *= 2;
978 frame.OffsetBy(0, size);
979 view->MovePenTo(BPoint(frame.left, frame.top));
980 view->SetFontSize(size);
981 view->DrawString("Haiku");
982 }
983
testSetFontFamilyAndStyle(BView * view,BRect frame)984 static void testSetFontFamilyAndStyle(BView *view, BRect frame)
985 {
986 view->DrawString("This is a test", BPoint(2, 6));
987
988 BFont font;
989 view->GetFont(&font);
990
991 int32 families = count_font_families();
992 font_family familyName;
993 get_font_family(families - 1, &familyName);
994
995 int32 styles = count_font_styles(familyName);
996 font_style styleName;
997 get_font_style(familyName, styles - 1, &styleName);
998 font.SetFamilyAndStyle(familyName, styleName);
999 view->SetFont(&font);
1000 view->DrawString( "This is a test", BPoint(2, 19));
1001 }
1002
testSetDrawingMode(BView * view,BRect frame)1003 static void testSetDrawingMode(BView *view, BRect frame)
1004 {
1005 frame.InsetBy(2, 2);
1006 view->StrokeLine(frame.LeftTop(), frame.RightBottom());
1007 view->StrokeLine(frame.LeftBottom(), frame.RightTop());
1008 view->SetDrawingMode(B_OP_ALPHA);
1009 rgb_color color = kRed;
1010 color.alpha = 127;
1011 view->SetHighColor(color);
1012 view->FillRect(frame, B_SOLID_HIGH);
1013 }
1014
testPushPopState(BView * view,BRect frame)1015 static void testPushPopState(BView *view, BRect frame)
1016 {
1017 frame.InsetBy(2, 2);
1018 view->SetHighColor(kGreen);
1019 view->PushState();
1020 view->SetHighColor(kRed);
1021 view->PopState();
1022
1023 view->FillRect(frame, B_SOLID_HIGH);
1024 }
1025
testFontRotation(BView * view,BRect frame)1026 static void testFontRotation(BView* view, BRect frame)
1027 {
1028 BFont font;
1029 view->GetFont(&font);
1030
1031 font.SetRotation(90);
1032 view->SetFont(&font, B_FONT_ROTATION);
1033 view->DrawString("This is a test!", BPoint(frame.Width() / 2, frame.bottom - 3));
1034
1035 view->GetFont(&font);
1036 if (font.Rotation() != 90.0)
1037 fprintf(stderr, "Error: Rotation is %f but should be 90.0\n", font.Rotation());
1038 }
1039
1040
testClipToRect(BView * view,BRect frame)1041 static void testClipToRect(BView* view, BRect frame)
1042 {
1043 BRect clipped = frame;
1044 clipped.InsetBy(5, 5);
1045
1046 view->ClipToRect(clipped);
1047
1048 view->FillRect(frame);
1049 }
1050
1051
testClipToInverseRect(BView * view,BRect frame)1052 static void testClipToInverseRect(BView* view, BRect frame)
1053 {
1054 BRect clipped = frame;
1055 clipped.InsetBy(5, 5);
1056
1057 view->ClipToInverseRect(clipped);
1058
1059 view->FillRect(frame);
1060 }
1061
1062
testClipToShape(BView * view,BRect frame)1063 static void testClipToShape(BView* view, BRect frame)
1064 {
1065 frame.InsetBy(2, 2);
1066 BShape shape;
1067 shape.MoveTo(BPoint(frame.left, frame.bottom));
1068 shape.LineTo(BPoint(frame.right, frame.top));
1069 shape.LineTo(BPoint(frame.left, frame.top));
1070 shape.LineTo(BPoint(frame.right, frame.bottom));
1071 view->ClipToShape(&shape);
1072
1073 view->FillRect(frame);
1074 }
1075
1076
testClipToInverseShape(BView * view,BRect frame)1077 static void testClipToInverseShape(BView* view, BRect frame)
1078 {
1079 frame.InsetBy(2, 2);
1080 BShape shape;
1081 shape.MoveTo(BPoint(frame.left, frame.bottom));
1082 shape.LineTo(BPoint(frame.right, frame.top));
1083 shape.LineTo(BPoint(frame.left, frame.top));
1084 shape.LineTo(BPoint(frame.right, frame.bottom));
1085 view->ClipToInverseShape(&shape);
1086
1087 view->FillRect(frame);
1088 }
1089
1090
1091 // TODO
1092 // - blending mode
1093 // - line mode
1094 // - push/pop state
1095 // - move pen
1096 // - set font
1097
1098
1099 TestCase gTestCases[] = {
1100 { "Test No Operation", testNoOp },
1101 { "Test DrawChar", testDrawChar },
1102 { "Test Draw String", testDrawString },
1103 { "Test Draw String With Length", testDrawStringWithLength },
1104 { "Test Draw String With Offsets", testDrawStringWithOffsets },
1105 { "Test Draw String Without Position", testDrawStringWithoutPosition },
1106 { "Test FillArc", testFillArc },
1107 { "Test StrokeArc", testStrokeArc },
1108 // testFillBezier fails under BeOS because the
1109 // direct draw version is not correct
1110 { "Test FillBezier", testFillBezier },
1111 { "Test StrokeBezier", testStrokeBezier },
1112 { "Test FillEllipse", testFillEllipse },
1113 { "Test StrokeEllipse", testStrokeEllipse },
1114 { "Test FillPolygon", testFillPolygon },
1115 { "Test StrokePolygon", testStrokePolygon },
1116 { "Test FillRect", testFillRect },
1117 { "Test FillRectGradientLinear", testFillRectGradientLinear },
1118 { "Test FillRectGradientRadial", testFillRectGradientRadial },
1119 { "Test FillRectGradientRadialFocus", testFillRectGradientRadialFocus },
1120 { "Test FillRectGradientDiamond", testFillRectGradientDiamond },
1121 { "Test FillRectGradientConic", testFillRectGradientConic },
1122 { "Test StrokeRect", testStrokeRect },
1123 { "Test FillRegion", testFillRegion },
1124 { "Test FillRegionGradientLinear", testFillRegionGradientLinear },
1125 { "Test FillRegionGradientRadial", testFillRegionGradientRadial },
1126 { "Test FillRegionGradientRadialFocus", testFillRegionGradientRadialFocus },
1127 { "Test FillRegionGradientDiamond", testFillRegionGradientDiamond },
1128 { "Test FillRegionGradientConic", testFillRegionGradientConic },
1129 { "Test FillRoundRect", testFillRoundRect },
1130 { "Test FillRoundRectGradientLinear", testFillRoundRectGradientLinear },
1131 { "Test FillRoundRectGradientRadial", testFillRoundRectGradientRadial },
1132 { "Test FillRoundRectGradientRadialFocus", testFillRoundRectGradientRadialFocus },
1133 { "Test FillRoundRectGradientDiamond", testFillRoundRectGradientDiamond },
1134 { "Test FillRoundRectGradientConic", testFillRoundRectGradientConic },
1135 { "Test StrokeRoundRect", testStrokeRoundRect },
1136 { "Test FillTriangle", testFillTriangle },
1137 { "Test FillTriangleGradientLinear", testFillTriangleGradientLinear },
1138 { "Test FillTriangleGradientRadial", testFillTriangleGradientRadial },
1139 { "Test FillTriangleGradientRadialFocus", testFillTriangleGradientRadialFocus },
1140 { "Test FillTriangleGradientDiamond", testFillTriangleGradientDiamond },
1141 { "Test FillTriangleGradientConic", testFillTriangleGradientConic },
1142 { "Test StrokeTriangle", testStrokeTriangle },
1143 { "Test StrokeLine", testStrokeLine },
1144 { "Test FillShape", testFillShape },
1145 { "Test StrokeShape", testStrokeShape },
1146 { "Test Record Picture", testRecordPicture },
1147 { "Test Record And Play Picture", testRecordAndPlayPicture },
1148 { "Test Record And Play Picture With Offset", testRecordAndPlayPictureWithOffset },
1149 { "Test AppendToPicture", testAppendToPicture },
1150 { "Test Draw Scaled Picture", testDrawScaledPicture },
1151 { "Test LineArray", testLineArray },
1152 { "Test InvertRect", testInvertRect },
1153 { "Test InvertRectSetDrawingMode", testInvertRectSetDrawingMode },
1154 { "Test DrawBitmap", testDrawBitmap },
1155 { "Test DrawBitmapAtPoint", testDrawBitmapAtPoint },
1156 { "Test DrawBitmapAtRect", testDrawBitmapAtRect },
1157 { "Test DrawLargeBitmap", testDrawLargeBitmap },
1158 { "Test ConstrainClippingRegion", testConstrainClippingRegion },
1159 { "Test ClipToPicture", testClipToPicture },
1160 { "Test ClipToInversePicture", testClipToInversePicture },
1161 { "Test ClipToRect", testClipToRect },
1162 { "Test ClipToInverseRect", testClipToInverseRect },
1163 { "Test ClipToShape", testClipToShape },
1164 { "Test ClipToInverseShape", testClipToInverseShape },
1165 { "Test SetPenSize", testSetPenSize },
1166 { "Test SetPenSize2", testSetPenSize2 },
1167 { "Test Pattern", testPattern },
1168 { "Test SetOrigin", testSetOrigin },
1169 { "Test SetOrigin2", testSetOrigin2 },
1170 { "Test SetScale", testSetScale },
1171 // testSetScale2 fails under BeOS. The picture versions of the
1172 // rectangle are twice as large as the direct draw version
1173 { "Test SetScale2", testSetScale2 },
1174 { "Test SetScale3", testSetScale3 },
1175 { "Test SetOriginAndScale", testSetOriginAndScale },
1176 { "Test SetOriginAndScale2", testSetOriginAndScale2 },
1177 { "Test SetOriginAndScale3", testSetOriginAndScale3 },
1178 { "Test SetOriginAndScale4", testSetOriginAndScale4 },
1179 { "Test SetOriginAndScale5", testSetOriginAndScale5 },
1180 { "Test SetFontSize", testSetFontSize },
1181 { "Test SetFontFamilyAndStyle", testSetFontFamilyAndStyle },
1182 { "Test SetDrawingMode", testSetDrawingMode },
1183 { "Test PushPopState", testPushPopState },
1184 { "Test FontRotation", testFontRotation },
1185 { NULL, NULL }
1186 };
1187
1188
1189