/*
 * 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. 
 */

#pragma once

#include "AlphaPremultiplication.h"
#include "DisplayListItemBufferIdentifier.h"
#include "DisplayListItemType.h"
#include "FloatRoundedRect.h"
#include "Font.h"
#include "GlyphBuffer.h"
#include "Gradient.h"
#include "GraphicsContext.h"
#include "GraphicsContextFlushIdentifier.h"
#include "Image.h"
#include "MediaPlayerIdentifier.h"
#include "Pattern.h"
#include "PixelBuffer.h"
#include "RenderingResourceIdentifier.h"
#include "SharedBuffer.h"
#include <variant>
#include <wtf/EnumTraits.h>
#include <wtf/TypeCasts.h>

namespace WTF {
class TextStream;
}

namespace WebCore {

class MediaPlayer;
struct ImagePaintingOptions;

namespace DisplayList {

struct ItemHandle;

/* isInlineItem indicates whether the object needs to be passed through IPC::Encoder in order to serialize,
 * or whether we can just use placement new and be done.
 * It needs to match (1) RemoteImageBufferProxy::encodeItem(), (2) RemoteRenderingBackend::decodeItem(),
 * and (3) isInlineItem() in DisplayListItemType.cpp.
 *
 * isDrawingItem indicates if this command can affect dirty rects.
 * We can do things like skip drawing items when replaying them if their extents don't intersect with the current clip.
 * It needs to match isDrawingItem() in DisplayListItemType.cpp. */

class Save {
public:
    static constexpr ItemType itemType = ItemType::Save;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    WEBCORE_EXPORT void apply(GraphicsContext&) const;
};

class Restore {
public:
    static constexpr ItemType itemType = ItemType::Restore;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    WEBCORE_EXPORT void apply(GraphicsContext&) const;
};

class Translate {
public:
    static constexpr ItemType itemType = ItemType::Translate;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    Translate(float x, float y)
        : m_x(x)
        , m_y(y)
    {
    }

    float x() const { return m_x; }
    float y() const { return m_y; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    float m_x { 0 };
    float m_y { 0 };
};

class Rotate {
public:
    static constexpr ItemType itemType = ItemType::Rotate;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    Rotate(float angle)
        : m_angle(angle)
    {
    }

    float angle() const { return m_angle; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    float m_angle { 0 }; // In radians.
};

class Scale {
public:
    static constexpr ItemType itemType = ItemType::Scale;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    Scale(const FloatSize& size)
        : m_size(size)
    {
    }

    const FloatSize& amount() const { return m_size; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    FloatSize m_size;
};

class SetCTM {
public:
    static constexpr ItemType itemType = ItemType::SetCTM;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetCTM(const AffineTransform& transform)
        : m_transform(transform)
    {
    }

    const AffineTransform& transform() const { return m_transform; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    AffineTransform m_transform;
};

class ConcatenateCTM {
public:
    static constexpr ItemType itemType = ItemType::ConcatenateCTM;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    ConcatenateCTM(const AffineTransform& transform)
        : m_transform(transform)
    {
    }

    const AffineTransform& transform() const { return m_transform; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    AffineTransform m_transform;
};

class SetInlineFillColor {
public:
    static constexpr ItemType itemType = ItemType::SetInlineFillColor;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetInlineFillColor() = default;
    SetInlineFillColor(SRGBA<uint8_t> colorData)
        : m_colorData(colorData)
    {
    }

    Color color() const { return { m_colorData }; }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    SRGBA<uint8_t> m_colorData;
};

class SetInlineStrokeColor {
public:
    static constexpr ItemType itemType = ItemType::SetInlineStrokeColor;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetInlineStrokeColor() = default;
    SetInlineStrokeColor(SRGBA<uint8_t> colorData)
        : m_colorData(colorData)
    {
    }

    Color color() const { return { m_colorData }; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    SRGBA<uint8_t> m_colorData;
};

class SetStrokeThickness {
public:
    static constexpr ItemType itemType = ItemType::SetStrokeThickness;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetStrokeThickness(float thickness)
        : m_thickness(thickness)
    {
    }

    float thickness() const { return m_thickness; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    float m_thickness { 0 };
};

class SetState {
public:
    static constexpr ItemType itemType = ItemType::SetState;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = false;

    WEBCORE_EXPORT SetState(const GraphicsContextState&, GraphicsContextState::StateChangeFlags);

    const GraphicsContextStateChange& stateChange() const { return m_stateChange; }
    const Pattern::Parameters& strokePatternParameters() const { return m_strokePattern.parameters; }
    const Pattern::Parameters& fillPatternParameters() const { return m_fillPattern.parameters; }
    RenderingResourceIdentifier strokePatternImageIdentifier() const { return m_strokePattern.tileImageIdentifier; }
    RenderingResourceIdentifier fillPatternImageIdentifier() const { return m_fillPattern.tileImageIdentifier; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<SetState> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&, NativeImage* strokePatternImage, NativeImage* fillPatternImage);

private:
    struct PatternData {
        RenderingResourceIdentifier tileImageIdentifier;
        Pattern::Parameters parameters;
    };

    WEBCORE_EXPORT SetState(const GraphicsContextStateChange&, const PatternData& strokePattern, const PatternData& fillPattern);

