/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "RenderView.h"

#include "Document.h"
#include "Element.h"
#include "FloatQuad.h"
#include "FloatingObjects.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLBodyElement.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLHtmlElement.h"
#include "HTMLIFrameElement.h"
#include "HitTestResult.h"
#include "ImageQualityController.h"
#include "LayoutState.h"
#include "NodeTraversal.h"
#include "Page.h"
#include "RenderDescendantIterator.h"
#include "RenderGeometryMap.h"
#include "RenderIterator.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
#include "RenderLayerCompositor.h"
#include "RenderMultiColumnFlow.h"
#include "RenderMultiColumnSet.h"
#include "RenderMultiColumnSpannerPlaceholder.h"
#include "RenderQuote.h"
#include "RenderTreeBuilder.h"
#include "RenderWidget.h"
#include "ScrollbarTheme.h"
#include "Settings.h"
#include "StyleInheritedData.h"
#include "TransformState.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/SetForScope.h>
#include <wtf/StackStats.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(RenderView);

struct FrameFlatteningLayoutDisallower {
    FrameFlatteningLayoutDisallower(FrameView& frameView)
        : m_frameView(frameView)
        , m_disallowLayout(frameView.effectiveFrameFlattening() != FrameFlattening::Disabled)
    {
        if (m_disallowLayout)
            m_frameView.startDisallowingLayout();
    }

    ~FrameFlatteningLayoutDisallower()
    {
        if (m_disallowLayout)
            m_frameView.endDisallowingLayout();
    }

private:
    FrameView& m_frameView;
    bool m_disallowLayout { false };
};

RenderView::RenderView(Document& document, RenderStyle&& style)
    : RenderBlockFlow(document, WTFMove(style))
    , m_frameView(*document.view())
    , m_selection(*this)
    , m_lazyRepaintTimer(*this, &RenderView::lazyRepaintTimerFired)
{
    setIsRenderView();

    // FIXME: We should find a way to enforce this at compile time.
    ASSERT(document.view());

    // init RenderObject attributes
    setInline(false);
    
    m_minPreferredLogicalWidth = 0;
    m_maxPreferredLogicalWidth = 0;

    setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
    
    setPositionState(AbsolutePosition); // to 0,0 :)
}

RenderView::~RenderView()
{
    ASSERT_WITH_MESSAGE(m_rendererCount == 1, "All other renderers in this render tree should have been destroyed");
}

void RenderView::scheduleLazyRepaint(RenderBox& renderer)
{
    if (renderer.renderBoxNeedsLazyRepaint())
        return;
    renderer.setRenderBoxNeedsLazyRepaint(true);
    m_renderersNeedingLazyRepaint.add(&renderer);
    if (!m_lazyRepaintTimer.isActive())
        m_lazyRepaintTimer.startOneShot(0_s);
}

void RenderView::unscheduleLazyRepaint(RenderBox& renderer)
{
    if (!renderer.renderBoxNeedsLazyRepaint())
        return;
    renderer.setRenderBoxNeedsLazyRepaint(false);
    m_renderersNeedingLazyRepaint.remove(&renderer);
    if (m_renderersNeedingLazyRepaint.isEmpty())
        m_lazyRepaintTimer.stop();
}

void RenderView::lazyRepaintTimerFired()
{
    for (auto& renderer : m_renderersNeedingLazyRepaint) {
        renderer->repaint();
        renderer->setRenderBoxNeedsLazyRepaint(false);
    }
    m_renderersNeedingLazyRepaint.clear();
}

bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
{
    return hitTest(request, result.hitTestLocation(), result);
}

bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
{
    document().updateLayout();
    
#if !ASSERT_DISABLED
    SetForScope<bool> hitTestRestorer { m_inHitTesting, true };
#endif

    FrameFlatteningLayoutDisallower disallower(frameView());

    bool resultLayer = layer()->hitTest(request, location, result);

    // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls,
    // so we need to test ScrollView scrollbars separately here. In case of using overlay scrollbars, the layer hit test
    // will always work so we need to check the ScrollView scrollbars in that case too.
    if (!resultLayer || ScrollbarTheme::theme().usesOverlayScrollbars()) {
        // FIXME: Consider if this test should be done unconditionally.
        if (request.allowsFrameScrollbars()) {
            IntPoint windowPoint = frameView().contentsToWindow(location.roundedPoint());
            if (Scrollbar* frameScrollbar = frameView().scrollbarAtPoint(windowPoint)) {
                result.setScrollbar(frameScrollbar);
                return true;
            }
        }
    }

    return resultLayer;
}

RenderBox::LogicalExtentComputedValues RenderView::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit) const
{
    return { !shouldUsePrintingLayout() ? LayoutUnit(viewLogicalHeight()) : logicalHeight, LayoutUnit(), ComputedMarginValues() };
}

void RenderView::updateLogicalWidth()
{
    setLogicalWidth(shouldUsePrintingLayout() ? m_pageLogicalSize->width() : LayoutUnit(viewLogicalWidth()));
}

LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType) const
{
    // Make sure block progression pagination for percentages uses the column extent and
    // not the view's extent. See https://bugs.webkit.org/show_bug.cgi?id=135204.
    if (multiColumnFlow() && multiColumnFlow()->firstMultiColumnSet())
        return multiColumnFlow()->firstMultiColumnSet()->computedColumnHeight();

#if PLATFORM(IOS)
    // Workaround for <rdar://problem/7166808>.
    if (document().isPluginDocument() && frameView().useFixedLayout())
        return frameView().fixedLayoutSize().height();
#endif
    return isHorizontalWritingMode() ? frameView().visibleHeight() : frameView().visibleWidth();
}

bool RenderView::isChildAllowed(const RenderObject& child, const RenderStyle&) const
{
    return child.isBox();
}

void RenderView::layout()
{
    StackStats::LayoutCheckPoint layoutCheckPoint;
    if (!document().paginated())
        m_pageLogicalSize = { };

    if (shouldUsePrintingLayout()) {
        if (!m_pageLogicalSize)
            m_pageLogicalSize = LayoutSize(logicalWidth(), 0);
        m_minPreferredLogicalWidth = m_pageLogicalSize->width();
        m_maxPreferredLogicalWidth = m_minPreferredLogicalWidth;
    }

    // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
    bool relayoutChildren = !shouldUsePrintingLayout() && (width() != viewWidth() || height() != viewHeight());
    if (relayoutChildren) {
        setChildNeedsLayout(MarkOnlyThis);

        for (auto& box : childrenOfType<RenderBox>(*this)) {
            if (box.hasRelativeLogicalHeight()
                || box.style().logicalHeight().isPercentOrCalculated()
                || box.style().logicalMinHeight().isPercentOrCalculated()
                || box.style().logicalMaxHeight().isPercentOrCalculated()
                || box.isSVGRoot()
                )
                box.setChildNeedsLayout(MarkOnlyThis);
        }
    }

    ASSERT(!frameView().layoutContext().layoutState());
    if (!needsLayout())
        return;

    LayoutStateMaintainer statePusher(*this, { }, false, m_pageLogicalSize.value_or(LayoutSize()).height(), m_pageLogicalHeightChanged);

    m_pageLogicalHeightChanged = false;

    RenderBlockFlow::layout();

#ifndef NDEBUG
    frameView().layoutContext().checkLayoutState();
#endif
    clearNeedsLayout();
}

LayoutUnit RenderView::pageOrViewLogicalHeight() const
{
    if (document().printing())
        return m_pageLogicalSize->height();
    
    if (multiColumnFlow() && !style().hasInlineColumnAxis()) {
        if (int pageLength = frameView().pagination().pageLength)
            return pageLength;
    }

    return viewLogicalHeight();
}

