1 /* 2 * Copyright 2001-2018, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * Adi Oanca <adioanca@mymail.ro> 8 * Stephan Aßmus <superstippi@gmx.de> 9 * Axel Dörfler, axeld@pinc-software.de 10 * Michael Pfeiffer <laplace@users.sourceforge.net> 11 * Julian Harnath <julian.harnath@rwth-aachen.de> 12 * Joseph Groover <looncraz@looncraz.net> 13 */ 14 15 //! Data classes for working with BView states and draw parameters 16 17 #include "DrawState.h" 18 19 #include <new> 20 #include <stdio.h> 21 22 #include <Region.h> 23 #include <ShapePrivate.h> 24 25 #include "AlphaMask.h" 26 #include "LinkReceiver.h" 27 #include "LinkSender.h" 28 #include "ServerProtocolStructs.h" 29 30 31 using std::nothrow; 32 33 34 DrawState::DrawState() 35 : 36 fOrigin(0.0f, 0.0f), 37 fCombinedOrigin(0.0f, 0.0f), 38 fScale(1.0f), 39 fCombinedScale(1.0f), 40 fTransform(), 41 fCombinedTransform(), 42 fClippingRegion(NULL), 43 fAlphaMask(NULL), 44 45 fHighColor((rgb_color){ 0, 0, 0, 255 }), 46 fLowColor((rgb_color){ 255, 255, 255, 255 }), 47 fWhichHighColor(B_NO_COLOR), 48 fWhichLowColor(B_NO_COLOR), 49 fWhichHighColorTint(B_NO_TINT), 50 fWhichLowColorTint(B_NO_TINT), 51 fPattern(kSolidHigh), 52 53 fDrawingMode(B_OP_COPY), 54 fAlphaSrcMode(B_PIXEL_ALPHA), 55 fAlphaFncMode(B_ALPHA_OVERLAY), 56 fDrawingModeLocked(false), 57 58 fPenLocation(0.0f, 0.0f), 59 fPenSize(1.0f), 60 61 fFontAliasing(false), 62 fSubPixelPrecise(false), 63 fLineCapMode(B_BUTT_CAP), 64 fLineJoinMode(B_MITER_JOIN), 65 fMiterLimit(B_DEFAULT_MITER_LIMIT), 66 fFillRule(B_NONZERO), 67 fPreviousState(NULL) 68 { 69 fUnscaledFontSize = fFont.Size(); 70 } 71 72 73 DrawState::DrawState(const DrawState& other) 74 : 75 fOrigin(other.fOrigin), 76 fCombinedOrigin(other.fCombinedOrigin), 77 fScale(other.fScale), 78 fCombinedScale(other.fCombinedScale), 79 fTransform(other.fTransform), 80 fCombinedTransform(other.fCombinedTransform), 81 fClippingRegion(NULL), 82 fAlphaMask(NULL), 83 84 fHighColor(other.fHighColor), 85 fLowColor(other.fLowColor), 86 fWhichHighColor(other.fWhichHighColor), 87 fWhichLowColor(other.fWhichLowColor), 88 fWhichHighColorTint(other.fWhichHighColorTint), 89 fWhichLowColorTint(other.fWhichLowColorTint), 90 fPattern(other.fPattern), 91 92 fDrawingMode(other.fDrawingMode), 93 fAlphaSrcMode(other.fAlphaSrcMode), 94 fAlphaFncMode(other.fAlphaFncMode), 95 fDrawingModeLocked(other.fDrawingModeLocked), 96 97 fPenLocation(other.fPenLocation), 98 fPenSize(other.fPenSize), 99 100 fFont(other.fFont), 101 fFontAliasing(other.fFontAliasing), 102 103 fSubPixelPrecise(other.fSubPixelPrecise), 104 105 fLineCapMode(other.fLineCapMode), 106 fLineJoinMode(other.fLineJoinMode), 107 fMiterLimit(other.fMiterLimit), 108 fFillRule(other.fFillRule), 109 110 // Since fScale is reset to 1.0, the unscaled 111 // font size is the current size of the font 112 // (which is from->fUnscaledFontSize * from->fCombinedScale) 113 fUnscaledFontSize(other.fUnscaledFontSize), 114 fPreviousState(NULL) 115 { 116 } 117 118 119 DrawState::~DrawState() 120 { 121 delete fClippingRegion; 122 delete fPreviousState; 123 } 124 125 126 DrawState* 127 DrawState::PushState() 128 { 129 DrawState* next = new (nothrow) DrawState(*this); 130 131 if (next != NULL) { 132 // Prepare state as derived from this state 133 next->fOrigin = BPoint(0.0, 0.0); 134 next->fScale = 1.0; 135 next->fTransform.Reset(); 136 next->fPreviousState = this; 137 next->SetAlphaMask(fAlphaMask); 138 } 139 140 return next; 141 } 142 143 144 DrawState* 145 DrawState::PopState() 146 { 147 DrawState* previous = PreviousState(); 148 149 fPreviousState = NULL; 150 delete this; 151 152 return previous; 153 } 154 155 156 uint16 157 DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link) 158 { 159 uint16 mask; 160 link.Read<uint16>(&mask); 161 162 if ((mask & B_FONT_FAMILY_AND_STYLE) != 0) { 163 uint32 fontID; 164 link.Read<uint32>(&fontID); 165 fFont.SetFamilyAndStyle(fontID); 166 } 167 168 if ((mask & B_FONT_SIZE) != 0) { 169 float size; 170 link.Read<float>(&size); 171 fUnscaledFontSize = size; 172 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 173 } 174 175 if ((mask & B_FONT_SHEAR) != 0) { 176 float shear; 177 link.Read<float>(&shear); 178 fFont.SetShear(shear); 179 } 180 181 if ((mask & B_FONT_ROTATION) != 0) { 182 float rotation; 183 link.Read<float>(&rotation); 184 fFont.SetRotation(rotation); 185 } 186 187 if ((mask & B_FONT_FALSE_BOLD_WIDTH) != 0) { 188 float falseBoldWidth; 189 link.Read<float>(&falseBoldWidth); 190 fFont.SetFalseBoldWidth(falseBoldWidth); 191 } 192 193 if ((mask & B_FONT_SPACING) != 0) { 194 uint8 spacing; 195 link.Read<uint8>(&spacing); 196 fFont.SetSpacing(spacing); 197 } 198 199 if ((mask & B_FONT_ENCODING) != 0) { 200 uint8 encoding; 201 link.Read<uint8>(&encoding); 202 fFont.SetEncoding(encoding); 203 } 204 205 if ((mask & B_FONT_FACE) != 0) { 206 uint16 face; 207 link.Read<uint16>(&face); 208 fFont.SetFace(face); 209 } 210 211 if ((mask & B_FONT_FLAGS) != 0) { 212 uint32 flags; 213 link.Read<uint32>(&flags); 214 fFont.SetFlags(flags); 215 } 216 217 return mask; 218 } 219 220 221 void 222 DrawState::ReadFromLink(BPrivate::LinkReceiver& link) 223 { 224 ViewSetStateInfo info; 225 226 link.Read<ViewSetStateInfo>(&info); 227 228 // BAffineTransform is transmitted as a double array 229 double transform[6]; 230 link.Read<double[6]>(&transform); 231 if (fTransform.Unflatten(B_AFFINE_TRANSFORM_TYPE, transform, 232 sizeof(transform)) != B_OK) { 233 return; 234 } 235 236 fPenLocation = info.penLocation; 237 fPenSize = info.penSize; 238 fHighColor = info.highColor; 239 fLowColor = info.lowColor; 240 fWhichHighColor = info.whichHighColor; 241 fWhichLowColor = info.whichLowColor; 242 fWhichHighColorTint = info.whichHighColorTint; 243 fWhichLowColorTint = info.whichLowColorTint; 244 fPattern = info.pattern; 245 fDrawingMode = info.drawingMode; 246 fOrigin = info.origin; 247 fScale = info.scale; 248 fLineJoinMode = info.lineJoin; 249 fLineCapMode = info.lineCap; 250 fMiterLimit = info.miterLimit; 251 fFillRule = info.fillRule; 252 fAlphaSrcMode = info.alphaSourceMode; 253 fAlphaFncMode = info.alphaFunctionMode; 254 fFontAliasing = info.fontAntialiasing; 255 256 if (fPreviousState != NULL) { 257 fCombinedOrigin = fPreviousState->fCombinedOrigin + fOrigin; 258 fCombinedScale = fPreviousState->fCombinedScale * fScale; 259 fCombinedTransform = fPreviousState->fCombinedTransform * fTransform; 260 } else { 261 fCombinedOrigin = fOrigin; 262 fCombinedScale = fScale; 263 fCombinedTransform = fTransform; 264 } 265 266 267 // read clipping 268 // TODO: This could be optimized, but the user clipping regions are rarely 269 // used, so it's low priority... 270 int32 clipRectCount; 271 link.Read<int32>(&clipRectCount); 272 273 if (clipRectCount >= 0) { 274 BRegion region; 275 BRect rect; 276 for (int32 i = 0; i < clipRectCount; i++) { 277 link.Read<BRect>(&rect); 278 region.Include(rect); 279 } 280 SetClippingRegion(®ion); 281 } else { 282 // No user clipping used 283 SetClippingRegion(NULL); 284 } 285 } 286 287 288 void 289 DrawState::WriteToLink(BPrivate::LinkSender& link) const 290 { 291 // Attach font state 292 ViewGetStateInfo info; 293 info.fontID = fFont.GetFamilyAndStyle(); 294 info.fontSize = fFont.Size(); 295 info.fontShear = fFont.Shear(); 296 info.fontRotation = fFont.Rotation(); 297 info.fontFalseBoldWidth = fFont.FalseBoldWidth(); 298 info.fontSpacing = fFont.Spacing(); 299 info.fontEncoding = fFont.Encoding(); 300 info.fontFace = fFont.Face(); 301 info.fontFlags = fFont.Flags(); 302 303 // Attach view state 304 info.viewStateInfo.penLocation = fPenLocation; 305 info.viewStateInfo.penSize = fPenSize; 306 info.viewStateInfo.highColor = fHighColor; 307 info.viewStateInfo.lowColor = fLowColor; 308 info.viewStateInfo.whichHighColor = fWhichHighColor; 309 info.viewStateInfo.whichLowColor = fWhichLowColor; 310 info.viewStateInfo.whichHighColorTint = fWhichHighColorTint; 311 info.viewStateInfo.whichLowColorTint = fWhichLowColorTint; 312 info.viewStateInfo.pattern = (::pattern)fPattern.GetPattern(); 313 info.viewStateInfo.drawingMode = fDrawingMode; 314 info.viewStateInfo.origin = fOrigin; 315 info.viewStateInfo.scale = fScale; 316 info.viewStateInfo.lineJoin = fLineJoinMode; 317 info.viewStateInfo.lineCap = fLineCapMode; 318 info.viewStateInfo.miterLimit = fMiterLimit; 319 info.viewStateInfo.fillRule = fFillRule; 320 info.viewStateInfo.alphaSourceMode = fAlphaSrcMode; 321 info.viewStateInfo.alphaFunctionMode = fAlphaFncMode; 322 info.viewStateInfo.fontAntialiasing = fFontAliasing; 323 324 325 link.Attach<ViewGetStateInfo>(info); 326 327 // BAffineTransform is transmitted as a double array 328 double transform[6]; 329 if (fTransform.Flatten(transform, sizeof(transform)) != B_OK) 330 return; 331 link.Attach<double[6]>(transform); 332 333 // TODO: Could be optimized, but is low prio, since most views do not 334 // use a custom clipping region... 335 if (fClippingRegion != NULL) { 336 int32 clippingRectCount = fClippingRegion->CountRects(); 337 link.Attach<int32>(clippingRectCount); 338 for (int i = 0; i < clippingRectCount; i++) 339 link.Attach<BRect>(fClippingRegion->RectAt(i)); 340 } else { 341 // no client clipping 342 link.Attach<int32>(-1); 343 } 344 } 345 346 347 void 348 DrawState::SetOrigin(BPoint origin) 349 { 350 fOrigin = origin; 351 352 // NOTE: the origins of earlier states are never expected to 353 // change, only the topmost state ever changes 354 if (fPreviousState != NULL) { 355 fCombinedOrigin.x = fPreviousState->fCombinedOrigin.x 356 + fOrigin.x * fPreviousState->fCombinedScale; 357 fCombinedOrigin.y = fPreviousState->fCombinedOrigin.y 358 + fOrigin.y * fPreviousState->fCombinedScale; 359 } else { 360 fCombinedOrigin = fOrigin; 361 } 362 } 363 364 365 void 366 DrawState::SetScale(float scale) 367 { 368 if (fScale == scale) 369 return; 370 371 fScale = scale; 372 373 // NOTE: the scales of earlier states are never expected to 374 // change, only the topmost state ever changes 375 if (fPreviousState != NULL) 376 fCombinedScale = fPreviousState->fCombinedScale * fScale; 377 else 378 fCombinedScale = fScale; 379 380 // update font size 381 // NOTE: This is what makes the call potentially expensive, 382 // hence the introductory check 383 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 384 } 385 386 387 void 388 DrawState::SetTransform(BAffineTransform transform) 389 { 390 if (fTransform == transform) 391 return; 392 393 fTransform = transform; 394 395 // NOTE: the transforms of earlier states are never expected to 396 // change, only the topmost state ever changes 397 if (fPreviousState != NULL) 398 fCombinedTransform = fPreviousState->fCombinedTransform * fTransform; 399 else 400 fCombinedTransform = fTransform; 401 } 402 403 404 /* Can be used to temporarily disable all BAffineTransforms in the state 405 stack, and later reenable them. 406 */ 407 void 408 DrawState::SetTransformEnabled(bool enabled) 409 { 410 if (enabled) { 411 BAffineTransform temp = fTransform; 412 SetTransform(BAffineTransform()); 413 SetTransform(temp); 414 } 415 else 416 fCombinedTransform = BAffineTransform(); 417 } 418 419 420 DrawState* 421 DrawState::Squash() const 422 { 423 DrawState* const squashedState = new(nothrow) DrawState(*this); 424 return squashedState->PushState(); 425 } 426 427 428 void 429 DrawState::SetClippingRegion(const BRegion* region) 430 { 431 if (region) { 432 if (fClippingRegion != NULL) 433 *fClippingRegion = *region; 434 else 435 fClippingRegion = new(nothrow) BRegion(*region); 436 } else { 437 delete fClippingRegion; 438 fClippingRegion = NULL; 439 } 440 } 441 442 443 bool 444 DrawState::HasClipping() const 445 { 446 if (fClippingRegion != NULL) 447 return true; 448 if (fPreviousState != NULL) 449 return fPreviousState->HasClipping(); 450 return false; 451 } 452 453 454 bool 455 DrawState::HasAdditionalClipping() const 456 { 457 return fClippingRegion != NULL; 458 } 459 460 461 bool 462 DrawState::GetCombinedClippingRegion(BRegion* region) const 463 { 464 if (fClippingRegion != NULL) { 465 BRegion localTransformedClipping(*fClippingRegion); 466 SimpleTransform penTransform; 467 Transform(penTransform); 468 penTransform.Apply(&localTransformedClipping); 469 if (fPreviousState != NULL 470 && fPreviousState->GetCombinedClippingRegion(region)) { 471 localTransformedClipping.IntersectWith(region); 472 } 473 *region = localTransformedClipping; 474 return true; 475 } else { 476 if (fPreviousState != NULL) 477 return fPreviousState->GetCombinedClippingRegion(region); 478 } 479 return false; 480 } 481 482 483 bool 484 DrawState::ClipToRect(BRect rect, bool inverse) 485 { 486 if (!rect.IsValid()) 487 return false; 488 489 if (!fCombinedTransform.IsIdentity()) { 490 if (fCombinedTransform.IsDilation()) { 491 BPoint points[2] = { rect.LeftTop(), rect.RightBottom() }; 492 fCombinedTransform.Apply(&points[0], 2); 493 rect.Set(points[0].x, points[0].y, points[1].x, points[1].y); 494 } else { 495 uint32 ops[] = { 496 OP_MOVETO | OP_LINETO | 3, 497 OP_CLOSE 498 }; 499 BPoint points[4] = { 500 BPoint(rect.left, rect.top), 501 BPoint(rect.right, rect.top), 502 BPoint(rect.right, rect.bottom), 503 BPoint(rect.left, rect.bottom) 504 }; 505 shape_data rectShape; 506 rectShape.opList = &ops[0]; 507 rectShape.opCount = 2; 508 rectShape.opSize = sizeof(uint32) * 2; 509 rectShape.ptList = &points[0]; 510 rectShape.ptCount = 4; 511 rectShape.ptSize = sizeof(BPoint) * 4; 512 513 ClipToShape(&rectShape, inverse); 514 return true; 515 } 516 } 517 518 if (inverse) { 519 if (fClippingRegion == NULL) { 520 fClippingRegion = new(nothrow) BRegion(BRect( 521 -(1 << 16), -(1 << 16), (1 << 16), (1 << 16))); 522 // TODO: we should have a definition for a rect (or region) 523 // with "infinite" area. For now, this region size should do... 524 } 525 fClippingRegion->Exclude(rect); 526 } else { 527 if (fClippingRegion == NULL) 528 fClippingRegion = new(nothrow) BRegion(rect); 529 else { 530 BRegion rectRegion(rect); 531 fClippingRegion->IntersectWith(&rectRegion); 532 } 533 } 534 535 return false; 536 } 537 538 539 void 540 DrawState::ClipToShape(shape_data* shape, bool inverse) 541 { 542 if (shape->ptCount == 0) 543 return; 544 545 if (!fCombinedTransform.IsIdentity()) 546 fCombinedTransform.Apply(shape->ptList, shape->ptCount); 547 548 AlphaMask* const mask = ShapeAlphaMask::Create(GetAlphaMask(), *shape, 549 BPoint(0, 0), inverse); 550 551 SetAlphaMask(mask); 552 if (mask != NULL) 553 mask->ReleaseReference(); 554 } 555 556 557 void 558 DrawState::SetAlphaMask(AlphaMask* mask) 559 { 560 // NOTE: In BeOS, it wasn't possible to clip to a BPicture and keep 561 // regular custom clipping to a BRegion at the same time. 562 fAlphaMask.SetTo(mask); 563 } 564 565 566 AlphaMask* 567 DrawState::GetAlphaMask() const 568 { 569 return fAlphaMask.Get(); 570 } 571 572 573 // #pragma mark - 574 575 576 void 577 DrawState::Transform(SimpleTransform& transform) const 578 { 579 transform.AddOffset(fCombinedOrigin.x, fCombinedOrigin.y); 580 transform.SetScale(fCombinedScale); 581 } 582 583 584 void 585 DrawState::InverseTransform(SimpleTransform& transform) const 586 { 587 transform.AddOffset(-fCombinedOrigin.x, -fCombinedOrigin.y); 588 if (fCombinedScale != 0.0) 589 transform.SetScale(1.0 / fCombinedScale); 590 } 591 592 593 // #pragma mark - 594 595 596 void 597 DrawState::SetHighColor(rgb_color color) 598 { 599 fHighColor = color; 600 } 601 602 603 void 604 DrawState::SetLowColor(rgb_color color) 605 { 606 fLowColor = color; 607 } 608 609 610 void 611 DrawState::SetHighUIColor(color_which which, float tint) 612 { 613 fWhichHighColor = which; 614 fWhichHighColorTint = tint; 615 } 616 617 618 color_which 619 DrawState::HighUIColor(float* tint) const 620 { 621 if (tint != NULL) 622 *tint = fWhichHighColorTint; 623 624 return fWhichHighColor; 625 } 626 627 628 void 629 DrawState::SetLowUIColor(color_which which, float tint) 630 { 631 fWhichLowColor = which; 632 fWhichLowColorTint = tint; 633 } 634 635 636 color_which 637 DrawState::LowUIColor(float* tint) const 638 { 639 if (tint != NULL) 640 *tint = fWhichLowColorTint; 641 642 return fWhichLowColor; 643 } 644 645 646 void 647 DrawState::SetPattern(const Pattern& pattern) 648 { 649 fPattern = pattern; 650 } 651 652 653 bool 654 DrawState::SetDrawingMode(drawing_mode mode) 655 { 656 if (!fDrawingModeLocked) { 657 fDrawingMode = mode; 658 return true; 659 } 660 return false; 661 } 662 663 664 bool 665 DrawState::SetBlendingMode(source_alpha srcMode, alpha_function fncMode) 666 { 667 if (!fDrawingModeLocked) { 668 fAlphaSrcMode = srcMode; 669 fAlphaFncMode = fncMode; 670 return true; 671 } 672 return false; 673 } 674 675 676 void 677 DrawState::SetDrawingModeLocked(bool locked) 678 { 679 fDrawingModeLocked = locked; 680 } 681 682 683 684 void 685 DrawState::SetPenLocation(BPoint location) 686 { 687 fPenLocation = location; 688 } 689 690 691 BPoint 692 DrawState::PenLocation() const 693 { 694 return fPenLocation; 695 } 696 697 698 void 699 DrawState::SetPenSize(float size) 700 { 701 fPenSize = size; 702 } 703 704 705 //! returns the scaled pen size 706 float 707 DrawState::PenSize() const 708 { 709 float penSize = fPenSize * fCombinedScale; 710 // NOTE: As documented in the BeBook, 711 // pen size is never smaller than 1.0. 712 // This is supposed to be the smallest 713 // possible device size. 714 if (penSize < 1.0) 715 penSize = 1.0; 716 return penSize; 717 } 718 719 720 //! returns the unscaled pen size 721 float 722 DrawState::UnscaledPenSize() const 723 { 724 // NOTE: As documented in the BeBook, 725 // pen size is never smaller than 1.0. 726 // This is supposed to be the smallest 727 // possible device size. 728 return max_c(fPenSize, 1.0); 729 } 730 731 732 //! sets the font to be already scaled by fScale 733 void 734 DrawState::SetFont(const ServerFont& font, uint32 flags) 735 { 736 if (flags == B_FONT_ALL) { 737 fFont = font; 738 fUnscaledFontSize = font.Size(); 739 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 740 } else { 741 // family & style 742 if ((flags & B_FONT_FAMILY_AND_STYLE) != 0) 743 fFont.SetFamilyAndStyle(font.GetFamilyAndStyle()); 744 // size 745 if ((flags & B_FONT_SIZE) != 0) { 746 fUnscaledFontSize = font.Size(); 747 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 748 } 749 // shear 750 if ((flags & B_FONT_SHEAR) != 0) 751 fFont.SetShear(font.Shear()); 752 // rotation 753 if ((flags & B_FONT_ROTATION) != 0) 754 fFont.SetRotation(font.Rotation()); 755 // spacing 756 if ((flags & B_FONT_SPACING) != 0) 757 fFont.SetSpacing(font.Spacing()); 758 // encoding 759 if ((flags & B_FONT_ENCODING) != 0) 760 fFont.SetEncoding(font.Encoding()); 761 // face 762 if ((flags & B_FONT_FACE) != 0) 763 fFont.SetFace(font.Face()); 764 // flags 765 if ((flags & B_FONT_FLAGS) != 0) 766 fFont.SetFlags(font.Flags()); 767 } 768 } 769 770 771 void 772 DrawState::SetForceFontAliasing(bool aliasing) 773 { 774 fFontAliasing = aliasing; 775 } 776 777 778 void 779 DrawState::SetSubPixelPrecise(bool precise) 780 { 781 fSubPixelPrecise = precise; 782 } 783 784 785 void 786 DrawState::SetLineCapMode(cap_mode mode) 787 { 788 fLineCapMode = mode; 789 } 790 791 792 void 793 DrawState::SetLineJoinMode(join_mode mode) 794 { 795 fLineJoinMode = mode; 796 } 797 798 799 void 800 DrawState::SetMiterLimit(float limit) 801 { 802 fMiterLimit = limit; 803 } 804 805 806 void 807 DrawState::SetFillRule(int32 fillRule) 808 { 809 fFillRule = fillRule; 810 } 811 812 813 void 814 DrawState::PrintToStream() const 815 { 816 printf("\t Origin: (%.1f, %.1f)\n", fOrigin.x, fOrigin.y); 817 printf("\t Scale: %.2f\n", fScale); 818 printf("\t Transform: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f\n", 819 fTransform.sx, fTransform.shy, fTransform.shx, 820 fTransform.sy, fTransform.tx, fTransform.ty); 821 822 printf("\t Pen Location and Size: (%.1f, %.1f) - %.2f (%.2f)\n", 823 fPenLocation.x, fPenLocation.y, PenSize(), fPenSize); 824 825 printf("\t HighColor: r=%d g=%d b=%d a=%d\n", 826 fHighColor.red, fHighColor.green, fHighColor.blue, fHighColor.alpha); 827 printf("\t LowColor: r=%d g=%d b=%d a=%d\n", 828 fLowColor.red, fLowColor.green, fLowColor.blue, fLowColor.alpha); 829 printf("\t WhichHighColor: %i\n", fWhichHighColor); 830 printf("\t WhichLowColor: %i\n", fWhichLowColor); 831 printf("\t WhichHighColorTint: %.3f\n", fWhichHighColorTint); 832 printf("\t WhichLowColorTint: %.3f\n", fWhichLowColorTint); 833 printf("\t Pattern: %" B_PRIu64 "\n", fPattern.GetInt64()); 834 835 printf("\t DrawMode: %" B_PRIu32 "\n", (uint32)fDrawingMode); 836 printf("\t AlphaSrcMode: %" B_PRId32 "\t AlphaFncMode: %" B_PRId32 "\n", 837 (int32)fAlphaSrcMode, (int32)fAlphaFncMode); 838 839 printf("\t LineCap: %d\t LineJoin: %d\t MiterLimit: %.2f\n", 840 (int16)fLineCapMode, (int16)fLineJoinMode, fMiterLimit); 841 842 if (fClippingRegion != NULL) 843 fClippingRegion->PrintToStream(); 844 845 printf("\t ===== Font Data =====\n"); 846 printf("\t Style: CURRENTLY NOT SET\n"); // ??? 847 printf("\t Size: %.1f (%.1f)\n", fFont.Size(), fUnscaledFontSize); 848 printf("\t Shear: %.2f\n", fFont.Shear()); 849 printf("\t Rotation: %.2f\n", fFont.Rotation()); 850 printf("\t Spacing: %" B_PRId32 "\n", fFont.Spacing()); 851 printf("\t Encoding: %" B_PRId32 "\n", fFont.Encoding()); 852 printf("\t Face: %d\n", fFont.Face()); 853 printf("\t Flags: %" B_PRIu32 "\n", fFont.Flags()); 854 } 855 856