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