LayoutUnit RenderView::clientLogicalWidthForFixedPosition() const
{
    // FIXME: If the FrameView's fixedVisibleContentRect() is not empty, perhaps it should be consulted here too?
    if (frameView().fixedElementsLayoutRelativeToFrame())
        return (isHorizontalWritingMode() ? frameView().visibleWidth() : frameView().visibleHeight()) / frameView().frame().frameScaleFactor();

#if PLATFORM(IOS)
    if (frameView().useCustomFixedPositionLayoutRect())
        return isHorizontalWritingMode() ? frameView().customFixedPositionLayoutRect().width() : frameView().customFixedPositionLayoutRect().height();
#endif

    if (settings().visualViewportEnabled())
        return isHorizontalWritingMode() ? frameView().layoutViewportRect().width() : frameView().layoutViewportRect().height();

    return clientLogicalWidth();
}

LayoutUnit RenderView::clientLogicalHeightForFixedPosition() const
{
    // FIXME: If the FrameView's fixedVisibleContentRect() is not empty, perhaps it should be consulted here too?
    if (frameView().fixedElementsLayoutRelativeToFrame())
        return (isHorizontalWritingMode() ? frameView().visibleHeight() : frameView().visibleWidth()) / frameView().frame().frameScaleFactor();

#if PLATFORM(IOS)
    if (frameView().useCustomFixedPositionLayoutRect())
        return isHorizontalWritingMode() ? frameView().customFixedPositionLayoutRect().height() : frameView().customFixedPositionLayoutRect().width();
#endif

    if (settings().visualViewportEnabled())
        return isHorizontalWritingMode() ? frameView().layoutViewportRect().height() : frameView().layoutViewportRect().width();

    return clientLogicalHeight();
}

void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
{
    // If a container was specified, and was not nullptr or the RenderView,
    // then we should have found it by now.
    ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
    ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == (mode & IsFixed));

    if (mode & IsFixed)
        transformState.move(toLayoutSize(frameView().scrollPositionRespectingCustomFixedPosition()));

    if (!repaintContainer && mode & UseTransforms && shouldUseTransformFromContainer(nullptr)) {
        TransformationMatrix t;
        getTransformFromContainer(nullptr, LayoutSize(), t);
        transformState.applyTransform(t);
    }
}

const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
{
    // If a container was specified, and was not nullptr or the RenderView,
    // then we should have found it by now.
    ASSERT_ARG(ancestorToStopAt, !ancestorToStopAt || ancestorToStopAt == this);

    LayoutPoint scrollPosition = frameView().scrollPositionRespectingCustomFixedPosition();

    if (!ancestorToStopAt && shouldUseTransformFromContainer(nullptr)) {
        TransformationMatrix t;
        getTransformFromContainer(nullptr, LayoutSize(), t);
        geometryMap.pushView(this, toLayoutSize(scrollPosition), &t);
    } else
        geometryMap.pushView(this, toLayoutSize(scrollPosition));

    return nullptr;
}

void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
{
    if (mode & UseTransforms && shouldUseTransformFromContainer(nullptr)) {
        TransformationMatrix t;
        getTransformFromContainer(nullptr, LayoutSize(), t);
        transformState.applyTransform(t);
    }

    if (mode & IsFixed)
        transformState.move(toLayoutSize(frameView().scrollPositionRespectingCustomFixedPosition()));
}

bool RenderView::requiresColumns(int) const
{
    return frameView().pagination().mode != Pagination::Unpaginated;
}

void RenderView::computeColumnCountAndWidth()
{
    int columnWidth = contentLogicalWidth();
    if (style().hasInlineColumnAxis()) {
        if (int pageLength = frameView().pagination().pageLength)
            columnWidth = pageLength;
    }
    setComputedColumnCountAndWidth(1, columnWidth);
}

void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
    ASSERT(!needsLayout());
    // RenderViews should never be called to paint with an offset not on device pixels.
    ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset);

    // This avoids painting garbage between columns if there is a column gap.
    if (frameView().pagination().mode != Pagination::Unpaginated && paintInfo.shouldPaintWithinRoot(*this))
        paintInfo.context().fillRect(paintInfo.rect, frameView().baseBackgroundColor());

    paintObject(paintInfo, paintOffset);
}

