1 /* 2 * Copyright 2001-2015, 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 void 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 218 219 void 220 DrawState::ReadFromLink(BPrivate::LinkReceiver& link) 221 { 222 ViewSetStateInfo info; 223 224 link.Read<ViewSetStateInfo>(&info); 225 226 // BAffineTransform is transmitted as a double array 227 double transform[6]; 228 link.Read<double[6]>(&transform); 229 if (fTransform.Unflatten(B_AFFINE_TRANSFORM_TYPE, transform, 230 sizeof(transform)) != B_OK) { 231 return; 232 } 233 234 fPenLocation = info.penLocation; 235 fPenSize = info.penSize; 236 fHighColor = info.highColor; 237 fLowColor = info.lowColor; 238 fWhichHighColor = info.whichHighColor; 239 fWhichLowColor = info.whichLowColor; 240 fWhichHighColorTint = info.whichHighColorTint; 241 fWhichLowColorTint = info.whichLowColorTint; 242 fPattern = info.pattern; 243 fDrawingMode = info.drawingMode; 244 fOrigin = info.origin; 245 fScale = info.scale; 246 fLineJoinMode = info.lineJoin; 247 fLineCapMode = info.lineCap; 248 fMiterLimit = info.miterLimit; 249 fFillRule = info.fillRule; 250 fAlphaSrcMode = info.alphaSourceMode; 251 fAlphaFncMode = info.alphaFunctionMode; 252 fFontAliasing = info.fontAntialiasing; 253 254 if (fPreviousState != NULL) { 255 fCombinedOrigin = fPreviousState->fCombinedOrigin + fOrigin; 256 fCombinedScale = fPreviousState->fCombinedScale * fScale; 257 fCombinedTransform = fPreviousState->fCombinedTransform * fTransform; 258 } else { 259 fCombinedOrigin = fOrigin; 260 fCombinedScale = fScale; 261 fCombinedTransform = fTransform; 262 } 263 264 265 // read clipping 266 // TODO: This could be optimized, but the user clipping regions are rarely 267 // used, so it's low priority... 268 int32 clipRectCount; 269 link.Read<int32>(&clipRectCount); 270 271 if (clipRectCount >= 0) { 272 BRegion region; 273 BRect rect; 274 for (int32 i = 0; i < clipRectCount; i++) { 275 link.Read<BRect>(&rect); 276 region.Include(rect); 277 } 278 SetClippingRegion(®ion); 279 } else { 280 // No user clipping used 281 SetClippingRegion(NULL); 282 } 283 } 284 285 286 void 287 DrawState::WriteToLink(BPrivate::LinkSender& link) const 288 { 289 // Attach font state 290 ViewGetStateInfo info; 291 info.fontID = fFont.GetFamilyAndStyle(); 292 info.fontSize = fFont.Size(); 293 info.fontShear = fFont.Shear(); 294 info.fontRotation = fFont.Rotation(); 295 info.fontFalseBoldWidth = fFont.FalseBoldWidth(); 296 info.fontSpacing = fFont.Spacing(); 297 info.fontEncoding = fFont.Encoding(); 298 info.fontFace = fFont.Face(); 299 info.fontFlags = fFont.Flags(); 300 301 // Attach view state 302 info.viewStateInfo.penLocation = fPenLocation; 303 info.viewStateInfo.penSize = fPenSize; 304 info.viewStateInfo.highColor = fHighColor; 305 info.viewStateInfo.lowColor = fLowColor; 306 info.viewStateInfo.whichHighColor = fWhichHighColor; 307 info.viewStateInfo.whichLowColor = fWhichLowColor; 308 info.viewStateInfo.whichHighColorTint = fWhichHighColorTint; 309 info.viewStateInfo.whichLowColorTint = fWhichLowColorTint; 310 info.viewStateInfo.pattern = (::pattern)fPattern.GetPattern(); 311 info.viewStateInfo.drawingMode = fDrawingMode; 312 info.viewStateInfo.origin = fOrigin; 313 info.viewStateInfo.scale = fScale; 314 info.viewStateInfo.lineJoin = fLineJoinMode; 315 info.viewStateInfo.lineCap = fLineCapMode; 316 info.viewStateInfo.miterLimit = fMiterLimit; 317 info.viewStateInfo.fillRule = fFillRule; 318 info.viewStateInfo.alphaSourceMode = fAlphaSrcMode; 319 info.viewStateInfo.alphaFunctionMode = fAlphaFncMode; 320 info.viewStateInfo.fontAntialiasing = fFontAliasing; 321 322 323 link.Attach<ViewGetStateInfo>(info); 324 325 // BAffineTransform is transmitted as a double array 326 double transform[6]; 327 if (fTransform.Flatten(transform, sizeof(transform)) != B_OK) 328 return; 329 link.Attach<double[6]>(transform); 330 331 // TODO: Could be optimized, but is low prio, since most views do not 332 // use a custom clipping region... 333 if (fClippingRegion != NULL) { 334 int32 clippingRectCount = fClippingRegion->CountRects(); 335 link.Attach<int32>(clippingRectCount); 336 for (int i = 0; i < clippingRectCount; i++) 337 link.Attach<BRect>(fClippingRegion->RectAt(i)); 338 } else { 339 // no client clipping 340 link.Attach<int32>(-1); 341 } 342 } 343 344 345 void 346 DrawState::SetOrigin(BPoint origin) 347 { 348 fOrigin = origin; 349 350 // NOTE: the origins of earlier states are never expected to 351 // change, only the topmost state ever changes 352 if (fPreviousState != NULL) { 353 fCombinedOrigin.x = fPreviousState->fCombinedOrigin.x 354 + fOrigin.x * fPreviousState->fCombinedScale; 355 fCombinedOrigin.y = fPreviousState->fCombinedOrigin.y 356 + fOrigin.y * fPreviousState->fCombinedScale; 357 } else { 358 fCombinedOrigin = fOrigin; 359 } 360 } 361 362 363 void 364 DrawState::SetScale(float scale) 365 { 366 if (fScale == scale) 367 return; 368 369 fScale = scale; 370 371 // NOTE: the scales of earlier states are never expected to 372 // change, only the topmost state ever changes 373 if (fPreviousState != NULL) 374 fCombinedScale = fPreviousState->fCombinedScale * fScale; 375 else 376 fCombinedScale = fScale; 377 378 // update font size 379 // NOTE: This is what makes the call potentially expensive, 380 // hence the introductory check 381 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 382 } 383 384 385 void 386 DrawState::SetTransform(BAffineTransform transform) 387 { 388 if (fTransform == transform) 389 return; 390 391 fTransform = transform; 392 393 // NOTE: the transforms of earlier states are never expected to 394 // change, only the topmost state ever changes 395 if (fPreviousState != NULL) 396 fCombinedTransform = fPreviousState->fCombinedTransform * fTransform; 397 else 398 fCombinedTransform = fTransform; 399 } 400 401 402 /* Can be used to temporarily disable all BAffineTransforms in the state 403 stack, and later reenable them. 404 */ 405 void 406 DrawState::SetTransformEnabled(bool enabled) 407 { 408 if (enabled) { 409 BAffineTransform temp = fTransform; 410 SetTransform(BAffineTransform()); 411 SetTransform(temp); 412 } 413 else 414 fCombinedTransform = BAffineTransform(); 415 } 416 417 418 DrawState* 419 DrawState::Squash() const 420 { 421 DrawState* const squashedState = new(nothrow) DrawState(*this); 422 return squashedState->PushState(); 423 } 424 425 426 void 427 DrawState::SetClippingRegion(const BRegion* region) 428 { 429 if (region) { 430 if (fClippingRegion != NULL) 431 *fClippingRegion = *region; 432 else 433 fClippingRegion = new(nothrow) BRegion(*region); 434 } else { 435 delete fClippingRegion; 436 fClippingRegion = NULL; 437 } 438 } 439 440 441 bool 442 DrawState::HasClipping() const 443 { 444 if (fClippingRegion != NULL) 445 return true; 446 if (fPreviousState != NULL) 447 return fPreviousState->HasClipping(); 448 return false; 449 } 450 451 452 bool 453 DrawState::HasAdditionalClipping() const 454 { 455 return fClippingRegion != NULL; 456 } 457 458 459 bool 460 DrawState::GetCombinedClippingRegion(BRegion* region) const 461 { 462 if (fClippingRegion != NULL) { 463 BRegion localTransformedClipping(*fClippingRegion); 464 SimpleTransform penTransform; 465 Transform(penTransform); 466 penTransform.Apply(&localTransformedClipping); 467 if (fPreviousState != NULL 468 && fPreviousState->GetCombinedClippingRegion(region)) { 469 localTransformedClipping.IntersectWith(region); 470 } 471 *region = localTransformedClipping; 472 return true; 473 } else { 474 if (fPreviousState != NULL) 475 return fPreviousState->GetCombinedClippingRegion(region); 476 } 477 return false; 478 } 479 480 481 bool 482 DrawState::ClipToRect(BRect rect, bool inverse) 483 { 484 if (!rect.IsValid()) 485 return false; 486 487 if (!fCombinedTransform.IsIdentity()) { 488 if (fCombinedTransform.IsDilation()) { 489 BPoint points[2] = { rect.LeftTop(), rect.RightBottom() }; 490 fCombinedTransform.Apply(&points[0], 2); 491 rect.Set(points[0].x, points[0].y, points[1].x, points[1].y); 492 } else { 493 uint32 ops[] = { 494 OP_MOVETO | OP_LINETO | 3, 495 OP_CLOSE 496 }; 497 BPoint points[4] = { 498 BPoint(rect.left, rect.top), 499 BPoint(rect.right, rect.top), 500 BPoint(rect.right, rect.bottom), 501 BPoint(rect.left, rect.bottom) 502 }; 503 shape_data rectShape; 504 rectShape.opList = &ops[0]; 505 rectShape.opCount = 2; 506 rectShape.opSize = sizeof(uint32) * 2; 507 rectShape.ptList = &points[0]; 508 rectShape.ptCount = 4; 509 rectShape.ptSize = sizeof(BPoint) * 4; 510 511 ClipToShape(&rectShape, inverse); 512 return true; 513 } 514 } 515 516 if (inverse) { 517 if (fClippingRegion == NULL) { 518 fClippingRegion = new(nothrow) BRegion(BRect( 519 -(1 << 16), -(1 << 16), (1 << 16), (1 << 16))); 520 // TODO: we should have a definition for a rect (or region) 521 // with "infinite" area. For now, this region size should do... 522 } 523 fClippingRegion->Exclude(rect); 524 } else { 525 if (fClippingRegion == NULL) 526 fClippingRegion = new(nothrow) BRegion(rect); 527 else { 528 BRegion rectRegion(rect); 529 fClippingRegion->IntersectWith(&rectRegion); 530 } 531 } 532 533 return false; 534 } 535 536 537 void 538 DrawState::ClipToShape(shape_data* shape, bool inverse) 539 { 540 if (shape->ptCount == 0) 541 return; 542 543 if (!fCombinedTransform.IsIdentity()) 544 fCombinedTransform.Apply(shape->ptList, shape->ptCount); 545 546 AlphaMask* const mask = ShapeAlphaMask::Create(GetAlphaMask(), *shape, 547 BPoint(0, 0), inverse); 548 549 SetAlphaMask(mask); 550 if (mask != NULL) 551 mask->ReleaseReference(); 552 } 553 554 555 void 556 DrawState::SetAlphaMask(AlphaMask* mask) 557 { 558 // NOTE: In BeOS, it wasn't possible to clip to a BPicture and keep 559 // regular custom clipping to a BRegion at the same time. 560 fAlphaMask.SetTo(mask); 561 } 562 563 564 AlphaMask* 565 DrawState::GetAlphaMask() const 566 { 567 return fAlphaMask.Get(); 568 } 569 570 571 // #pragma mark - 572 573 574 void 575 DrawState::Transform(SimpleTransform& transform) const 576 { 577 transform.AddOffset(fCombinedOrigin.x, fCombinedOrigin.y); 578 transform.SetScale(fCombinedScale); 579 } 580 581 582 void 583 DrawState::InverseTransform(SimpleTransform& transform) const 584 { 585 transform.AddOffset(-fCombinedOrigin.x, -fCombinedOrigin.y); 586 if (fCombinedScale != 0.0) 587 transform.SetScale(1.0 / fCombinedScale); 588 } 589 590 591 // #pragma mark - 592 593 594 void 595 DrawState::SetHighColor(rgb_color color) 596 { 597 fHighColor = color; 598 } 599 600 601 void 602 DrawState::SetLowColor(rgb_color color) 603 { 604 fLowColor = color; 605 } 606 607 608 void 609 DrawState::SetHighUIColor(color_which which, float tint) 610 { 611 fWhichHighColor = which; 612 fWhichHighColorTint = tint; 613 } 614 615 616 color_which 617 DrawState::HighUIColor(float* tint) const 618 { 619 if (tint != NULL) 620 *tint = fWhichHighColorTint; 621 622 return fWhichHighColor; 623 } 624 625 626 void 627 DrawState::SetLowUIColor(color_which which, float tint) 628 { 629 fWhichLowColor = which; 630 fWhichLowColorTint = tint; 631 } 632 633 634 color_which 635 DrawState::LowUIColor(float* tint) const 636 { 637 if (tint != NULL) 638 *tint = fWhichLowColorTint; 639 640 return fWhichLowColor; 641 } 642 643 644 void 645 DrawState::SetPattern(const Pattern& pattern) 646 { 647 fPattern = pattern; 648 } 649 650 651 bool 652 DrawState::SetDrawingMode(drawing_mode mode) 653 { 654 if (!fDrawingModeLocked) { 655 fDrawingMode = mode; 656 return true; 657 } 658 return false; 659 } 660 661 662 bool 663 DrawState::SetBlendingMode(source_alpha srcMode, alpha_function fncMode) 664 { 665 if (!fDrawingModeLocked) { 666 fAlphaSrcMode = srcMode; 667 fAlphaFncMode = fncMode; 668 return true; 669 } 670 return false; 671 } 672 673 674 void 675 DrawState::SetDrawingModeLocked(bool locked) 676 { 677 fDrawingModeLocked = locked; 678 } 679 680 681 682 void 683 DrawState::SetPenLocation(BPoint location) 684 { 685 fPenLocation = location; 686 } 687 688 689 BPoint 690 DrawState::PenLocation() const 691 { 692 return fPenLocation; 693 } 694 695 696 void 697 DrawState::SetPenSize(float size) 698 { 699 fPenSize = size; 700 } 701 702 703 //! returns the scaled pen size 704 float 705 DrawState::PenSize() const 706 { 707 float penSize = fPenSize * fCombinedScale; 708 // NOTE: As documented in the BeBook, 709 // pen size is never smaller than 1.0. 710 // This is supposed to be the smallest 711 // possible device size. 712 if (penSize < 1.0) 713 penSize = 1.0; 714 return penSize; 715 } 716 717 718 //! returns the unscaled pen size 719 float 720 DrawState::UnscaledPenSize() const 721 { 722 // NOTE: As documented in the BeBook, 723 // pen size is never smaller than 1.0. 724 // This is supposed to be the smallest 725 // possible device size. 726 return max_c(fPenSize, 1.0); 727 } 728 729 730 //! sets the font to be already scaled by fScale 731 void 732 DrawState::SetFont(const ServerFont& font, uint32 flags) 733 { 734 if (flags == B_FONT_ALL) { 735 fFont = font; 736 fUnscaledFontSize = font.Size(); 737 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 738 } else { 739 // family & style 740 if ((flags & B_FONT_FAMILY_AND_STYLE) != 0) 741 fFont.SetFamilyAndStyle(font.GetFamilyAndStyle()); 742 // size 743 if ((flags & B_FONT_SIZE) != 0) { 744 fUnscaledFontSize = font.Size(); 745 fFont.SetSize(fUnscaledFontSize * fCombinedScale); 746 } 747 // shear 748 if ((flags & B_FONT_SHEAR) != 0) 749 fFont.SetShear(font.Shear()); 750 // rotation 751 if ((flags & B_FONT_ROTATION) != 0) 752 fFont.SetRotation(font.Rotation()); 753 // spacing 754 if ((flags & B_FONT_SPACING) != 0) 755 fFont.SetSpacing(font.Spacing()); 756 // encoding 757 if ((flags & B_FONT_ENCODING) != 0) 758 fFont.SetEncoding(font.Encoding()); 759 // face 760 if ((flags & B_FONT_FACE) != 0) 761 fFont.SetFace(font.Face()); 762 // flags 763 if ((flags & B_FONT_FLAGS) != 0) 764 fFont.SetFlags(font.Flags()); 765 } 766 } 767 768 769 void 770 DrawState::SetForceFontAliasing(bool aliasing) 771 { 772 fFontAliasing = aliasing; 773 } 774 775 776 void 777 DrawState::SetSubPixelPrecise(bool precise) 778 { 779 fSubPixelPrecise = precise; 780 } 781 782 783 void 784 DrawState::SetLineCapMode(cap_mode mode) 785 { 786 fLineCapMode = mode; 787 } 788 789 790 void 791 DrawState::SetLineJoinMode(join_mode mode) 792 { 793 fLineJoinMode = mode; 794 } 795 796 797 void 798 DrawState::SetMiterLimit(float limit) 799 { 800 fMiterLimit = limit; 801 } 802 803 804 void 805 DrawState::SetFillRule(int32 fillRule) 806 { 807 fFillRule = fillRule; 808 } 809 810 811 void 812 DrawState::PrintToStream() const 813 { 814 printf("\t Origin: (%.1f, %.1f)\n", fOrigin.x, fOrigin.y); 815 printf("\t Scale: %.2f\n", fScale); 816 printf("\t Transform: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f\n", 817 fTransform.sx, fTransform.shy, fTransform.shx, 818 fTransform.sy, fTransform.tx, fTransform.ty); 819 820 printf("\t Pen Location and Size: (%.1f, %.1f) - %.2f (%.2f)\n", 821 fPenLocation.x, fPenLocation.y, PenSize(), fPenSize); 822 823 printf("\t HighColor: r=%d g=%d b=%d a=%d\n", 824 fHighColor.red, fHighColor.green, fHighColor.blue, fHighColor.alpha); 825 printf("\t LowColor: r=%d g=%d b=%d a=%d\n", 826 fLowColor.red, fLowColor.green, fLowColor.blue, fLowColor.alpha); 827 printf("\t WhichHighColor: %i\n", fWhichHighColor); 828 printf("\t WhichLowColor: %i\n", fWhichLowColor); 829 printf("\t WhichHighColorTint: %.3f\n", fWhichHighColorTint); 830 printf("\t WhichLowColorTint: %.3f\n", fWhichLowColorTint); 831 printf("\t Pattern: %" B_PRIu64 "\n", fPattern.GetInt64()); 832 833 printf("\t DrawMode: %" B_PRIu32 "\n", (uint32)fDrawingMode); 834 printf("\t AlphaSrcMode: %" B_PRId32 "\t AlphaFncMode: %" B_PRId32 "\n", 835 (int32)fAlphaSrcMode, (int32)fAlphaFncMode); 836 837 printf("\t LineCap: %d\t LineJoin: %d\t MiterLimit: %.2f\n", 838 (int16)fLineCapMode, (int16)fLineJoinMode, fMiterLimit); 839 840 if (fClippingRegion != NULL) 841 fClippingRegion->PrintToStream(); 842 843 printf("\t ===== Font Data =====\n"); 844 printf("\t Style: CURRENTLY NOT SET\n"); // ??? 845 printf("\t Size: %.1f (%.1f)\n", fFont.Size(), fUnscaledFontSize); 846 printf("\t Shear: %.2f\n", fFont.Shear()); 847 printf("\t Rotation: %.2f\n", fFont.Rotation()); 848 printf("\t Spacing: %" B_PRId32 "\n", fFont.Spacing()); 849 printf("\t Encoding: %" B_PRId32 "\n", fFont.Encoding()); 850 printf("\t Face: %d\n", fFont.Face()); 851 printf("\t Flags: %" B_PRIu32 "\n", fFont.Flags()); 852 } 853 854