/*
 * Copyright (C) 2015-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. ``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
 * 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 "DisplayListItems.h"

#include "DisplayListReplayer.h"
#include "FontCascade.h"
#include "ImageBuffer.h"
#include "MediaPlayer.h"
#include "SharedBuffer.h"
#include <wtf/text/TextStream.h>

#if USE(CG)
#include "GraphicsContextPlatformPrivateCG.h"
#endif

namespace WebCore {
namespace DisplayList {

// Should match RenderTheme::platformFocusRingWidth()
static const float platformFocusRingWidth = 3;

void Save::apply(GraphicsContext& context) const
{
    context.save();
}

void Restore::apply(GraphicsContext& context) const
{
    context.restore();
}

void Translate::apply(GraphicsContext& context) const
{
    context.translate(m_x, m_y);
}

static TextStream& operator<<(TextStream& ts, const Translate& item)
{
    ts.dumpProperty("x", item.x());
    ts.dumpProperty("y", item.y());

    return ts;
}

void Rotate::apply(GraphicsContext& context) const
{
    context.rotate(m_angle);
}

static TextStream& operator<<(TextStream& ts, const Rotate& item)
{
    ts.dumpProperty("angle", item.angle());

    return ts;
}

void Scale::apply(GraphicsContext& context) const
{
    context.scale(m_size);
}

static TextStream& operator<<(TextStream& ts, const Scale& item)
{
    ts.dumpProperty("size", item.amount());

    return ts;
}

void SetCTM::apply(GraphicsContext& context) const
{
    context.setCTM(m_transform);
}

static TextStream& operator<<(TextStream& ts, const SetCTM& item)
{
    ts.dumpProperty("set-ctm", item.transform());

    return ts;
}

void ConcatenateCTM::apply(GraphicsContext& context) const
{
    context.concatCTM(m_transform);
}

static TextStream& operator<<(TextStream& ts, const ConcatenateCTM& item)
{
    ts.dumpProperty("ctm", item.transform());

    return ts;
}

void SetInlineFillColor::apply(GraphicsContext& context) const
{
    context.setFillColor(color());
}

static TextStream& operator<<(TextStream& ts, const SetInlineFillColor& state)
{
    ts.dumpProperty("color", state.color());
    return ts;
}

void SetInlineStrokeColor::apply(GraphicsContext& context) const
{
    context.setStrokeColor(color());
}

static TextStream& operator<<(TextStream& ts, const SetInlineStrokeColor& state)
{
    ts.dumpProperty("color", state.color());
    return ts;
}

void SetStrokeThickness::apply(GraphicsContext& context) const
{
    context.setStrokeThickness(m_thickness);
}

static TextStream& operator<<(TextStream& ts, const SetStrokeThickness& state)
{
    ts.dumpProperty("thickness", state.thickness());
    return ts;
}

SetState::SetState(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
    : m_stateChange(state, flags)
{
}

SetState::SetState(const GraphicsContextStateChange& stateChange, const PatternData& strokePattern, const PatternData& fillPattern)
    : m_stateChange(stateChange)
    , m_strokePattern(strokePattern)
    , m_fillPattern(fillPattern)
{
}

void SetState::apply(GraphicsContext& context, NativeImage* strokePatternImage, NativeImage* fillPatternImage)
{
    if (m_stateChange.m_changeFlags.contains(GraphicsContextState::StrokePatternChange) && strokePatternImage)
        m_stateChange.m_state.strokePattern = Pattern::create(*strokePatternImage, m_strokePattern.parameters);
    if (m_stateChange.m_changeFlags.contains(GraphicsContextState::FillPatternChange) && fillPatternImage)
        m_stateChange.m_state.fillPattern = Pattern::create(*fillPatternImage, m_fillPattern.parameters);
    m_stateChange.apply(context);
}

static TextStream& operator<<(TextStream& ts, const SetState& state)
{
    ts << state.stateChange();
    return ts;
}

void SetLineCap::apply(GraphicsContext& context) const
{
    context.setLineCap(m_lineCap);
}

static TextStream& operator<<(TextStream& ts, const SetLineCap& lineCap)
{
    ts.dumpProperty("line-cap", lineCap.lineCap());
    return ts;
}

void SetLineDash::apply(GraphicsContext& context) const
{
    context.setLineDash(m_dashArray, m_dashOffset);
}

static TextStream& operator<<(TextStream& ts, const SetLineDash& lineDash)
{
    ts.dumpProperty("dash-array", lineDash.dashArray());
    ts.dumpProperty("dash-offset", lineDash.dashOffset());
    return ts;
}

void SetLineJoin::apply(GraphicsContext& context) const
{
    context.setLineJoin(m_lineJoin);
}

static TextStream& operator<<(TextStream& ts, const SetLineJoin& lineJoin)
{
    ts.dumpProperty("line-join", lineJoin.lineJoin());
    return ts;
}

void SetMiterLimit::apply(GraphicsContext& context) const
{
    context.setMiterLimit(m_miterLimit);
}

static TextStream& operator<<(TextStream& ts, const SetMiterLimit& miterLimit)
{
    ts.dumpProperty("mitre-limit", miterLimit.miterLimit());
    return ts;
}

void ClearShadow::apply(GraphicsContext& context) const
{
    context.clearShadow();
}

void Clip::apply(GraphicsContext& context) const
{
    context.clip(m_rect);
}

static TextStream& operator<<(TextStream& ts, const Clip& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

void ClipOut::apply(GraphicsContext& context) const
{
    context.clipOut(m_rect);
}

static TextStream& operator<<(TextStream& ts, const ClipOut& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

NO_RETURN_DUE_TO_ASSERT void ClipToImageBuffer::apply(GraphicsContext&) const
{
    ASSERT_NOT_REACHED();
}

void ClipToImageBuffer::apply(GraphicsContext& context, WebCore::ImageBuffer& imageBuffer) const
{
    context.clipToImageBuffer(imageBuffer, m_destinationRect);
}

static TextStream& operator<<(TextStream& ts, const ClipToImageBuffer& item)
{
    ts.dumpProperty("image-buffer-identifier", item.imageBufferIdentifier());
    ts.dumpProperty("dest-rect", item.destinationRect());
    return ts;
}

void ClipOutToPath::apply(GraphicsContext& context) const
{
    context.clipOut(m_path);
}

static TextStream& operator<<(TextStream& ts, const ClipOutToPath& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

void ClipPath::apply(GraphicsContext& context) const
{
    context.clipPath(m_path, m_windRule);
}

static TextStream& operator<<(TextStream& ts, const ClipPath& item)
{
    ts.dumpProperty("path", item.path());
    ts.dumpProperty("wind-rule", item.windRule());
    return ts;
}

static TextStream& operator<<(TextStream& ts, const BeginClipToDrawingCommands& item)
{
    ts.dumpProperty("destination", item.destination());
    ts.dumpProperty("color-space", item.colorSpace());
    return ts;
}

static TextStream& operator<<(TextStream& ts, const EndClipToDrawingCommands& item)
{
    ts.dumpProperty("destination", item.destination());
    return ts;
}

DrawGlyphs::DrawGlyphs(RenderingResourceIdentifier fontIdentifier, Vector<GlyphBufferGlyph, 128>&& glyphs, Vector<GlyphBufferAdvance, 128>&& advances, const FloatRect& bounds, const FloatPoint& localAnchor, FontSmoothingMode smoothingMode)
    : m_fontIdentifier(fontIdentifier)
    , m_glyphs(WTFMove(glyphs))
    , m_advances(WTFMove(advances))
    , m_bounds(bounds)
    , m_localAnchor(localAnchor)
    , m_smoothingMode(smoothingMode)
{
}

DrawGlyphs::DrawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& localAnchor, FontSmoothingMode smoothingMode)
    : m_fontIdentifier(font.renderingResourceIdentifier())
    , m_localAnchor(localAnchor)
    , m_smoothingMode(smoothingMode)
{
    m_glyphs.reserveInitialCapacity(count);
    m_advances.reserveInitialCapacity(count);
    for (unsigned i = 0; i < count; ++i) {
        m_glyphs.uncheckedAppend(glyphs[i]);
        m_advances.uncheckedAppend(advances[i]);
    }
    computeBounds(font);
}

void DrawGlyphs::apply(GraphicsContext& context, const Font& font) const
{
    context.drawGlyphs(font, m_glyphs.data(), m_advances.data(), m_glyphs.size(), anchorPoint(), m_smoothingMode);
}

void DrawGlyphs::computeBounds(const Font& font)
{
    // FIXME: This code doesn't actually take the extents of the glyphs into consideration. It assumes that
    // the glyph lies entirely within its [(ascent + descent), advance] rect.
    float ascent = font.fontMetrics().floatAscent();
    float descent = font.fontMetrics().floatDescent();
    FloatPoint current = localAnchor();
    size_t numGlyphs = m_glyphs.size();
    for (size_t i = 0; i < numGlyphs; ++i) {
        GlyphBufferAdvance advance = m_advances[i];
        FloatRect glyphRect = FloatRect(current.x(), current.y() - ascent, width(advance), ascent + descent);
        m_bounds.unite(glyphRect);

        current.move(width(advance), height(advance));
    }
}

static TextStream& operator<<(TextStream& ts, const DrawGlyphs& item)
{
    // FIXME: dump more stuff.
    ts.dumpProperty("local-anchor", item.localAnchor());
    ts.dumpProperty("anchor-point", item.anchorPoint());
    ts.dumpProperty("length", item.glyphs().size());

    return ts;
}

NO_RETURN_DUE_TO_ASSERT void DrawImageBuffer::apply(GraphicsContext&) const
{
    ASSERT_NOT_REACHED();
}

void DrawImageBuffer::apply(GraphicsContext& context, WebCore::ImageBuffer& imageBuffer) const
{
    context.drawImageBuffer(imageBuffer, m_destinationRect, m_srcRect, m_options);
}

static TextStream& operator<<(TextStream& ts, const DrawImageBuffer& item)
{
    ts.dumpProperty("image-buffer-identifier", item.imageBufferIdentifier());
    ts.dumpProperty("source-rect", item.source());
    ts.dumpProperty("dest-rect", item.destinationRect());
    return ts;
}

NO_RETURN_DUE_TO_ASSERT void DrawNativeImage::apply(GraphicsContext&) const
{
    ASSERT_NOT_REACHED();
}

void DrawNativeImage::apply(GraphicsContext& context, NativeImage& image) const
{
    context.drawNativeImage(image, m_imageSize, m_destinationRect, m_srcRect, m_options);
}

static TextStream& operator<<(TextStream& ts, const DrawNativeImage& item)
{
    // FIXME: dump more stuff.
    ts.dumpProperty("image-identifier", item.imageIdentifier());
    ts.dumpProperty("source-rect", item.source());
    ts.dumpProperty("dest-rect", item.destinationRect());
    return ts;
}

DrawPattern::DrawPattern(RenderingResourceIdentifier imageIdentifier, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
    : m_imageIdentifier(imageIdentifier)
    , m_imageSize(imageSize)
    , m_destination(destRect)
    , m_tileRect(tileRect)
    , m_patternTransform(patternTransform)
    , m_phase(phase)
    , m_spacing(spacing)
    , m_options(options)
{
}

NO_RETURN_DUE_TO_ASSERT void DrawPattern::apply(GraphicsContext&) const
{
    ASSERT_NOT_REACHED();
}

void DrawPattern::apply(GraphicsContext& context, NativeImage& image) const
{
    context.drawPattern(image, m_imageSize, m_destination, m_tileRect, m_patternTransform, m_phase, m_spacing, m_options);
}

static TextStream& operator<<(TextStream& ts, const DrawPattern& item)
{
    ts.dumpProperty("image-identifier", item.imageIdentifier());
    ts.dumpProperty("pattern-transform", item.patternTransform());
    ts.dumpProperty("tile-rect", item.tileRect());
    ts.dumpProperty("dest-rect", item.destRect());
    ts.dumpProperty("phase", item.phase());
    ts.dumpProperty("spacing", item.spacing());
    return ts;
}

void DrawRect::apply(GraphicsContext& context) const
{
    context.drawRect(m_rect, m_borderThickness);
}

static TextStream& operator<<(TextStream& ts, const DrawRect& item)
{
    ts.dumpProperty("rect", item.rect());
    ts.dumpProperty("border-thickness", item.borderThickness());
    return ts;
}

std::optional<FloatRect> DrawLine::localBounds(const GraphicsContext&) const
{
    FloatRect bounds;
    bounds.fitToPoints(m_point1, m_point2);
    return bounds;
}

void DrawLine::apply(GraphicsContext& context) const
{
    context.drawLine(m_point1, m_point2);
}

static TextStream& operator<<(TextStream& ts, const DrawLine& item)
{
    ts.dumpProperty("point-1", item.point1());
    ts.dumpProperty("point-2", item.point2());
    return ts;
}

DrawLinesForText::DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines)
    : m_blockLocation(blockLocation)
    , m_localAnchor(localAnchor)
    , m_widths(widths)
    , m_thickness(thickness)
    , m_printing(printing)
    , m_doubleLines(doubleLines)
{
}

void DrawLinesForText::apply(GraphicsContext& context) const
{
    context.drawLinesForText(point(), m_thickness, m_widths, m_printing, m_doubleLines);
}

std::optional<FloatRect> DrawLinesForText::localBounds(const GraphicsContext&) const
{
    // This function needs to return a value equal to or enclosing what GraphicsContext::computeLineBoundsAndAntialiasingModeForText() returns.

    if (!m_widths.size())
        return FloatRect();

    FloatRect result(point(), FloatSize(m_widths.last(), m_thickness));
    result.inflate(1); // Account for pixel snapping. FIXME: This isn't perfect, as it doesn't take the CTM into account.
    return result;
}

static TextStream& operator<<(TextStream& ts, const DrawLinesForText& item)
{
    ts.dumpProperty("block-location", item.blockLocation());
    ts.dumpProperty("local-anchor", item.localAnchor());
    ts.dumpProperty("point", item.point());
    ts.dumpProperty("thickness", item.thickness());
    ts.dumpProperty("double", item.doubleLines());
    ts.dumpProperty("widths", item.widths());
    ts.dumpProperty("is-printing", item.isPrinting());
    ts.dumpProperty("double", item.doubleLines());
    return ts;
}

void DrawDotsForDocumentMarker::apply(GraphicsContext& context) const
{
    context.drawDotsForDocumentMarker(m_rect, {
        static_cast<DocumentMarkerLineStyle::Mode>(m_styleMode),
        m_styleShouldUseDarkAppearance,
    });
}

std::optional<FloatRect> DrawDotsForDocumentMarker::localBounds(const GraphicsContext&) const
{
    return m_rect;
}

static TextStream& operator<<(TextStream& ts, const DrawDotsForDocumentMarker& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

void DrawEllipse::apply(GraphicsContext& context) const
{
    context.drawEllipse(m_rect);
}

static TextStream& operator<<(TextStream& ts, const DrawEllipse& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

void DrawPath::apply(GraphicsContext& context) const
{
    context.drawPath(m_path);
}

static TextStream& operator<<(TextStream& ts, const DrawPath&)
{
    // FIXME: add logging for paths.
    return ts;
}

void DrawFocusRingPath::apply(GraphicsContext& context) const
{
    context.drawFocusRing(m_path, m_width, m_offset, m_color);
}

std::optional<FloatRect> DrawFocusRingPath::localBounds(const GraphicsContext&) const
{
    FloatRect result = m_path.fastBoundingRect();
    result.inflate(platformFocusRingWidth);
    return result;
}

static TextStream& operator<<(TextStream& ts, const DrawFocusRingPath& item)
{
//    ts.dumpProperty("path", item.path()); // FIXME: add logging for paths.
    ts.dumpProperty("width", item.width());
    ts.dumpProperty("offset", item.offset());
    ts.dumpProperty("color", item.color());
    return ts;
}

DrawFocusRingRects::DrawFocusRingRects(const Vector<FloatRect>& rects, float width, float offset, const Color& color)
    : m_rects(rects)
    , m_width(width)
    , m_offset(offset)
    , m_color(color)
{
}

void DrawFocusRingRects::apply(GraphicsContext& context) const
{
    context.drawFocusRing(m_rects, m_width, m_offset, m_color);
}

std::optional<FloatRect> DrawFocusRingRects::localBounds(const GraphicsContext&) const
{
    FloatRect result;
    for (auto& rect : m_rects)
        result.unite(rect);
    result.inflate(platformFocusRingWidth);
    return result;
}

static TextStream& operator<<(TextStream& ts, const DrawFocusRingRects& item)
{
    ts.dumpProperty("rects", item.rects());
    ts.dumpProperty("width", item.width());
    ts.dumpProperty("offset", item.offset());
    ts.dumpProperty("color", item.color());
    return ts;
}

void FillRect::apply(GraphicsContext& context) const
{
    context.fillRect(m_rect);
}

static TextStream& operator<<(TextStream& ts, const FillRect& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

void FillRectWithColor::apply(GraphicsContext& context) const
{
    context.fillRect(m_rect, m_color);
}

static TextStream& operator<<(TextStream& ts, const FillRectWithColor& item)
{
    ts.dumpProperty("rect", item.rect());
    ts.dumpProperty("color", item.color());
    return ts;
}

FillRectWithGradient::FillRectWithGradient(const FloatRect& rect, Gradient& gradient)
    : m_rect(rect)
    , m_gradient(gradient)
{
}

void FillRectWithGradient::apply(GraphicsContext& context) const
{
    context.fillRect(m_rect, m_gradient.get());
}

static TextStream& operator<<(TextStream& ts, const FillRectWithGradient& item)
{
    // FIXME: log gradient.
    ts.dumpProperty("rect", item.rect());
    return ts;
}

void FillCompositedRect::apply(GraphicsContext& context) const
{
    context.fillRect(m_rect, m_color, m_op, m_blendMode);
}

static TextStream& operator<<(TextStream& ts, const FillCompositedRect& item)
{
    ts.dumpProperty("rect", item.rect());
    ts.dumpProperty("color", item.color());
    ts.dumpProperty("composite-operation", item.compositeOperator());
    ts.dumpProperty("blend-mode", item.blendMode());
    return ts;
}

void FillRoundedRect::apply(GraphicsContext& context) const
{
    context.fillRoundedRect(m_rect, m_color, m_blendMode);
}

static TextStream& operator<<(TextStream& ts, const FillRoundedRect& item)
{
    ts.dumpProperty("rect", item.roundedRect());
    ts.dumpProperty("color", item.color());
    ts.dumpProperty("blend-mode", item.blendMode());
    return ts;
}

void FillRectWithRoundedHole::apply(GraphicsContext& context) const
{
    context.fillRectWithRoundedHole(m_rect, m_roundedHoleRect, m_color);
}

static TextStream& operator<<(TextStream& ts, const FillRectWithRoundedHole& item)
{
    ts.dumpProperty("rect", item.rect());
    ts.dumpProperty("rounded-hole-rect", item.roundedHoleRect());
    ts.dumpProperty("color", item.color());
    return ts;
}

#if ENABLE(INLINE_PATH_DATA)

void FillLine::apply(GraphicsContext& context) const
{
    context.fillPath(path());
}

static TextStream& operator<<(TextStream& ts, const FillLine& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

void FillArc::apply(GraphicsContext& context) const
{
    context.fillPath(path());
}

static TextStream& operator<<(TextStream& ts, const FillArc& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

void FillQuadCurve::apply(GraphicsContext& context) const
{
    context.fillPath(path());
}

static TextStream& operator<<(TextStream& ts, const FillQuadCurve& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

void FillBezierCurve::apply(GraphicsContext& context) const
{
    context.fillPath(path());
}

static TextStream& operator<<(TextStream& ts, const FillBezierCurve& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

#endif // ENABLE(INLINE_PATH_DATA)

void FillPath::apply(GraphicsContext& context) const
{
    context.fillPath(m_path);
}

static TextStream& operator<<(TextStream& ts, const FillPath& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

void FillEllipse::apply(GraphicsContext& context) const
{
    context.fillEllipse(m_rect);
}

static TextStream& operator<<(TextStream& ts, const FillEllipse& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

static TextStream& operator<<(TextStream& ts, const GetPixelBuffer& item)
{
    ts.dumpProperty("outputFormat", item.outputFormat());
    ts.dumpProperty("srcRect", item.srcRect());
    return ts;
}

PutPixelBuffer::PutPixelBuffer(const PixelBuffer& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
    : m_srcRect(srcRect)
    , m_destPoint(destPoint)
    , m_pixelBuffer(pixelBuffer.deepClone()) // This copy is actually required to preserve the semantics of putPixelBuffer().
    , m_destFormat(destFormat)
{
}

PutPixelBuffer::PutPixelBuffer(PixelBuffer&& pixelBuffer, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat)
    : m_srcRect(srcRect)
    , m_destPoint(destPoint)
    , m_pixelBuffer(WTFMove(pixelBuffer))
    , m_destFormat(destFormat)
{
}

PutPixelBuffer::PutPixelBuffer(const PutPixelBuffer& other)
    : m_srcRect(other.m_srcRect)
    , m_destPoint(other.m_destPoint)
    , m_pixelBuffer(other.m_pixelBuffer.deepClone())
    , m_destFormat(other.m_destFormat)
{
}

PutPixelBuffer& PutPixelBuffer::operator=(const PutPixelBuffer& other)
{
    PutPixelBuffer copy { other };
    swap(copy);
    return *this;
}

void PutPixelBuffer::swap(PutPixelBuffer& other)
{
    std::swap(m_srcRect, other.m_srcRect);
    std::swap(m_destPoint, other.m_destPoint);
    std::swap(m_pixelBuffer, other.m_pixelBuffer);
    std::swap(m_destFormat, other.m_destFormat);
}

static TextStream& operator<<(TextStream& ts, const PutPixelBuffer& item)
{
    ts.dumpProperty("pixelBufferSize", item.pixelBuffer().size());
    ts.dumpProperty("srcRect", item.srcRect());
    ts.dumpProperty("destPoint", item.destPoint());
    ts.dumpProperty("destFormat", item.destFormat());
    return ts;
}

#if ENABLE(VIDEO)
PaintFrameForMedia::PaintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
    : m_identifier(player.identifier())
    , m_destination(destination)
{
}

NO_RETURN_DUE_TO_ASSERT void PaintFrameForMedia::apply(GraphicsContext&) const
{
    // Should be handled by the delegate.
    ASSERT_NOT_REACHED();
}

static TextStream& operator<<(TextStream& ts, const PaintFrameForMedia& item)
{
    ts.dumpProperty("destination", item.destination());
    return ts;
}
#endif

std::optional<FloatRect> StrokeRect::localBounds(const GraphicsContext&) const
{
    FloatRect bounds = m_rect;
    bounds.expand(m_lineWidth, m_lineWidth);
    return bounds;
}

void StrokeRect::apply(GraphicsContext& context) const
{
    context.strokeRect(m_rect, m_lineWidth);
}

static TextStream& operator<<(TextStream& ts, const StrokeRect& item)
{
    ts.dumpProperty("rect", item.rect());
    ts.dumpProperty("line-width", item.lineWidth());
    return ts;
}

std::optional<FloatRect> StrokePath::localBounds(const GraphicsContext& context) const
{
    // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
    float strokeThickness = context.strokeThickness();

    FloatRect bounds = m_path.fastBoundingRect();
    bounds.expand(strokeThickness, strokeThickness);
    return bounds;
}

void StrokePath::apply(GraphicsContext& context) const
{
    context.strokePath(m_path);
}

static TextStream& operator<<(TextStream& ts, const StrokePath& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

std::optional<FloatRect> StrokeEllipse::localBounds(const GraphicsContext& context) const
{
    float strokeThickness = context.strokeThickness();

    FloatRect bounds = m_rect;
    bounds.expand(strokeThickness, strokeThickness);
    return bounds;
}

void StrokeEllipse::apply(GraphicsContext& context) const
{
    context.strokeEllipse(m_rect);
}

static TextStream& operator<<(TextStream& ts, const StrokeEllipse& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

std::optional<FloatRect> StrokeLine::localBounds(const GraphicsContext& context) const
{
    float strokeThickness = context.strokeThickness();

    FloatRect bounds;
    bounds.fitToPoints(start(), end());
    bounds.expand(strokeThickness, strokeThickness);
    return bounds;
}

void StrokeLine::apply(GraphicsContext& context) const
{
#if ENABLE(INLINE_PATH_DATA)
    auto path = Path::from(InlinePathData { LineData { start(), end() } });
#else
    Path path;
    path.moveTo(start());
    path.addLineTo(end());
#endif
    context.strokePath(path);
}

static TextStream& operator<<(TextStream& ts, const StrokeLine& item)
{
    ts.dumpProperty("start", item.start());
    ts.dumpProperty("end", item.end());
    return ts;
}

#if ENABLE(INLINE_PATH_DATA)

std::optional<FloatRect> StrokeArc::localBounds(const GraphicsContext& context) const
{
    // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
    float strokeThickness = context.strokeThickness();

    auto bounds = path().fastBoundingRect();
    bounds.expand(strokeThickness, strokeThickness);
    return bounds;
}

void StrokeArc::apply(GraphicsContext& context) const
{
    context.strokePath(path());
}

static TextStream& operator<<(TextStream& ts, const StrokeArc& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

std::optional<FloatRect> StrokeQuadCurve::localBounds(const GraphicsContext& context) const
{
    // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
    float strokeThickness = context.strokeThickness();

    auto bounds = path().fastBoundingRect();
    bounds.expand(strokeThickness, strokeThickness);
    return bounds;
}

void StrokeQuadCurve::apply(GraphicsContext& context) const
{
    context.strokePath(path());
}

static TextStream& operator<<(TextStream& ts, const StrokeQuadCurve& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

std::optional<FloatRect> StrokeBezierCurve::localBounds(const GraphicsContext& context) const
{
    // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
    float strokeThickness = context.strokeThickness();

    auto bounds = path().fastBoundingRect();
    bounds.expand(strokeThickness, strokeThickness);
    return bounds;
}

void StrokeBezierCurve::apply(GraphicsContext& context) const
{
    context.strokePath(path());
}

static TextStream& operator<<(TextStream& ts, const StrokeBezierCurve& item)
{
    ts.dumpProperty("path", item.path());
    return ts;
}

#endif // ENABLE(INLINE_PATH_DATA)

void ClearRect::apply(GraphicsContext& context) const
{
    context.clearRect(m_rect);
}

static TextStream& operator<<(TextStream& ts, const ClearRect& item)
{
    ts.dumpProperty("rect", item.rect());
    return ts;
}

void BeginTransparencyLayer::apply(GraphicsContext& context) const
{
    context.beginTransparencyLayer(m_opacity);
}

static TextStream& operator<<(TextStream& ts, const BeginTransparencyLayer& item)
{
    ts.dumpProperty("opacity", item.opacity());
    return ts;
}

void EndTransparencyLayer::apply(GraphicsContext& context) const
{
    if (context.isInTransparencyLayer())
        context.endTransparencyLayer();
}

#if USE(CG)

void ApplyStrokePattern::apply(GraphicsContext& context) const
{
    context.applyStrokePattern();
}

void ApplyFillPattern::apply(GraphicsContext& context) const
{
    context.applyFillPattern();
}
#endif

void ApplyDeviceScaleFactor::apply(GraphicsContext& context) const
{
    context.applyDeviceScaleFactor(m_scaleFactor);
}

static TextStream& operator<<(TextStream& ts, const ApplyDeviceScaleFactor& item)
{
    ts.dumpProperty("scale-factor", item.scaleFactor());
    return ts;
}

void FlushContext::apply(GraphicsContext&) const
{
    // Handled by client.
}

static TextStream& operator<<(TextStream& ts, const FlushContext& item)
{
    ts.dumpProperty("identifier", item.identifier());
    return ts;
}

static TextStream& operator<<(TextStream& ts, ItemType type)
{
    switch (type) {
    case ItemType::Save: ts << "save"; break;
    case ItemType::Restore: ts << "restore"; break;
    case ItemType::Translate: ts << "translate"; break;
    case ItemType::Rotate: ts << "rotate"; break;
    case ItemType::Scale: ts << "scale"; break;
    case ItemType::SetCTM: ts << "set-ctm"; break;
    case ItemType::ConcatenateCTM: ts << "concatentate-ctm"; break;
    case ItemType::SetInlineFillColor: ts << "set-inline-fill-color"; break;
    case ItemType::SetInlineStrokeColor: ts << "set-inline-stroke-color"; break;
    case ItemType::SetStrokeThickness: ts << "set-stroke-thickness"; break;
    case ItemType::SetState: ts << "set-state"; break;
    case ItemType::SetLineCap: ts << "set-line-cap"; break;
    case ItemType::SetLineDash: ts << "set-line-dash"; break;
    case ItemType::SetLineJoin: ts << "set-line-join"; break;
    case ItemType::SetMiterLimit: ts << "set-miter-limit"; break;
    case ItemType::Clip: ts << "clip"; break;
    case ItemType::ClipOut: ts << "clip-out"; break;
    case ItemType::ClipToImageBuffer: ts << "clip-to-image-buffer"; break;
    case ItemType::ClipOutToPath: ts << "clip-out-to-path"; break;
    case ItemType::ClipPath: ts << "clip-path"; break;
    case ItemType::BeginClipToDrawingCommands: ts << "begin-clip-to-drawing-commands:"; break;
    case ItemType::EndClipToDrawingCommands: ts << "end-clip-to-drawing-commands"; break;
    case ItemType::DrawGlyphs: ts << "draw-glyphs"; break;
    case ItemType::DrawImageBuffer: ts << "draw-image-buffer"; break;
    case ItemType::DrawNativeImage: ts << "draw-native-image"; break;
    case ItemType::DrawPattern: ts << "draw-pattern"; break;
    case ItemType::DrawRect: ts << "draw-rect"; break;
    case ItemType::DrawLine: ts << "draw-line"; break;
    case ItemType::DrawLinesForText: ts << "draw-lines-for-text"; break;
    case ItemType::DrawDotsForDocumentMarker: ts << "draw-dots-for-document-marker"; break;
    case ItemType::DrawEllipse: ts << "draw-ellipse"; break;
    case ItemType::DrawPath: ts << "draw-path"; break;
    case ItemType::DrawFocusRingPath: ts << "draw-focus-ring-path"; break;
    case ItemType::DrawFocusRingRects: ts << "draw-focus-ring-rects"; break;
    case ItemType::FillRect: ts << "fill-rect"; break;
    case ItemType::FillRectWithColor: ts << "fill-rect-with-color"; break;
    case ItemType::FillRectWithGradient: ts << "fill-rect-with-gradient"; break;
    case ItemType::FillCompositedRect: ts << "fill-composited-rect"; break;
    case ItemType::FillRoundedRect: ts << "fill-rounded-rect"; break;
    case ItemType::FillRectWithRoundedHole: ts << "fill-rect-with-rounded-hole"; break;
#if ENABLE(INLINE_PATH_DATA)
    case ItemType::FillLine: ts << "fill-line"; break;
    case ItemType::FillArc: ts << "fill-arc"; break;
    case ItemType::FillQuadCurve: ts << "fill-quad-curve"; break;
    case ItemType::FillBezierCurve: ts << "fill-bezier-curve"; break;
#endif
    case ItemType::FillPath: ts << "fill-path"; break;
    case ItemType::FillEllipse: ts << "fill-ellipse"; break;
    case ItemType::FlushContext: ts << "flush-context"; break;
    case ItemType::GetPixelBuffer: ts << "get-pixel-buffer"; break;
    case ItemType::PutPixelBuffer: ts << "put-pixel-buffer"; break;
#if ENABLE(VIDEO)
    case ItemType::PaintFrameForMedia: ts << "paint-frame-for-media"; break;
#endif
    case ItemType::StrokeRect: ts << "stroke-rect"; break;
    case ItemType::StrokeLine: ts << "stroke-line"; break;
#if ENABLE(INLINE_PATH_DATA)
    case ItemType::StrokeArc: ts << "stroke-arc"; break;
    case ItemType::StrokeQuadCurve: ts << "stroke-quad-curve"; break;
    case ItemType::StrokeBezierCurve: ts << "stroke-bezier-curve"; break;
#endif
    case ItemType::StrokePath: ts << "stroke-path"; break;
    case ItemType::StrokeEllipse: ts << "stroke-ellipse"; break;
    case ItemType::ClearRect: ts << "clear-rect"; break;
    case ItemType::BeginTransparencyLayer: ts << "begin-transparency-layer"; break;
    case ItemType::EndTransparencyLayer: ts << "end-transparency-layer"; break;
#if USE(CG)
    case ItemType::ApplyStrokePattern: ts << "apply-stroke-pattern"; break;
    case ItemType::ApplyFillPattern: ts << "apply-fill-pattern"; break;
#endif
    case ItemType::ApplyDeviceScaleFactor: ts << "apply-device-scale-factor"; break;
    case ItemType::ClearShadow: ts << "clear-shadow"; break;
    }
    return ts;
}

TextStream& operator<<(TextStream& ts, ItemHandle item)
{
    ts << item.type();

    switch (item.type()) {
    case ItemType::Translate:
        ts << item.get<Translate>();
        break;
    case ItemType::Rotate:
        ts << item.get<Rotate>();
        break;
    case ItemType::Scale:
        ts << item.get<Scale>();
        break;
    case ItemType::SetCTM:
        ts << item.get<SetCTM>();
        break;
    case ItemType::ConcatenateCTM:
        ts << item.get<ConcatenateCTM>();
        break;
    case ItemType::SetInlineFillColor:
        ts << item.get<SetInlineFillColor>();
        break;
    case ItemType::SetInlineStrokeColor:
        ts << item.get<SetInlineStrokeColor>();
        break;
    case ItemType::SetStrokeThickness:
        ts << item.get<SetStrokeThickness>();
        break;
    case ItemType::SetState:
        ts << item.get<SetState>();
        break;
    case ItemType::SetLineCap:
        ts << item.get<SetLineCap>();
        break;
    case ItemType::SetLineDash:
        ts << item.get<SetLineDash>();
        break;
    case ItemType::SetLineJoin:
        ts << item.get<SetLineJoin>();
        break;
    case ItemType::SetMiterLimit:
        ts << item.get<SetMiterLimit>();
        break;
    case ItemType::Clip:
        ts << item.get<Clip>();
        break;
    case ItemType::ClipOut:
        ts << item.get<ClipOut>();
        break;
    case ItemType::ClipToImageBuffer:
        ts << item.get<ClipToImageBuffer>();
        break;
    case ItemType::ClipOutToPath:
        ts << item.get<ClipOutToPath>();
        break;
    case ItemType::ClipPath:
        ts << item.get<ClipPath>();
        break;
    case ItemType::BeginClipToDrawingCommands:
        ts << item.get<BeginClipToDrawingCommands>();
        break;
    case ItemType::EndClipToDrawingCommands:
        ts << item.get<EndClipToDrawingCommands>();
        break;
    case ItemType::DrawGlyphs:
        ts << item.get<DrawGlyphs>();
        break;
    case ItemType::DrawImageBuffer:
        ts << item.get<DrawImageBuffer>();
        break;
    case ItemType::DrawNativeImage:
        ts << item.get<DrawNativeImage>();
        break;
    case ItemType::DrawPattern:
        ts << item.get<DrawPattern>();
        break;
    case ItemType::DrawRect:
        ts << item.get<DrawRect>();
        break;
    case ItemType::DrawLine:
        ts << item.get<DrawLine>();
        break;
    case ItemType::DrawLinesForText:
        ts << item.get<DrawLinesForText>();
        break;
    case ItemType::DrawDotsForDocumentMarker:
        ts << item.get<DrawDotsForDocumentMarker>();
        break;
    case ItemType::DrawEllipse:
        ts << item.get<DrawEllipse>();
        break;
    case ItemType::DrawPath:
        ts << item.get<DrawPath>();
        break;
    case ItemType::DrawFocusRingPath:
        ts << item.get<DrawFocusRingPath>();
        break;
    case ItemType::DrawFocusRingRects:
        ts << item.get<DrawFocusRingRects>();
        break;
    case ItemType::FillRect:
        ts << item.get<FillRect>();
        break;
    case ItemType::FillRectWithColor:
        ts << item.get<FillRectWithColor>();
        break;
    case ItemType::FillRectWithGradient:
        ts << item.get<FillRectWithGradient>();
        break;
    case ItemType::FillCompositedRect:
        ts << item.get<FillCompositedRect>();
        break;
    case ItemType::FillRoundedRect:
        ts << item.get<FillRoundedRect>();
        break;
    case ItemType::FillRectWithRoundedHole:
        ts << item.get<FillRectWithRoundedHole>();
        break;
#if ENABLE(INLINE_PATH_DATA)
    case ItemType::FillLine:
        ts << item.get<FillLine>();
        break;
    case ItemType::FillArc:
        ts << item.get<FillArc>();
        break;
    case ItemType::FillQuadCurve:
        ts << item.get<FillQuadCurve>();
        break;
    case ItemType::FillBezierCurve:
        ts << item.get<FillBezierCurve>();
        break;
#endif
    case ItemType::FillPath:
        ts << item.get<FillPath>();
        break;
    case ItemType::FillEllipse:
        ts << item.get<FillEllipse>();
        break;
    case ItemType::FlushContext:
        ts << item.get<FlushContext>();
        break;
    case ItemType::GetPixelBuffer:
        ts << item.get<GetPixelBuffer>();
        break;
    case ItemType::PutPixelBuffer:
        ts << item.get<PutPixelBuffer>();
        break;
#if ENABLE(VIDEO)
    case ItemType::PaintFrameForMedia:
        ts << item.get<PaintFrameForMedia>();
        break;
#endif
    case ItemType::StrokeRect:
        ts << item.get<StrokeRect>();
        break;
    case ItemType::StrokeLine:
        ts << item.get<StrokeLine>();
        break;
#if ENABLE(INLINE_PATH_DATA)
    case ItemType::StrokeArc:
        ts << item.get<StrokeArc>();
        break;
    case ItemType::StrokeQuadCurve:
        ts << item.get<StrokeQuadCurve>();
        break;
    case ItemType::StrokeBezierCurve:
        ts << item.get<StrokeBezierCurve>();
        break;
#endif
    case ItemType::StrokePath:
        ts << item.get<StrokePath>();
        break;
    case ItemType::StrokeEllipse:
        ts << item.get<StrokeEllipse>();
        break;
    case ItemType::ClearRect:
        ts << item.get<ClearRect>();
        break;
    case ItemType::BeginTransparencyLayer:
        ts << item.get<BeginTransparencyLayer>();
        break;
    case ItemType::ApplyDeviceScaleFactor:
        ts << item.get<ApplyDeviceScaleFactor>();
        break;

    // Items with no additional data.
    case ItemType::Save:
    case ItemType::Restore:
    case ItemType::EndTransparencyLayer:
#if USE(CG)
    case ItemType::ApplyStrokePattern:
    case ItemType::ApplyFillPattern:
#endif
    case ItemType::ClearShadow:
        break;
    }
    return ts;
}

}
}