RenderElement* RenderView::rendererForRootBackground() const
{
    auto* firstChild = this->firstChild();
    if (!firstChild)
        return nullptr;
    ASSERT(is<RenderElement>(*firstChild));
    auto& documentRenderer = downcast<RenderElement>(*firstChild);

    if (documentRenderer.hasBackground())
        return &documentRenderer;

    // We propagate the background only for HTML content.
    if (!is<HTMLHtmlElement>(documentRenderer.element()))
        return &documentRenderer;

    if (auto* body = document().body()) {
        if (auto* renderer = body->renderer())
            return renderer;
    }
    return &documentRenderer;
}

static inline bool rendererObscuresBackground(const RenderElement& rootElement)
{
    auto& style = rootElement.style();
    if (style.visibility() != VISIBLE || style.opacity() != 1 || style.hasTransform())
        return false;

    if (style.hasBorderRadius())
        return false;

    if (rootElement.isComposited())
        return false;

    auto* rendererForBackground = rootElement.view().rendererForRootBackground();
    if (!rendererForBackground)
        return false;

    if (rendererForBackground->style().backgroundClip() == TextFillBox)
        return false;

    return true;
}

void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
{
    if (!paintInfo.shouldPaintWithinRoot(*this))
        return;

    // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
    // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
    // layers with reflections, or transformed layers.
    // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
    // a transform, transparency layer, etc.
    for (HTMLFrameOwnerElement* element = document().ownerElement(); element && element->renderer(); element = element->document().ownerElement()) {
        RenderLayer* layer = element->renderer()->enclosingLayer();
        if (layer->cannotBlitToWindow()) {
            frameView().setCannotBlitToWindow();
            break;
        }

        if (RenderLayer* compositingLayer = layer->enclosingCompositingLayerForRepaint()) {
            if (!compositingLayer->backing()->paintsIntoWindow()) {
                frameView().setCannotBlitToWindow();
                break;
            }
        }
    }

    if (document().ownerElement())
        return;

    if (paintInfo.skipRootBackground())
        return;

    bool rootFillsViewport = false;
    bool rootObscuresBackground = false;
    Element* documentElement = document().documentElement();
    if (RenderElement* rootRenderer = documentElement ? documentElement->renderer() : nullptr) {
        // The document element's renderer is currently forced to be a block, but may not always be.
        RenderBox* rootBox = is<RenderBox>(*rootRenderer) ? downcast<RenderBox>(rootRenderer) : nullptr;
        rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
        rootObscuresBackground = rendererObscuresBackground(*rootRenderer);
    }

    bool backgroundShouldExtendBeyondPage = settings().backgroundShouldExtendBeyondPage();
    compositor().setRootExtendedBackgroundColor(backgroundShouldExtendBeyondPage ? frameView().documentBackgroundColor() : Color());

    Page* page = document().page();
    float pageScaleFactor = page ? page->pageScaleFactor() : 1;

    // If painting will entirely fill the view, no need to fill the background.
    if (rootFillsViewport && rootObscuresBackground && pageScaleFactor >= 1)
        return;

    // This code typically only executes if the root element's visibility has been set to hidden,
    // if there is a transform on the <html>, or if there is a page scale factor less than 1.
    // Only fill with a background color (typically white) if we're the root document, 
    // since iframes/frames with no background in the child document should show the parent's background.
    // We use the base background color unless the backgroundShouldExtendBeyondPage setting is set,
    // in which case we use the document's background color.
    if (frameView().isTransparent()) // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
        frameView().setCannotBlitToWindow(); // The parent must show behind the child.
    else {
        const Color& documentBackgroundColor = frameView().documentBackgroundColor();
        const Color& backgroundColor = (backgroundShouldExtendBeyondPage && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView().baseBackgroundColor();
        if (backgroundColor.isVisible()) {
            CompositeOperator previousOperator = paintInfo.context().compositeOperation();
            paintInfo.context().setCompositeOperation(CompositeCopy);
            paintInfo.context().fillRect(paintInfo.rect, backgroundColor);
            paintInfo.context().setCompositeOperation(previousOperator);
        } else
            paintInfo.context().clearRect(paintInfo.rect);
    }
}

bool RenderView::shouldRepaint(const LayoutRect& rect) const
{
    return !printing() && !rect.isEmpty();
}

void RenderView::repaintRootContents()
{
    if (layer()->isComposited()) {
        layer()->setBackingNeedsRepaint(GraphicsLayer::DoNotClipToLayer);
        return;
    }

    // Always use layoutOverflowRect() to fix rdar://problem/27182267.
    // This should be cleaned up via webkit.org/b/159913 and webkit.org/b/159914.
    RenderLayerModelObject* repaintContainer = containerForRepaint();
    repaintUsingContainer(repaintContainer, computeRectForRepaint(layoutOverflowRect(), repaintContainer));
}

void RenderView::repaintViewRectangle(const LayoutRect& repaintRect) const
{
    if (!shouldRepaint(repaintRect))
        return;

    // FIXME: enclosingRect is needed as long as we integral snap ScrollView/FrameView/RenderWidget size/position.
    IntRect enclosingRect = enclosingIntRect(repaintRect);
    if (auto ownerElement = document().ownerElement()) {
        RenderBox* ownerBox = ownerElement->renderBox();
        if (!ownerBox)
            return;
        LayoutRect viewRect = this->viewRect();
#if PLATFORM(IOS)
        // Don't clip using the visible rect since clipping is handled at a higher level on iPhone.
        LayoutRect adjustedRect = enclosingRect;
#else
        LayoutRect adjustedRect = intersection(enclosingRect, viewRect);
#endif
        adjustedRect.moveBy(-viewRect.location());
        adjustedRect.moveBy(ownerBox->contentBoxRect().location());

        // A dirty rect in an iframe is relative to the contents of that iframe.
        // When we traverse between parent frames and child frames, we need to make sure
        // that the coordinate system is mapped appropriately between the iframe's contents
        // and the Renderer that contains the iframe. This transformation must account for a
        // left scrollbar (if one exists).
        FrameView& frameView = this->frameView();
        if (frameView.shouldPlaceBlockDirectionScrollbarOnLeft() && frameView.verticalScrollbar())
            adjustedRect.move(LayoutSize(frameView.verticalScrollbar()->occupiedWidth(), 0));

        ownerBox->repaintRectangle(adjustedRect);
        return;
    }

    frameView().addTrackedRepaintRect(snapRectToDevicePixels(repaintRect, document().deviceScaleFactor()));
    if (!m_accumulatedRepaintRegion) {
        frameView().repaintContentRectangle(enclosingRect);
        return;
    }
    m_accumulatedRepaintRegion->unite(enclosingRect);

    // Region will get slow if it gets too complex. Merge all rects so far to bounds if this happens.
    // FIXME: Maybe there should be a region type that does this automatically.
    static const unsigned maximumRepaintRegionGridSize = 16 * 16;
    if (m_accumulatedRepaintRegion->gridSize() > maximumRepaintRegionGridSize)
        m_accumulatedRepaintRegion = std::make_unique<Region>(m_accumulatedRepaintRegion->bounds());
}

void RenderView::flushAccumulatedRepaintRegion() const
{
    ASSERT(!document().ownerElement());
    ASSERT(m_accumulatedRepaintRegion);
    auto repaintRects = m_accumulatedRepaintRegion->rects();
    for (auto& rect : repaintRects)
        frameView().repaintContentRectangle(rect);
    m_accumulatedRepaintRegion = nullptr;
}

void RenderView::repaintViewAndCompositedLayers()
{
    repaintRootContents();

    RenderLayerCompositor& compositor = this->compositor();
    if (compositor.inCompositingMode())
        compositor.repaintCompositedLayers();
}

LayoutRect RenderView::visualOverflowRect() const
{
    if (frameView().paintsEntireContents())
        return layoutOverflowRect();

    return RenderBlockFlow::visualOverflowRect();
}

LayoutRect RenderView::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const
{
    // If a container was specified, and was not nullptr or the RenderView,
    // then we should have found it by now.
    ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);

    if (printing())
        return rect;
    
    LayoutRect adjustedRect = rect;
    if (style().isFlippedBlocksWritingMode()) {
        // We have to flip by hand since the view's logical height has not been determined.  We
        // can use the viewport width and height.
        if (style().isHorizontalWritingMode())
            adjustedRect.setY(viewHeight() - adjustedRect.maxY());
        else
            adjustedRect.setX(viewWidth() - adjustedRect.maxX());
    }

    if (context.m_hasPositionFixedDescendant)
        adjustedRect.moveBy(frameView().scrollPositionRespectingCustomFixedPosition());
    
    // Apply our transform if we have one (because of full page zooming).
    if (!repaintContainer && layer() && layer()->transform())
        adjustedRect = LayoutRect(layer()->transform()->mapRect(snapRectToDevicePixels(adjustedRect, document().deviceScaleFactor())));
    return adjustedRect;
}

