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
13static const rgb_color kBlack = {0, 0, 0};
14static const rgb_color kWhite = {255, 255, 255};
15static const rgb_color kRed = {255, 0, 0};
16static const rgb_color kGreen = {0, 255, 0};
17static const rgb_color kBlue = {0, 0, 255};
18
19static 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
26static void testNoOp(BView *view, BRect frame)
27{
28	// no op
29}
30
31static 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
39static 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
54static 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
69static void testFillArc(BView *view, BRect frame)
70{
71	frame.InsetBy(2, 2);
72	view->FillArc(frame, 45, 180);
73}
74
75static void testStrokeArc(BView *view, BRect frame)
76{
77	frame.InsetBy(2, 2);
78	view->StrokeArc(frame, 45, 180);
79}
80
81static 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
92static 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
103static 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
114static 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
125static 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
138static 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
151static void testFillRect(BView *view, BRect frame)
152{
153	frame.InsetBy(2, 2);
154	view->FillRect(frame);
155}
156
157static void testStrokeRect(BView *view, BRect frame)
158{
159	frame.InsetBy(2, 2);
160	view->StrokeRect(frame);
161}
162
163static 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
172static void testFillRoundRect(BView *view, BRect frame)
173{
174	frame.InsetBy(2, 2);
175	view->FillRoundRect(frame, 5, 3);
176}
177
178static void testStrokeRoundRect(BView *view, BRect frame)
179{
180	frame.InsetBy(2, 2);
181	view->StrokeRoundRect(frame, 5, 3);
182}
183
184static 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
194static 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
204static 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
218static 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
229static 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
240static 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
249static 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
260static 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
277static 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
297static 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
314static 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
331static void testInvertRect(BView *view, BRect frame)
332{
333	frame.InsetBy(2, 2);
334	view->InvertRect(frame);
335}
336
337static bool isBorder(int32 x, int32 y, int32 width, int32 height) {
338	return x == 0 || y == 0 || x == width - 1 || y == height - 1;
339}
340
341static 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
365static void testDrawBitmap(BView *view, BRect frame) {
366	BBitmap bitmap(frame, B_RGBA32);
367	fillBitmap(bitmap);
368	view->DrawBitmap(&bitmap, BPoint(0, 0));
369}
370
371static 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
384static 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
392static 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
403static 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
424static 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
440static 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
457static 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
489static 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
504static 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
524static 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
544static 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
556static 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
563static 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
575static 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
590static 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
604static 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
622static 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
640static 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
667static 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
687static 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
704static 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
723static 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
735static 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
746static 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
768TestCase 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