    GraphicsContextStateChange m_stateChange;
    PatternData m_strokePattern;
    PatternData m_fillPattern;
};

template<class Encoder>
void SetState::encode(Encoder& encoder) const
{
    auto changeFlags = m_stateChange.m_changeFlags;
    encoder << changeFlags;

    auto& state = m_stateChange.m_state;

    if (changeFlags.contains(GraphicsContextState::StrokeGradientChange)) {
        ASSERT(state.strokeGradient);
        encoder << *state.strokeGradient;
    }

    if (changeFlags.contains(GraphicsContextState::StrokePatternChange)) {
        ASSERT(state.strokePattern);
        encoder << state.strokePattern->tileImage().renderingResourceIdentifier();
        encoder << state.strokePattern->parameters();
    }

    if (changeFlags.contains(GraphicsContextState::FillGradientChange)) {
        ASSERT(state.fillGradient);
        encoder << *state.fillGradient;
    }

    if (changeFlags.contains(GraphicsContextState::FillPatternChange)) {
        ASSERT(state.fillPattern);
        encoder << state.fillPattern->tileImage().renderingResourceIdentifier();
        encoder << state.fillPattern->parameters();
    }

    if (changeFlags.contains(GraphicsContextState::ShadowChange)) {
        encoder << state.shadowOffset;
        encoder << state.shadowBlur;
        encoder << state.shadowColor;
        encoder << state.shadowRadiusMode;
    }

    if (changeFlags.contains(GraphicsContextState::StrokeThicknessChange))
        encoder << state.strokeThickness;

    if (changeFlags.contains(GraphicsContextState::TextDrawingModeChange))
        encoder << state.textDrawingMode;

    if (changeFlags.contains(GraphicsContextState::StrokeColorChange))
        encoder << state.strokeColor;

    if (changeFlags.contains(GraphicsContextState::FillColorChange))
        encoder << state.fillColor;

    if (changeFlags.contains(GraphicsContextState::StrokeStyleChange))
        encoder << state.strokeStyle;

    if (changeFlags.contains(GraphicsContextState::FillRuleChange))
        encoder << state.fillRule;

    if (changeFlags.contains(GraphicsContextState::CompositeOperationChange))
        encoder << state.compositeOperator;

    if (changeFlags.contains(GraphicsContextState::BlendModeChange))
        encoder << state.blendMode;

    if (changeFlags.contains(GraphicsContextState::ImageInterpolationQualityChange))
        encoder << state.imageInterpolationQuality;

    if (changeFlags.contains(GraphicsContextState::AlphaChange))
        encoder << state.alpha;

    if (changeFlags.contains(GraphicsContextState::ShouldAntialiasChange))
        encoder << state.shouldAntialias;

    if (changeFlags.contains(GraphicsContextState::ShouldSmoothFontsChange))
        encoder << state.shouldSmoothFonts;

    if (changeFlags.contains(GraphicsContextState::ShouldSubpixelQuantizeFontsChange))
        encoder << state.shouldSubpixelQuantizeFonts;

    if (changeFlags.contains(GraphicsContextState::ShadowsIgnoreTransformsChange))
        encoder << state.shadowsIgnoreTransforms;
}

template<class Decoder>
std::optional<SetState> SetState::decode(Decoder& decoder)
{
    std::optional<GraphicsContextState::StateChangeFlags> changeFlags;
    decoder >> changeFlags;
    if (!changeFlags)
        return std::nullopt;

    GraphicsContextStateChange stateChange;
    stateChange.m_changeFlags = *changeFlags;

    PatternData strokePattern;
    PatternData fillPattern;

    if (stateChange.m_changeFlags.contains(GraphicsContextState::StrokeGradientChange)) {
        auto strokeGradient = Gradient::decode(decoder);
        if (!strokeGradient)
            return std::nullopt;

        stateChange.m_state.strokeGradient = WTFMove(*strokeGradient);
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::StrokePatternChange)) {
        std::optional<RenderingResourceIdentifier> renderingResourceIdentifier;
        decoder >> renderingResourceIdentifier;
        if (!renderingResourceIdentifier)
            return std::nullopt;

        std::optional<Pattern::Parameters> parameters;
        decoder >> parameters;
        if (!parameters)
            return std::nullopt;

        strokePattern = { *renderingResourceIdentifier, *parameters };
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::FillGradientChange)) {
        auto fillGradient = Gradient::decode(decoder);
        if (!fillGradient)
            return std::nullopt;

        stateChange.m_state.fillGradient = WTFMove(*fillGradient);
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::FillPatternChange)) {
        std::optional<RenderingResourceIdentifier> renderingResourceIdentifier;
        decoder >> renderingResourceIdentifier;
        if (!renderingResourceIdentifier)
            return std::nullopt;

        std::optional<Pattern::Parameters> parameters;
        decoder >> parameters;
        if (!parameters)
            return std::nullopt;

        fillPattern = { *renderingResourceIdentifier, *parameters };
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::ShadowChange)) {
        std::optional<FloatSize> shadowOffset;
        decoder >> shadowOffset;
        if (!shadowOffset)
            return std::nullopt;

        stateChange.m_state.shadowOffset = *shadowOffset;

        std::optional<float> shadowBlur;
        decoder >> shadowBlur;
        if (!shadowBlur)
            return std::nullopt;

        stateChange.m_state.shadowBlur = *shadowBlur;

        std::optional<Color> shadowColor;
        decoder >> shadowColor;
        if (!shadowColor)
            return std::nullopt;

        stateChange.m_state.shadowColor = *shadowColor;

        std::optional<ShadowRadiusMode> shadowRadiusMode;
        decoder >> shadowRadiusMode;
        if (!shadowRadiusMode)
            return std::nullopt;

        stateChange.m_state.shadowRadiusMode = WTFMove(*shadowRadiusMode);
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::StrokeThicknessChange)) {
        std::optional<float> strokeThickness;
        decoder >> strokeThickness;
        if (!strokeThickness)
            return std::nullopt;

        stateChange.m_state.strokeThickness = *strokeThickness;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::TextDrawingModeChange)) {
        std::optional<TextDrawingModeFlags> textDrawingMode;
        decoder >> textDrawingMode;
        if (!textDrawingMode)
            return std::nullopt;

        stateChange.m_state.textDrawingMode = WTFMove(*textDrawingMode);
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::StrokeColorChange)) {
        std::optional<Color> strokeColor;
        decoder >> strokeColor;
        if (!strokeColor)
            return std::nullopt;

        stateChange.m_state.strokeColor = *strokeColor;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::FillColorChange)) {
        std::optional<Color> fillColor;
        decoder >> fillColor;
        if (!fillColor)
            return std::nullopt;

        stateChange.m_state.fillColor = *fillColor;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::StrokeStyleChange)) {
        StrokeStyle strokeStyle;
        if (!decoder.decode(strokeStyle))
            return std::nullopt;

        stateChange.m_state.strokeStyle = strokeStyle;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::FillRuleChange)) {
        std::optional<WindRule> fillRule;
        decoder >> fillRule;
        if (!fillRule)
            return std::nullopt;

        stateChange.m_state.fillRule = *fillRule;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::CompositeOperationChange)) {
        std::optional<CompositeOperator> compositeOperator;
        decoder >> compositeOperator;
        if (!compositeOperator)
            return std::nullopt;

        stateChange.m_state.compositeOperator = *compositeOperator;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::BlendModeChange)) {
        std::optional<BlendMode> blendMode;
        decoder >> blendMode;
        if (!blendMode)
            return std::nullopt;

        stateChange.m_state.blendMode = *blendMode;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::ImageInterpolationQualityChange)) {
        std::optional<InterpolationQuality> imageInterpolationQuality;
        decoder >> imageInterpolationQuality;
        if (!imageInterpolationQuality)
            return std::nullopt;

        stateChange.m_state.imageInterpolationQuality = *imageInterpolationQuality;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::AlphaChange)) {
        std::optional<float> alpha;
        decoder >> alpha;
        if (!alpha)
            return std::nullopt;

        stateChange.m_state.alpha = *alpha;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::ShouldAntialiasChange)) {
        std::optional<bool> shouldAntialias;
        decoder >> shouldAntialias;
        if (!shouldAntialias)
            return std::nullopt;

        stateChange.m_state.shouldAntialias = *shouldAntialias;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::ShouldSmoothFontsChange)) {
        std::optional<bool> shouldSmoothFonts;
        decoder >> shouldSmoothFonts;
        if (!shouldSmoothFonts)
            return std::nullopt;

        stateChange.m_state.shouldSmoothFonts = *shouldSmoothFonts;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::ShouldSubpixelQuantizeFontsChange)) {
        std::optional<bool> shouldSubpixelQuantizeFonts;
        decoder >> shouldSubpixelQuantizeFonts;
        if (!shouldSubpixelQuantizeFonts)
            return std::nullopt;

        stateChange.m_state.shouldSubpixelQuantizeFonts = *shouldSubpixelQuantizeFonts;
    }

    if (stateChange.m_changeFlags.contains(GraphicsContextState::ShadowsIgnoreTransformsChange)) {
        std::optional<bool> shadowsIgnoreTransforms;
        decoder >> shadowsIgnoreTransforms;
        if (!shadowsIgnoreTransforms)
            return std::nullopt;

        stateChange.m_state.shadowsIgnoreTransforms = *shadowsIgnoreTransforms;
    }

    return {{ stateChange, strokePattern, fillPattern }};
}

class SetLineCap {
public:
    static constexpr ItemType itemType = ItemType::SetLineCap;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetLineCap(LineCap lineCap)
        : m_lineCap(lineCap)
    {
    }

    LineCap lineCap() const { return m_lineCap; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    LineCap m_lineCap;
};

class SetLineDash {
public:
    static constexpr ItemType itemType = ItemType::SetLineDash;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = false;

    SetLineDash(const DashArray& dashArray, float dashOffset)
        : m_dashArray(dashArray)
        , m_dashOffset(dashOffset)
    {
    }