bool RenderView::isScrollableOrRubberbandableBox() const
{
    // The main frame might be allowed to rubber-band even if there is no content to scroll to. This is unique to
    // the main frame; subframes and overflow areas have to have content that can be scrolled to in order to rubber-band.
    FrameView::Scrollability defineScrollable = frame().ownerElement() ? FrameView::Scrollability::Scrollable : FrameView::Scrollability::ScrollableOrRubberbandable;
    return frameView().isScrollable(defineScrollable);
}

void RenderView::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
{
    rects.append(snappedIntRect(accumulatedOffset, layer()->size()));
}

void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
{
    if (wasFixed)
        *wasFixed = false;
    quads.append(FloatRect(FloatPoint(), layer()->size()));
}

bool RenderView::printing() const
{
    return document().printing();
}

bool RenderView::shouldUsePrintingLayout() const
{
    if (!printing())
        return false;
    return frameView().frame().shouldUsePrintingLayout();
}

LayoutRect RenderView::viewRect() const
{
    if (shouldUsePrintingLayout())
        return LayoutRect(LayoutPoint(), size());
    return frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect);
}

IntRect RenderView::unscaledDocumentRect() const
{
    LayoutRect overflowRect(layoutOverflowRect());
    flipForWritingMode(overflowRect);
    return snappedIntRect(overflowRect);
}

