From e6a598a2f4a3f359259f314699d8993b21c6847f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ximo=20Casta=C3=B1eda?= Date: Sun, 12 Sep 2021 20:37:57 +0200 Subject: [PATCH] ControlLook: fix clipping Remove ConstrainClippingRegion calls as they do not take into account view transformations. Clip drawing to the drawing rect, not the updated area. Fixes #12890 Change-Id: Ie76cb83e0af03213008da78407de25261daea5df Reviewed-on: https://review.haiku-os.org/c/haiku/+/4457 Tested-by: Commit checker robot Reviewed-by: Adrien Destugues Reviewed-by: waddlesplash --- headers/os/interface/ControlLook.h | 3 + src/kits/interface/ControlLook.cpp | 32 +++ src/kits/interface/HaikuControlLook.cpp | 265 +++++++++++++----------- 3 files changed, 178 insertions(+), 122 deletions(-) diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index 9ba32efb93..b8d9bf4881 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -430,6 +430,9 @@ public: virtual float GetScrollBarWidth( orientation orientation = B_VERTICAL); + static bool ShouldDraw(BView* view, const BRect& rect, + const BRect& updateRect); + private: // FBC padding virtual void _ReservedControlLook6(); diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp index e009b56489..7dce80c4c4 100644 --- a/src/kits/interface/ControlLook.cpp +++ b/src/kits/interface/ControlLook.cpp @@ -62,6 +62,38 @@ BControlLook::ComposeIconSize(int32 size) } +bool +BControlLook::ShouldDraw(BView* view, const BRect& rect, const BRect& updateRect) +{ + if (!rect.IsValid()) + return false; + + BPoint points[4]; + points[0] = rect.LeftTop(); + points[1] = rect.RightBottom(); + points[2] = rect.LeftBottom(); + points[3] = rect.RightTop(); + + view->TransformTo(B_VIEW_COORDINATES).Apply(points, 4); + + BRect dest; + dest.left = dest.right = points[0].x; + dest.top = dest.bottom = points[0].y; + for (int i = 1; i < 4; i++) { + dest.left = std::min(dest.left, points[i].x); + dest.right = std::max(dest.right, points[i].x); + dest.top = std::min(dest.top, points[i].y); + dest.bottom = std::max(dest.bottom, points[i].y); + } + dest.left = floorf(dest.left); + dest.right = ceilf(dest.right); + dest.top = floorf(dest.top); + dest.bottom = ceilf(dest.bottom); + + return dest.Intersects(updateRect); +} + + void BControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, diff --git a/src/kits/interface/HaikuControlLook.cpp b/src/kits/interface/HaikuControlLook.cpp index ab2ef31d8f..b93cb57b8a 100644 --- a/src/kits/interface/HaikuControlLook.cpp +++ b/src/kits/interface/HaikuControlLook.cpp @@ -174,7 +174,7 @@ HaikuControlLook::DrawMenuBarBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // the surface edges @@ -295,7 +295,7 @@ HaikuControlLook::DrawMenuBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // inner bevel colors @@ -327,7 +327,7 @@ HaikuControlLook::DrawMenuItemBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // surface edges @@ -366,7 +366,7 @@ void HaikuControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, const rgb_color& barColor, float progressPosition) { - if (!rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; _DrawOuterResessedFrame(view, rect, base, 0.6); @@ -419,7 +419,7 @@ void HaikuControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags) { - if (!rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; rgb_color dark1BorderColor; @@ -491,7 +491,7 @@ void HaikuControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags) { - if (!rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; rgb_color borderColor; @@ -563,14 +563,13 @@ HaikuControlLook::DrawScrollBarBorder(BView* view, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); bool isEnabled = (flags & B_DISABLED) == 0; bool isFocused = (flags & B_FOCUSED) != 0; @@ -619,12 +618,13 @@ HaikuControlLook::DrawScrollBarButton(BView* view, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, int32 direction, orientation orientation, bool down) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; + view->PushState(); + // clip to button - BRegion buttonRegion(rect); - view->ConstrainClippingRegion(&buttonRegion); + view->ClipToRect(rect); bool isEnabled = (flags & B_DISABLED) == 0; @@ -638,8 +638,7 @@ HaikuControlLook::DrawScrollBarButton(BView* view, BRect rect, // almost but not quite B_DARKEN_MAX_TINT // revert clipping constraints - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + view->PopState(); } void @@ -657,14 +656,13 @@ HaikuControlLook::DrawScrollBarBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); bool isEnabled = (flags & B_DISABLED) == 0; @@ -754,14 +752,13 @@ HaikuControlLook::DrawScrollBarThumb(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, orientation orientation, uint32 knobStyle) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); // flags bool isEnabled = (flags & B_DISABLED) == 0; @@ -1117,12 +1114,9 @@ HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, float sliderScale, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; - // save the clipping constraints of the view - view->PushState(); - // separate the bar in two sides float sliderPosition; BRect leftBarSide = rect; @@ -1141,30 +1135,16 @@ HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect rightBarSide.bottom = sliderPosition - 1; } - // fill the background for the corners, exclude the middle bar for now - BRegion region(rect); - region.Exclude(rightBarSide); - view->ConstrainClippingRegion(®ion); - view->PushState(); - + view->ClipToRect(leftBarSide); DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, orientation); - view->PopState(); - region.Set(rect); - region.Exclude(leftBarSide); - view->ConstrainClippingRegion(®ion); - view->PushState(); - + view->ClipToRect(rightBarSide); DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, orientation); - - view->PopState(); - - // restore the clipping constraints of the view view->PopState(); } @@ -1174,7 +1154,7 @@ HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect const rgb_color& base, rgb_color fillColor, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // separate the rect into corners @@ -1195,9 +1175,9 @@ HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect } // fill the background for the corners, exclude the middle bar for now - BRegion region(rect); - region.Exclude(barRect); - view->ConstrainClippingRegion(®ion); + view->PushState(); + view->ClipToRect(rect); + view->ClipToInverseRect(barRect); if ((flags & B_BLEND_FRAME) == 0) { view->SetHighColor(base); @@ -1285,7 +1265,9 @@ HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); } - view->ConstrainClippingRegion(NULL); + view->PopState(); + if ((flags & B_BLEND_FRAME) != 0) + view->SetDrawingMode(B_OP_ALPHA); view->BeginLineArray(4); if (orientation == B_HORIZONTAL) { @@ -1324,7 +1306,7 @@ void HaikuControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // figure out frame color @@ -1418,7 +1400,7 @@ HaikuControlLook::DrawSliderTriangle(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, const rgb_color& fill, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // figure out frame color @@ -1536,7 +1518,7 @@ HaikuControlLook::DrawSliderHashMarks(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, int32 count, hash_mark_location location, uint32 flags, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; rgb_color lightColor; @@ -1626,7 +1608,7 @@ HaikuControlLook::DrawTabFrame(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders, border_style borderStyle, uint32 side) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; if (side == BTabView::kTopSide || side == BTabView::kBottomSide) { @@ -1660,7 +1642,7 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders, uint32 side, int32, int32, int32, int32) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // Snap the rectangle to pixels to avoid rounding errors. @@ -1672,9 +1654,8 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, // save the clipping constraints of the view view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); rgb_color edgeShadowColor; rgb_color edgeLightColor; @@ -1729,10 +1710,12 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, - kRoundCornerRadius); rightBottomCorner.top = floorf(rect.bottom - kRoundCornerRadius); + BRect roundCorner[2]; + switch (side) { case B_TOP_BORDER: - clipping.Exclude(leftTopCorner); - clipping.Exclude(rightTopCorner); + roundCorner[0] = leftTopCorner; + roundCorner[1] = rightTopCorner; // draw the left top corner _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, @@ -1745,8 +1728,8 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, fillGradient); break; case B_BOTTOM_BORDER: - clipping.Exclude(leftBottomCorner); - clipping.Exclude(rightBottomCorner); + roundCorner[0] = leftBottomCorner; + roundCorner[1] = rightBottomCorner; // draw the left bottom corner _DrawRoundCornerLeftBottom(view, leftBottomCorner, updateRect, base, @@ -1759,8 +1742,8 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, fillGradient); break; case B_LEFT_BORDER: - clipping.Exclude(leftTopCorner); - clipping.Exclude(leftBottomCorner); + roundCorner[0] = leftTopCorner; + roundCorner[1] = leftBottomCorner; // draw the left top corner _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, @@ -1773,8 +1756,8 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, fillGradient); break; case B_RIGHT_BORDER: - clipping.Exclude(rightTopCorner); - clipping.Exclude(rightBottomCorner); + roundCorner[0] = rightTopCorner; + roundCorner[1] = rightBottomCorner; // draw the right top corner _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, @@ -1789,7 +1772,8 @@ HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, } // clip out the corners - view->ConstrainClippingRegion(&clipping); + view->ClipToInverseRect(roundCorner[0]); + view->ClipToInverseRect(roundCorner[1]); uint32 bordersToDraw = 0; switch (side) { @@ -1840,7 +1824,7 @@ HaikuControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders, uint32 side, int32, int32, int32, int32) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; rgb_color edgeShadowColor; @@ -1942,7 +1926,7 @@ HaikuControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect const rgb_color& base, orientation orientation, uint32 flags, uint32 borders) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; rgb_color background; @@ -2102,7 +2086,7 @@ HaikuControlLook::DrawTextControlBorder(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, uint32 borders) { - if (!rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; rgb_color dark1BorderColor; @@ -2333,7 +2317,7 @@ HaikuControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, const BAlignment& alignment, const rgb_color* textColor) { - if (!rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; if (label == NULL && icon == NULL) @@ -2521,9 +2505,8 @@ HaikuControlLook::_DrawButtonFrame(BView* view, BRect& rect, // save the clipping constraints of the view view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); // If the button is flat and neither activated nor otherwise highlighted // (mouse hovering or focussed), draw it flat. @@ -2602,9 +2585,10 @@ HaikuControlLook::_DrawButtonFrame(BView* view, BRect& rect, BRect leftTopCorner(floorf(rect.left), floorf(rect.top), floorf(rect.left + leftTopRadius), floorf(rect.top + leftTopRadius)); - clipping.Exclude(leftTopCorner); + BRect cornerRect(leftTopCorner); _DrawRoundCornerFrameLeftTop(view, leftTopCorner, updateRect, cornerBgColor, edgeShadowColor, frameLightColor); + view->ClipToInverseRect(cornerRect); } if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 @@ -2613,10 +2597,11 @@ HaikuControlLook::_DrawButtonFrame(BView* view, BRect& rect, BRect rightTopCorner(floorf(rect.right - rightTopRadius), floorf(rect.top), floorf(rect.right), floorf(rect.top + rightTopRadius)); - clipping.Exclude(rightTopCorner); + BRect cornerRect(rightTopCorner); _DrawRoundCornerFrameRightTop(view, rightTopCorner, updateRect, cornerBgColor, edgeShadowColor, edgeLightColor, frameLightColor, frameShadowColor); + view->ClipToInverseRect(cornerRect); } if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 @@ -2625,10 +2610,11 @@ HaikuControlLook::_DrawButtonFrame(BView* view, BRect& rect, BRect leftBottomCorner(floorf(rect.left), floorf(rect.bottom - leftBottomRadius), floorf(rect.left + leftBottomRadius), floorf(rect.bottom)); - clipping.Exclude(leftBottomCorner); + BRect cornerRect(leftBottomCorner); _DrawRoundCornerFrameLeftBottom(view, leftBottomCorner, updateRect, cornerBgColor, edgeShadowColor, edgeLightColor, frameLightColor, frameShadowColor); + view->ClipToInverseRect(cornerRect); } if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 @@ -2637,14 +2623,12 @@ HaikuControlLook::_DrawButtonFrame(BView* view, BRect& rect, BRect rightBottomCorner(floorf(rect.right - rightBottomRadius), floorf(rect.bottom - rightBottomRadius), floorf(rect.right), floorf(rect.bottom)); - clipping.Exclude(rightBottomCorner); + BRect cornerRect(rightBottomCorner); _DrawRoundCornerFrameRightBottom(view, rightBottomCorner, updateRect, cornerBgColor, edgeLightColor, frameShadowColor); + view->ClipToInverseRect(cornerRect); } - // clip out the corners - view->ConstrainClippingRegion(&clipping); - // draw outer edge if ((flags & B_DEFAULT_BUTTON) != 0) { _DrawOuterResessedFrame(view, rect, defaultIndicatorColor, @@ -2803,9 +2787,8 @@ HaikuControlLook::_DrawButtonBackground(BView* view, BRect& rect, // save the clipping constraints of the view view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); // If the button is flat and neither activated nor otherwise highlighted // (mouse hovering or focussed), draw it flat. @@ -2816,6 +2799,7 @@ HaikuControlLook::_DrawButtonBackground(BView* view, BRect& rect, _DrawFlatButtonBackground(view, rect, updateRect, base, popupIndicator, flags, borders, orientation); } else { + BRegion clipping(rect); _DrawNonFlatButtonBackground(view, rect, updateRect, clipping, leftTopRadius, rightTopRadius, leftBottomRadius, rightBottomRadius, base, popupIndicator, flags, borders, orientation); @@ -2882,8 +2866,10 @@ HaikuControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect, floorf(rect.left + leftTopRadius - 2.0), floorf(rect.top + leftTopRadius - 2.0)); clipping.Exclude(leftTopCorner); + BRect cornerRect(leftTopCorner); _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, bevelLightColor, fillGradient); + view->ClipToInverseRect(cornerRect); } if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 @@ -2893,8 +2879,10 @@ HaikuControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect, floorf(rect.top), floorf(rect.right), floorf(rect.top + rightTopRadius - 2.0)); clipping.Exclude(rightTopCorner); + BRect cornerRect(rightTopCorner); _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect, bevelLightColor, bevelShadowColor, fillGradient); + view->ClipToInverseRect(cornerRect); } if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 @@ -2905,8 +2893,10 @@ HaikuControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect, floorf(rect.left + leftBottomRadius - 2.0), floorf(rect.bottom)); clipping.Exclude(leftBottomCorner); + BRect cornerRect(leftBottomCorner); _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, updateRect, bevelLightColor, bevelShadowColor, fillGradient); + view->ClipToInverseRect(cornerRect); } if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 @@ -2916,13 +2906,12 @@ HaikuControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect, floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), floorf(rect.bottom)); clipping.Exclude(rightBottomCorner); + BRect cornerRect(rightBottomCorner); _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, updateRect, bevelShadowColor, fillGradient); + view->ClipToInverseRect(cornerRect); } - // clip out the corners - view->ConstrainClippingRegion(&clipping); - // draw inner bevel if ((flags & B_ACTIVATED) != 0) { @@ -3042,7 +3031,7 @@ HaikuControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect, float leftBottomRadius, float rightBottomRadius, const rgb_color& base, bool popupIndicator, uint32 flags) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; if (popupIndicator) { @@ -3091,15 +3080,14 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, float leftBottomRadius, float rightBottomRadius, const rgb_color& base, uint32 flags, uint32 borders) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; // save the clipping constraints of the view view->PushState(); - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); + // set clipping constraints to rect + view->ClipToRect(rect); // frame colors rgb_color frameLightColor = _FrameLightColor(base, flags); @@ -3146,10 +3134,10 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, BRect leftTopCorner(floorf(rect.left), floorf(rect.top), floorf(rect.left + leftTopRadius - 2.0), floorf(rect.top + leftTopRadius - 2.0)); - clipping.Exclude(leftTopCorner); + BRect cornerRect(leftTopCorner); - BRegion cornerClipping(leftTopCorner); - view->ConstrainClippingRegion(&cornerClipping); + view->PushState(); + view->ClipToRect(cornerRect); BRect ellipseRect(leftTopCorner); ellipseRect.InsetBy(-1.0, -1.0); @@ -3163,6 +3151,9 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, // draw the bevel and background _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, bevelColor1, fillGradient); + + view->PopState(); + view->ClipToInverseRect(cornerRect); } if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 @@ -3171,10 +3162,10 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), floorf(rect.top), floorf(rect.right), floorf(rect.top + rightTopRadius - 2.0)); - clipping.Exclude(rightTopCorner); + BRect cornerRect(rightTopCorner); - BRegion cornerClipping(rightTopCorner); - view->ConstrainClippingRegion(&cornerClipping); + view->PushState(); + view->ClipToRect(cornerRect); BRect ellipseRect(rightTopCorner); ellipseRect.InsetBy(-1.0, -1.0); @@ -3197,6 +3188,9 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, // draw the bevel and background _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect, bevelColor1, bevelColor3, fillGradient); + + view->PopState(); + view->ClipToInverseRect(cornerRect); } if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 @@ -3206,10 +3200,10 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, floorf(rect.bottom - leftBottomRadius + 2.0), floorf(rect.left + leftBottomRadius - 2.0), floorf(rect.bottom)); - clipping.Exclude(leftBottomCorner); + BRect cornerRect(leftBottomCorner); - BRegion cornerClipping(leftBottomCorner); - view->ConstrainClippingRegion(&cornerClipping); + view->PushState(); + view->ClipToRect(cornerRect); BRect ellipseRect(leftBottomCorner); ellipseRect.InsetBy(-1.0, -1.0); @@ -3232,6 +3226,9 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, // draw the bevel and background _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, updateRect, bevelColor2, bevelColor3, fillGradient); + + view->PopState(); + view->ClipToInverseRect(cornerRect); } if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 @@ -3240,10 +3237,10 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), floorf(rect.bottom)); - clipping.Exclude(rightBottomCorner); + BRect cornerRect(rightBottomCorner); - BRegion cornerClipping(rightBottomCorner); - view->ConstrainClippingRegion(&cornerClipping); + view->PushState(); + view->ClipToRect(cornerRect); BRect ellipseRect(rightBottomCorner); ellipseRect.InsetBy(-1.0, -1.0); @@ -3257,10 +3254,10 @@ HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, // draw the bevel and background _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, updateRect, bevelColor3, fillGradient); - } - // clip out the corners - view->ConstrainClippingRegion(&clipping); + view->PopState(); + view->ClipToInverseRect(cornerRect); + } // draw the bevel _DrawFrame(view, rect, @@ -3295,9 +3292,10 @@ HaikuControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect, const BRect& updateRect, const rgb_color& background, const rgb_color& edgeColor, const rgb_color& frameColor) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); // background view->SetHighColor(background); @@ -3321,6 +3319,8 @@ HaikuControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect, // prepare for bevel cornerRect.left++; cornerRect.top++; + + view->PopState(); } @@ -3329,9 +3329,10 @@ HaikuControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRe const BRect& updateRect, const rgb_color& bevelColor, const BGradientLinear& fillGradient) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); BRect ellipseRect(cornerRect); ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; @@ -3344,6 +3345,8 @@ HaikuControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRe // gradient ellipseRect.InsetBy(1, 1); view->FillEllipse(ellipseRect, fillGradient); + + view->PopState(); } @@ -3369,9 +3372,10 @@ HaikuControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect, const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, const rgb_color& frameTopColor, const rgb_color& frameRightColor) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); // background view->SetHighColor(background); @@ -3407,6 +3411,8 @@ HaikuControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect, // prepare for bevel cornerRect.right--; cornerRect.top++; + + view->PopState(); } @@ -3415,9 +3421,10 @@ HaikuControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerR const BRect& updateRect, const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, const BGradientLinear& fillGradient) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); BRect ellipseRect(cornerRect); ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; @@ -3434,6 +3441,8 @@ HaikuControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerR // gradient ellipseRect.InsetBy(1, 1); view->FillEllipse(ellipseRect, fillGradient); + + view->PopState(); } @@ -3459,9 +3468,10 @@ HaikuControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, const rgb_color& frameLeftColor, const rgb_color& frameBottomColor) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); // background view->SetHighColor(background); @@ -3497,6 +3507,8 @@ HaikuControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect // prepare for bevel cornerRect.left++; cornerRect.bottom--; + + view->PopState(); } @@ -3505,9 +3517,10 @@ HaikuControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& corne const BRect& updateRect, const rgb_color& bevelLeftColor, const rgb_color& bevelBottomColor, const BGradientLinear& fillGradient) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); BRect ellipseRect(cornerRect); ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; @@ -3524,6 +3537,8 @@ HaikuControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& corne // gradient ellipseRect.InsetBy(1, 1); view->FillEllipse(ellipseRect, fillGradient); + + view->PopState(); } @@ -3545,9 +3560,10 @@ HaikuControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRec const BRect& updateRect, const rgb_color& background, const rgb_color& edgeColor, const rgb_color& frameColor) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); // background view->SetHighColor(background); @@ -3571,6 +3587,8 @@ HaikuControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRec // prepare for bevel cornerRect.right--; cornerRect.bottom--; + + view->PopState(); } @@ -3579,9 +3597,10 @@ HaikuControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view, BRect& cornerRect, const BRect& updateRect, const rgb_color& bevelColor, const BGradientLinear& fillGradient) { + view->PushState(); + // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); + view->ClipToRect(cornerRect); BRect ellipseRect(cornerRect); ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; @@ -3594,6 +3613,8 @@ HaikuControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view, // gradient ellipseRect.InsetBy(1, 1); view->FillEllipse(ellipseRect, fillGradient); + + view->PopState(); } @@ -3606,7 +3627,7 @@ HaikuControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, float leftInset, float topInset, float rightInset, float bottomInset, orientation orientation) { - if (!rect.IsValid() || !rect.Intersects(updateRect)) + if (!ShouldDraw(view, rect, updateRect)) return; BGradientLinear gradient;