/*
 * Copyright (C) 2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "InlineBoxPainter.h"

#include "GraphicsContext.h"
#include "InlineIteratorLineBox.h"
#include "LegacyInlineFlowBox.h"
#include "PaintInfo.h"
#include "RenderBlockFlow.h"
#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderView.h"

namespace WebCore {

InlineBoxPainter::InlineBoxPainter(const LegacyInlineFlowBox& inlineBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    : InlineBoxPainter(*InlineIterator::inlineBoxFor(inlineBox), paintInfo, paintOffset)
{
}

#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
InlineBoxPainter::InlineBoxPainter(const LayoutIntegration::InlineContent& inlineContent, const InlineDisplay::Box& box, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    : InlineBoxPainter(*InlineIterator::inlineBoxFor(inlineContent, box), paintInfo, paintOffset)
{
}
#endif

InlineBoxPainter::InlineBoxPainter(const InlineIterator::InlineBox& inlineBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    : m_inlineBox(inlineBox)
    , m_paintInfo(paintInfo)
    , m_paintOffset(paintOffset)
    , m_renderer(m_inlineBox.renderer())
    , m_isFirstLineBox(m_inlineBox.lineBox()->isFirst())
    , m_isRootInlineBox(m_inlineBox.isRootInlineBox())
    , m_isHorizontal(m_inlineBox.isHorizontal())
{
}

InlineBoxPainter::~InlineBoxPainter() = default;

void InlineBoxPainter::paint()
{
    if (m_paintInfo.phase == PaintPhase::Outline || m_paintInfo.phase == PaintPhase::SelfOutline) {
        if (renderer().style().visibility() != Visibility::Visible || !renderer().hasOutline() || m_isRootInlineBox)
            return;

        auto& inlineFlow = downcast<RenderInline>(renderer());
        RenderBlock* containingBlock = nullptr;

        bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isContinuation();
        if (containingBlockPaintsContinuationOutline) {
            // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
            // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
            // anonymous blocks. In this case, it is better to bail out and paint it ourself.
            RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
            if (!enclosingAnonymousBlock->isAnonymousBlock())
                containingBlockPaintsContinuationOutline = false;
            else {
                containingBlock = enclosingAnonymousBlock->containingBlock();
                for (auto* box = &renderer(); box != containingBlock; box = &box->parent()->enclosingBoxModelObject()) {
                    if (box->hasSelfPaintingLayer()) {
                        containingBlockPaintsContinuationOutline = false;
                        break;
                    }
                }
            }
        }

        if (containingBlockPaintsContinuationOutline) {
            // Add ourselves to the containing block of the entire continuation so that it can
            // paint us atomically.
            containingBlock->addContinuationWithOutline(downcast<RenderInline>(renderer().element()->renderer()));
        } else if (!inlineFlow.isContinuation())
            m_paintInfo.outlineObjects->add(&inlineFlow);

        return;
    }

    if (m_paintInfo.phase == PaintPhase::Mask) {
        paintMask();
        return;
    }

    paintDecorations();
}

static LayoutRect clipRectForNinePieceImageStrip(const InlineIterator::InlineBox& box, const NinePieceImage& image, const LayoutRect& paintRect)
{
    LayoutRect clipRect(paintRect);
    auto& style = box.renderer().style();
    LayoutBoxExtent outsets = style.imageOutsets(image);
    auto [hasClosedLeftEdge, hasClosedRightEdge] = box.hasClosedLeftAndRightEdge();
    if (box.isHorizontal()) {
        clipRect.setY(paintRect.y() - outsets.top());
        clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom());
        if (hasClosedLeftEdge) {
            clipRect.setX(paintRect.x() - outsets.left());
            clipRect.setWidth(paintRect.width() + outsets.left());
        }
        if (hasClosedRightEdge)
            clipRect.setWidth(clipRect.width() + outsets.right());
    } else {
        clipRect.setX(paintRect.x() - outsets.left());
        clipRect.setWidth(paintRect.width() + outsets.left() + outsets.right());
        if (hasClosedLeftEdge) {
            clipRect.setY(paintRect.y() - outsets.top());
            clipRect.setHeight(paintRect.height() + outsets.top());
        }
        if (hasClosedRightEdge)
            clipRect.setHeight(clipRect.height() + outsets.bottom());
    }
    return clipRect;
}

void InlineBoxPainter::paintMask()
{
    if (!m_paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible || m_paintInfo.phase != PaintPhase::Mask)
        return;

    // Move x/y to our coordinates.
    auto localRect = LayoutRect { m_inlineBox.visualRect() };
    LayoutPoint adjustedPaintOffset = m_paintOffset + localRect.location();

    const NinePieceImage& maskNinePieceImage = renderer().style().maskBoxImage();
    StyleImage* maskBoxImage = renderer().style().maskBoxImage().image();

    // Figure out if we need to push a transparency layer to render our mask.
    bool pushTransparencyLayer = false;
    bool compositedMask = renderer().hasLayer() && renderer().layer()->hasCompositedMask();
    bool flattenCompositingLayers = renderer().view().frameView().paintBehavior().contains(PaintBehavior::FlattenCompositingLayers);
    CompositeOperator compositeOp = CompositeOperator::SourceOver;
    if (!compositedMask || flattenCompositingLayers) {
        if ((maskBoxImage && renderer().style().maskLayers().hasImage()) || renderer().style().maskLayers().next())
            pushTransparencyLayer = true;

        compositeOp = CompositeOperator::DestinationIn;
        if (pushTransparencyLayer) {
            m_paintInfo.context().setCompositeOperation(CompositeOperator::DestinationIn);
            m_paintInfo.context().beginTransparencyLayer(1.0f);
            compositeOp = CompositeOperator::SourceOver;
        }
    }

    LayoutRect paintRect = LayoutRect(adjustedPaintOffset, localRect.size());

    paintFillLayers(Color(), renderer().style().maskLayers(), paintRect, compositeOp);

    bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(&renderer(), renderer().style().effectiveZoom());
    if (!hasBoxImage || !maskBoxImage->isLoaded()) {
        if (pushTransparencyLayer)
            m_paintInfo.context().endTransparencyLayer();
        return; // Don't paint anything while we wait for the image to load.
    }

    bool hasSingleLine = !m_inlineBox.previousInlineBox() && !m_inlineBox.nextInlineBox();
    if (hasSingleLine)
        renderer().paintNinePieceImage(m_paintInfo.context(), LayoutRect(adjustedPaintOffset, localRect.size()), renderer().style(), maskNinePieceImage, compositeOp);
    else {
        // We have a mask image that spans multiple lines.
        // We need to adjust _tx and _ty by the width of all previous lines.
        LayoutUnit logicalOffsetOnLine;
        for (auto box = m_inlineBox.previousInlineBox(); box; box.traversePreviousInlineBox())
            logicalOffsetOnLine += box->logicalWidth();
        LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
        for (auto box = m_inlineBox.iterator(); box; box.traverseNextInlineBox())
            totalLogicalWidth += box->logicalWidth();
        LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
        LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
        LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : localRect.width();
        LayoutUnit stripHeight = isHorizontal() ? localRect.height() : totalLogicalWidth;

        LayoutRect clipRect = clipRectForNinePieceImageStrip(m_inlineBox, maskNinePieceImage, paintRect);
        GraphicsContextStateSaver stateSaver(m_paintInfo.context());
        m_paintInfo.context().clip(clipRect);
        renderer().paintNinePieceImage(m_paintInfo.context(), LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage, compositeOp);
    }

    if (pushTransparencyLayer)
        m_paintInfo.context().endTransparencyLayer();
}

void InlineBoxPainter::paintDecorations()
{
    if (!m_paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible || m_paintInfo.phase != PaintPhase::Foreground)
        return;

    if (!m_isRootInlineBox && !renderer().hasVisibleBoxDecorations())
        return;

    auto& style = this->style();
    // You can use p::first-line to specify a background. If so, the root inline boxes for
    // a line may actually have to paint a background.
    if (m_isRootInlineBox && (!m_isFirstLineBox || &style == &renderer().style()))
        return;

    // Move x/y to our coordinates.
    auto localRect = LayoutRect { m_inlineBox.visualRect() };
    LayoutPoint adjustedPaintoffset = m_paintOffset + localRect.location();
    GraphicsContext& context = m_paintInfo.context();
    LayoutRect paintRect = LayoutRect(adjustedPaintoffset, localRect.size());
    // Shadow comes first and is behind the background and border.
    if (!renderer().boxShadowShouldBeAppliedToBackground(adjustedPaintoffset, BackgroundBleedNone, m_inlineBox))
        paintBoxShadow(ShadowStyle::Normal, paintRect);

    auto color = style.visitedDependentColor(CSSPropertyBackgroundColor);
    auto compositeOp = renderer().document().compositeOperatorForBackgroundColor(color, renderer());

    color = style.colorByApplyingColorFilter(color);

    paintFillLayers(color, style.backgroundLayers(), paintRect, compositeOp);
    paintBoxShadow(ShadowStyle::Inset, paintRect);

    // :first-line cannot be used to put borders on a line. Always paint borders with our
    // non-first-line style.
    if (m_isRootInlineBox || !renderer().style().hasVisibleBorderDecoration())
        return;

    const NinePieceImage& borderImage = renderer().style().borderImage();
    StyleImage* borderImageSource = borderImage.image();
    bool hasBorderImage = borderImageSource && borderImageSource->canRender(&renderer(), style.effectiveZoom());
    if (hasBorderImage && !borderImageSource->isLoaded())
        return; // Don't paint anything while we wait for the image to load.

    bool hasSingleLine = !m_inlineBox.previousInlineBox() && !m_inlineBox.nextInlineBox();
    if (!hasBorderImage || hasSingleLine) {
        auto [hasClosedLeftEdge, hasClosedRightEdge] = m_inlineBox.hasClosedLeftAndRightEdge();
        renderer().paintBorder(m_paintInfo, paintRect, style, BackgroundBleedNone, hasClosedLeftEdge, hasClosedRightEdge);
        return;
    }

    // We have a border image that spans multiple lines.
    // We need to adjust tx and ty by the width of all previous lines.
    // Think of border image painting on inlines as though you had one long line, a single continuous
    // strip. Even though that strip has been broken up across multiple lines, you still paint it
    // as though you had one single line. This means each line has to pick up the image where
    // the previous line left off.
    // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
    // but it isn't even clear how this should work at all.
    LayoutUnit logicalOffsetOnLine;
    for (auto box = m_inlineBox.previousInlineBox(); box; box.traversePreviousInlineBox())
        logicalOffsetOnLine += box->logicalWidth();
    LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
    for (auto box = m_inlineBox.iterator(); box; box.traverseNextInlineBox())
        totalLogicalWidth += box->logicalWidth();

    LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
    LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
    LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : localRect.width();
    LayoutUnit stripHeight = isHorizontal() ? localRect.height() : totalLogicalWidth;

    LayoutRect clipRect = clipRectForNinePieceImageStrip(m_inlineBox, borderImage, paintRect);
    GraphicsContextStateSaver stateSaver(context);
    context.clip(clipRect);
    renderer().paintBorder(m_paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), style);
}

void InlineBoxPainter::paintFillLayers(const Color& color, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op)
{
    Vector<const FillLayer*, 8> layers;
    for (auto* layer = &fillLayer; layer; layer = layer->next())
        layers.append(layer);
    layers.reverse();
    for (auto* layer : layers)
        paintFillLayer(color, *layer, rect, op);
}

void InlineBoxPainter::paintFillLayer(const Color& color, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op)
{
    auto* image = fillLayer.image();
    bool hasFillImage = image && image->canRender(&renderer(), renderer().style().effectiveZoom());
    bool hasFillImageOrBorderRadious = hasFillImage || renderer().style().hasBorderRadius();
    bool hasSingleLine = !m_inlineBox.previousInlineBox() && !m_inlineBox.nextInlineBox();

    if (!hasFillImageOrBorderRadious || hasSingleLine || m_isRootInlineBox) {
        renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, { }, op);
        return;
    }

#if ENABLE(CSS_BOX_DECORATION_BREAK)
    if (renderer().style().boxDecorationBreak() == BoxDecorationBreak::Clone) {
        GraphicsContextStateSaver stateSaver(m_paintInfo.context());
        m_paintInfo.context().clip({ rect.location(), m_inlineBox.visualRectIgnoringBlockDirection().size() });
        renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, { }, op);
        return;
    }
#endif

    // We have a fill image that spans multiple lines.
    // We need to adjust tx and ty by the width of all previous lines.
    // Think of background painting on inlines as though you had one long line, a single continuous
    // strip. Even though that strip has been broken up across multiple lines, you still paint it
    // as though you had one single line. This means each line has to pick up the background where
    // the previous line left off.
    LayoutUnit logicalOffsetOnLine;
    LayoutUnit totalLogicalWidth;
    if (renderer().style().direction() == TextDirection::LTR) {
        for (auto box = m_inlineBox.previousInlineBox(); box; box.traversePreviousInlineBox())
            logicalOffsetOnLine += box->logicalWidth();
        totalLogicalWidth = logicalOffsetOnLine;
        for (auto box = m_inlineBox.iterator(); box; box.traverseNextInlineBox())
            totalLogicalWidth += box->logicalWidth();
    } else {
        for (auto box = m_inlineBox.nextInlineBox(); box; box.traverseNextInlineBox())
            logicalOffsetOnLine += box->logicalWidth();
        totalLogicalWidth = logicalOffsetOnLine;
        for (auto box = m_inlineBox.iterator(); box; box.traversePreviousInlineBox())
            totalLogicalWidth += box->logicalWidth();
    }
    LayoutRect backgroundImageStrip {
        rect.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu),
        rect.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine),
        isHorizontal() ? totalLogicalWidth : LayoutUnit(m_inlineBox.visualRectIgnoringBlockDirection().width()),
        isHorizontal() ? LayoutUnit(m_inlineBox.visualRectIgnoringBlockDirection().height()) : totalLogicalWidth
    };

    GraphicsContextStateSaver stateSaver(m_paintInfo.context());
    m_paintInfo.context().clip(FloatRect { rect });
    renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, backgroundImageStrip, op);
}

void InlineBoxPainter::paintBoxShadow(ShadowStyle shadowStyle, const LayoutRect& paintRect)
{
    bool hasSingleLine = !m_inlineBox.previousInlineBox() && !m_inlineBox.nextInlineBox();
    if (hasSingleLine || m_isRootInlineBox) {
        renderer().paintBoxShadow(m_paintInfo, paintRect, style(), shadowStyle);
        return;
    }

    // FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't
    // protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines
    auto [hasClosedLeftEdge, hasClosedRightEdge] = m_inlineBox.hasClosedLeftAndRightEdge();
    renderer().paintBoxShadow(m_paintInfo, paintRect, style(), shadowStyle, hasClosedLeftEdge, hasClosedRightEdge);
}

const RenderStyle& InlineBoxPainter::style() const
{
    return m_isFirstLineBox ? renderer().firstLineStyle() : renderer().style();
}

}