    const DashArray& dashArray() const { return m_dashArray; }
    float dashOffset() const { return m_dashOffset; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<SetLineDash> decode(Decoder&);

private:
    DashArray m_dashArray;
    float m_dashOffset;
};

template<class Encoder>
void SetLineDash::encode(Encoder& encoder) const
{
    encoder << m_dashArray;
    encoder << m_dashOffset;
}

template<class Decoder>
std::optional<SetLineDash> SetLineDash::decode(Decoder& decoder)
{
    std::optional<DashArray> dashArray;
    decoder >> dashArray;
    if (!dashArray)
        return std::nullopt;

    std::optional<float> dashOffset;
    decoder >> dashOffset;
    if (!dashOffset)
        return std::nullopt;

    return {{ *dashArray, *dashOffset }};
}

class SetLineJoin {
public:
    static constexpr ItemType itemType = ItemType::SetLineJoin;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetLineJoin(LineJoin lineJoin)
        : m_lineJoin(lineJoin)
    {
    }

    LineJoin lineJoin() const { return m_lineJoin; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    LineJoin m_lineJoin;
};

class SetMiterLimit {
public:
    static constexpr ItemType itemType = ItemType::SetMiterLimit;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    SetMiterLimit(float miterLimit)
        : m_miterLimit(miterLimit)
    {
    }

    float miterLimit() const { return m_miterLimit; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    float m_miterLimit;
};

class ClearShadow {
public:
    static constexpr ItemType itemType = ItemType::ClearShadow;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    WEBCORE_EXPORT void apply(GraphicsContext&) const;
};

// FIXME: treat as drawing item?
class Clip {
public:
    static constexpr ItemType itemType = ItemType::Clip;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    Clip(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    const FloatRect& rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    FloatRect m_rect;
};

class ClipOut {
public:
    static constexpr ItemType itemType = ItemType::ClipOut;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    ClipOut(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    const FloatRect& rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    FloatRect m_rect;
};

class ClipToImageBuffer {
public:
    static constexpr ItemType itemType = ItemType::ClipToImageBuffer;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    ClipToImageBuffer(RenderingResourceIdentifier imageBufferIdentifier, const FloatRect& destinationRect)
        : m_imageBufferIdentifier(imageBufferIdentifier)
        , m_destinationRect(destinationRect)
    {
    }
    
    RenderingResourceIdentifier imageBufferIdentifier() const { return m_imageBufferIdentifier; }
    FloatRect destinationRect() const { return m_destinationRect; }
    bool isValid() const { return m_imageBufferIdentifier.isValid(); }

    WEBCORE_EXPORT void apply(GraphicsContext&, WebCore::ImageBuffer&) const;

    NO_RETURN_DUE_TO_ASSERT void apply(GraphicsContext&) const;

private:
    RenderingResourceIdentifier m_imageBufferIdentifier;
    FloatRect m_destinationRect;
};

class ClipOutToPath {
public:
    static constexpr ItemType itemType = ItemType::ClipOutToPath;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = false;

    ClipOutToPath(Path&& path)
        : m_path(WTFMove(path))
    {
    }

    ClipOutToPath(const Path& path)
        : m_path(path)
    {
    }

    const Path& path() const { return m_path; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<ClipOutToPath> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    Path m_path;
};

template<class Encoder>
void ClipOutToPath::encode(Encoder& encoder) const
{
    encoder << m_path;
}

template<class Decoder>
std::optional<ClipOutToPath> ClipOutToPath::decode(Decoder& decoder)
{
    std::optional<Path> path;
    decoder >> path;
    if (!path)
        return std::nullopt;

    return {{ WTFMove(*path) }};
}

class ClipPath {
public:
    static constexpr ItemType itemType = ItemType::ClipPath;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = false;

    ClipPath(Path&& path, WindRule windRule)
        : m_path(WTFMove(path))
        , m_windRule(windRule)
    {
    }

    ClipPath(const Path& path, WindRule windRule)
        : m_path(path)
        , m_windRule(windRule)
    {
    }

    const Path& path() const { return m_path; }
    WindRule windRule() const { return m_windRule; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<ClipPath> decode(Decoder&);

private:
    Path m_path;
    WindRule m_windRule;
};

template<class Encoder>
void ClipPath::encode(Encoder& encoder) const
{
    encoder << m_path;
    encoder << m_windRule;
}

template<class Decoder>
std::optional<ClipPath> ClipPath::decode(Decoder& decoder)
{
    std::optional<Path> path;
    decoder >> path;
    if (!path)
        return std::nullopt;

    std::optional<WindRule> windRule;
    decoder >> windRule;
    if (!windRule)
        return std::nullopt;

    return {{ WTFMove(*path), *windRule }};
}

class BeginClipToDrawingCommands {
public:
    static constexpr ItemType itemType = ItemType::BeginClipToDrawingCommands;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = false;

    BeginClipToDrawingCommands(const FloatRect& destination, DestinationColorSpace colorSpace)
        : m_destination(destination)
        , m_colorSpace(WTFMove(colorSpace))
    {
    }

    // Explicit destructor added to force non-trivial destructor on all platforms
    // as the encoding logic currently hardcodes which display list item types need
    // out of line treatment rather than using the isInlineItem constant.
    ~BeginClipToDrawingCommands() { }

    const FloatRect& destination() const { return m_destination; }
    const DestinationColorSpace& colorSpace() const { return m_colorSpace; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<BeginClipToDrawingCommands> decode(Decoder&);

private:
    FloatRect m_destination;
    DestinationColorSpace m_colorSpace;
};

template<class Encoder>
void BeginClipToDrawingCommands::encode(Encoder& encoder) const
{
    encoder << m_destination;
    encoder << m_colorSpace;
}

template<class Decoder>
std::optional<BeginClipToDrawingCommands> BeginClipToDrawingCommands::decode(Decoder& decoder)
{
    std::optional<FloatRect> destination;
    decoder >> destination;
    if (!destination)
        return std::nullopt;

    std::optional<DestinationColorSpace> colorSpace;
    decoder >> colorSpace;
    if (!colorSpace)
        return std::nullopt;

    return {{ *destination, WTFMove(*colorSpace) }};
}

class EndClipToDrawingCommands {
public:
    static constexpr ItemType itemType = ItemType::EndClipToDrawingCommands;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    EndClipToDrawingCommands(const FloatRect& destination)
        : m_destination(destination)
    {
    }

    const FloatRect& destination() const { return m_destination; }

private:
    FloatRect m_destination;
};

class DrawGlyphs {
public:
    static constexpr ItemType itemType = ItemType::DrawGlyphs;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    RenderingResourceIdentifier fontIdentifier() { return m_fontIdentifier; }
    const FloatPoint& localAnchor() const { return m_localAnchor; }
    FloatPoint anchorPoint() const { return m_localAnchor; }
    const Vector<GlyphBufferGlyph, 16>& glyphs() const { return m_glyphs; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<DrawGlyphs> decode(Decoder&);

    WEBCORE_EXPORT DrawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned count, const FloatPoint& localAnchor, FontSmoothingMode);
    WEBCORE_EXPORT DrawGlyphs(RenderingResourceIdentifier, Vector<GlyphBufferGlyph, 128>&&, Vector<GlyphBufferAdvance, 128>&&, const FloatRect&, const FloatPoint& localAnchor, FontSmoothingMode);

    WEBCORE_EXPORT void apply(GraphicsContext&, const Font&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_bounds; }

private:
    void computeBounds(const Font&);