bool RenderView::rootBackgroundIsEntirelyFixed() const
{
    if (auto* rootBackgroundRenderer = rendererForRootBackground())
        return rootBackgroundRenderer->style().hasEntirelyFixedBackground();
    return false;
}
    
LayoutRect RenderView::unextendedBackgroundRect() const
{
    // FIXME: What is this? Need to patch for new columns?
    return unscaledDocumentRect();
}
    
LayoutRect RenderView::backgroundRect() const
{
    // FIXME: New columns care about this?
    if (frameView().hasExtendedBackgroundRectForPainting())
        return frameView().extendedBackgroundRectForPainting();

    return unextendedBackgroundRect();
}

IntRect RenderView::documentRect() const
{
    FloatRect overflowRect(unscaledDocumentRect());
    if (hasTransform())
        overflowRect = layer()->currentTransform().mapRect(overflowRect);
    return IntRect(overflowRect);
}

int RenderView::viewHeight() const
{
    int height = 0;
    if (!shouldUsePrintingLayout()) {
        height = frameView().layoutHeight();
        height = frameView().useFixedLayout() ? ceilf(style().effectiveZoom() * float(height)) : height;
    }
    return height;
}

int RenderView::viewWidth() const
{
    int width = 0;
    if (!shouldUsePrintingLayout()) {
        width = frameView().layoutWidth();
        width = frameView().useFixedLayout() ? ceilf(style().effectiveZoom() * float(width)) : width;
    }
    return width;
}

int RenderView::viewLogicalHeight() const
{
    int height = style().isHorizontalWritingMode() ? viewHeight() : viewWidth();
    return height;
}

