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