    RenderingResourceIdentifier m_fontIdentifier;
    Vector<GlyphBufferGlyph, 16> m_glyphs;
    Vector<GlyphBufferAdvance, 16> m_advances;
    FloatRect m_bounds;
    FloatPoint m_localAnchor;
    FontSmoothingMode m_smoothingMode;
};

template<class Encoder>
void DrawGlyphs::encode(Encoder& encoder) const
{
    encoder << m_fontIdentifier;
    encoder << m_glyphs;
    encoder << m_advances;
    encoder << m_bounds;
    encoder << m_localAnchor;
    encoder << m_smoothingMode;
}

template<class Decoder>
std::optional<DrawGlyphs> DrawGlyphs::decode(Decoder& decoder)
{
    std::optional<RenderingResourceIdentifier> fontIdentifier;
    decoder >> fontIdentifier;
    if (!fontIdentifier)
        return std::nullopt;

    std::optional<Vector<GlyphBufferGlyph, 128>> glyphs;
    decoder >> glyphs;
    if (!glyphs)
        return std::nullopt;

    std::optional<Vector<GlyphBufferAdvance, 128>> advances;
    decoder >> advances;
    if (!advances)
        return std::nullopt;

    if (glyphs->size() != advances->size())
        return std::nullopt;

    std::optional<FloatRect> bounds;
    decoder >> bounds;
    if (!bounds)
        return std::nullopt;

    std::optional<FloatPoint> localAnchor;
    decoder >> localAnchor;
    if (!localAnchor)
        return std::nullopt;

    std::optional<FontSmoothingMode> smoothingMode;
    decoder >> smoothingMode;
    if (!smoothingMode)
        return std::nullopt;

    return {{ *fontIdentifier, WTFMove(*glyphs), WTFMove(*advances), *bounds, *localAnchor, *smoothingMode }};
}

class DrawImageBuffer {
public:
    static constexpr ItemType itemType = ItemType::DrawImageBuffer;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    DrawImageBuffer(RenderingResourceIdentifier imageBufferIdentifier, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options)
        : m_imageBufferIdentifier(imageBufferIdentifier)
        , m_destinationRect(destRect)
        , m_srcRect(srcRect)
        , m_options(options)
    {
    }

    RenderingResourceIdentifier imageBufferIdentifier() const { return m_imageBufferIdentifier; }
    FloatRect source() const { return m_srcRect; }
    FloatRect destinationRect() const { return m_destinationRect; }
    ImagePaintingOptions options() const { return m_options; }
    // FIXME: We might want to validate ImagePaintingOptions.
    bool isValid() const { return m_imageBufferIdentifier.isValid(); }

    WEBCORE_EXPORT void apply(GraphicsContext&, WebCore::ImageBuffer&) const;

    NO_RETURN_DUE_TO_ASSERT void apply(GraphicsContext&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_destinationRect; }

private:
    RenderingResourceIdentifier m_imageBufferIdentifier;
    FloatRect m_destinationRect;
    FloatRect m_srcRect;
    ImagePaintingOptions m_options;
};

class DrawNativeImage {
public:
    static constexpr ItemType itemType = ItemType::DrawNativeImage;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    DrawNativeImage(RenderingResourceIdentifier imageIdentifier, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options)
        : m_imageIdentifier(imageIdentifier)
        , m_imageSize(imageSize)
        , m_destinationRect(destRect)
        , m_srcRect(srcRect)
        , m_options(options)
    {
    }

    RenderingResourceIdentifier imageIdentifier() const { return m_imageIdentifier; }
    const FloatRect& source() const { return m_srcRect; }
    const FloatRect& destinationRect() const { return m_destinationRect; }
    // FIXME: We might want to validate ImagePaintingOptions.
    bool isValid() const { return m_imageIdentifier.isValid(); }

    NO_RETURN_DUE_TO_ASSERT void apply(GraphicsContext&) const;
    WEBCORE_EXPORT void apply(GraphicsContext&, NativeImage&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_destinationRect; }

private:
    RenderingResourceIdentifier m_imageIdentifier;
    FloatSize m_imageSize;
    FloatRect m_destinationRect;
    FloatRect m_srcRect;
    ImagePaintingOptions m_options;
};

class DrawPattern {
public:
    static constexpr ItemType itemType = ItemType::DrawPattern;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    WEBCORE_EXPORT DrawPattern(RenderingResourceIdentifier, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { });

    RenderingResourceIdentifier imageIdentifier() const { return m_imageIdentifier; }
    FloatSize imageSize() const { return m_imageSize; }
    FloatRect destRect() const { return m_destination; }
    FloatRect tileRect() const { return m_tileRect; }
    const AffineTransform& patternTransform() const { return m_patternTransform; }
    FloatPoint phase() const { return m_phase; }
    FloatSize spacing() const { return m_spacing; }
    // FIXME: We might want to validate ImagePaintingOptions.
    bool isValid() const { return m_imageIdentifier.isValid(); }

    NO_RETURN_DUE_TO_ASSERT void apply(GraphicsContext&) const;
    WEBCORE_EXPORT void apply(GraphicsContext&, NativeImage&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_destination; }

private:
    RenderingResourceIdentifier m_imageIdentifier;
    FloatSize m_imageSize;
    FloatRect m_destination;
    FloatRect m_tileRect;
    AffineTransform m_patternTransform;
    FloatPoint m_phase;
    FloatSize m_spacing;
    ImagePaintingOptions m_options;
};

class BeginTransparencyLayer {
public:
    static constexpr ItemType itemType = ItemType::BeginTransparencyLayer;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true; // Is drawing item because the size of the transparency layer is implicitly the clip bounds.

    BeginTransparencyLayer(float opacity)
        : m_opacity(opacity)
    {
    }

    float opacity() const { return m_opacity; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    float m_opacity;
};

class EndTransparencyLayer {
public:
    static constexpr ItemType itemType = ItemType::EndTransparencyLayer;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

class DrawRect {
public:
    static constexpr ItemType itemType = ItemType::DrawRect;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    DrawRect(FloatRect rect, float borderThickness)
        : m_rect(rect)
        , m_borderThickness(borderThickness)
    {
    }

    FloatRect rect() const { return m_rect; }
    float borderThickness() const { return m_borderThickness; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
    float m_borderThickness;
};

class DrawLine {
public:
    static constexpr ItemType itemType = ItemType::DrawLine;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    DrawLine(FloatPoint point1, FloatPoint point2)
        : m_point1(point1)
        , m_point2(point2)
    {
    }

    FloatPoint point1() const { return m_point1; }
    FloatPoint point2() const { return m_point2; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatPoint m_point1;
    FloatPoint m_point2;
};

class DrawLinesForText {
public:
    static constexpr ItemType itemType = ItemType::DrawLinesForText;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    WEBCORE_EXPORT DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, float thickness, const DashArray& widths, bool printing, bool doubleLines);

