michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "DisplayListClipState.h" michael@0: michael@0: #include "nsDisplayList.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: const DisplayItemClip* michael@0: DisplayListClipState::GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder) michael@0: { michael@0: if (mCurrentCombinedClip) { michael@0: return mCurrentCombinedClip; michael@0: } michael@0: if (!mClipContentDescendants && !mClipContainingBlockDescendants) { michael@0: return nullptr; michael@0: } michael@0: if (mClipContentDescendants) { michael@0: if (mClipContainingBlockDescendants) { michael@0: DisplayItemClip intersection = *mClipContentDescendants; michael@0: intersection.IntersectWith(*mClipContainingBlockDescendants); michael@0: mCurrentCombinedClip = aBuilder->AllocateDisplayItemClip(intersection); michael@0: } else { michael@0: mCurrentCombinedClip = michael@0: aBuilder->AllocateDisplayItemClip(*mClipContentDescendants); michael@0: } michael@0: } else { michael@0: mCurrentCombinedClip = michael@0: aBuilder->AllocateDisplayItemClip(*mClipContainingBlockDescendants); michael@0: } michael@0: return mCurrentCombinedClip; michael@0: } michael@0: michael@0: void michael@0: DisplayListClipState::ClipContainingBlockDescendants(const nsRect& aRect, michael@0: const nscoord* aRadii, michael@0: DisplayItemClip& aClipOnStack) michael@0: { michael@0: if (aRadii) { michael@0: aClipOnStack.SetTo(aRect, aRadii); michael@0: } else { michael@0: aClipOnStack.SetTo(aRect); michael@0: } michael@0: if (mClipContainingBlockDescendants) { michael@0: aClipOnStack.IntersectWith(*mClipContainingBlockDescendants); michael@0: } michael@0: mClipContainingBlockDescendants = &aClipOnStack; michael@0: mCurrentCombinedClip = nullptr; michael@0: } michael@0: michael@0: void michael@0: DisplayListClipState::ClipContentDescendants(const nsRect& aRect, michael@0: const nscoord* aRadii, michael@0: DisplayItemClip& aClipOnStack) michael@0: { michael@0: if (aRadii) { michael@0: aClipOnStack.SetTo(aRect, aRadii); michael@0: } else { michael@0: aClipOnStack.SetTo(aRect); michael@0: } michael@0: if (mClipContentDescendants) { michael@0: aClipOnStack.IntersectWith(*mClipContentDescendants); michael@0: } michael@0: mClipContentDescendants = &aClipOnStack; michael@0: mCurrentCombinedClip = nullptr; michael@0: } michael@0: michael@0: void michael@0: DisplayListClipState::ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder, michael@0: nsIFrame* aFrame, michael@0: DisplayItemClip& aClipOnStack, michael@0: uint32_t aFlags) michael@0: { michael@0: nscoord radii[8]; michael@0: bool hasBorderRadius = aFrame->GetContentBoxBorderRadii(radii); michael@0: if (!hasBorderRadius && (aFlags & ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT)) { michael@0: return; michael@0: } michael@0: michael@0: nsRect clipRect = aFrame->GetContentRectRelativeToSelf() + michael@0: aBuilder->ToReferenceFrame(aFrame); michael@0: // If we have a border-radius, we have to clip our content to that michael@0: // radius. michael@0: ClipContainingBlockDescendants(clipRect, hasBorderRadius ? radii : nullptr, michael@0: aClipOnStack); michael@0: } michael@0: michael@0: DisplayListClipState::AutoSaveRestore::AutoSaveRestore(nsDisplayListBuilder* aBuilder) michael@0: : mState(aBuilder->ClipState()) michael@0: , mSavedState(aBuilder->ClipState()) michael@0: , mClipUsed(false) michael@0: , mRestored(false) michael@0: {} michael@0: michael@0: }