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
DrawState()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
DrawState(const DrawState & other)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
~DrawState()117 DrawState::~DrawState()
118 {
119 }
120
121
122 DrawState*
PushState()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*
PopState()141 DrawState::PopState()
142 {
143 return fPreviousState.Detach();
144 }
145
146
147 uint16
ReadFontFromLink(BPrivate::LinkReceiver & link,AppFontManager * fontManager)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
ReadFromLink(BPrivate::LinkReceiver & link)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
WriteToLink(BPrivate::LinkSender & link) const281 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
SetOrigin(BPoint origin)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
SetScale(float scale)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
SetTransform(BAffineTransform transform)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
SetTransformEnabled(bool enabled)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*
Squash() const413 DrawState::Squash() const
414 {
415 DrawState* const squashedState = new(nothrow) DrawState(*this);
416 return squashedState->PushState();
417 }
418
419
420 void
SetClippingRegion(const BRegion * region)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
HasClipping() const435 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
HasAdditionalClipping() const446 DrawState::HasAdditionalClipping() const
447 {
448 return fClippingRegion.IsSet();
449 }
450
451
452 bool
GetCombinedClippingRegion(BRegion * region) const453 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
ClipToRect(BRect rect,bool inverse)475 DrawState::ClipToRect(BRect rect, bool inverse)
476 {
477 if (!rect.IsValid()) {
478 if (!inverse) {
479 if (!fClippingRegion.IsSet())
480 fClippingRegion.SetTo(new(nothrow) BRegion());
481 else
482 fClippingRegion->MakeEmpty();
483 }
484 return false;
485 }
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.IsSet()) {
518 fClippingRegion.SetTo(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.IsSet())
526 fClippingRegion.SetTo(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
ClipToShape(shape_data * shape,bool inverse)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 BReference<AlphaMask> const mask(ShapeAlphaMask::Create(GetAlphaMask(), *shape,
547 BPoint(0, 0), inverse), true);
548
549 SetAlphaMask(mask);
550 }
551
552
553 void
SetAlphaMask(AlphaMask * mask)554 DrawState::SetAlphaMask(AlphaMask* mask)
555 {
556 // NOTE: In BeOS, it wasn't possible to clip to a BPicture and keep
557 // regular custom clipping to a BRegion at the same time.
558 fAlphaMask.SetTo(mask);
559 }
560
561
562 AlphaMask*
GetAlphaMask() const563 DrawState::GetAlphaMask() const
564 {
565 return fAlphaMask.Get();
566 }
567
568
569 // #pragma mark -
570
571
572 void
Transform(SimpleTransform & transform) const573 DrawState::Transform(SimpleTransform& transform) const
574 {
575 transform.AddOffset(fCombinedOrigin.x, fCombinedOrigin.y);
576 transform.SetScale(fCombinedScale);
577 }
578
579
580 void
InverseTransform(SimpleTransform & transform) const581 DrawState::InverseTransform(SimpleTransform& transform) const
582 {
583 transform.AddOffset(-fCombinedOrigin.x, -fCombinedOrigin.y);
584 if (fCombinedScale != 0.0)
585 transform.SetScale(1.0 / fCombinedScale);
586 }
587
588
589 // #pragma mark -
590
591
592 void
SetHighColor(rgb_color color)593 DrawState::SetHighColor(rgb_color color)
594 {
595 fHighColor = color;
596 }
597
598
599 void
SetLowColor(rgb_color color)600 DrawState::SetLowColor(rgb_color color)
601 {
602 fLowColor = color;
603 }
604
605
606 void
SetHighUIColor(color_which which,float tint)607 DrawState::SetHighUIColor(color_which which, float tint)
608 {
609 fWhichHighColor = which;
610 fWhichHighColorTint = tint;
611 }
612
613
614 color_which
HighUIColor(float * tint) const615 DrawState::HighUIColor(float* tint) const
616 {
617 if (tint != NULL)
618 *tint = fWhichHighColorTint;
619
620 return fWhichHighColor;
621 }
622
623
624 void
SetLowUIColor(color_which which,float tint)625 DrawState::SetLowUIColor(color_which which, float tint)
626 {
627 fWhichLowColor = which;
628 fWhichLowColorTint = tint;
629 }
630
631
632 color_which
LowUIColor(float * tint) const633 DrawState::LowUIColor(float* tint) const
634 {
635 if (tint != NULL)
636 *tint = fWhichLowColorTint;
637
638 return fWhichLowColor;
639 }
640
641
642 void
SetPattern(const Pattern & pattern)643 DrawState::SetPattern(const Pattern& pattern)
644 {
645 fPattern = pattern;
646 }
647
648
649 bool
SetDrawingMode(drawing_mode mode)650 DrawState::SetDrawingMode(drawing_mode mode)
651 {
652 if (!fDrawingModeLocked) {
653 fDrawingMode = mode;
654 return true;
655 }
656 return false;
657 }
658
659
660 bool
SetBlendingMode(source_alpha srcMode,alpha_function fncMode)661 DrawState::SetBlendingMode(source_alpha srcMode, alpha_function fncMode)
662 {
663 if (!fDrawingModeLocked) {
664 fAlphaSrcMode = srcMode;
665 fAlphaFncMode = fncMode;
666 return true;
667 }
668 return false;
669 }
670
671
672 void
SetDrawingModeLocked(bool locked)673 DrawState::SetDrawingModeLocked(bool locked)
674 {
675 fDrawingModeLocked = locked;
676 }
677
678
679
680 void
SetPenLocation(BPoint location)681 DrawState::SetPenLocation(BPoint location)
682 {
683 fPenLocation = location;
684 }
685
686
687 BPoint
PenLocation() const688 DrawState::PenLocation() const
689 {
690 return fPenLocation;
691 }
692
693
694 void
SetPenSize(float size)695 DrawState::SetPenSize(float size)
696 {
697 fPenSize = size;
698 }
699
700
701 //! returns the scaled pen size
702 float
PenSize() const703 DrawState::PenSize() const
704 {
705 float penSize = fPenSize * fCombinedScale;
706 // NOTE: As documented in the BeBook,
707 // pen size is never smaller than 1.0.
708 // This is supposed to be the smallest
709 // possible device size.
710 if (penSize < 1.0)
711 penSize = 1.0;
712 return penSize;
713 }
714
715
716 //! returns the unscaled pen size
717 float
UnscaledPenSize() const718 DrawState::UnscaledPenSize() const
719 {
720 // NOTE: As documented in the BeBook,
721 // pen size is never smaller than 1.0.
722 // This is supposed to be the smallest
723 // possible device size.
724 return max_c(fPenSize, 1.0);
725 }
726
727
728 //! sets the font to be already scaled by fScale
729 void
SetFont(const ServerFont & font,uint32 flags)730 DrawState::SetFont(const ServerFont& font, uint32 flags)
731 {
732 if (flags == B_FONT_ALL) {
733 fFont = font;
734 fUnscaledFontSize = font.Size();
735 fFont.SetSize(fUnscaledFontSize * fCombinedScale);
736 } else {
737 // family & style
738 if ((flags & B_FONT_FAMILY_AND_STYLE) != 0)
739 fFont.SetFamilyAndStyle(font.GetFamilyAndStyle());
740 // size
741 if ((flags & B_FONT_SIZE) != 0) {
742 fUnscaledFontSize = font.Size();
743 fFont.SetSize(fUnscaledFontSize * fCombinedScale);
744 }
745 // shear
746 if ((flags & B_FONT_SHEAR) != 0)
747 fFont.SetShear(font.Shear());
748 // rotation
749 if ((flags & B_FONT_ROTATION) != 0)
750 fFont.SetRotation(font.Rotation());
751 // spacing
752 if ((flags & B_FONT_SPACING) != 0)
753 fFont.SetSpacing(font.Spacing());
754 // encoding
755 if ((flags & B_FONT_ENCODING) != 0)
756 fFont.SetEncoding(font.Encoding());
757 // face
758 if ((flags & B_FONT_FACE) != 0)
759 fFont.SetFace(font.Face());
760 // flags
761 if ((flags & B_FONT_FLAGS) != 0)
762 fFont.SetFlags(font.Flags());
763 }
764 }
765
766
767 void
SetForceFontAliasing(bool aliasing)768 DrawState::SetForceFontAliasing(bool aliasing)
769 {
770 fFontAliasing = aliasing;
771 }
772
773
774 void
SetSubPixelPrecise(bool precise)775 DrawState::SetSubPixelPrecise(bool precise)
776 {
777 fSubPixelPrecise = precise;
778 }
779
780
781 void
SetLineCapMode(cap_mode mode)782 DrawState::SetLineCapMode(cap_mode mode)
783 {
784 fLineCapMode = mode;
785 }
786
787
788 void
SetLineJoinMode(join_mode mode)789 DrawState::SetLineJoinMode(join_mode mode)
790 {
791 fLineJoinMode = mode;
792 }
793
794
795 void
SetMiterLimit(float limit)796 DrawState::SetMiterLimit(float limit)
797 {
798 fMiterLimit = limit;
799 }
800
801
802 void
SetFillRule(int32 fillRule)803 DrawState::SetFillRule(int32 fillRule)
804 {
805 fFillRule = fillRule;
806 }
807
808
809 void
PrintToStream() const810 DrawState::PrintToStream() const
811 {
812 printf("\t Origin: (%.1f, %.1f)\n", fOrigin.x, fOrigin.y);
813 printf("\t Scale: %.2f\n", fScale);
814 printf("\t Transform: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f\n",
815 fTransform.sx, fTransform.shy, fTransform.shx,
816 fTransform.sy, fTransform.tx, fTransform.ty);
817
818 printf("\t Pen Location and Size: (%.1f, %.1f) - %.2f (%.2f)\n",
819 fPenLocation.x, fPenLocation.y, PenSize(), fPenSize);
820
821 printf("\t HighColor: r=%d g=%d b=%d a=%d\n",
822 fHighColor.red, fHighColor.green, fHighColor.blue, fHighColor.alpha);
823 printf("\t LowColor: r=%d g=%d b=%d a=%d\n",
824 fLowColor.red, fLowColor.green, fLowColor.blue, fLowColor.alpha);
825 printf("\t WhichHighColor: %i\n", fWhichHighColor);
826 printf("\t WhichLowColor: %i\n", fWhichLowColor);
827 printf("\t WhichHighColorTint: %.3f\n", fWhichHighColorTint);
828 printf("\t WhichLowColorTint: %.3f\n", fWhichLowColorTint);
829 printf("\t Pattern: %" B_PRIu64 "\n", fPattern.GetInt64());
830
831 printf("\t DrawMode: %" B_PRIu32 "\n", (uint32)fDrawingMode);
832 printf("\t AlphaSrcMode: %" B_PRId32 "\t AlphaFncMode: %" B_PRId32 "\n",
833 (int32)fAlphaSrcMode, (int32)fAlphaFncMode);
834
835 printf("\t LineCap: %d\t LineJoin: %d\t MiterLimit: %.2f\n",
836 (int16)fLineCapMode, (int16)fLineJoinMode, fMiterLimit);
837
838 if (fClippingRegion.IsSet())
839 fClippingRegion->PrintToStream();
840
841 printf("\t ===== Font Data =====\n");
842 printf("\t Style: CURRENTLY NOT SET\n"); // ???
843 printf("\t Size: %.1f (%.1f)\n", fFont.Size(), fUnscaledFontSize);
844 printf("\t Shear: %.2f\n", fFont.Shear());
845 printf("\t Rotation: %.2f\n", fFont.Rotation());
846 printf("\t Spacing: %" B_PRId32 "\n", fFont.Spacing());
847 printf("\t Encoding: %" B_PRId32 "\n", fFont.Encoding());
848 printf("\t Face: %d\n", fFont.Face());
849 printf("\t Flags: %" B_PRIu32 "\n", fFont.Flags());
850 }
851
852