    void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; }
    const FloatPoint& blockLocation() const { return m_blockLocation; }
    const FloatSize& localAnchor() const { return m_localAnchor; }
    FloatPoint point() const { return m_blockLocation + m_localAnchor; }
    float thickness() const { return m_thickness; }
    const DashArray& widths() const { return m_widths; }
    bool isPrinting() const { return m_printing; }
    bool doubleLines() const { return m_doubleLines; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<DrawLinesForText> decode(Decoder&);

private:
    FloatPoint m_blockLocation;
    FloatSize m_localAnchor;
    DashArray m_widths;
    float m_thickness;
    bool m_printing;
    bool m_doubleLines;
};

template<class Encoder>
void DrawLinesForText::encode(Encoder& encoder) const
{
    encoder << m_blockLocation;
    encoder << m_localAnchor;
    encoder << m_widths;
    encoder << m_thickness;
    encoder << m_printing;
    encoder << m_doubleLines;
}

template<class Decoder>
std::optional<DrawLinesForText> DrawLinesForText::decode(Decoder& decoder)
{
    std::optional<FloatPoint> blockLocation;
    decoder >> blockLocation;
    if (!blockLocation)
        return std::nullopt;

    std::optional<FloatSize> localAnchor;
    decoder >> localAnchor;
    if (!localAnchor)
        return std::nullopt;

    std::optional<DashArray> widths;
    decoder >> widths;
    if (!widths)
        return std::nullopt;

    std::optional<float> thickness;
    decoder >> thickness;
    if (!thickness)
        return std::nullopt;

    std::optional<bool> printing;
    decoder >> printing;
    if (!printing)
        return std::nullopt;

    std::optional<bool> doubleLines;
    decoder >> doubleLines;
    if (!doubleLines)
        return std::nullopt;

    return {{ *blockLocation, *localAnchor, *thickness, *widths, *printing, *doubleLines }};
}

class DrawDotsForDocumentMarker {
public:
    static constexpr ItemType itemType = ItemType::DrawDotsForDocumentMarker;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    using UnderlyingDocumentMarkerLineStyleType = std::underlying_type<DocumentMarkerLineStyle::Mode>::type;

    DrawDotsForDocumentMarker(const FloatRect& rect, const DocumentMarkerLineStyle& style)
        : m_rect(rect)
        , m_styleMode(static_cast<UnderlyingDocumentMarkerLineStyleType>(style.mode))
        , m_styleShouldUseDarkAppearance(style.shouldUseDarkAppearance)
    {
    }

    DrawDotsForDocumentMarker(const FloatRect& rect, UnderlyingDocumentMarkerLineStyleType styleMode, bool styleShouldUseDarkAppearance)
        : m_rect(rect)
        , m_styleMode(styleMode)
        , m_styleShouldUseDarkAppearance(styleShouldUseDarkAppearance)
    {
    }

    bool isValid() const { return isValidEnum<DocumentMarkerLineStyle::Mode>(m_styleMode); }

    FloatRect rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
    UnderlyingDocumentMarkerLineStyleType m_styleMode { 0 };
    bool m_styleShouldUseDarkAppearance { false };
};

class DrawEllipse {
public:
    static constexpr ItemType itemType = ItemType::DrawEllipse;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    DrawEllipse(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    FloatRect rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
};

class DrawPath {
public:
    static constexpr ItemType itemType = ItemType::DrawPath;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    DrawPath(const Path& path)
        : m_path(path)
    {
    }

    DrawPath(Path&& path)
        : m_path(WTFMove(path))
    {
    }

    const Path& path() const { return m_path; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<DrawPath> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_path.fastBoundingRect(); }

private:
    Path m_path;
};

template<class Encoder>
void DrawPath::encode(Encoder& encoder) const
{
    encoder << m_path;
}

template<class Decoder>
std::optional<DrawPath> DrawPath::decode(Decoder& decoder)
{
    std::optional<Path> path;
    decoder >> path;
    if (!path)
        return std::nullopt;

    return {{ WTFMove(*path) }};
}

class DrawFocusRingPath {
public:
    static constexpr ItemType itemType = ItemType::DrawFocusRingPath;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    DrawFocusRingPath(Path&& path, float width, float offset, Color color)
        : m_path(WTFMove(path))
        , m_width(width)
        , m_offset(offset)
        , m_color(color)
    {
    }

    DrawFocusRingPath(const Path& path, float width, float offset, Color color)
        : m_path(path)
        , m_width(width)
        , m_offset(offset)
        , m_color(color)
    {
    }

    const Path& path() const { return m_path; }
    float width() const { return m_width; }
    float offset() const { return m_offset; }
    const Color& color() const { return m_color; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<DrawFocusRingPath> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    Path m_path;
    float m_width;
    float m_offset;
    Color m_color;
};

template<class Encoder>
void DrawFocusRingPath::encode(Encoder& encoder) const
{
    encoder << m_path;
    encoder << m_width;
    encoder << m_offset;
    encoder << m_color;
}

template<class Decoder>
std::optional<DrawFocusRingPath> DrawFocusRingPath::decode(Decoder& decoder)
{
    std::optional<Path> path;
    decoder >> path;
    if (!path)
        return std::nullopt;

    std::optional<float> width;
    decoder >> width;
    if (!width)
        return std::nullopt;

    std::optional<float> offset;
    decoder >> offset;
    if (!offset)
        return std::nullopt;

    std::optional<Color> color;
    decoder >> color;
    if (!color)
        return std::nullopt;

    return {{ WTFMove(*path), *width, *offset, *color }};
}

class DrawFocusRingRects {
public:
    static constexpr ItemType itemType = ItemType::DrawFocusRingRects;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    WEBCORE_EXPORT DrawFocusRingRects(const Vector<FloatRect>&, float width, float offset, const Color&);

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

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<DrawFocusRingRects> decode(Decoder&);

private:
    Vector<FloatRect> m_rects;
    float m_width;
    float m_offset;
    Color m_color;
};

template<class Encoder>
void DrawFocusRingRects::encode(Encoder& encoder) const
{
    encoder << m_rects;
    encoder << m_width;
    encoder << m_offset;
    encoder << m_color;
}

template<class Decoder>
std::optional<DrawFocusRingRects> DrawFocusRingRects::decode(Decoder& decoder)
{
    std::optional<Vector<FloatRect>> rects;
    decoder >> rects;
    if (!rects)
        return std::nullopt;

    std::optional<float> width;
    decoder >> width;
    if (!width)
        return std::nullopt;

    std::optional<float> offset;
    decoder >> offset;
    if (!offset)
        return std::nullopt;

    std::optional<Color> color;
    decoder >> color;
    if (!color)
        return std::nullopt;

    return {{ *rects, *width, *offset, *color }};
}

class FillRect {
public:
    static constexpr ItemType itemType = ItemType::FillRect;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    FillRect(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    const FloatRect& rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
};

class FillRectWithColor {
public:
    static constexpr ItemType itemType = ItemType::FillRectWithColor;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    FillRectWithColor(const FloatRect& rect, const Color& color)
        : m_rect(rect)
        , m_color(color)
    {
    }

    FloatRect rect() const { return m_rect; }
    const Color& color() const { return m_color; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<FillRectWithColor> decode(Decoder&);

private:
    FloatRect m_rect;
    Color m_color;
};

template<class Encoder>
void FillRectWithColor::encode(Encoder& encoder) const
{
    encoder << m_rect;
    encoder << m_color;
}

template<class Decoder>
std::optional<FillRectWithColor> FillRectWithColor::decode(Decoder& decoder)
{
    std::optional<FloatRect> rect;
    decoder >> rect;
    if (!rect)
        return std::nullopt;

    std::optional<Color> color;
    decoder >> color;
    if (!color)
        return std::nullopt;

    return {{ *rect, *color }};
}

class FillRectWithGradient {
public:
    static constexpr ItemType itemType = ItemType::FillRectWithGradient;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    WEBCORE_EXPORT FillRectWithGradient(const FloatRect&, Gradient&);

