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