From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- layout/forms/nsButtonFrameRenderer.cpp | 471 --------------------------------- 1 file changed, 471 deletions(-) delete mode 100644 layout/forms/nsButtonFrameRenderer.cpp (limited to 'layout/forms/nsButtonFrameRenderer.cpp') diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp deleted file mode 100644 index 598610cf72..0000000000 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "nsButtonFrameRenderer.h" -#include "nsCSSRendering.h" -#include "nsPresContext.h" -#include "nsPresContextInlines.h" -#include "nsGkAtoms.h" -#include "nsCSSPseudoElements.h" -#include "nsNameSpaceManager.h" -#include "mozilla/ServoStyleSet.h" -#include "mozilla/Unused.h" -#include "nsDisplayList.h" -#include "nsITheme.h" -#include "nsIFrame.h" -#include "mozilla/dom/Element.h" - -#include "gfxUtils.h" -#include "mozilla/layers/RenderRootStateManager.h" - -using namespace mozilla; -using namespace mozilla::image; -using namespace mozilla::layers; - -namespace mozilla { -class nsDisplayButtonBoxShadowOuter; -class nsDisplayButtonBorder; -class nsDisplayButtonForeground; -} // namespace mozilla - -nsButtonFrameRenderer::nsButtonFrameRenderer() : mFrame(nullptr) { - MOZ_COUNT_CTOR(nsButtonFrameRenderer); -} - -nsButtonFrameRenderer::~nsButtonFrameRenderer() { - MOZ_COUNT_DTOR(nsButtonFrameRenderer); -} - -void nsButtonFrameRenderer::SetFrame(nsIFrame* aFrame, - nsPresContext* aPresContext) { - mFrame = aFrame; - ReResolveStyles(aPresContext); -} - -nsIFrame* nsButtonFrameRenderer::GetFrame() { return mFrame; } - -void nsButtonFrameRenderer::SetDisabled(bool aDisabled, bool aNotify) { - dom::Element* element = mFrame->GetContent()->AsElement(); - if (aDisabled) - element->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, u""_ns, aNotify); - else - element->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, aNotify); -} - -bool nsButtonFrameRenderer::isDisabled() { - return mFrame->GetContent()->AsElement()->IsDisabled(); -} - -nsresult nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder, - nsDisplayList* aBackground, - nsDisplayList* aForeground) { - if (!mFrame->StyleEffects()->mBoxShadow.IsEmpty()) { - aBackground->AppendNewToTop(aBuilder, - GetFrame()); - } - - nsRect buttonRect = - mFrame->GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame); - - const AppendedBackgroundType result = - nsDisplayBackgroundImage::AppendBackgroundItemsToTop( - aBuilder, mFrame, buttonRect, aBackground); - if (result == AppendedBackgroundType::None) { - aBuilder->BuildCompositorHitTestInfoIfNeeded(GetFrame(), aBackground); - } - - aBackground->AppendNewToTop(aBuilder, GetFrame(), - this); - - // Only display focus rings if we actually have them. Since at most one - // button would normally display a focus ring, most buttons won't have them. - if (mInnerFocusStyle && mInnerFocusStyle->StyleBorder()->HasBorder() && - mFrame->IsThemed() && - mFrame->PresContext()->Theme()->ThemeWantsButtonInnerFocusRing()) { - aForeground->AppendNewToTop(aBuilder, GetFrame(), - this); - } - return NS_OK; -} - -void nsButtonFrameRenderer::GetButtonInnerFocusRect(const nsRect& aRect, - nsRect& aResult) { - aResult = aRect; - aResult.Deflate(mFrame->GetUsedBorderAndPadding()); - - if (mInnerFocusStyle) { - nsMargin innerFocusPadding(0, 0, 0, 0); - mInnerFocusStyle->StylePadding()->GetPadding(innerFocusPadding); - - nsMargin framePadding = mFrame->GetUsedPadding(); - - innerFocusPadding.top = std::min(innerFocusPadding.top, framePadding.top); - innerFocusPadding.right = - std::min(innerFocusPadding.right, framePadding.right); - innerFocusPadding.bottom = - std::min(innerFocusPadding.bottom, framePadding.bottom); - innerFocusPadding.left = - std::min(innerFocusPadding.left, framePadding.left); - - aResult.Inflate(innerFocusPadding); - } -} - -ImgDrawResult nsButtonFrameRenderer::PaintInnerFocusBorder( - nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, - gfxContext& aRenderingContext, const nsRect& aDirtyRect, - const nsRect& aRect) { - // we draw the -moz-focus-inner border just inside the button's - // normal border and padding, to match Windows themes. - - nsRect rect; - - PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages() - ? PaintBorderFlags::SyncDecodeImages - : PaintBorderFlags(); - - ImgDrawResult result = ImgDrawResult::SUCCESS; - - if (mInnerFocusStyle) { - GetButtonInnerFocusRect(aRect, rect); - - result &= - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, - aDirtyRect, rect, mInnerFocusStyle, flags); - } - - return result; -} - -Maybe -nsButtonFrameRenderer::CreateInnerFocusBorderRenderer( - nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, - gfxContext* aRenderingContext, const nsRect& aDirtyRect, - const nsRect& aRect, bool* aBorderIsEmpty) { - if (mInnerFocusStyle) { - nsRect rect; - GetButtonInnerFocusRect(aRect, rect); - - gfx::DrawTarget* dt = - aRenderingContext ? aRenderingContext->GetDrawTarget() : nullptr; - return nsCSSRendering::CreateBorderRenderer( - aPresContext, dt, mFrame, aDirtyRect, rect, mInnerFocusStyle, - aBorderIsEmpty); - } - - return Nothing(); -} - -ImgDrawResult nsButtonFrameRenderer::PaintBorder(nsDisplayListBuilder* aBuilder, - nsPresContext* aPresContext, - gfxContext& aRenderingContext, - const nsRect& aDirtyRect, - const nsRect& aRect) { - // get the button rect this is inside the focus and outline rects - nsRect buttonRect = aRect; - ComputedStyle* context = mFrame->Style(); - - PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages() - ? PaintBorderFlags::SyncDecodeImages - : PaintBorderFlags(); - - nsCSSRendering::PaintBoxShadowInner(aPresContext, aRenderingContext, mFrame, - buttonRect); - - ImgDrawResult result = - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, - aDirtyRect, buttonRect, context, borderFlags); - - return result; -} - -/** - * Call this when styles change - */ -void nsButtonFrameRenderer::ReResolveStyles(nsPresContext* aPresContext) { - // get all the styles - ServoStyleSet* styleSet = aPresContext->StyleSet(); - - // get styles assigned to -moz-focus-inner (ie dotted border on Windows) - mInnerFocusStyle = styleSet->ProbePseudoElementStyle( - *mFrame->GetContent()->AsElement(), PseudoStyleType::mozFocusInner, - nullptr, mFrame->Style()); -} - -ComputedStyle* nsButtonFrameRenderer::GetComputedStyle(int32_t aIndex) const { - switch (aIndex) { - case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX: - return mInnerFocusStyle; - default: - return nullptr; - } -} - -void nsButtonFrameRenderer::SetComputedStyle(int32_t aIndex, - ComputedStyle* aComputedStyle) { - switch (aIndex) { - case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX: - mInnerFocusStyle = aComputedStyle; - break; - } -} - -namespace mozilla { - -class nsDisplayButtonBoxShadowOuter : public nsPaintedDisplayItem { - public: - nsDisplayButtonBoxShadowOuter(nsDisplayListBuilder* aBuilder, - nsIFrame* aFrame) - : nsPaintedDisplayItem(aBuilder, aFrame) { - MOZ_COUNT_CTOR(nsDisplayButtonBoxShadowOuter); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonBoxShadowOuter) - - virtual bool CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) override; - - bool CanBuildWebRenderDisplayItems(); - - virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const override; - NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER) -}; - -nsRect nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const { - *aSnap = false; - return mFrame->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); -} - -void nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - nsRect frameRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); - - nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame, - frameRect, GetPaintRect(aBuilder, aCtx)); -} - -bool nsDisplayButtonBoxShadowOuter::CanBuildWebRenderDisplayItems() { - // FIXME(emilio): Is this right? That doesn't make much sense. - if (mFrame->StyleEffects()->mBoxShadow.IsEmpty()) { - return false; - } - - bool hasBorderRadius; - bool nativeTheme = - nsCSSRendering::HasBoxShadowNativeTheme(mFrame, hasBorderRadius); - - // We don't support native themed things yet like box shadows around - // input buttons. - return !nativeTheme; -} - -bool nsDisplayButtonBoxShadowOuter::CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) { - if (!CanBuildWebRenderDisplayItems()) { - return false; - } - int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); - nsRect shadowRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); - LayoutDeviceRect deviceBox = - LayoutDeviceRect::FromAppUnits(shadowRect, appUnitsPerDevPixel); - wr::LayoutRect deviceBoxRect = wr::ToLayoutRect(deviceBox); - - bool dummy; - LayoutDeviceRect clipRect = LayoutDeviceRect::FromAppUnits( - GetBounds(aDisplayListBuilder, &dummy), appUnitsPerDevPixel); - wr::LayoutRect deviceClipRect = wr::ToLayoutRect(clipRect); - - bool hasBorderRadius; - Unused << nsCSSRendering::HasBoxShadowNativeTheme(mFrame, hasBorderRadius); - - LayoutDeviceSize zeroSize; - wr::BorderRadius borderRadius = - wr::ToBorderRadius(zeroSize, zeroSize, zeroSize, zeroSize); - if (hasBorderRadius) { - gfx::RectCornerRadii borderRadii; - hasBorderRadius = nsCSSRendering::GetBorderRadii(shadowRect, shadowRect, - mFrame, borderRadii); - if (hasBorderRadius) { - borderRadius = wr::ToBorderRadius(borderRadii); - } - } - - const Span shadows = - mFrame->StyleEffects()->mBoxShadow.AsSpan(); - MOZ_ASSERT(!shadows.IsEmpty()); - - for (const StyleBoxShadow& shadow : Reversed(shadows)) { - if (shadow.inset) { - continue; - } - float blurRadius = - float(shadow.base.blur.ToAppUnits()) / float(appUnitsPerDevPixel); - gfx::DeviceColor shadowColor = - ToDeviceColor(nsCSSRendering::GetShadowColor(shadow.base, mFrame, 1.0)); - - LayoutDevicePoint shadowOffset = LayoutDevicePoint::FromAppUnits( - nsPoint(shadow.base.horizontal.ToAppUnits(), - shadow.base.vertical.ToAppUnits()), - appUnitsPerDevPixel); - - float spreadRadius = - float(shadow.spread.ToAppUnits()) / float(appUnitsPerDevPixel); - - aBuilder.PushBoxShadow(deviceBoxRect, deviceClipRect, !BackfaceIsHidden(), - deviceBoxRect, wr::ToLayoutVector2D(shadowOffset), - wr::ToColorF(shadowColor), blurRadius, spreadRadius, - borderRadius, wr::BoxShadowClipMode::Outset); - } - return true; -} - -class nsDisplayButtonBorder final : public nsPaintedDisplayItem { - public: - nsDisplayButtonBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsButtonFrameRenderer* aRenderer) - : nsPaintedDisplayItem(aBuilder, aFrame), mBFR(aRenderer) { - MOZ_COUNT_CTOR(nsDisplayButtonBorder); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonBorder) - - virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, - HitTestState* aState, - nsTArray* aOutFrames) override { - aOutFrames->AppendElement(mFrame); - } - virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const override; - virtual bool CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) override; - NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND) - private: - nsButtonFrameRenderer* mBFR; -}; - -bool nsDisplayButtonBorder::CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) { - // This is really a combination of paint box shadow inner + - // paint border. - aBuilder.StartGroup(this); - const nsRect buttonRect = nsRect(ToReferenceFrame(), mFrame->GetSize()); - bool snap; - nsRect visible = GetBounds(aDisplayListBuilder, &snap); - nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands( - aBuilder, aSc, visible, mFrame, buttonRect); - - bool borderIsEmpty = false; - Maybe br = nsCSSRendering::CreateBorderRenderer( - mFrame->PresContext(), nullptr, mFrame, nsRect(), - nsRect(ToReferenceFrame(), mFrame->GetSize()), mFrame->Style(), - &borderIsEmpty, mFrame->GetSkipSides()); - if (!br) { - if (borderIsEmpty) { - aBuilder.FinishGroup(); - } else { - aBuilder.CancelGroup(true); - } - - return borderIsEmpty; - } - - br->CreateWebRenderCommands(this, aBuilder, aResources, aSc); - aBuilder.FinishGroup(); - return true; -} - -void nsDisplayButtonBorder::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - NS_ASSERTION(mFrame, "No frame?"); - nsPresContext* pc = mFrame->PresContext(); - nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - - // draw the border and background inside the focus and outline borders - Unused << mBFR->PaintBorder(aBuilder, pc, *aCtx, GetPaintRect(aBuilder, aCtx), - r); -} - -nsRect nsDisplayButtonBorder::GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const { - *aSnap = false; - return aBuilder->IsForEventDelivery() - ? nsRect(ToReferenceFrame(), mFrame->GetSize()) - : mFrame->InkOverflowRectRelativeToSelf() + ToReferenceFrame(); -} - -class nsDisplayButtonForeground final : public nsPaintedDisplayItem { - public: - nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsButtonFrameRenderer* aRenderer) - : nsPaintedDisplayItem(aBuilder, aFrame), mBFR(aRenderer) { - MOZ_COUNT_CTOR(nsDisplayButtonForeground); - } - MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayButtonForeground) - - void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; - bool CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) override; - NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND) - private: - nsButtonFrameRenderer* mBFR; -}; - -void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder, - gfxContext* aCtx) { - nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - - // Draw the -moz-focus-inner border - Unused << mBFR->PaintInnerFocusBorder(aBuilder, mFrame->PresContext(), *aCtx, - GetPaintRect(aBuilder, aCtx), r); -} - -bool nsDisplayButtonForeground::CreateWebRenderCommands( - mozilla::wr::DisplayListBuilder& aBuilder, - mozilla::wr::IpcResourceUpdateQueue& aResources, - const StackingContextHelper& aSc, - mozilla::layers::RenderRootStateManager* aManager, - nsDisplayListBuilder* aDisplayListBuilder) { - Maybe br; - bool borderIsEmpty = false; - bool dummy; - nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - br = mBFR->CreateInnerFocusBorderRenderer( - aDisplayListBuilder, mFrame->PresContext(), nullptr, - GetBounds(aDisplayListBuilder, &dummy), r, &borderIsEmpty); - - if (!br) { - return borderIsEmpty; - } - - aBuilder.StartGroup(this); - br->CreateWebRenderCommands(this, aBuilder, aResources, aSc); - aBuilder.FinishGroup(); - - return true; -} - -} // namespace mozilla -- cgit v1.2.3