    const FloatRect& rect() const { return m_rect; }
    const Gradient& gradient() const { return m_gradient.get(); }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<FillRectWithGradient> decode(Decoder&);

private:
    FloatRect m_rect;
    mutable Ref<Gradient> m_gradient; // FIXME: Make this not mutable
};

template<class Encoder>
void FillRectWithGradient::encode(Encoder& encoder) const
{
    encoder << m_rect;
    encoder << m_gradient.get();
}

template<class Decoder>
std::optional<FillRectWithGradient> FillRectWithGradient::decode(Decoder& decoder)
{
    std::optional<FloatRect> rect;
    decoder >> rect;
    if (!rect)
        return std::nullopt;

    auto gradient = Gradient::decode(decoder);
    if (!gradient)
        return std::nullopt;

    return {{ *rect, gradient->get() }};
}

class FillCompositedRect {
public:
    static constexpr ItemType itemType = ItemType::FillCompositedRect;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    FillCompositedRect(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode)
        : m_rect(rect)
        , m_color(color)
        , m_op(op)
        , m_blendMode(blendMode)
    {
    }

    FloatRect rect() const { return m_rect; }
    const Color& color() const { return m_color; }
    CompositeOperator compositeOperator() const { return m_op; }
    BlendMode blendMode() const { return m_blendMode; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<FillCompositedRect> decode(Decoder&);

private:
    FloatRect m_rect;
    Color m_color;
    CompositeOperator m_op;
    BlendMode m_blendMode;
};

template<class Encoder>
void FillCompositedRect::encode(Encoder& encoder) const
{
    encoder << m_rect;
    encoder << m_color;
    encoder << m_op;
    encoder << m_blendMode;
}

template<class Decoder>
std::optional<FillCompositedRect> FillCompositedRect::decode(Decoder& decoder)
{
    std::optional<FloatRect> rect;
    decoder >> rect;
    if (!rect)
        return std::nullopt;

    std::optional<Color> color;
    decoder >> color;
    if (!color)
        return std::nullopt;

    std::optional<CompositeOperator> op;
    decoder >> op;
    if (!op)
        return std::nullopt;

    std::optional<BlendMode> blendMode;
    decoder >> blendMode;
    if (!blendMode)
        return std::nullopt;

    return {{ *rect, *color, *op, *blendMode }};
}

class FillRoundedRect {
public:
    static constexpr ItemType itemType = ItemType::FillRoundedRect;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    FillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode)
        : m_rect(rect)
        , m_color(color)
        , m_blendMode(blendMode)
    {
    }

    const FloatRoundedRect& roundedRect() const { return m_rect; }
    const Color& color() const { return m_color; }
    BlendMode blendMode() const { return m_blendMode; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<FillRoundedRect> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_rect.rect(); }

private:
    FloatRoundedRect m_rect;
    Color m_color;
    BlendMode m_blendMode;
};

template<class Encoder>
void FillRoundedRect::encode(Encoder& encoder) const
{
    encoder << m_rect;
    encoder << m_color;
    encoder << m_blendMode;
}

template<class Decoder>
std::optional<FillRoundedRect> FillRoundedRect::decode(Decoder& decoder)
{
    std::optional<FloatRoundedRect> rect;
    decoder >> rect;
    if (!rect)
        return std::nullopt;

    std::optional<Color> color;
    decoder >> color;
    if (!color)
        return std::nullopt;

    std::optional<BlendMode> blendMode;
    decoder >> blendMode;
    if (!blendMode)
        return std::nullopt;

    return {{ *rect, *color, *blendMode }};
}

class FillRectWithRoundedHole {
public:
    static constexpr ItemType itemType = ItemType::FillRectWithRoundedHole;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    FillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
        : m_rect(rect)
        , m_roundedHoleRect(roundedHoleRect)
        , m_color(color)
    {
    }

    const FloatRect& rect() const { return m_rect; }
    const FloatRoundedRect& roundedHoleRect() const { return m_roundedHoleRect; }
    const Color& color() const { return m_color; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<FillRectWithRoundedHole> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
    FloatRoundedRect m_roundedHoleRect;
    Color m_color;
};

template<class Encoder>
void FillRectWithRoundedHole::encode(Encoder& encoder) const
{
    encoder << m_rect;
    encoder << m_roundedHoleRect;
    encoder << m_color;
}

template<class Decoder>
std::optional<FillRectWithRoundedHole> FillRectWithRoundedHole::decode(Decoder& decoder)
{
    std::optional<FloatRect> rect;
    decoder >> rect;
    if (!rect)
        return std::nullopt;

    std::optional<FloatRoundedRect> roundedHoleRect;
    decoder >> roundedHoleRect;
    if (!roundedHoleRect)
        return std::nullopt;

    std::optional<Color> color;
    decoder >> color;
    if (!color)
        return std::nullopt;

    return {{ *rect, *roundedHoleRect, *color }};
}

#if ENABLE(INLINE_PATH_DATA)

class FillLine {
public:
    static constexpr ItemType itemType = ItemType::FillLine;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    FillLine(const LineData& lineData)
        : m_lineData(lineData)
    {
    }