void RenderView::setPageLogicalSize(LayoutSize size)
{
    if (!m_pageLogicalSize || m_pageLogicalSize->height() != size.height())
        m_pageLogicalHeightChanged = true;

    m_pageLogicalSize = size;
}

float RenderView::zoomFactor() const
{
    return frameView().frame().pageZoomFactor();
}

IntSize RenderView::viewportSizeForCSSViewportUnits() const
{
    return frameView().viewportSizeForCSSViewportUnits();
}

void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
{
    if (result.innerNode())
        return;

    if (multiColumnFlow() && multiColumnFlow()->firstMultiColumnSet())
        return multiColumnFlow()->firstMultiColumnSet()->updateHitTestResult(result, point);

    Node* node = document().documentElement();
    if (node) {
        result.setInnerNode(node);
        if (!result.innerNonSharedNode())
            result.setInnerNonSharedNode(node);

        LayoutPoint adjustedPoint = point;
        offsetForContents(adjustedPoint);

        result.setLocalPoint(adjustedPoint);
    }
}

// FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
// Do not add callers of this function!
// The idea here is to take into account what object is moving the pagination point, and
// thus choose the best place to chop it.
void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
{
    // Nobody else can set a page break once we have a forced break.
    if (m_legacyPrinting.m_forcedPageBreak)
        return;

    // Forced breaks always win over unforced breaks.
    if (forcedBreak) {
        m_legacyPrinting.m_forcedPageBreak = true;
        m_legacyPrinting.m_bestTruncatedAt = y;
        return;
    }

    // Prefer the widest object that tries to move the pagination point
    LayoutRect boundingBox = forRenderer->borderBoundingBox();
    if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
        m_legacyPrinting.m_truncatorWidth = boundingBox.width();
        m_legacyPrinting.m_bestTruncatedAt = y;
    }
}

bool RenderView::usesCompositing() const
{
    return m_compositor && m_compositor->inCompositingMode();
}

RenderLayerCompositor& RenderView::compositor()
{
    if (!m_compositor)
        m_compositor = std::make_unique<RenderLayerCompositor>(*this);

    return *m_compositor;
}

void RenderView::setIsInWindow(bool isInWindow)
{
    if (m_compositor)
        m_compositor->setIsInWindow(isInWindow);
}

void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    RenderBlockFlow::styleDidChange(diff, oldStyle);

    frameView().styleDidChange();
}

ImageQualityController& RenderView::imageQualityController()
{
    if (!m_imageQualityController)
        m_imageQualityController = std::make_unique<ImageQualityController>(*this);
    return *m_imageQualityController;
}

void RenderView::registerForVisibleInViewportCallback(RenderElement& renderer)
{
    ASSERT(!m_visibleInViewportRenderers.contains(&renderer));
    m_visibleInViewportRenderers.add(&renderer);
}

void RenderView::unregisterForVisibleInViewportCallback(RenderElement& renderer)
{
    ASSERT(m_visibleInViewportRenderers.contains(&renderer));
    m_visibleInViewportRenderers.remove(&renderer);
}

void RenderView::updateVisibleViewportRect(const IntRect& visibleRect)
{
    resumePausedImageAnimationsIfNeeded(visibleRect);

    for (auto* renderer : m_visibleInViewportRenderers) {
        auto state = visibleRect.intersects(enclosingIntRect(renderer->absoluteClippedOverflowRect())) ? VisibleInViewportState::Yes : VisibleInViewportState::No;
        renderer->setVisibleInViewportState(state);
    }
}

void RenderView::addRendererWithPausedImageAnimations(RenderElement& renderer, CachedImage& image)
{
    ASSERT(!renderer.hasPausedImageAnimations() || m_renderersWithPausedImageAnimation.contains(&renderer));

    renderer.setHasPausedImageAnimations(true);
    auto& images = m_renderersWithPausedImageAnimation.ensure(&renderer, [] {
        return Vector<CachedImage*>();
    }).iterator->value;
    if (!images.contains(&image))
        images.append(&image);
}

