xref: /haiku/src/tests/kits/interface/flatten_picture/PictureTestCases.cpp (revision 7d6915b4d08ffe728cd38af02843d5e98ddfe0db)
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 <stdio.h>
12 
13 static const rgb_color kBlack = {0, 0, 0};
14 static const rgb_color kWhite = {255, 255, 255};
15 static const rgb_color kRed = {255, 0, 0};
16 static const rgb_color kGreen = {0, 255, 0};
17 static const rgb_color kBlue = {0, 0, 255};
18 
19 static BPoint centerPoint(BRect rect)
20 {
21 	int x = (int)(rect.left + rect.IntegerWidth() / 2);
22 	int y = (int)(rect.top + rect.IntegerHeight() / 2);
23 	return BPoint(x, y);
24 }
25 
26 static void testNoOp(BView *view, BRect frame)
27 {
28 	// no op
29 }
30 
31 static void testDrawChar(BView *view, BRect frame)
32 {
33 	view->MovePenTo(frame.left, frame.bottom - 5);
34 	view->DrawChar('A');
35 
36 	view->DrawChar('B', BPoint(frame.left + 20, frame.bottom - 5));
37 }
38 
39 static void testDrawString(BView *view, BRect frame)
40 {
41 	BFont font;
42 	view->GetFont(&font);
43 	font_height height;
44 	font.GetHeight(&height);
45 	float baseline = frame.bottom - height.descent;
46 	// draw base line
47 	view->SetHighColor(kGreen);
48 	view->StrokeLine(BPoint(frame.left, baseline - 1), BPoint(frame.right, baseline -1));
49 
50 	view->SetHighColor(kBlack);
51 	view->DrawString("Haiku [ÖÜÄöüä]", BPoint(frame.left, baseline));
52 }
53 
54 static void testDrawStringWithLength(BView *view, BRect frame)
55 {
56 	BFont font;
57 	view->GetFont(&font);
58 	font_height height;
59 	font.GetHeight(&height);
60 	float baseline = frame.bottom - height.descent;
61 	// draw base line
62 	view->SetHighColor(kGreen);
63 	view->StrokeLine(BPoint(frame.left, baseline - 1), BPoint(frame.right, baseline -1));
64 
65 	view->SetHighColor(kBlack);
66 	view->DrawString("Haiku [ÖÜÄöüä]", 13, BPoint(frame.left, baseline));
67 }
68 
69 static void testFillArc(BView *view, BRect frame)
70 {
71 	frame.InsetBy(2, 2);
72 	view->FillArc(frame, 45, 180);
73 }
74 
75 static void testStrokeArc(BView *view, BRect frame)
76 {
77 	frame.InsetBy(2, 2);
78 	view->StrokeArc(frame, 45, 180);
79 }
80 
81 static void testFillBezier(BView *view, BRect frame)
82 {
83 	frame.InsetBy(2, 2);
84 	BPoint points[4];
85 	points[0] = BPoint(frame.left, frame.bottom);
86 	points[1] = BPoint(frame.left, frame.top);
87 	points[1] = BPoint(frame.left, frame.top);
88 	points[3] = BPoint(frame.right, frame.top);
89 	view->FillBezier(points);
90 }
91 
92 static void testStrokeBezier(BView *view, BRect frame)
93 {
94 	frame.InsetBy(2, 2);
95 	BPoint points[4];
96 	points[0] = BPoint(frame.left, frame.bottom);
97 	points[1] = BPoint(frame.left, frame.top);
98 	points[1] = BPoint(frame.left, frame.top);
99 	points[3] = BPoint(frame.right, frame.top);
100 	view->StrokeBezier(points);
101 }
102 
103 static void testFillEllipse(BView *view, BRect frame)
104 {
105 	frame.InsetBy(2, 2);
106 	view->FillEllipse(frame);
107 
108 	view->SetHighColor(kRed);
109 	float r = frame.Width() / 3;
110 	float s = frame.Height() / 4;
111 	view->FillEllipse(centerPoint(frame), r, s);
112 }
113 
114 static void testStrokeEllipse(BView *view, BRect frame)
115 {
116 	frame.InsetBy(2, 2);
117 	view->StrokeEllipse(frame);
118 
119 	view->SetHighColor(kRed);
120 	float r = frame.Width() / 3;
121 	float s = frame.Height() / 4;
122 	view->StrokeEllipse(centerPoint(frame), r, s);
123 }
124 
125 static void testFillPolygon(BView *view, BRect frame)
126 {
127 	frame.InsetBy(2, 2);
128 
129 	BPoint points[4];
130 	points[0] = BPoint(frame.left, frame.top);
131 	points[1] = BPoint(frame.right, frame.bottom);
132 	points[2] = BPoint(frame.right, frame.top);
133 	points[3] = BPoint(frame.left, frame.bottom);
134 
135 	view->FillPolygon(points, 4);
136 }
137 
138 static void testStrokePolygon(BView *view, BRect frame)
139 {
140 	frame.InsetBy(2, 2);
141 
142 	BPoint points[4];
143 	points[0] = BPoint(frame.left, frame.top);
144 	points[1] = BPoint(frame.right, frame.bottom);
145 	points[2] = BPoint(frame.right, frame.top);
146 	points[3] = BPoint(frame.left, frame.bottom);
147 
148 	view->StrokePolygon(points, 4);
149 }
150 
151 static void testFillRect(BView *view, BRect frame)
152 {
153 	frame.InsetBy(2, 2);
154 	view->FillRect(frame);
155 }
156 
157 static void testStrokeRect(BView *view, BRect frame)
158 {
159 	frame.InsetBy(2, 2);
160 	view->StrokeRect(frame);
161 }
162 
163 static void testFillRegion(BView *view, BRect frame)
164 {
165 	frame.InsetBy(2, 2);
166 	BRegion region(frame);
167 	frame.InsetBy(2, 2);
168 	region.Exclude(frame);
169 	view->FillRegion(&region);
170 }
171 
172 static void testFillRoundRect(BView *view, BRect frame)
173 {
174 	frame.InsetBy(2, 2);
175 	view->FillRoundRect(frame, 5, 3);
176 }
177 
178 static void testStrokeRoundRect(BView *view, BRect frame)
179 {
180 	frame.InsetBy(2, 2);
181 	view->StrokeRoundRect(frame, 5, 3);
182 }
183 
184 static void testFillTriangle(BView *view, BRect frame)
185 {
186 	frame.InsetBy(2, 2);
187 	BPoint points[3];
188 	points[0] = BPoint(frame.left, frame.bottom);
189 	points[1] = BPoint(centerPoint(frame).x, frame.top);
190 	points[2] = BPoint(frame.right, frame.bottom);
191 	view->FillTriangle(points[0], points[1], points[2]);
192 }
193 
194 static void testStrokeTriangle(BView *view, BRect frame)
195 {
196 	frame.InsetBy(2, 2);
197 	BPoint points[3];
198 	points[0] = BPoint(frame.left, frame.bottom);
199 	points[1] = BPoint(centerPoint(frame).x, frame.top);
200 	points[2] = BPoint(frame.right, frame.bottom);
201 	view->StrokeTriangle(points[0], points[1], points[2]);
202 }
203 
204 static void testStrokeLine(BView *view, BRect frame)
205 {
206 	frame.InsetBy(2, 2);
207 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
208 
209 	frame.top += 2;
210 	frame.bottom -= 2;
211 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.bottom));
212 
213 	frame.bottom += 2;;
214 	frame.top = frame.bottom;
215 	view->StrokeLine(BPoint(frame.right, frame.top), BPoint(frame.left, frame.top));
216 }
217 
218 static void testFillShape(BView *view, BRect frame)
219 {
220 	frame.InsetBy(2, 2);
221 	BShape shape;
222 	shape.MoveTo(BPoint(frame.left, frame.bottom));
223 	shape.LineTo(BPoint(frame.right, frame.top));
224 	shape.LineTo(BPoint(frame.left, frame.top));
225 	shape.LineTo(BPoint(frame.right, frame.bottom));
226 	view->FillShape(&shape);
227 }
228 
229 static void testStrokeShape(BView *view, BRect frame)
230 {
231 	frame.InsetBy(2, 2);
232 	BShape shape;
233 	shape.MoveTo(BPoint(frame.left, frame.bottom));
234 	shape.LineTo(BPoint(frame.right, frame.top));
235 	shape.LineTo(BPoint(frame.left, frame.top));
236 	shape.LineTo(BPoint(frame.right, frame.bottom));
237 	view->StrokeShape(&shape);
238 }
239 
240 static void testRecordPicture(BView *view, BRect frame)
241 {
242 	BPicture *picture = new BPicture();
243 	view->BeginPicture(picture);
244 	view->FillRect(frame);
245 	view->EndPicture();
246 	delete picture;
247 }
248 
249 static void testRecordAndPlayPicture(BView *view, BRect frame)
250 {
251 	BPicture *picture = new BPicture();
252 	view->BeginPicture(picture);
253 	frame.InsetBy(2, 2);
254 	view->FillRect(frame);
255 	view->EndPicture();
256 	view->DrawPicture(picture);
257 	delete picture;
258 }
259 
260 static void testRecordAndPlayPictureWithOffset(BView *view, BRect frame)
261 {
262 	BPicture *picture = new BPicture();
263 	view->BeginPicture(picture);
264 	frame.InsetBy(frame.Width() / 4, frame.Height() / 4);
265 	frame.OffsetTo(0, 0);
266 	view->FillRect(frame);
267 	view->EndPicture();
268 
269 	view->DrawPicture(picture, BPoint(10, 10));
270 	// color of picture should not change
271 	view->SetLowColor(kGreen);
272 	view->SetLowColor(kRed);
273 	view->DrawPicture(picture, BPoint(0, 0));
274 	delete picture;
275 }
276 
277 static void testAppendToPicture(BView *view, BRect frame)
278 {
279 	frame.InsetBy(2, 2);
280 	view->BeginPicture(new BPicture());
281 	view->FillRect(frame);
282 	BPicture* picture = view->EndPicture();
283 	if (picture == NULL)
284 		return;
285 
286 	frame.InsetBy(2, 2);
287 	view->AppendToPicture(picture);
288 	view->SetHighColor(kRed);
289 	view->FillRect(frame);
290 	if (view->EndPicture() != picture)
291 		return;
292 
293 	view->DrawPicture(picture);
294 	delete picture;
295 }
296 
297 static void testDrawScaledPicture(BView* view, BRect frame)
298 {
299 	view->BeginPicture(new BPicture());
300 	view->FillRect(BRect(0, 0, 15, 15));
301 	BPicture* picture = view->EndPicture();
302 
303 	// first unscaled at left, top
304 	view->DrawPicture(picture, BPoint(2, 2));
305 
306 	// draw scaled at middle top
307 	view->SetScale(0.5);
308 	// the drawing offset must be scaled too!
309 	view->DrawPicture(picture, BPoint(frame.Width(), 4));
310 
311 	delete picture;
312 }
313 
314 static void testLineArray(BView *view, BRect frame)
315 {
316 	frame.InsetBy(2, 2);
317 	view->BeginLineArray(3);
318 	view->AddLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top), kBlack);
319 
320 	frame.top += 2;
321 	frame.bottom -= 2;
322 	view->AddLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.bottom), kRed);
323 
324 	frame.bottom += 2;;
325 	frame.top = frame.bottom;
326 	view->AddLine(BPoint(frame.right, frame.top), BPoint(frame.left, frame.top), kGreen);
327 
328 	view->EndLineArray();
329 }
330 
331 static void testInvertRect(BView *view, BRect frame)
332 {
333 	frame.InsetBy(2, 2);
334 	view->InvertRect(frame);
335 }
336 
337 static bool isBorder(int32 x, int32 y, int32 width, int32 height) {
338 	return x == 0 || y == 0 || x == width - 1 || y == height - 1;
339 }
340 
341 static void fillBitmap(BBitmap &bitmap) {
342 	int32 height = bitmap.Bounds().IntegerHeight()+1;
343 	int32 width = bitmap.Bounds().IntegerWidth()+1;
344 	for (int32 y = 0; y < height; y ++) {
345 		for (int32 x = 0; x < width; x ++) {
346 			char *pixel = (char*)bitmap.Bits();
347 			pixel += bitmap.BytesPerRow() * y + 4 * x;
348 			if (isBorder(x, y, width, height)) {
349 				// fill with green
350 				pixel[0] = 255;
351 				pixel[1] = 0;
352 				pixel[2] = 255;
353 				pixel[3] = 0;
354 			} else  {
355 				// fill with blue
356 				pixel[0] = 255;
357 				pixel[1] = 0;
358 				pixel[2] = 0;
359 				pixel[3] = 255;
360 			}
361 		}
362 	}
363 }
364 
365 static void testDrawBitmap(BView *view, BRect frame) {
366 	BBitmap bitmap(frame, B_RGBA32);
367 	fillBitmap(bitmap);
368 	view->DrawBitmap(&bitmap, BPoint(0, 0));
369 }
370 
371 static void testDrawBitmapAtPoint(BView *view, BRect frame) {
372 	frame.InsetBy(2, 2);
373 
374 	BRect bounds(frame);
375 	bounds.OffsetTo(0, 0);
376 	bounds.right /= 2;
377 	bounds.bottom /= 2;
378 
379 	BBitmap bitmap(bounds, B_RGBA32);
380 	fillBitmap(bitmap);
381 	view->DrawBitmap(&bitmap, centerPoint(frame));
382 }
383 
384 static void testDrawBitmapAtRect(BView *view, BRect frame) {
385 	BRect bounds(frame);
386 	BBitmap bitmap(bounds, B_RGBA32);
387 	fillBitmap(bitmap);
388 	frame.InsetBy(2, 2);
389 	view->DrawBitmap(&bitmap, frame);
390 }
391 
392 static void testDrawLargeBitmap(BView *view, BRect frame) {
393 	BRect bounds(frame);
394 	bounds.OffsetTo(0, 0);
395 	bounds.right *= 4;
396 	bounds.bottom *= 4;
397 	BBitmap bitmap(bounds, B_RGBA32);
398 	fillBitmap(bitmap);
399 	frame.InsetBy(2, 2);
400 	view->DrawBitmap(&bitmap, frame);
401 }
402 
403 static void testConstrainClippingRegion(BView *view, BRect frame)
404 {
405 	frame.InsetBy(2, 2);
406 	// draw background
407 	view->SetHighColor(kRed);
408 	view->FillRect(frame);
409 
410 	frame.InsetBy(1, 1);
411 	BRegion region(frame);
412 	BRect r(frame);
413 	r.InsetBy(r.IntegerWidth() / 4, r.IntegerHeight() / 4);
414 	region.Exclude(r);
415 	view->ConstrainClippingRegion(&region);
416 
417 	frame.InsetBy(-1, -1);
418 	view->SetHighColor(kBlack);
419 	view->FillRect(frame);
420 	// a filled black rectangle with a red one pixel border
421 	// and inside a red rectangle should be drawn.
422 }
423 
424 static void testClipToPicture(BView *view, BRect frame)
425 {
426 	frame.InsetBy(2, 2);
427 	view->BeginPicture(new BPicture());
428 	view->FillEllipse(frame);
429 	BPicture *picture = view->EndPicture();
430 	if (picture == NULL)
431 		return;
432 
433 	view->ClipToPicture(picture);
434 	delete picture;
435 
436 	view->FillRect(frame);
437 	// black ellipse should be drawn
438 }
439 
440 static void testClipToInversePicture(BView *view, BRect frame)
441 {
442 	frame.InsetBy(2, 2);
443 
444 	view->BeginPicture(new BPicture());
445 	view->FillEllipse(frame);
446 	BPicture *picture = view->EndPicture();
447 	if (picture == NULL)
448 		return;
449 
450 	view->ClipToInversePicture(picture);
451 	delete picture;
452 
453 	view->FillRect(frame);
454 	// white ellipse inside a black rectangle
455 }
456 
457 static void testSetPenSize(BView *view, BRect frame)
458 {
459 	frame.InsetBy(8, 2);
460 	float x = centerPoint(frame).x;
461 
462 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
463 
464 	frame.OffsetBy(0, 5);
465 	view->SetPenSize(1);
466 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
467 	view->SetPenSize(0);
468 	view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
469 
470 	frame.OffsetBy(0, 5);
471 	view->SetPenSize(1);
472 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
473 	view->SetPenSize(2);
474 	view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
475 
476 	frame.OffsetBy(0, 5);
477 	view->SetPenSize(1);
478 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
479 	view->SetPenSize(3);
480 	view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
481 
482 	frame.OffsetBy(0, 5);
483 	view->SetPenSize(1);
484 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(x, frame.top));
485 	view->SetPenSize(4);
486 	view->StrokeLine(BPoint(x+1, frame.top), BPoint(frame.right, frame.top));
487 }
488 
489 static void testSetPenSize2(BView *view, BRect frame)
490 {
491 	// test if pen size is scaled too
492 	frame.InsetBy(2, 2);
493 	frame.OffsetBy(0, 5);
494 	view->SetPenSize(4);
495 	view->StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
496 	view->SetScale(0.5);
497 	view->StrokeLine(BPoint(frame.left + 2, frame.bottom), BPoint(frame.right + 2, frame.bottom));
498 
499 	// black line from left to right, 4 pixel size
500 	// below black line with half the length of the first one
501 	// and 2 pixel size
502 }
503 
504 static void testPattern(BView *view, BRect frame)
505 {
506 	frame.InsetBy(2, 2);
507 	int x = frame.IntegerWidth() / 3;
508 	frame.right = frame.left + x - 2;
509 		// -2 for an empty pixel row between
510 		// filled rectangles
511 
512 	view->SetLowColor(kGreen);
513 	view->SetHighColor(kRed);
514 
515 	view->FillRect(frame, B_SOLID_HIGH);
516 
517 	frame.OffsetBy(x, 0);
518 	view->FillRect(frame, B_MIXED_COLORS);
519 
520 	frame.OffsetBy(x, 0);
521 	view->FillRect(frame, B_SOLID_LOW);
522 }
523 
524 static void testSetOrigin(BView *view, BRect frame)
525 {
526 	BPoint origin = view->Origin();
527 	BPoint center = centerPoint(frame);
528 	view->SetOrigin(center);
529 
530 	BRect r(0, 0, center.x, center.y);
531 	view->SetHighColor(kBlue);
532 	view->FillRect(r);
533 
534 	view->SetOrigin(origin);
535 	view->SetHighColor(kRed);
536 	view->FillRect(r);
537 
538 	// red rectangle in left, top corner
539 	// blue rectangle in right, bottom corner
540 	// the red rectangle overwrites the
541 	// top, left pixel of the blue rectangle
542 }
543 
544 static void testSetOrigin2(BView *view, BRect frame)
545 {
546 	BPoint center = centerPoint(frame);
547 	BRect r(0, 0, center.x, center.y);
548 	view->SetOrigin(center);
549 	view->PushState();
550 		view->SetOrigin(BPoint(-center.x, 0));
551 		view->FillRect(r);
552 	view->PopState();
553 	// black rectangle in left, bottom corner
554 }
555 
556 static void testSetScale(BView *view, BRect frame)
557 {
558 	view->SetScale(0.5);
559 	view->FillRect(frame);
560 	// black rectangle in left, top corner
561 }
562 
563 static void testSetScale2(BView *view, BRect frame)
564 {
565 	view->SetScale(0.5);
566 	view->PushState();
567 		view->SetScale(0.5);
568 		view->FillRect(frame);
569 	view->PopState();
570 	// black rectangle in left, top corner
571 	// with half the size of the rectangle
572 	// from test testSetScaling
573 }
574 
575 static void testSetScale3(BView *view, BRect frame)
576 {
577 	view->SetScale(0.5);
578 	view->PushState();
579 		// if the second scale value differs slightly
580 		// the bug under BeOS R5 in testSetScale2
581 		// does not occur
582 		view->SetScale(0.5000001);
583 		view->FillRect(frame);
584 	view->PopState();
585 	// black rectangle in left, top corner
586 	// with half the size of the rectangle
587 	// from test testSetScaling
588 }
589 
590 static void testSetOriginAndScale(BView *view, BRect frame)
591 {
592 	frame.InsetBy(2, 2);
593 	BPoint center = centerPoint(frame);
594 
595 	BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
596 	view->SetOrigin(center);
597 	view->FillRect(r);
598 
599 	view->SetScale(0.5);
600 	view->SetHighColor(kRed);
601 	view->FillRect(r);
602 }
603 
604 static void testSetOriginAndScale2(BView *view, BRect frame)
605 {
606 	frame.InsetBy(2, 2);
607 	BPoint center = centerPoint(frame);
608 
609 	BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
610 	view->SetOrigin(center);
611 	view->FillRect(r);
612 
613 	view->SetScale(0.5);
614 	view->SetHighColor(kRed);
615 	view->FillRect(r);
616 
617 	view->SetOrigin(0, 0);
618 	view->SetHighColor(kGreen);
619 	view->FillRect(r);
620 }
621 
622 static void testSetOriginAndScale3(BView *view, BRect frame)
623 {
624 	frame.InsetBy(2, 2);
625 	BPoint center = centerPoint(frame);
626 
627 	BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
628 	view->SetOrigin(center);
629 	view->FillRect(r);
630 
631 	view->SetScale(0.5);
632 	view->SetHighColor(kRed);
633 	view->FillRect(r);
634 
635 	view->SetScale(0.25);
636 	view->SetHighColor(kGreen);
637 	view->FillRect(r);
638 }
639 
640 static void testSetOriginAndScale4(BView *view, BRect frame)
641 {
642 	frame.InsetBy(2, 2);
643 	BPoint center = centerPoint(frame);
644 
645 	BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
646 	view->SetOrigin(center);
647 	view->FillRect(r);
648 
649 	view->SetScale(0.5);
650 	view->SetHighColor(kRed);
651 	view->FillRect(r);
652 
653 	view->PushState();
654 		//
655 		view->SetOrigin(center.x+1, center.y);
656 			// +1 to work around BeOS bug
657 			// where setting the origin has no
658 			// effect if it is the same as
659 			// the previous value althou
660 			// it is from the "outer" coordinate
661 			// system
662 		view->SetHighColor(kGreen);
663 		view->FillRect(r);
664 	view->PopState();
665 }
666 
667 static void testSetOriginAndScale5(BView *view, BRect frame)
668 {
669 	frame.InsetBy(2, 2);
670 	BPoint center = centerPoint(frame);
671 
672 	BRect r(0, 0, frame.IntegerWidth() / 2, frame.IntegerHeight() / 2);
673 	view->SetOrigin(center);
674 	view->FillRect(r);
675 
676 	view->SetScale(0.5);
677 	view->SetHighColor(kRed);
678 	view->FillRect(r);
679 
680 	view->PushState();
681 		view->SetScale(0.75);
682 		view->SetHighColor(kGreen);
683 		view->FillRect(r);
684 	view->PopState();
685 }
686 
687 static void testSetFontSize(BView *view, BRect frame)
688 {
689 	frame.InsetBy(2, 2);
690 	int size = frame.IntegerHeight() / 3;
691 
692 	frame.OffsetBy(0, size);
693 	view->MovePenTo(BPoint(frame.left, frame.top));
694 	view->SetFontSize(size);
695 	view->DrawString("Haiku");
696 
697 	size *= 2;
698 	frame.OffsetBy(0, size);
699 	view->MovePenTo(BPoint(frame.left, frame.top));
700 	view->SetFontSize(size);
701 	view->DrawString("Haiku");
702 }
703 
704 static void testSetFontFamilyAndStyle(BView *view, BRect frame)
705 {
706 	view->DrawString("This is a test", BPoint(2, 6));
707 
708 	BFont font;
709 	view->GetFont(&font);
710 
711 	int32 families = count_font_families();
712 	font_family familyName;
713 	get_font_family(families - 1, &familyName);
714 
715 	int32 styles = count_font_styles(familyName);
716 	font_style styleName;
717 	get_font_style(familyName, styles - 1, &styleName);
718 	font.SetFamilyAndStyle(familyName, styleName);
719 	view->SetFont(&font);
720 	view->DrawString( "This is a test", BPoint(2, 19));
721 }
722 
723 static void testSetDrawingMode(BView *view, BRect frame)
724 {
725 	frame.InsetBy(2, 2);
726 	view->StrokeLine(frame.LeftTop(), frame.RightBottom());
727 	view->StrokeLine(frame.LeftBottom(), frame.RightTop());
728 	view->SetDrawingMode(B_OP_ALPHA);
729 	rgb_color color = kRed;
730 	color.alpha = 127;
731 	view->SetHighColor(color);
732 	view->FillRect(frame, B_SOLID_HIGH);
733 }
734 
735 static void testPushPopState(BView *view, BRect frame)
736 {
737 	frame.InsetBy(2, 2);
738 	view->SetHighColor(kGreen);
739 	view->PushState();
740 	view->SetHighColor(kRed);
741 	view->PopState();
742 
743 	view->FillRect(frame, B_SOLID_HIGH);
744 }
745 
746 static void testFontRotation(BView* view, BRect frame)
747 {
748 	BFont font;
749 	view->GetFont(&font);
750 
751 	font.SetRotation(90);
752 	view->SetFont(&font, B_FONT_ROTATION);
753 	view->DrawString("This is a test!", BPoint(frame.Width() / 2, frame.bottom - 3));
754 
755 	view->GetFont(&font);
756 	if (font.Rotation() != 90.0)
757 		fprintf(stderr, "Error: Rotation is %f but should be 90.0\n", font.Rotation());
758 }
759 
760 // TODO
761 // - blending mode
762 // - line mode
763 // - push/pop state
764 // - move pen
765 // - set font
766 
767 
768 TestCase gTestCases[] = {
769 	{ "Test No Operation", testNoOp },
770 	{ "Test DrawChar", testDrawChar },
771 	{ "Test Draw String", testDrawString },
772 	{ "Test Draw String With Length", testDrawStringWithLength },
773 	{ "Test FillArc", testFillArc },
774 	{ "Test StrokeArc", testStrokeArc },
775 	// testFillBezier fails under BeOS because the
776 	// direct draw version is not correct
777 	{ "Test FillBezier", testFillBezier },
778 	{ "Test StrokeBezier", testStrokeBezier },
779 	{ "Test FillEllipse", testFillEllipse },
780 	{ "Test StrokeEllipse", testStrokeEllipse },
781 	{ "Test FillPolygon", testFillPolygon },
782 	{ "Test StrokePolygon", testStrokePolygon },
783 	{ "Test FillRect", testFillRect },
784 	{ "Test StrokeRect", testStrokeRect },
785 	{ "Test FillRegion", testFillRegion },
786 	{ "Test FillRoundRect", testFillRoundRect },
787 	{ "Test StrokeRoundRect", testStrokeRoundRect },
788 	{ "Test FillTriangle", testFillTriangle },
789 	{ "Test StrokeTriangle", testStrokeTriangle },
790 	{ "Test StrokeLine", testStrokeLine },
791 	{ "Test FillShape", testFillShape },
792 	{ "Test StrokeShape", testStrokeShape },
793 	{ "Test Record Picture", testRecordPicture },
794 	{ "Test Record And Play Picture", testRecordAndPlayPicture },
795 	{ "Test Record And Play Picture With Offset", testRecordAndPlayPictureWithOffset },
796 	{ "Test AppendToPicture", testAppendToPicture },
797 	{ "Test Draw Scaled Picture", testDrawScaledPicture },
798 	{ "Test LineArray", testLineArray },
799 	{ "Test InvertRect", testInvertRect },
800 	{ "Test DrawBitmap", testDrawBitmap },
801 	{ "Test DrawBitmapAtPoint", testDrawBitmapAtPoint },
802 	{ "Test DrawBitmapAtRect", testDrawBitmapAtRect },
803 	{ "Test DrawLargeBitmap", testDrawLargeBitmap },
804 	{ "Test ConstrainClippingRegion", testConstrainClippingRegion },
805 	{ "Test ClipToPicture", testClipToPicture },
806 	{ "Test ClipToInversePicture", testClipToInversePicture },
807 	{ "Test SetPenSize", testSetPenSize },
808 	{ "Test SetPenSize2", testSetPenSize2 },
809 	{ "Test Pattern", testPattern },
810 	{ "Test SetOrigin", testSetOrigin },
811 	{ "Test SetOrigin2", testSetOrigin2 },
812 	{ "Test SetScale", testSetScale },
813 	// testSetScale2 fails under BeOS. The picture versions of the
814 	// rectangle are twice as large as the direct draw version
815 	{ "Test SetScale2*", testSetScale2 },
816 	{ "Test SetScale3", testSetScale3 },
817 	{ "Test SetOriginAndScale", testSetOriginAndScale },
818 	{ "Test SetOriginAndScale2", testSetOriginAndScale2 },
819 	{ "Test SetOriginAndScale3", testSetOriginAndScale3 },
820 	{ "Test SetOriginAndScale4", testSetOriginAndScale4 },
821 	{ "Test SetOriginAndScale5", testSetOriginAndScale5 },
822 	{ "Test SetFontSize", testSetFontSize },
823 	{ "Test SetFontFamilyAndStyle", testSetFontFamilyAndStyle },
824 	{ "Test SetDrawingMode", testSetDrawingMode },
825 	{ "Test PushPopState", testPushPopState },
826 	{ "Test FontRotation", testFontRotation },
827 	{ NULL, NULL }
828 };
829 
830 
831