/*
 * Copyright (C) 2018 Metrological Group B.V.
 * Copyright (C) 2018 Igalia S.L.
 *
 * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * HOLDER 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 "NicosiaCairoOperationRecorder.h"

#include "CairoOperations.h"
#include "FloatRoundedRect.h"
#include "Gradient.h"
#include "ImageBuffer.h"
#include "NicosiaPaintingOperationReplayCairo.h"
#include <type_traits>
#include <wtf/text/TextStream.h>

#if PLATFORM(WPE) || PLATFORM(GTK)
#include "ThemeAdwaita.h"
#endif

namespace Nicosia {
using namespace WebCore;

GraphicsContextCairo& contextForReplay(PaintingOperationReplay& operationReplay)
{
    return static_cast<PaintingOperationReplayCairo&>(operationReplay).platformContext;
}

template<typename... Args>
struct OperationData {
    template<std::size_t I>
    auto arg() const -> std::tuple_element_t<I, const std::tuple<Args...>>&
    {
        return std::get<I>(arguments);
    }

    std::tuple<Args...> arguments;
};

template<> struct OperationData<> { };

template<typename T, typename... Args>
auto createCommand(Args&&... arguments) -> std::enable_if_t<std::is_base_of<OperationData<std::decay_t<Args>...>, T>::value, std::unique_ptr<PaintingOperation>>
{
    auto* command = new T();
    command->arguments = std::make_tuple(std::forward<Args>(arguments)...);
    return std::unique_ptr<PaintingOperation>(command);
}

template<typename T>
auto createCommand() -> std::enable_if_t<std::is_base_of<OperationData<>, T>::value, std::unique_ptr<PaintingOperation>>
{
    return makeUnique<T>();
}

CairoOperationRecorder::CairoOperationRecorder(PaintingOperations& commandList)
    : m_commandList(commandList)
{
    m_stateStack.append({ { }, { }, FloatRect::infiniteRect() });
}

void CairoOperationRecorder::didUpdateState(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
{
    if (flags & GraphicsContextState::StrokeThicknessChange) {
        struct StrokeThicknessChange final : PaintingOperation, OperationData<float> {
            virtual ~StrokeThicknessChange() = default;

            void execute(PaintingOperationReplay& replayer) override
            {
                Cairo::State::setStrokeThickness(contextForReplay(replayer), arg<0>());
            }

            void dump(TextStream& ts) override
            {
                ts << indent << "StrokeThicknessChange<>\n";
            }
        };

        append(createCommand<StrokeThicknessChange>(state.strokeThickness));
    }

    if (flags & GraphicsContextState::StrokeStyleChange) {
        struct StrokeStyleChange final : PaintingOperation, OperationData<StrokeStyle> {
            virtual ~StrokeStyleChange() = default;

            void execute(PaintingOperationReplay& replayer) override
            {
                Cairo::State::setStrokeStyle(contextForReplay(replayer), arg<0>());
            }

            void dump(TextStream& ts) override
            {
                ts << indent << "StrokeStyleChange<>\n";
            }
        };

        append(createCommand<StrokeStyleChange>(state.strokeStyle));
    }

    if (flags & GraphicsContextState::CompositeOperationChange) {
        struct CompositeOperationChange final : PaintingOperation, OperationData<CompositeOperator, BlendMode> {
            virtual ~CompositeOperationChange() = default;

            void execute(PaintingOperationReplay& replayer) override
            {
                Cairo::State::setCompositeOperation(contextForReplay(replayer), arg<0>(), arg<1>());
            }

            void dump(TextStream& ts) override
            {
                ts << indent << "CompositeOperationChange<>\n";
            }
        };

        append(createCommand<CompositeOperationChange>(state.compositeOperator, state.blendMode));
    }

    if (flags & GraphicsContextState::ShouldAntialiasChange) {
        struct ShouldAntialiasChange final : PaintingOperation, OperationData<bool> {
            virtual ~ShouldAntialiasChange() = default;

            void execute(PaintingOperationReplay& replayer) override
            {
                Cairo::State::setShouldAntialias(contextForReplay(replayer), arg<0>());
            }

            void dump(TextStream& ts) override
            {
                ts << indent << "ShouldAntialiasChange<>\n";
            }
        };

        append(createCommand<ShouldAntialiasChange>(state.shouldAntialias));
    }
}

void CairoOperationRecorder::setLineCap(LineCap lineCap)
{
    struct SetLineCap final : PaintingOperation, OperationData<LineCap> {
        virtual ~SetLineCap() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::setLineCap(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "SetLineCap<>\n";
        }
    };

    append(createCommand<SetLineCap>(lineCap));
}

void CairoOperationRecorder::setLineDash(const DashArray& dashes, float dashOffset)
{
    struct SetLineDash final : PaintingOperation, OperationData<DashArray, float> {
        virtual ~SetLineDash() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::setLineDash(contextForReplay(replayer), arg<0>(), arg<1>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "SetLineDash<>\n";
        }
    };

    append(createCommand<SetLineDash>(dashes, dashOffset));
}

void CairoOperationRecorder::setLineJoin(LineJoin lineJoin)
{
    struct SetLineJoin final : PaintingOperation, OperationData<LineJoin> {
        virtual ~SetLineJoin() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::setLineJoin(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "SetLineJoin<>\n";
        }
    };

    append(createCommand<SetLineJoin>(lineJoin));
}

void CairoOperationRecorder::setMiterLimit(float miterLimit)
{
    struct SetMiterLimit final : PaintingOperation, OperationData<float> {
        virtual ~SetMiterLimit() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::setMiterLimit(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "SetMiterLimit<>\n";
        }
    };

    append(createCommand<SetMiterLimit>(miterLimit));
}

void CairoOperationRecorder::fillRect(const FloatRect& rect)
{
    struct FillRect final : PaintingOperation, OperationData<FloatRect, Cairo::FillSource, Cairo::ShadowState> {
        virtual ~FillRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::fillRect(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillRect<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<FillRect>(rect, Cairo::FillSource(state), Cairo::ShadowState(state)));
}

void CairoOperationRecorder::fillRect(const FloatRect& rect, const Color& color)
{
    struct FillRect final : PaintingOperation, OperationData<FloatRect, Color, Cairo::ShadowState> {
        virtual ~FillRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::fillRect(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillRect<>\n";
        }
    };

    append(createCommand<FillRect>(rect, color, Cairo::ShadowState(state())));
}

void CairoOperationRecorder::fillRect(const FloatRect& rect, Gradient& gradient)
{
    struct FillRect final : PaintingOperation, OperationData<FloatRect, RefPtr<cairo_pattern_t>> {
        virtual ~FillRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            auto& platformContext = contextForReplay(replayer);
            platformContext.save();
            Cairo::fillRect(platformContext, arg<0>(), arg<1>().get());
            platformContext.restore();
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillRect<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<FillRect>(rect, gradient.createPattern(1.0, state.fillGradientSpaceTransform)));
}

void CairoOperationRecorder::fillRect(const FloatRect& rect, const Color& color, CompositeOperator compositeOperator, BlendMode blendMode)
{
    struct FillRect final : PaintingOperation, OperationData<FloatRect, Color, CompositeOperator, BlendMode, Cairo::ShadowState, CompositeOperator> {
        virtual ~FillRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            auto& platformContext = contextForReplay(replayer);

            Cairo::State::setCompositeOperation(platformContext, arg<2>(), arg<3>());
            Cairo::fillRect(platformContext, arg<0>(), arg<1>(), arg<4>());
            Cairo::State::setCompositeOperation(platformContext, arg<5>(), BlendMode::Normal);
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillRect<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<FillRect>(rect, color, compositeOperator, blendMode, Cairo::ShadowState(state), state.compositeOperator));
}

void CairoOperationRecorder::fillRoundedRect(const FloatRoundedRect& roundedRect, const Color& color, BlendMode blendMode)
{
    struct FillRoundedRect final : PaintingOperation, OperationData<FloatRoundedRect, Color, CompositeOperator, BlendMode, Cairo::ShadowState> {
        virtual ~FillRoundedRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            auto& platformContext = contextForReplay(replayer);

            Cairo::State::setCompositeOperation(platformContext, arg<2>(), arg<3>());

            auto& rect = arg<0>();
            if (rect.isRounded())
                Cairo::fillRoundedRect(platformContext, rect, arg<1>(), arg<4>());
            else
                Cairo::fillRect(platformContext, rect.rect(), arg<1>(), arg<4>());

            Cairo::State::setCompositeOperation(platformContext, arg<2>(), BlendMode::Normal);
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillRoundedRect<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<FillRoundedRect>(roundedRect, color, state.compositeOperator, blendMode, Cairo::ShadowState(state)));
}

void CairoOperationRecorder::fillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
{
    struct FillRectWithRoundedHole final : PaintingOperation, OperationData<FloatRect, FloatRoundedRect, Cairo::ShadowState> {
        virtual ~FillRectWithRoundedHole() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::fillRectWithRoundedHole(contextForReplay(replayer), arg<0>(), arg<1>(), { }, arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillRectWithRoundedHole<>\n";
        }
    };

    UNUSED_PARAM(color);
    append(createCommand<FillRectWithRoundedHole>(rect, roundedHoleRect, Cairo::ShadowState(state())));
}

void CairoOperationRecorder::fillPath(const Path& path)
{
    struct FillPath final : PaintingOperation, OperationData<Path, Cairo::FillSource, Cairo::ShadowState> {
        virtual ~FillPath() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::fillPath(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillPath<>\n";
        }
    };

    if (path.isEmpty())
        return;

    auto& state = this->state();
    append(createCommand<FillPath>(path, Cairo::FillSource(state), Cairo::ShadowState(state)));
}

void CairoOperationRecorder::fillEllipse(const FloatRect& rect)
{
    struct FillEllipse final : PaintingOperation, OperationData<FloatRect, Cairo::FillSource, Cairo::ShadowState> {
        virtual ~FillEllipse() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Path path;
            path.addEllipse(arg<0>());
            Cairo::fillPath(contextForReplay(replayer), path, arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "FillEllipse<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<FillEllipse>(rect, Cairo::FillSource(state), Cairo::ShadowState(state)));
}

void CairoOperationRecorder::strokeRect(const FloatRect& rect, float lineWidth)
{
    struct StrokeRect final : PaintingOperation, OperationData<FloatRect, float, Cairo::StrokeSource, Cairo::ShadowState> {
        virtual ~StrokeRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::strokeRect(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>(), arg<3>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "StrokeRect<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<StrokeRect>(rect, lineWidth, Cairo::StrokeSource(state), Cairo::ShadowState(state)));
}

void CairoOperationRecorder::strokePath(const Path& path)
{
    struct StrokePath final : PaintingOperation, OperationData<Path, Cairo::StrokeSource, Cairo::ShadowState> {
        virtual ~StrokePath() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::strokePath(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "StrokePath<>\n";
        }
    };

    if (path.isEmpty())
        return;

    auto& state = this->state();
    append(createCommand<StrokePath>(path, Cairo::StrokeSource(state), Cairo::ShadowState(state)));
}

void CairoOperationRecorder::strokeEllipse(const FloatRect& rect)
{
    struct StrokeEllipse final : PaintingOperation, OperationData<FloatRect, Cairo::StrokeSource, Cairo::ShadowState> {
        virtual ~StrokeEllipse() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Path path;
            path.addEllipse(arg<0>());
            Cairo::strokePath(contextForReplay(replayer), path, arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "StrokeEllipse<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<StrokeEllipse>(rect, Cairo::StrokeSource(state), Cairo::ShadowState(state)));
}

void CairoOperationRecorder::clearRect(const FloatRect& rect)
{
    struct ClearRect final : PaintingOperation, OperationData<FloatRect> {
        virtual ~ClearRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::clearRect(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "ClearRect<>\n";
        }
    };

    append(createCommand<ClearRect>(rect));
}

void CairoOperationRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& point, FontSmoothingMode fontSmoothing)
{
    struct DrawGlyphs final : PaintingOperation, OperationData<Cairo::FillSource, Cairo::StrokeSource, Cairo::ShadowState, FloatPoint, RefPtr<cairo_scaled_font_t>, float, Vector<cairo_glyph_t>, float, TextDrawingModeFlags, float, FloatSize, Color, FontSmoothingMode> {
        virtual ~DrawGlyphs() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawGlyphs(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>(), arg<3>(), arg<4>().get(),
                arg<5>(), arg<6>(), arg<7>(), arg<8>(), arg<9>(), arg<10>(), arg<11>(), arg<12>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawGlyphs<>\n";
        }
    };

    if (!font.platformData().size())
        return;

    auto xOffset = point.x();
    Vector<cairo_glyph_t> cairoGlyphs(numGlyphs);
    {
        auto yOffset = point.y();
        for (size_t i = 0; i < numGlyphs; ++i) {
            cairoGlyphs[i] = { glyphs[i], xOffset, yOffset };
            xOffset += advances[i].width();
        }
    }

    auto& state = this->state();
    append(createCommand<DrawGlyphs>(Cairo::FillSource(state), Cairo::StrokeSource(state),
        Cairo::ShadowState(state), point,
        RefPtr<cairo_scaled_font_t>(font.platformData().scaledFont()),
        font.syntheticBoldOffset(), WTFMove(cairoGlyphs), xOffset, state.textDrawingMode,
        state.strokeThickness, state.shadowOffset, state.shadowColor, fontSmoothing));
}

void CairoOperationRecorder::drawImageBuffer(ImageBuffer&, const FloatRect&, const FloatRect&, const ImagePaintingOptions&)
{
    // FIXME: Not implemented.
}

void CairoOperationRecorder::drawNativeImage(NativeImage& nativeImage, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options)
{
    struct DrawNativeImage final : PaintingOperation, OperationData<RefPtr<cairo_surface_t>, FloatRect, FloatRect, ImagePaintingOptions, float, Cairo::ShadowState> {
        virtual ~DrawNativeImage() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawPlatformImage(contextForReplay(replayer), arg<0>().get(), arg<1>(), arg<2>(), arg<3>(), arg<4>(), arg<5>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawNativeImage<>\n";
        }
    };

    UNUSED_PARAM(imageSize);
    auto& state = this->state();
    append(createCommand<DrawNativeImage>(nativeImage.platformImage(), destRect, srcRect, ImagePaintingOptions(options, state.imageInterpolationQuality), state.alpha, Cairo::ShadowState(state)));
}

void CairoOperationRecorder::drawPattern(NativeImage& nativeImage, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
{
    struct DrawPattern final : PaintingOperation, OperationData<RefPtr<cairo_surface_t>, IntSize, FloatRect, FloatRect, AffineTransform, FloatPoint, ImagePaintingOptions> {
        virtual ~DrawPattern() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawPattern(contextForReplay(replayer), arg<0>().get(), arg<1>(), arg<2>(), arg<3>(), arg<4>(), arg<5>(), arg<6>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawPattern<>\n";
        }
    };

    UNUSED_PARAM(spacing);
    append(createCommand<DrawPattern>(nativeImage.platformImage(), IntSize(imageSize), destRect, tileRect, patternTransform, phase, options));
}

void CairoOperationRecorder::drawRect(const FloatRect& rect, float borderThickness)
{
    struct DrawRect final : PaintingOperation, OperationData<FloatRect, float, Color, StrokeStyle, Color> {
        virtual ~DrawRect() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawRect(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>(), arg<3>(), arg<4>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawRect<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<DrawRect>(rect, borderThickness, state.fillColor, state.strokeStyle, state.strokeColor));
}

void CairoOperationRecorder::drawLine(const FloatPoint& point1, const FloatPoint& point2)
{
    struct DrawLine final : PaintingOperation, OperationData<FloatPoint, FloatPoint, StrokeStyle, Color, float, bool> {
        virtual ~DrawLine() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawLine(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>(), arg<3>(), arg<4>(), arg<5>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawLine<>\n";
        }
    };

    if (strokeStyle() == NoStroke)
        return;

    auto& state = this->state();
    append(createCommand<DrawLine>(point1, point2, state.strokeStyle, state.strokeColor, state.strokeThickness, state.shouldAntialias));
}

void CairoOperationRecorder::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines, StrokeStyle)
{
    struct DrawLinesForText final : PaintingOperation, OperationData<FloatPoint, float, DashArray, bool, bool, Color> {
        virtual ~DrawLinesForText() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawLinesForText(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>(), arg<3>(), arg<4>(), arg<5>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawLinesForText<>\n";
        }
    };

    if (widths.isEmpty())
        return;

    auto& state = this->state();
    append(createCommand<DrawLinesForText>(point, thickness, widths, printing, doubleUnderlines, state.strokeColor));
}

void CairoOperationRecorder::drawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
{
    struct DrawDotsForDocumentMarker final : PaintingOperation, OperationData<FloatRect, DocumentMarkerLineStyle> {
        virtual ~DrawDotsForDocumentMarker() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawDotsForDocumentMarker(contextForReplay(replayer), arg<0>(), arg<1>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawDotsForDocumentMarker<>\n";
        }
    };

    append(createCommand<DrawDotsForDocumentMarker>(rect, style));
}

void CairoOperationRecorder::drawEllipse(const FloatRect& rect)
{
    struct DrawEllipse final : PaintingOperation, OperationData<FloatRect, Color, StrokeStyle, Color, float> {
        virtual ~DrawEllipse() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawEllipse(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>(), arg<3>(), arg<4>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawEllipse<>\n";
        }
    };

    auto& state = this->state();
    append(createCommand<DrawEllipse>(rect, state.fillColor, state.strokeStyle, state.strokeColor, state.strokeThickness));
}

void CairoOperationRecorder::drawFocusRing(const Path& path, float width, float offset, const Color& color)
{
#if PLATFORM(WPE) || PLATFORM(GTK)
    ThemeAdwaita::paintFocus(*this, path, color);
    UNUSED_PARAM(width);
#else
    struct DrawFocusRing final : PaintingOperation, OperationData<Path, float, Color> {
        virtual ~DrawFocusRing() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawFocusRing(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawFocusRing<>\n";
        }
    };

    append(createCommand<DrawFocusRing>(path, width, color));
#endif
    UNUSED_PARAM(offset);
}

void CairoOperationRecorder::drawFocusRing(const Vector<FloatRect>& rects, float width, float offset, const Color& color)
{
#if PLATFORM(WPE) || PLATFORM(GTK)
    ThemeAdwaita::paintFocus(*this, rects, color);
    UNUSED_PARAM(width);
#else
    struct DrawFocusRing final : PaintingOperation, OperationData<Vector<FloatRect>, float, Color> {
        virtual ~DrawFocusRing() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::drawFocusRing(contextForReplay(replayer), arg<0>(), arg<1>(), arg<2>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "DrawFocusRing<>\n";
        }
    };

    append(createCommand<DrawFocusRing>(rects, width, color));
#endif
    UNUSED_PARAM(offset);
}

void CairoOperationRecorder::save()
{
    struct Save final : PaintingOperation, OperationData<> {
        virtual ~Save() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            contextForReplay(replayer).save();
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "Save<>\n";
        }
    };

    GraphicsContext::save();

    append(createCommand<Save>());

    m_stateStack.append(m_stateStack.last());
}

void CairoOperationRecorder::restore()
{
    struct Restore final : PaintingOperation, OperationData<> {
        virtual ~Restore() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            contextForReplay(replayer).restore();
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "Restore<>\n";
        }
    };

    if (!stackSize())
        return;

    GraphicsContext::restore();

    if (m_stateStack.isEmpty())
        return;

    append(createCommand<Restore>());

    m_stateStack.removeLast();
    if (m_stateStack.isEmpty())
        m_stateStack.clear();
}

void CairoOperationRecorder::translate(float x, float y)
{
    struct Translate final : PaintingOperation, OperationData<float, float> {
        virtual ~Translate() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::translate(contextForReplay(replayer), arg<0>(), arg<1>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "Translate<>\n";
        }
    };

    append(createCommand<Translate>(x, y));

    {
        auto& state = m_stateStack.last();
        state.ctm.translate(x, y);

        AffineTransform t;
        t.translate(-x, -y);
        state.ctmInverse = t * state.ctmInverse;
    }
}

void CairoOperationRecorder::rotate(float angleInRadians)
{
    struct Rotate final : PaintingOperation, OperationData<float> {
        virtual ~Rotate() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::rotate(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "Rotate<>\n";
        }
    };

    append(createCommand<Rotate>(angleInRadians));

    {
        auto& state = m_stateStack.last();
        state.ctm.rotate(angleInRadians);

        AffineTransform t;
        t.rotate(angleInRadians);
        state.ctmInverse = t * state.ctmInverse;
    }
}

void CairoOperationRecorder::scale(const FloatSize& size)
{
    struct Scale final : PaintingOperation, OperationData<FloatSize> {
        virtual ~Scale() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::scale(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "Scale<>\n";
        }
    };

    append(createCommand<Scale>(size));

    {
        auto& state = m_stateStack.last();
        state.ctm.scale(size.width(), size.height());

        AffineTransform t;
        t.scale(1 / size.width(), 1 / size.height());
        state.ctmInverse = t * state.ctmInverse;
    }
}

void CairoOperationRecorder::concatCTM(const AffineTransform& transform)
{
    struct ConcatCTM final : PaintingOperation, OperationData<AffineTransform> {
        virtual ~ConcatCTM() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::concatCTM(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "ConcatCTM<>\n";
        }
    };

    auto inverse = transform.inverse();
    if (!inverse)
        return;

    append(createCommand<ConcatCTM>(transform));

    auto& state = m_stateStack.last();
    state.ctm *= transform;
    state.ctmInverse = inverse.value() * state.ctmInverse;
}

void CairoOperationRecorder::setCTM(const AffineTransform& transform)
{
    struct SetCTM final : PaintingOperation, OperationData<AffineTransform> {
        virtual ~SetCTM() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::State::setCTM(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "SetCTM<>\n";
        }
    };

    auto inverse = transform.inverse();
    if (!inverse)
        return;

    append(createCommand<SetCTM>(transform));

    auto& state = m_stateStack.last();
    state.ctm = transform;
    state.ctmInverse = inverse.value();
}

AffineTransform CairoOperationRecorder::getCTM(GraphicsContext::IncludeDeviceScale) const
{
    return m_stateStack.last().ctm;
}

void CairoOperationRecorder::beginTransparencyLayer(float opacity)
{
    struct BeginTransparencyLayer final : PaintingOperation, OperationData<float> {
        virtual ~BeginTransparencyLayer() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::beginTransparencyLayer(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "BeginTransparencyLayer<>\n";
        }
    };

    GraphicsContext::beginTransparencyLayer(opacity);

    append(createCommand<BeginTransparencyLayer>(opacity));
}

void CairoOperationRecorder::endTransparencyLayer()
{
    struct EndTransparencyLayer final : PaintingOperation, OperationData<> {
        virtual ~EndTransparencyLayer() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::endTransparencyLayer(contextForReplay(replayer));
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "EndTransparencyLayer<>\n";
        }
    };

    GraphicsContext::endTransparencyLayer();

    append(createCommand<EndTransparencyLayer>());
}

void CairoOperationRecorder::clip(const FloatRect& rect)
{
    struct Clip final : PaintingOperation, OperationData<FloatRect> {
        virtual ~Clip() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::clip(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "Clip<>\n";
        }
    };

    append(createCommand<Clip>(rect));

    {
        auto& state = m_stateStack.last();
        state.clipBounds.intersect(state.ctm.mapRect(rect));
    }
}

void CairoOperationRecorder::clipOut(const FloatRect& rect)
{
    struct ClipOut final : PaintingOperation, OperationData<FloatRect> {
        virtual ~ClipOut() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::clipOut(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "ClipOut<>\n";
        }
    };

    append(createCommand<ClipOut>(rect));
}

void CairoOperationRecorder::clipOut(const Path& path)
{
    struct ClipOut final : PaintingOperation, OperationData<Path> {
        virtual ~ClipOut() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::clipOut(contextForReplay(replayer), arg<0>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "ClipOut<>\n";
        }
    };

    append(createCommand<ClipOut>(path));
}

void CairoOperationRecorder::clipPath(const Path& path, WindRule clipRule)
{
    struct ClipPath final : PaintingOperation, OperationData<Path, WindRule> {
        virtual ~ClipPath() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::clipPath(contextForReplay(replayer), arg<0>(), arg<1>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "ClipPath<>\n";
        }
    };

    append(createCommand<ClipPath>(path, clipRule));

    {
        auto& state = m_stateStack.last();
        state.clipBounds.intersect(state.ctm.mapRect(path.fastBoundingRect()));
    }
}

IntRect CairoOperationRecorder::clipBounds() const
{
    auto& state = m_stateStack.last();
    return enclosingIntRect(state.ctmInverse.mapRect(state.clipBounds));
}

void CairoOperationRecorder::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& destRect)
{
    struct ClipToImageBuffer final: PaintingOperation, OperationData<RefPtr<cairo_surface_t>, FloatRect> {
        virtual ~ClipToImageBuffer() = default;

        void execute(PaintingOperationReplay& replayer) override
        {
            Cairo::clipToImageBuffer(contextForReplay(replayer), arg<0>().get(), arg<1>());
        }

        void dump(TextStream& ts) override
        {
            ts << indent << "ClipToImageBuffer<>\n";
        }
    };

    RefPtr<Image> image = buffer.copyImage(DontCopyBackingStore);
    if (!image)
        return;

    if (auto nativeImage = image->nativeImageForCurrentFrame())
        append(createCommand<ClipToImageBuffer>(nativeImage->platformImage(), destRect));
}

void CairoOperationRecorder::applyDeviceScaleFactor(float)
{
}

FloatRect CairoOperationRecorder::roundToDevicePixels(const FloatRect& rect, GraphicsContext::RoundingMode)
{
    return rect;
}

void CairoOperationRecorder::append(std::unique_ptr<PaintingOperation>&& command)
{
    m_commandList.append(WTFMove(command));
}

GraphicsContext::ClipToDrawingCommandsResult CairoOperationRecorder::clipToDrawingCommands(const FloatRect&, const DestinationColorSpace&, Function<void(GraphicsContext&)>&&)
{
    // FIXME: Not implemented.
    return ClipToDrawingCommandsResult::Success;
}

#if ENABLE(VIDEO)
void CairoOperationRecorder::paintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
{
    // FIXME: Not implemented.
    GraphicsContext::paintFrameForMedia(player, destination);
}
#endif

} // namespace Nicosia
