diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 1ef5c1525800..a1d4b1a563a9 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -5288,15 +5288,6 @@ void AddDisplayItemToBottom(nsDisplayListBuilder* aBuilder, aList->AppendToTop(&list); } -void PresShell::AddPrintPreviewBackgroundItem(nsDisplayListBuilder* aBuilder, - nsDisplayList* aList, - nsIFrame* aFrame, - const nsRect& aBounds) { - nsDisplayItem* item = MakeDisplayItem( - aBuilder, aFrame, aBounds, NS_RGB(115, 115, 115)); - AddDisplayItemToBottom(aBuilder, aList, item); -} - static bool AddCanvasBackgroundColor(const nsDisplayList* aList, nsIFrame* aCanvasFrame, nscolor aColor, bool aCSSBackgroundColor) { @@ -5451,33 +5442,28 @@ PresShell::CanvasBackground PresShell::ComputeCanvasBackground() const { // If we have a frame tree and it has style information that // specifies the background color of the canvas, update our local // cache of that color. - nsIFrame* rootStyleFrame = FrameConstructor()->GetRootElementStyleFrame(); - if (!rootStyleFrame) { + nsIFrame* canvas = GetCanvasFrame(); + if (!canvas) { // If the root element of the document (ie html) has style 'display: none' // then the document's background color does not get drawn; return the color // we actually draw. return {GetDefaultBackgroundColorToDraw(), false}; } - const ComputedStyle* bgStyle = - nsCSSRendering::FindRootFrameBackground(rootStyleFrame); - // XXX We should really be passing the canvasframe, not the root element - // style frame but we don't have access to the canvasframe here. It isn't - // a problem because only a few frames can return something other than true - // and none of them would be a canvas frame or root element style frame. + const nsIFrame* bgFrame = nsCSSRendering::FindBackgroundFrame(canvas); nscolor color = NS_RGBA(0, 0, 0, 0); bool drawBackgroundImage = false; bool drawBackgroundColor = false; - const nsStyleDisplay* disp = rootStyleFrame->StyleDisplay(); + const nsStyleDisplay* disp = bgFrame->StyleDisplay(); StyleAppearance appearance = disp->EffectiveAppearance(); - if (rootStyleFrame->IsThemed(disp) && + if (bgFrame->IsThemed(disp) && appearance != StyleAppearance::MozWinBorderlessGlass) { // Ignore the CSS background-color if -moz-appearance is used and it is // not one of the glass values. (Windows 7 Glass has traditionally not // overridden background colors, so we preserve that behavior for now.) } else { color = nsCSSRendering::DetermineBackgroundColor( - mPresContext, bgStyle, rootStyleFrame, drawBackgroundImage, + mPresContext, bgFrame->Style(), canvas, drawBackgroundImage, drawBackgroundColor); } if (!IsTransparentContainerElement()) { diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h index 8cb7831b1519..5b771ba87ea1 100644 --- a/layout/base/PresShell.h +++ b/layout/base/PresShell.h @@ -905,15 +905,6 @@ class PresShell final : public nsStubDocumentObserver, CanvasBackground ComputeCanvasBackground() const; void UpdateCanvasBackground(); - /** - * Add a solid color item to the bottom of aList with frame aFrame and - * bounds aBounds representing the dark grey background behind the page of a - * print preview presentation. - */ - void AddPrintPreviewBackgroundItem(nsDisplayListBuilder* aBuilder, - nsDisplayList* aList, nsIFrame* aFrame, - const nsRect& aBounds); - /** * Computes the backstop color for the view: transparent if in a transparent * widget, otherwise the PresContext default background color. This color is diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 2849c55dabde..0d7e52effa5e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2849,36 +2849,23 @@ void nsLayoutUtils::AddExtraBackgroundItems(nsDisplayListBuilder* aBuilder, const nsRect& aCanvasArea, const nsRegion& aVisibleRegion, nscolor aBackstop) { - LayoutFrameType frameType = aFrame->Type(); - nsPresContext* presContext = aFrame->PresContext(); - PresShell* presShell = presContext->PresShell(); - - // For the viewport frame in print preview/page layout we want to paint - // the grey background behind the page, not the canvas color. - if (frameType == LayoutFrameType::Viewport && - nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) { - nsRect bounds = - nsRect(aBuilder->ToReferenceFrame(aFrame), aFrame->GetSize()); - nsDisplayListBuilder::AutoBuildingDisplayList buildingDisplayList( - aBuilder, aFrame, bounds, bounds); - presShell->AddPrintPreviewBackgroundItem(aBuilder, aList, aFrame, bounds); - } else if (frameType != LayoutFrameType::Page) { + if (aFrame->IsPageFrame()) { // For printing, this function is first called on an nsPageFrame, which // creates a display list with a PageContent item. The PageContent item's - // paint function calls this function on the nsPageFrame's child which is - // an nsPageContentFrame. We only want to add the canvas background color - // item once, for the nsPageContentFrame. - - // Add the canvas background color to the bottom of the list. This - // happens after we've built the list so that AddCanvasBackgroundColorItem - // can monkey with the contents if necessary. - nsRect canvasArea = aVisibleRegion.GetBounds(); - canvasArea.IntersectRect(aCanvasArea, canvasArea); - nsDisplayListBuilder::AutoBuildingDisplayList buildingDisplayList( - aBuilder, aFrame, canvasArea, canvasArea); - presShell->AddCanvasBackgroundColorItem(aBuilder, aList, aFrame, canvasArea, - aBackstop); + // paint function calls this function on the nsPageFrame's child which is an + // nsPageContentFrame. We only want to add the canvas background color item + // once, for the nsPageContentFrame. + return; } + // Add the canvas background color to the bottom of the list. This + // happens after we've built the list so that AddCanvasBackgroundColorItem + // can monkey with the contents if necessary. + nsRect canvasArea = aVisibleRegion.GetBounds(); + canvasArea.IntersectRect(aCanvasArea, canvasArea); + nsDisplayListBuilder::AutoBuildingDisplayList buildingDisplayList( + aBuilder, aFrame, canvasArea, canvasArea); + aFrame->PresShell()->AddCanvasBackgroundColorItem(aBuilder, aList, aFrame, + canvasArea, aBackstop); } // #define PRINT_HITTESTINFO_STATS @@ -8557,12 +8544,6 @@ bool nsLayoutUtils::IsNonWrapperBlock(nsIFrame* aFrame) { return aFrame->IsBlockFrameOrSubclass() && !aFrame->IsBlockWrapper(); } -bool nsLayoutUtils::NeedsPrintPreviewBackground(nsPresContext* aPresContext) { - return aPresContext->IsRootPaginatedDocument() && - (aPresContext->Type() == nsPresContext::eContext_PrintPreview || - aPresContext->Type() == nsPresContext::eContext_PageLayout); -} - AutoMaybeDisableFontInflation::AutoMaybeDisableFontInflation(nsIFrame* aFrame) { // FIXME: Now that inflation calculations are based on the flow // root's NCA's (nearest common ancestor of its inflatable diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index c236184fdb48..a6aac5501435 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -485,21 +485,13 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, bounds = bounds.ScaleToOtherAppUnitsRoundOut(parentAPD, subdocAPD); } - // If we are in print preview/page layout we want to paint the grey - // background behind the page, not the canvas color. The canvas color gets - // painted on the page itself. - if (nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) { - presShell->AddPrintPreviewBackgroundItem(aBuilder, &childItems, frame, - bounds); - } else { - // Add the canvas background color to the bottom of the list. This - // happens after we've built the list so that - // AddCanvasBackgroundColorItem can monkey with the contents if - // necessary. - presShell->AddCanvasBackgroundColorItem( - aBuilder, &childItems, frame, bounds, NS_RGBA(0, 0, 0, 0), - AddCanvasBackgroundColorFlags::ForceDraw); - } + // Add the canvas background color to the bottom of the list. This + // happens after we've built the list so that + // AddCanvasBackgroundColorItem can monkey with the contents if + // necessary. + presShell->AddCanvasBackgroundColorItem( + aBuilder, &childItems, frame, bounds, NS_RGBA(0, 0, 0, 0), + AddCanvasBackgroundColorFlags::ForceDraw); } } diff --git a/layout/painting/nsCSSRendering.cpp b/layout/painting/nsCSSRendering.cpp index ad9c2c1dcbe0..1a1bc3d01f13 100644 --- a/layout/painting/nsCSSRendering.cpp +++ b/layout/painting/nsCSSRendering.cpp @@ -30,10 +30,12 @@ #include "skia/include/core/SkTextBlob.h" #include "BorderConsts.h" +#include "nsCanvasFrame.h" #include "nsStyleConsts.h" #include "nsPresContext.h" #include "nsIFrame.h" #include "nsIFrameInlines.h" +#include "nsPageSequenceFrame.h" #include "nsPoint.h" #include "nsRect.h" #include "nsFrameManager.h" @@ -1127,13 +1129,32 @@ void nsImageRenderer::ComputeObjectAnchorPoint(const Position& aPos, aImageSize.height, &aTopLeft->y, &aAnchorPoint->y); } +// In print / print preview we have multiple canvas frames (one for each page, +// and one for the document as a whole). For the topmost one, we really want the +// page sequence page background, not the root or body's background. +static nsIFrame* GetPageSequenceForCanvas(const nsIFrame* aCanvasFrame) { + MOZ_ASSERT(aCanvasFrame->IsCanvasFrame(), "not a canvas frame"); + nsPresContext* pc = aCanvasFrame->PresContext(); + if (!pc->IsPrintingOrPrintPreview()) { + return nullptr; + } + auto* ps = pc->PresShell()->GetPageSequenceFrame(); + if (!ps) { + return nullptr; + } + if (ps->GetParent() != aCanvasFrame) { + return nullptr; + } + return ps; +} + auto nsCSSRendering::FindEffectiveBackgroundColor(nsIFrame* aFrame, bool aStopAtThemed, bool aPreferBodyToCanvas) -> EffectiveBackgroundColor { MOZ_ASSERT(aFrame); - - auto BgColorIfNotTransparent = [](nsIFrame* aFrame) -> Maybe { + nsPresContext* pc = aFrame->PresContext(); + auto BgColorIfNotTransparent = [&](nsIFrame* aFrame) -> Maybe { nscolor c = aFrame->GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor); if (NS_GET_A(c) == 255) { @@ -1143,7 +1164,7 @@ auto nsCSSRendering::FindEffectiveBackgroundColor(nsIFrame* aFrame, // TODO(emilio): We should maybe just blend with ancestor bg colors and // such, but this is probably good enough for now, matches pre-existing // behavior. - const nscolor defaultBg = aFrame->PresContext()->DefaultBackgroundColor(); + const nscolor defaultBg = pc->DefaultBackgroundColor(); MOZ_ASSERT(NS_GET_A(defaultBg) == 255, "PreferenceSheet guarantees this"); return Some(NS_ComposeColors(defaultBg, c)); } @@ -1161,8 +1182,8 @@ auto nsCSSRendering::FindEffectiveBackgroundColor(nsIFrame* aFrame, } if (frame->IsCanvasFrame()) { - if (aPreferBodyToCanvas) { - if (auto* body = frame->PresContext()->Document()->GetBodyElement()) { + if (aPreferBodyToCanvas && !GetPageSequenceForCanvas(frame)) { + if (auto* body = pc->Document()->GetBodyElement()) { if (nsIFrame* f = body->GetPrimaryFrame()) { if (auto bg = BgColorIfNotTransparent(f)) { return {*bg}; @@ -1178,7 +1199,7 @@ auto nsCSSRendering::FindEffectiveBackgroundColor(nsIFrame* aFrame, } } - return {aFrame->PresContext()->DefaultBackgroundColor()}; + return {pc->DefaultBackgroundColor()}; } nsIFrame* nsCSSRendering::FindBackgroundStyleFrame(nsIFrame* aForFrame) { @@ -1251,6 +1272,20 @@ ComputedStyle* nsCSSRendering::FindRootFrameBackground(nsIFrame* aForFrame) { return FindBackgroundStyleFrame(aForFrame)->Style(); } +static nsIFrame* FindCanvasBackgroundFrame(const nsIFrame* aForFrame, + nsIFrame* aRootElementFrame) { + MOZ_ASSERT(aForFrame->IsCanvasFrame(), "not a canvas frame"); + if (auto* ps = GetPageSequenceForCanvas(aForFrame)) { + return ps; + } + if (aRootElementFrame) { + return nsCSSRendering::FindBackgroundStyleFrame(aRootElementFrame); + } + // This should always give transparent, so we'll fill it in with the default + // color if needed. This seems to happen a bit while a page is being loaded. + return const_cast(aForFrame); +} + // Helper for FindBackgroundFrame. Returns true if aForFrame has a meaningful // background that it should draw (i.e. that it hasn't propagated to another // frame). See documentation for FindBackground. diff --git a/layout/painting/nsCSSRendering.h b/layout/painting/nsCSSRendering.h index 6d71761c55c8..2e813ff1db7c 100644 --- a/layout/painting/nsCSSRendering.h +++ b/layout/painting/nsCSSRendering.h @@ -296,36 +296,6 @@ struct nsCSSRendering { */ static mozilla::ComputedStyle* FindRootFrameBackground(nsIFrame* aForFrame); - /** - * Returns background style information for the canvas. - * - * @param aForFrame - * the frame used to represent the canvas, in the CSS sense (i.e. - * aForFrame->IsCanvasFrame() must be true) - * @param aRootElementFrame - * the frame representing the root element of the document - * @param aBackground - * contains background style information for the canvas on return - */ - - static nsIFrame* FindCanvasBackgroundFrame(const nsIFrame* aForFrame, - nsIFrame* aRootElementFrame) { - MOZ_ASSERT(aForFrame->IsCanvasFrame(), "not a canvas frame"); - if (aRootElementFrame) { - return FindBackgroundStyleFrame(aRootElementFrame); - } - - // This should always give transparent, so we'll fill it in with the - // default color if needed. This seems to happen a bit while a page is - // being loaded. - return const_cast(aForFrame); - } - - static mozilla::ComputedStyle* FindCanvasBackground( - nsIFrame* aForFrame, nsIFrame* aRootElementFrame) { - return FindCanvasBackgroundFrame(aForFrame, aRootElementFrame)->Style(); - } - /** * Find a non-transparent background color on an ancestor, for various * contrast checks. Note that this only accounts for background-color and diff --git a/layout/style/res/ua.css b/layout/style/res/ua.css index d05914c8346b..71a0ad87d6af 100644 --- a/layout/style/res/ua.css +++ b/layout/style/res/ua.css @@ -301,7 +301,7 @@ /* Collection of pages in print/print preview. Visual styles may only appear * in print preview. */ display: block; - background: linear-gradient(#606060, #8a8a8a) fixed; + background: #606060 linear-gradient(#606060, #8a8a8a) fixed; print-color-adjust: exact; /* We always fill the available space in both directions */ height: 100%;