    Path path() const { return Path::from({m_lineData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return path().fastBoundingRect(); }

private:
    LineData m_lineData;
};

class FillArc {
public:
    static constexpr ItemType itemType = ItemType::FillArc;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    FillArc(const ArcData& arcData)
        : m_arcData(arcData)
    {
    }

    Path path() const { return Path::from({m_arcData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return path().fastBoundingRect(); }

private:
    ArcData m_arcData;
};

class FillQuadCurve {
public:
    static constexpr ItemType itemType = ItemType::FillQuadCurve;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    FillQuadCurve(const QuadCurveData& quadCurveData)
        : m_quadCurveData(quadCurveData)
    {
    }

    Path path() const { return Path::from({m_quadCurveData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return path().fastBoundingRect(); }

private:
    QuadCurveData m_quadCurveData;
};

class FillBezierCurve {
public:
    static constexpr ItemType itemType = ItemType::FillBezierCurve;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    FillBezierCurve(const BezierCurveData& bezierCurveData)
        : m_bezierCurveData(bezierCurveData)
    {
    }

    Path path() const { return Path::from({m_bezierCurveData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return path().fastBoundingRect(); }

private:
    BezierCurveData m_bezierCurveData;
};

#endif // ENABLE(INLINE_PATH_DATA)

class FillPath {
public:
    static constexpr ItemType itemType = ItemType::FillPath;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    FillPath(Path&& path)
        : m_path(WTFMove(path))
    {
    }

    FillPath(const Path& path)
        : m_path(path)
    {
    }

    const Path& path() const { return m_path; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<FillPath> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return m_path.fastBoundingRect(); }

private:
    Path m_path;
};

template<class Encoder>
void FillPath::encode(Encoder& encoder) const
{
    encoder << m_path;
}

template<class Decoder>
std::optional<FillPath> FillPath::decode(Decoder& decoder)
{
    std::optional<Path> path;
    decoder >> path;
    if (!path)
        return std::nullopt;

    return {{ WTFMove(*path) }};
}

class FillEllipse {
public:
    static constexpr ItemType itemType = ItemType::FillEllipse;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    FillEllipse(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    FloatRect rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
};

class GetPixelBuffer {
public:
    static constexpr ItemType itemType = ItemType::GetPixelBuffer;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = false;

    GetPixelBuffer(PixelBufferFormat outputFormat, const IntRect& srcRect)
        : m_srcRect(srcRect)
        , m_outputFormat(WTFMove(outputFormat))
    {
    }

    // Explicit destructor added to force non-trivial destructor on all platforms
    // as the encoding logic currently hardcodes which display list item types need
    // out of line treatment rather than using the isInlineItem constant.
    ~GetPixelBuffer() { }

    const PixelBufferFormat& outputFormat() const { return m_outputFormat; }
    IntRect srcRect() const { return m_srcRect; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<GetPixelBuffer> decode(Decoder&);

private:
    IntRect m_srcRect;
    PixelBufferFormat m_outputFormat;
};

template<class Encoder>
void GetPixelBuffer::encode(Encoder& encoder) const
{
    encoder << m_srcRect;
    encoder << m_outputFormat;
}

template<class Decoder>
std::optional<GetPixelBuffer> GetPixelBuffer::decode(Decoder& decoder)
{
    std::optional<IntRect> srcRect;
    decoder >> srcRect;
    if (!srcRect)
        return std::nullopt;

    std::optional<PixelBufferFormat> outputFormat;
    decoder >> outputFormat;
    if (!outputFormat)
        return std::nullopt;

    return {{ WTFMove(*outputFormat), *srcRect }};
}

class PutPixelBuffer {
public:
    static constexpr ItemType itemType = ItemType::PutPixelBuffer;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    WEBCORE_EXPORT PutPixelBuffer(const PixelBuffer&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);
    WEBCORE_EXPORT PutPixelBuffer(PixelBuffer&&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat);

    PutPixelBuffer(const PutPixelBuffer&);
    PutPixelBuffer(PutPixelBuffer&&) = default;
    PutPixelBuffer& operator=(const PutPixelBuffer&);
    PutPixelBuffer& operator=(PutPixelBuffer&&) = default;

    void swap(PutPixelBuffer&);

    const PixelBuffer& pixelBuffer() const { return m_pixelBuffer; }
    IntRect srcRect() const { return m_srcRect; }
    IntPoint destPoint() const { return m_destPoint; }
    AlphaPremultiplication destFormat() const { return m_destFormat; }

    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return std::nullopt; }
    std::optional<FloatRect> globalBounds() const { return {{ m_destPoint, m_srcRect.size() }}; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<PutPixelBuffer> decode(Decoder&);

private:
    IntRect m_srcRect;
    IntPoint m_destPoint;
    PixelBuffer m_pixelBuffer;
    AlphaPremultiplication m_destFormat;
};

template<class Encoder>
void PutPixelBuffer::encode(Encoder& encoder) const
{
    encoder << m_pixelBuffer;
    encoder << m_srcRect;
    encoder << m_destPoint;
    encoder << m_destFormat;
}

template<class Decoder>
std::optional<PutPixelBuffer> PutPixelBuffer::decode(Decoder& decoder)
{
    std::optional<PixelBuffer> pixelBuffer;
    std::optional<IntRect> srcRect;
    std::optional<IntPoint> destPoint;
    std::optional<AlphaPremultiplication> destFormat;

    decoder >> pixelBuffer;
    if (!pixelBuffer)
        return std::nullopt;

    decoder >> srcRect;
    if (!srcRect)
        return std::nullopt;

    decoder >> destPoint;
    if (!destPoint)
        return std::nullopt;

    decoder >> destFormat;
    if (!destFormat)
        return std::nullopt;

    return {{ WTFMove(*pixelBuffer), *srcRect, *destPoint, *destFormat }};
}

#if ENABLE(VIDEO)
class PaintFrameForMedia {
public:
    static constexpr ItemType itemType = ItemType::PaintFrameForMedia;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    PaintFrameForMedia(MediaPlayer&, const FloatRect& destination);

    const FloatRect& destination() const { return m_destination; }
    MediaPlayerIdentifier identifier() const { return m_identifier; }

    bool isValid() const { return m_identifier.isValid(); }

    NO_RETURN_DUE_TO_ASSERT void apply(GraphicsContext&) const;

    std::optional<FloatRect> localBounds(const GraphicsContext&) const { return std::nullopt; }
    std::optional<FloatRect> globalBounds() const { return { m_destination }; }

private:
    MediaPlayerIdentifier m_identifier;
    FloatRect m_destination;
};
#endif

class StrokeRect {
public:
    static constexpr ItemType itemType = ItemType::StrokeRect;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    StrokeRect(const FloatRect& rect, float lineWidth)
        : m_rect(rect)
        , m_lineWidth(lineWidth)
    {
    }

    FloatRect rect() const { return m_rect; }
    float lineWidth() const { return m_lineWidth; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
    float m_lineWidth;
};

class StrokeLine {
public:
    static constexpr ItemType itemType = ItemType::StrokeLine;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

#if ENABLE(INLINE_PATH_DATA)
    StrokeLine(const LineData& lineData)
        : m_start(lineData.start)
        , m_end(lineData.end)
    {
    }
#endif
    StrokeLine(const FloatPoint& start, const FloatPoint& end)
        : m_start(start)
        , m_end(end)
    {
    }

    FloatPoint start() const { return m_start; }
    FloatPoint end() const { return m_end; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatPoint m_start;
    FloatPoint m_end;
};

#if ENABLE(INLINE_PATH_DATA)

class StrokeArc {
public:
    static constexpr ItemType itemType = ItemType::StrokeArc;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    StrokeArc(const ArcData& arcData)
        : m_arcData(arcData)
    {
    }

    Path path() const { return Path::from({m_arcData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const;

private:
    ArcData m_arcData;
};

class StrokeQuadCurve {
public:
    static constexpr ItemType itemType = ItemType::StrokeQuadCurve;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    StrokeQuadCurve(const QuadCurveData& quadCurveData)
        : m_quadCurveData(quadCurveData)
    {
    }

    Path path() const { return Path::from({m_quadCurveData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const;

private:
    QuadCurveData m_quadCurveData;
};

class StrokeBezierCurve {
public:
    static constexpr ItemType itemType = ItemType::StrokeBezierCurve;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    StrokeBezierCurve(const BezierCurveData& bezierCurveData)
        : m_bezierCurveData(bezierCurveData)
    {
    }

    Path path() const { return Path::from({m_bezierCurveData}); }
    WEBCORE_EXPORT void apply(GraphicsContext&) const;
    std::optional<FloatRect> globalBounds() const { return std::nullopt; }
    std::optional<FloatRect> localBounds(const GraphicsContext&) const;

private:
    BezierCurveData m_bezierCurveData;
};

#endif // ENABLE(INLINE_PATH_DATA)

class StrokePath {
public:
    static constexpr ItemType itemType = ItemType::StrokePath;
    static constexpr bool isInlineItem = false;
    static constexpr bool isDrawingItem = true;

    StrokePath(Path&& path)
        : m_path(WTFMove(path))
    {
    }

    StrokePath(const Path& path)
        : m_path(path)
    {
    }

    const Path& path() const { return m_path; }

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static std::optional<StrokePath> decode(Decoder&);

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    Path m_path;
};

template<class Encoder>
void StrokePath::encode(Encoder& encoder) const
{
    encoder << m_path;
}

template<class Decoder>
std::optional<StrokePath> StrokePath::decode(Decoder& decoder)
{
    std::optional<Path> path;
    decoder >> path;
    if (!path)
        return std::nullopt;

    return {{ WTFMove(*path) }};
}

class StrokeEllipse {
public:
    static constexpr ItemType itemType = ItemType::StrokeEllipse;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    StrokeEllipse(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    const FloatRect& rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
};

class ClearRect {
public:
    static constexpr ItemType itemType = ItemType::ClearRect;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = true;

    ClearRect(const FloatRect& rect)
        : m_rect(rect)
    {
    }

    const FloatRect& rect() const { return m_rect; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

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

private:
    FloatRect m_rect;
};

#if USE(CG)

class ApplyStrokePattern {
public:
    static constexpr ItemType itemType = ItemType::ApplyStrokePattern;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    WEBCORE_EXPORT void apply(GraphicsContext&) const;
};

class ApplyFillPattern {
public:
    static constexpr ItemType itemType = ItemType::ApplyFillPattern;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    WEBCORE_EXPORT void apply(GraphicsContext&) const;
};

#endif

class ApplyDeviceScaleFactor {
public:
    static constexpr ItemType itemType = ItemType::ApplyDeviceScaleFactor;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    ApplyDeviceScaleFactor(float scaleFactor)
        : m_scaleFactor(scaleFactor)
    {
    }

    float scaleFactor() const { return m_scaleFactor; }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    float m_scaleFactor { 1 };
};

class FlushContext {
public:
    static constexpr ItemType itemType = ItemType::FlushContext;
    static constexpr bool isInlineItem = true;
    static constexpr bool isDrawingItem = false;

    explicit FlushContext(GraphicsContextFlushIdentifier identifier)
        : m_identifier(identifier)
    {
    }

    GraphicsContextFlushIdentifier identifier() const { return m_identifier; }
    bool isValid() const { return m_identifier.isValid(); }

    WEBCORE_EXPORT void apply(GraphicsContext&) const;

private:
    GraphicsContextFlushIdentifier m_identifier;
};

using DisplayListItem = std::variant
    < ApplyDeviceScaleFactor
    , BeginClipToDrawingCommands
    , BeginTransparencyLayer
    , ClearRect
    , ClearShadow
    , Clip
    , ClipOut
    , ClipOutToPath
    , ClipPath
    , ClipToImageBuffer
    , ConcatenateCTM
    , DrawDotsForDocumentMarker
    , DrawEllipse
    , DrawFocusRingPath
    , DrawFocusRingRects
    , DrawGlyphs
    , DrawImageBuffer
    , DrawLine
    , DrawLinesForText
    , DrawNativeImage
    , DrawPath
    , DrawPattern
    , DrawRect
    , EndClipToDrawingCommands
    , EndTransparencyLayer
    , FillCompositedRect
    , FillEllipse
    , FillPath
    , FillRect
    , FillRectWithColor
    , FillRectWithGradient
    , FillRectWithRoundedHole
    , FillRoundedRect
    , FlushContext
    , GetPixelBuffer
    , PutPixelBuffer
    , Restore
    , Rotate
    , Save
    , Scale
    , SetCTM
    , SetInlineFillColor
    , SetInlineStrokeColor
    , SetLineCap
    , SetLineDash
    , SetLineJoin
    , SetMiterLimit
    , SetState
    , SetStrokeThickness
    , StrokeEllipse
    , StrokeLine
    , StrokePath
    , StrokeRect
    , Translate

#if ENABLE(INLINE_PATH_DATA)
    , FillLine
    , FillArc
    , FillQuadCurve
    , FillBezierCurve
    , StrokeArc
    , StrokeQuadCurve
    , StrokeBezierCurve
#endif

#if ENABLE(VIDEO)
    , PaintFrameForMedia
#endif

#if USE(CG)
    , ApplyFillPattern
    , ApplyStrokePattern
#endif
>;

size_t paddedSizeOfTypeAndItemInBytes(const DisplayListItem&);
ItemType displayListItemType(const DisplayListItem&);

TextStream& operator<<(TextStream&, ItemHandle);

} // namespace DisplayList
} // namespace WebCore

namespace WTF {

template<> struct EnumTraits<WebCore::DisplayList::ItemType> {
    using values = EnumValues<
    WebCore::DisplayList::ItemType,
    WebCore::DisplayList::ItemType::Save,
    WebCore::DisplayList::ItemType::Restore,
    WebCore::DisplayList::ItemType::Translate,
    WebCore::DisplayList::ItemType::Rotate,
    WebCore::DisplayList::ItemType::Scale,
    WebCore::DisplayList::ItemType::SetCTM,
    WebCore::DisplayList::ItemType::ConcatenateCTM,
    WebCore::DisplayList::ItemType::SetInlineFillColor,
    WebCore::DisplayList::ItemType::SetInlineStrokeColor,
    WebCore::DisplayList::ItemType::SetStrokeThickness,
    WebCore::DisplayList::ItemType::SetState,
    WebCore::DisplayList::ItemType::SetLineCap,
    WebCore::DisplayList::ItemType::SetLineDash,
    WebCore::DisplayList::ItemType::SetLineJoin,
    WebCore::DisplayList::ItemType::SetMiterLimit,
    WebCore::DisplayList::ItemType::ClearShadow,
    WebCore::DisplayList::ItemType::Clip,
    WebCore::DisplayList::ItemType::ClipOut,
    WebCore::DisplayList::ItemType::ClipToImageBuffer,
    WebCore::DisplayList::ItemType::ClipOutToPath,
    WebCore::DisplayList::ItemType::ClipPath,
    WebCore::DisplayList::ItemType::BeginClipToDrawingCommands,
    WebCore::DisplayList::ItemType::EndClipToDrawingCommands,
    WebCore::DisplayList::ItemType::DrawGlyphs,
    WebCore::DisplayList::ItemType::DrawImageBuffer,
    WebCore::DisplayList::ItemType::DrawNativeImage,
    WebCore::DisplayList::ItemType::DrawPattern,
    WebCore::DisplayList::ItemType::DrawRect,
    WebCore::DisplayList::ItemType::DrawLine,
    WebCore::DisplayList::ItemType::DrawLinesForText,
    WebCore::DisplayList::ItemType::DrawDotsForDocumentMarker,
    WebCore::DisplayList::ItemType::DrawEllipse,
    WebCore::DisplayList::ItemType::DrawPath,
    WebCore::DisplayList::ItemType::DrawFocusRingPath,
    WebCore::DisplayList::ItemType::DrawFocusRingRects,
    WebCore::DisplayList::ItemType::FillRect,
    WebCore::DisplayList::ItemType::FillRectWithColor,
    WebCore::DisplayList::ItemType::FillRectWithGradient,
    WebCore::DisplayList::ItemType::FillCompositedRect,
    WebCore::DisplayList::ItemType::FillRoundedRect,
    WebCore::DisplayList::ItemType::FillRectWithRoundedHole,
#if ENABLE(INLINE_PATH_DATA)
    WebCore::DisplayList::ItemType::FillLine,
    WebCore::DisplayList::ItemType::FillArc,
    WebCore::DisplayList::ItemType::FillQuadCurve,
    WebCore::DisplayList::ItemType::FillBezierCurve,
#endif
    WebCore::DisplayList::ItemType::FillPath,
    WebCore::DisplayList::ItemType::FillEllipse,
    WebCore::DisplayList::ItemType::FlushContext,
    WebCore::DisplayList::ItemType::GetPixelBuffer,
    WebCore::DisplayList::ItemType::PutPixelBuffer,
#if ENABLE(VIDEO)
    WebCore::DisplayList::ItemType::PaintFrameForMedia,
#endif
    WebCore::DisplayList::ItemType::StrokeRect,
    WebCore::DisplayList::ItemType::StrokeLine,
#if ENABLE(INLINE_PATH_DATA)
    WebCore::DisplayList::ItemType::StrokeArc,
    WebCore::DisplayList::ItemType::StrokeQuadCurve,
    WebCore::DisplayList::ItemType::StrokeBezierCurve,
#endif
    WebCore::DisplayList::ItemType::StrokePath,
    WebCore::DisplayList::ItemType::StrokeEllipse,
    WebCore::DisplayList::ItemType::ClearRect,
    WebCore::DisplayList::ItemType::BeginTransparencyLayer,
    WebCore::DisplayList::ItemType::EndTransparencyLayer,
#if USE(CG)
    WebCore::DisplayList::ItemType::ApplyStrokePattern,
    WebCore::DisplayList::ItemType::ApplyFillPattern,
#endif
    WebCore::DisplayList::ItemType::ApplyDeviceScaleFactor
    >;

};

} // namespace WTF
