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 19static const rgb_color kBlack = {0, 0, 0}; 20static const rgb_color kWhite = {255, 255, 255}; 21static const rgb_color kRed = {255, 0, 0}; 22static const rgb_color kGreen = {0, 255, 0}; 23static const rgb_color kBlue = {0, 0, 255}; 24 25static 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 32static void testNoOp(BView *view, BRect frame) 33{ 34 // no op 35} 36 37static 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 45static 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 60static 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 76static 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 104static 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 125static void testFillArc(BView *view, BRect frame) 126{ 127 frame.InsetBy(2, 2); 128 view->FillArc(frame, 45, 180); 129} 130 131static void testStrokeArc(BView *view, BRect frame) 132{ 133 frame.InsetBy(2, 2); 134 view->StrokeArc(frame, 45, 180); 135} 136 137static 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 148static 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 159static 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 170static 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 181static 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 194static 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 207static void testFillRect(BView *view, BRect frame) 208{ 209 frame.InsetBy(2, 2); 210 view->FillRect(frame); 211} 212 213static 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 222static 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 231static 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 240static 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 249static 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 258static void testStrokeRect(BView *view, BRect frame) 259{ 260 frame.InsetBy(2, 2); 261 view->StrokeRect(frame); 262} 263 264static 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 273static 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 285static 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 297static 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 309static 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 321static 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 333static void testFillRoundRect(BView *view, BRect frame) 334{ 335 frame.InsetBy(2, 2); 336 view->FillRoundRect(frame, 5, 3); 337} 338 339static 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 348static 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 357static 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 365static 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 374static 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 383static void testStrokeRoundRect(BView *view, BRect frame) 384{ 385 frame.InsetBy(2, 2); 386 view->StrokeRoundRect(frame, 5, 3); 387} 388 389static 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 399static 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 412static 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 425static 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 438static 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 451static 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 464static 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 474static 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 488static 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 499static 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 510static 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 519static 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 530static 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 547static 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 567static 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 584static 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 601static void testInvertRect(BView *view, BRect frame) 602{ 603 frame.InsetBy(2, 2); 604 view->InvertRect(frame); 605} 606 607static 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 617static bool isBorder(int32 x, int32 y, int32 width, int32 height) { 618 return x == 0 || y == 0 || x == width - 1 || y == height - 1; 619} 620 621static 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 645static void testDrawBitmap(BView *view, BRect frame) { 646 BBitmap bitmap(frame, B_RGBA32); 647 fillBitmap(bitmap); 648 view->DrawBitmap(&bitmap, BPoint(0, 0)); 649} 650 651static 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 664static 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 672static 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 683static 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 704static 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 720static 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 737static 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 769static 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 784static 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 804static 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 824static 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 836static 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 843static 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 855static 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 870static 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 884static 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 902static 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 920static 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 947static 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 967static 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 984static 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 1003static 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 1015static 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 1026static 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 1041static 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 1052static 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 1063static 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 1077static 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 1099TestCase 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