void RenderView::removeRendererWithPausedImageAnimations(RenderElement& renderer)
{
    ASSERT(renderer.hasPausedImageAnimations());
    ASSERT(m_renderersWithPausedImageAnimation.contains(&renderer));

    renderer.setHasPausedImageAnimations(false);
    m_renderersWithPausedImageAnimation.remove(&renderer);
}

void RenderView::removeRendererWithPausedImageAnimations(RenderElement& renderer, CachedImage& image)
{
    ASSERT(renderer.hasPausedImageAnimations());

    auto it = m_renderersWithPausedImageAnimation.find(&renderer);
    ASSERT(it != m_renderersWithPausedImageAnimation.end());

    auto& images = it->value;
    if (!images.contains(&image))
        return;

    if (images.size() == 1)
        removeRendererWithPausedImageAnimations(renderer);
    else
        images.removeFirst(&image);
}

void RenderView::resumePausedImageAnimationsIfNeeded(IntRect visibleRect)
{
    Vector<std::pair<RenderElement*, CachedImage*>, 10> toRemove;
    for (auto& it : m_renderersWithPausedImageAnimation) {
        auto* renderer = it.key;
        for (auto* image : it.value) {
            if (renderer->repaintForPausedImageAnimationsIfNeeded(visibleRect, *image))
                toRemove.append(std::make_pair(renderer, image));
        }
    }
    for (auto& pair : toRemove)
        removeRendererWithPausedImageAnimations(*pair.first, *pair.second);
}

RenderView::RepaintRegionAccumulator::RepaintRegionAccumulator(RenderView* view)
{
    if (!view)
        return;

    auto* rootRenderView = view->document().topDocument().renderView();
    if (!rootRenderView)
        return;

    m_wasAccumulatingRepaintRegion = !!rootRenderView->m_accumulatedRepaintRegion;
    if (!m_wasAccumulatingRepaintRegion)
        rootRenderView->m_accumulatedRepaintRegion = std::make_unique<Region>();
    m_rootView = makeWeakPtr(*rootRenderView);
}

RenderView::RepaintRegionAccumulator::~RepaintRegionAccumulator()
{
    if (m_wasAccumulatingRepaintRegion)
        return;
    if (!m_rootView)
        return;
    m_rootView.get()->flushAccumulatedRepaintRegion();
}

unsigned RenderView::pageNumberForBlockProgressionOffset(int offset) const
{
    int columnNumber = 0;
    const Pagination& pagination = page().pagination();
    if (pagination.mode == Pagination::Unpaginated)
        return columnNumber;
    
    bool progressionIsInline = false;
    bool progressionIsReversed = false;
    
    if (multiColumnFlow()) {
        progressionIsInline = multiColumnFlow()->progressionIsInline();
        progressionIsReversed = multiColumnFlow()->progressionIsReversed();
    } else
        return columnNumber;
    
    if (!progressionIsInline) {
        if (!progressionIsReversed)
            columnNumber = (pagination.pageLength + pagination.gap - offset) / (pagination.pageLength + pagination.gap);
        else
            columnNumber = offset / (pagination.pageLength + pagination.gap);
    }

    return columnNumber;
}

unsigned RenderView::pageCount() const
{
    const Pagination& pagination = page().pagination();
    if (pagination.mode == Pagination::Unpaginated)
        return 0;
    
    if (multiColumnFlow() && multiColumnFlow()->firstMultiColumnSet())
        return multiColumnFlow()->firstMultiColumnSet()->columnCount();

    return 0;
}

#if ENABLE(CSS_SCROLL_SNAP)
void RenderView::registerBoxWithScrollSnapPositions(const RenderBox& box)
{
    m_boxesWithScrollSnapPositions.add(&box);
}

void RenderView::unregisterBoxWithScrollSnapPositions(const RenderBox& box)
{
    m_boxesWithScrollSnapPositions.remove(&box);
}
#endif

} // namespace WebCore
