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

#include "config.h"
#include "GraphicsContext.h"

#include "COMPtr.h"
#include "Direct2DOperations.h"
#include "Direct2DUtilities.h"
#include "DisplayListRecorder.h"
#include "FloatRoundedRect.h"
#include "GraphicsContextPlatformPrivateDirect2D.h"
#include "ImageBuffer.h"
#include "ImageDecoderDirect2D.h"
#include "Logging.h"
#include "NotImplemented.h"
#include "PlatformContextDirect2D.h"
#include <d2d1.h>
#include <d2d1effects.h>
#include <dwrite_3.h>
#include <wtf/URL.h>

#pragma warning (disable : 4756)


namespace WebCore {

GraphicsContext::GraphicsContext(HDC hdc, bool hasAlpha)
{
    platformInit(hdc, hasAlpha);
}

GraphicsContext::GraphicsContext(HDC hdc, ID2D1DCRenderTarget** renderTarget, RECT rect, bool hasAlpha)
{
    // Create a DC render target.
    auto targetProperties = Direct2D::renderTargetProperties();

    HRESULT hr = GraphicsContext::systemFactory()->CreateDCRenderTarget(&targetProperties, renderTarget);
    RELEASE_ASSERT(SUCCEEDED(hr));

    (*renderTarget)->BindDC(hdc, &rect);

    auto ownedPlatformContext = makeUnique<PlatformContextDirect2D>(*renderTarget);
    m_data = new GraphicsContextPlatformPrivate(WTFMove(ownedPlatformContext), BitmapRenderingContextType::GPUMemory);
    m_data->m_hdc = hdc;
}

GraphicsContext::GraphicsContext(PlatformContextDirect2D* platformGraphicsContext, BitmapRenderingContextType rendererType)
{
    platformInit(platformGraphicsContext, rendererType);
}

ID2D1Factory* GraphicsContext::systemFactory()
{
    static ID2D1Factory* direct2DFactory = nullptr;
    if (!direct2DFactory) {
#ifndef NDEBUG
        D2D1_FACTORY_OPTIONS options = { };
        options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
        HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, options, &direct2DFactory);
#else
        HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &direct2DFactory);
#endif
        RELEASE_ASSERT(SUCCEEDED(hr));
    }

    return direct2DFactory;
}

ID2D1RenderTarget* GraphicsContext::defaultRenderTarget()
{
    static ID2D1RenderTarget* defaultRenderTarget = nullptr;
    if (!defaultRenderTarget) {
        auto renderTargetProperties = D2D1::RenderTargetProperties();
        renderTargetProperties.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
        auto hwndRenderTargetProperties = D2D1::HwndRenderTargetProperties(::GetDesktopWindow(), D2D1::SizeU(10, 10));
        HRESULT hr = systemFactory()->CreateHwndRenderTarget(&renderTargetProperties, &hwndRenderTargetProperties, reinterpret_cast<ID2D1HwndRenderTarget**>(&defaultRenderTarget));
        RELEASE_ASSERT(SUCCEEDED(hr));
        defaultRenderTarget->AddRef();
    }

    return defaultRenderTarget;
}

void GraphicsContext::platformInit(HDC hdc, bool hasAlpha)
{
    if (!hdc)
        return;

    HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));

    DIBPixelData pixelData(bitmap);

    auto targetProperties = Direct2D::renderTargetProperties();

    COMPtr<ID2D1DCRenderTarget> renderTarget;
    HRESULT hr = systemFactory()->CreateDCRenderTarget(&targetProperties, &renderTarget);
    if (!SUCCEEDED(hr))
        return;

    RECT clientRect = IntRect(IntPoint(), pixelData.size());
    hr = renderTarget->BindDC(hdc, &clientRect);
    if (!SUCCEEDED(hr))
        return;

    auto ownedPlatformContext = makeUnique<PlatformContextDirect2D>(renderTarget.get());
    m_data = new GraphicsContextPlatformPrivate(WTFMove(ownedPlatformContext), BitmapRenderingContextType::GPUMemory);
    m_data->m_hdc = hdc;

    // Make sure the context starts in sync with our state.
    setPlatformFillColor(fillColor());
    setPlatformStrokeColor(strokeColor());
    setPlatformStrokeThickness(strokeThickness());
    // FIXME: m_state.imageInterpolationQuality = convertInterpolationQuality(CGContextGetInterpolationQuality(platformContext()));
}

void GraphicsContext::platformInit(PlatformContextDirect2D* platformContext)
{
    platformInit(platformContext, BitmapRenderingContextType::GPUMemory);
}

void GraphicsContext::platformInit(PlatformContextDirect2D* platformContext, BitmapRenderingContextType renderingType)
{
    if (!platformContext)
        return;

    m_data = new GraphicsContextPlatformPrivate(*platformContext, renderingType);

    // Make sure the context starts in sync with our state.
    setPlatformFillColor(fillColor());
    setPlatformStrokeColor(strokeColor());
    setPlatformStrokeThickness(strokeThickness());
    // FIXME: m_state.imageInterpolationQuality = convertInterpolationQuality(CGContextGetInterpolationQuality(platformContext()));
}

void GraphicsContext::platformDestroy()
{
    delete m_data;
}

PlatformContextDirect2D* GraphicsContext::platformContext() const
{
    if (m_impl)
        return m_impl->platformContext();
    ASSERT(!paintingDisabled());
    return &m_data->platformContext();
}

void GraphicsContextPlatformPrivate::syncContext(PlatformContextDirect2D&)
{
    notImplemented();
}

ID2D1RenderTarget* GraphicsContextPlatformPrivate::renderTarget()
{
    if (!m_platformContext.m_transparencyLayerStack.isEmpty())
        return m_platformContext.m_transparencyLayerStack.last().renderTarget.get();

    return m_platformContext.renderTarget();
}

void GraphicsContextPlatformPrivate::setAlpha(float alpha)
{
    ASSERT(m_platformContext.m_transparencyLayerStack.isEmpty());
    m_alpha = alpha;
}

float GraphicsContextPlatformPrivate::currentGlobalAlpha() const
{
    if (!m_platformContext.m_transparencyLayerStack.isEmpty())
        return m_platformContext.m_transparencyLayerStack.last().opacity;

    return m_alpha;
}

void GraphicsContext::savePlatformState()
{
    ASSERT(hasPlatformContext());
    Direct2D::save(*platformContext());
}

void GraphicsContext::restorePlatformState()
{
    ASSERT(hasPlatformContext());
    Direct2D::restore(*platformContext());
}

void GraphicsContext::drawNativeImage(const COMPtr<ID2D1Bitmap>& image, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->drawNativeImage(image, imageSize, destRect, srcRect, options);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    Direct2D::drawNativeImage(*platformContext(), image.get(), imageSize, destRect, srcRect, options, state.alpha, Direct2D::ShadowState(state));
}

void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
{
    bool createdBitmap = m_impl || !m_data->m_hdc || isInTransparencyLayer();
    if (!createdBitmap) {
        ASSERT(hasPlatformContext());
        Direct2D::restore(*platformContext());
        return;
    }

    if (!hdc || dstRect.isEmpty())
        return;

    auto sourceBitmap = adoptGDIObject(static_cast<HBITMAP>(::GetCurrentObject(hdc, OBJ_BITMAP)));

    DIBPixelData pixelData(sourceBitmap.get());
    ASSERT(pixelData.bitsPerPixel() == 32);

    auto bitmapProperties = Direct2D::bitmapProperties();

    ASSERT(hasPlatformContext());
    auto& platformContext = *this->platformContext();

    COMPtr<ID2D1Bitmap> bitmap;
    HRESULT hr = platformContext.renderTarget()->CreateBitmap(pixelData.size(), pixelData.buffer(), pixelData.bytesPerRow(), &bitmapProperties, &bitmap);
    ASSERT(SUCCEEDED(hr));

    PlatformContextStateSaver stateSaver(platformContext);

    // Note: The content in the HDC is inverted compared to Direct2D, so it needs to be flipped.
    auto context = platformContext.renderTarget();

    D2D1_MATRIX_3X2_F currentTransform;
    context->GetTransform(&currentTransform);

    AffineTransform transform(currentTransform);
    transform.translate(dstRect.location());
    transform.scale(1.0, -1.0);
    transform.translate(0, -dstRect.height());

    context->SetTransform(transform);
    context->DrawBitmap(bitmap.get(), D2D1::RectF(0, 0, dstRect.width(), dstRect.height()));

    ::DeleteDC(hdc);
}

void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point)
{
}

void GraphicsContext::drawFocusRing(const Path& path, float width, float offset, const Color& color)
{
}

void GraphicsContext::drawFocusRing(const Vector<FloatRect>& rects, float width, float offset, const Color& color)
{
}

void GraphicsContext::drawDotsForDocumentMarker(const FloatRect& rect, DocumentMarkerLineStyle style)
{
}

GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(PlatformContextDirect2D& platformContext, GraphicsContext::BitmapRenderingContextType renderingType)
    : m_platformContext(platformContext)
    , m_rendererType(renderingType)
{
    if (!m_platformContext.renderTarget())
        return;

    if (m_rendererType == GraphicsContext::BitmapRenderingContextType::GPUMemory)
        beginDraw();
}

GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(std::unique_ptr<PlatformContextDirect2D>&& ownedPlatformContext, GraphicsContext::BitmapRenderingContextType renderingType)
    : m_ownedPlatformContext(WTFMove(ownedPlatformContext))
    , m_platformContext(*m_ownedPlatformContext)
    , m_rendererType(renderingType)
{
    if (!m_platformContext.renderTarget())
        return;

    if (m_rendererType == GraphicsContext::BitmapRenderingContextType::GPUMemory)
        beginDraw();
}

GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
{
    if (!m_platformContext.renderTarget())
        return;

    if (m_platformContext.beginDrawCount)
        endDraw();
}

ID2D1SolidColorBrush* GraphicsContext::brushWithColor(const Color& color)
{
    ASSERT(hasPlatformContext());
    return platformContext()->brushWithColor(colorWithGlobalAlpha(color)).get();
}

void GraphicsContextPlatformPrivate::clip(const FloatRect& rect)
{
}

void GraphicsContextPlatformPrivate::clip(const Path& path)
{
}

void GraphicsContextPlatformPrivate::clip(ID2D1Geometry* path)
{
}

void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& affineTransform)
{
}

void GraphicsContextPlatformPrivate::flush()
{
}

void GraphicsContextPlatformPrivate::beginDraw()
{
    m_platformContext.beginDraw();
}

void GraphicsContextPlatformPrivate::endDraw()
{
    m_platformContext.endDraw();
}

void GraphicsContextPlatformPrivate::restore()
{
}

void GraphicsContextPlatformPrivate::save()
{
}

void GraphicsContextPlatformPrivate::scale(const FloatSize& size)
{
}

void GraphicsContextPlatformPrivate::setCTM(const AffineTransform& transform)
{
    ASSERT(m_platformContext.renderTarget());
    m_platformContext.renderTarget()->SetTransform(transform);
}

void GraphicsContextPlatformPrivate::translate(float x, float y)
{
}

void GraphicsContextPlatformPrivate::rotate(float angle)
{
}

D2D1_COLOR_F GraphicsContext::colorWithGlobalAlpha(const Color& color) const
{
    float colorAlpha = color.alphaAsFloat();
    float globalAlpha = m_data->currentGlobalAlpha();

    return D2D1::ColorF(color.rgb(), globalAlpha * colorAlpha);
}

ID2D1Brush* GraphicsContext::solidStrokeBrush() const
{
    return platformContext()->m_solidStrokeBrush.get();
}

ID2D1Brush* GraphicsContext::solidFillBrush() const
{
    return platformContext()->m_solidFillBrush.get();
}

ID2D1Brush* GraphicsContext::patternStrokeBrush() const
{
    return platformContext()->m_patternStrokeBrush.get();
}

ID2D1Brush* GraphicsContext::patternFillBrush() const
{
    return platformContext()->m_patternFillBrush.get();
}

void GraphicsContext::beginDraw()
{
    ASSERT(hasPlatformContext());
    platformContext()->beginDraw();
}

void GraphicsContext::endDraw()
{
    ASSERT(hasPlatformContext());
    platformContext()->endDraw();
}

void GraphicsContext::flush()
{
    ASSERT(hasPlatformContext());
    Direct2D::flush(*platformContext());
}

void GraphicsContext::drawPattern(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options)
{
    if (paintingDisabled() || !patternTransform.isInvertible())
        return;

    if (m_impl) {
        m_impl->drawPattern(image, destRect, tileRect, patternTransform, phase, spacing, options);
        return;
    }

    ASSERT(hasPlatformContext());
    if (auto tileImage = image.nativeImageForCurrentFrame(this))
        Direct2D::drawPattern(*platformContext(), WTFMove(tileImage), IntSize(image.size()), destRect, tileRect, patternTransform, phase, options.compositeOperator(), options.blendMode());
}

void GraphicsContext::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& destRect)
{
    if (paintingDisabled())
        return;

    FloatSize bufferDestinationSize = buffer.sizeForDestinationSize(destRect.size());
    notImplemented();
}

// Draws a filled rectangle with a stroked border.
void GraphicsContext::drawRect(const FloatRect& rect, float borderThickness)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->drawRect(rect, borderThickness);
        return;
    }

    ASSERT(!rect.isEmpty());
    ASSERT(hasPlatformContext());
    auto& state = this->state();
    Direct2D::drawRect(*platformContext(), rect, borderThickness, state.fillColor, state.strokeStyle, state.strokeColor);
}

void GraphicsContextPlatformPrivate::setLineCap(LineCap)
{
}

void GraphicsContextPlatformPrivate::setLineJoin(LineJoin)
{
}

void GraphicsContextPlatformPrivate::setStrokeStyle(StrokeStyle)
{
}

void GraphicsContextPlatformPrivate::setMiterLimit(float canvasMiterLimit)
{
    m_platformContext.setDashOffset(canvasMiterLimit);
}

void GraphicsContextPlatformPrivate::setDashOffset(float dashOffset)
{
    m_platformContext.setDashOffset(dashOffset);
}

void GraphicsContextPlatformPrivate::setPatternWidth(float patternWidth)
{
    m_platformContext.setPatternWidth(patternWidth);
}

void GraphicsContextPlatformPrivate::setPatternOffset(float patternOffset)
{
    m_platformContext.setPatternOffset(patternOffset);
}

void GraphicsContextPlatformPrivate::setStrokeThickness(float thickness)
{
    m_platformContext.setStrokeThickness(thickness);
}

void GraphicsContextPlatformPrivate::setDashes(const DashArray& dashes)
{
    m_platformContext.setDashes(dashes);
}

D2D1_STROKE_STYLE_PROPERTIES GraphicsContextPlatformPrivate::strokeStyleProperties() const
{
    return D2D1::StrokeStyleProperties(m_platformContext.m_lineCap, m_platformContext.m_lineCap, m_platformContext.m_lineCap, m_platformContext.m_lineJoin, m_platformContext.m_miterLimit, D2D1_DASH_STYLE_SOLID, 0.0f);
}

ID2D1StrokeStyle* GraphicsContext::platformStrokeStyle() const
{
    ASSERT(hasPlatformContext());
    return platformContext()->strokeStyle();
}

// This is only used to draw borders.
void GraphicsContext::drawLine(const FloatPoint& point1, const FloatPoint& point2)
{
    if (paintingDisabled())
        return;

    if (strokeStyle() == NoStroke)
        return;

    if (m_impl) {
        m_impl->drawLine(point1, point2);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    Direct2D::drawLine(*platformContext(), point1, point2, state.strokeStyle, state.strokeColor, state.strokeThickness, state.shouldAntialias);
}

void GraphicsContext::drawEllipse(const FloatRect& rect)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->drawEllipse(rect);
        return;
    }


    ASSERT(hasPlatformContext());
    auto& state = this->state();
    Direct2D::fillEllipse(*platformContext(), rect, state.fillColor, state.strokeStyle, state.strokeColor, state.strokeThickness);
}

void GraphicsContext::applyStrokePattern()
{
    if (paintingDisabled())
        return;

    auto context = platformContext();
    AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows

    const float patternAlpha = 1;
    platformContext()->m_patternStrokeBrush = adoptCOM(m_state.strokePattern->createPlatformPattern(*this, patternAlpha, userToBaseCTM));
}

void GraphicsContext::applyFillPattern()
{
    if (paintingDisabled())
        return;

    auto context = platformContext();
    AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows

    const float patternAlpha = 1;
    platformContext()->m_patternFillBrush = adoptCOM(m_state.fillPattern->createPlatformPattern(*this, patternAlpha, userToBaseCTM));
}

void GraphicsContext::drawPath(const Path& path)
{
    if (paintingDisabled() || path.isEmpty())
        return;

    if (m_impl) {
        m_impl->drawPath(path);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::drawPath(context, path, Direct2D::StrokeSource(state, *this), Direct2D::ShadowState(state));
}

void GraphicsContext::fillPath(const Path& path)
{
    if (paintingDisabled() || path.isEmpty())
        return;

    if (m_impl) {
        m_impl->fillPath(path);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::fillPath(context, path, Direct2D::FillSource(state, *this), Direct2D::ShadowState(state));
}

void GraphicsContext::strokePath(const Path& path)
{
    if (paintingDisabled() || path.isEmpty())
        return;

    if (m_impl) {
        m_impl->strokePath(path);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::strokePath(context, path, Direct2D::StrokeSource(state, *this), Direct2D::ShadowState(state));
}

void GraphicsContext::fillRect(const FloatRect& rect)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->fillRect(rect);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::fillRect(context, rect, Direct2D::FillSource(state, *this), Direct2D::ShadowState(state));
}

void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->fillRect(rect, color);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::fillRect(context, rect, color, Direct2D::ShadowState(state));
}

void GraphicsContext::platformFillRoundedRect(const FloatRoundedRect& rect, const Color& color)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    Direct2D::fillRoundedRect(*platformContext(), rect, color, Direct2D::ShadowState(state));
}

void GraphicsContext::fillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->fillRectWithRoundedHole(rect, roundedHoleRect, color);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::fillRectWithRoundedHole(context, rect, roundedHoleRect, Direct2D::FillSource(state, *this), Direct2D::ShadowState(state));
}

void GraphicsContext::clip(const FloatRect& rect)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->clip(rect);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::clip(*platformContext(), rect);
}

void GraphicsContext::clipOut(const FloatRect& rect)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->clipOut(rect);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::clipOut(*platformContext(), rect);
}

void GraphicsContext::clipOut(const Path& path)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->clipOut(path);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::clipOut(*platformContext(), path);
}

void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->clipPath(path, clipRule);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::clipPath(*platformContext(), path, clipRule);
}

IntRect GraphicsContext::clipBounds() const
{
    if (paintingDisabled())
        return IntRect();

    if (m_impl)
        return m_impl->clipBounds();

    ASSERT(hasPlatformContext());
    return Direct2D::State::getClipBounds(*platformContext());
}

void GraphicsContextPlatformPrivate::beginTransparencyLayer(float opacity)
{
}

void GraphicsContext::beginPlatformTransparencyLayer(float opacity)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);

    save();

    m_state.alpha = opacity;

    ASSERT(hasPlatformContext());
    Direct2D::beginTransparencyLayer(*platformContext(), opacity);
}

void GraphicsContextPlatformPrivate::endTransparencyLayer()
{
}

void GraphicsContext::endPlatformTransparencyLayer()
{
    if (paintingDisabled())
        return;

    ASSERT(hasPlatformContext());
    Direct2D::endTransparencyLayer(*platformContext());

    ASSERT(!m_impl);

    m_state.alpha = m_data->currentGlobalAlpha();

    restore();
}

bool GraphicsContext::supportsTransparencyLayers()
{
    return false;
}

void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, const Color& color)
{
    (void)offset;
    (void)blur;
    (void)color;
    notImplemented();
}

void GraphicsContext::clearPlatformShadow()
{
    if (paintingDisabled())
        return;
    notImplemented();
}

void GraphicsContext::setPlatformStrokeStyle(StrokeStyle style)
{
    if (paintingDisabled())
        return;

    ASSERT(hasPlatformContext());
    Direct2D::State::setStrokeStyle(*platformContext(), style);
}

void GraphicsContext::setMiterLimit(float limit)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        // Maybe this should be part of the state.
        m_impl->setMiterLimit(limit);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::setMiterLimit(*platformContext(), limit);
}

void GraphicsContext::clearRect(const FloatRect& rect)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->clearRect(rect);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::clearRect(*platformContext(), rect);
}

void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->strokeRect(rect, lineWidth);
        return;
    }

    ASSERT(hasPlatformContext());
    auto& state = this->state();
    auto& context = *platformContext();
    Direct2D::strokeRect(context, rect, lineWidth, Direct2D::StrokeSource(state, *this), Direct2D::ShadowState(state));
}

void GraphicsContext::setLineCap(LineCap cap)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->setLineCap(cap);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::setLineCap(*platformContext(), cap);
}

void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->setLineDash(dashes, dashOffset);
        return;
    }

    if (dashOffset < 0) {
        float length = 0;
        for (size_t i = 0; i < dashes.size(); ++i)
            length += static_cast<float>(dashes[i]);
        if (length)
            dashOffset = fmod(dashOffset, length) + length;
    }

    ASSERT(hasPlatformContext());
    Direct2D::setLineDash(*platformContext(), dashes, dashOffset);
}

void GraphicsContext::setLineJoin(LineJoin join)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->setLineJoin(join);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::setLineJoin(*platformContext(), join);
}

void GraphicsContext::canvasClip(const Path& path, WindRule fillRule)
{
    clipPath(path, fillRule);
}

void GraphicsContext::scale(const FloatSize& size)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->scale(size);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::scale(*platformContext(), size);
    // FIXME: m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}

void GraphicsContext::rotate(float angle)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->rotate(angle);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::rotate(*platformContext(), angle);
    // FIXME: m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}

void GraphicsContext::translate(float x, float y)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->translate(x, y);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::translate(*platformContext(), x, y);
    // FIXME: m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}

void GraphicsContext::concatCTM(const AffineTransform& transform)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->concatCTM(transform);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::concatCTM(*platformContext(), transform);
    // FIXME: m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}

void GraphicsContext::setCTM(const AffineTransform& transform)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        m_impl->setCTM(transform);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::State::setCTM(*platformContext(), transform);
    // FIXME: m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}

AffineTransform GraphicsContext::getCTM(IncludeDeviceScale includeScale) const
{
    if (paintingDisabled())
        return AffineTransform();

    if (m_impl)
        return m_impl->getCTM(includeScale);

    ASSERT(hasPlatformContext());
    return Direct2D::State::getCTM(*platformContext());
}

FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode roundingMode)
{
    if (paintingDisabled())
        return rect;

    if (m_impl)
        return m_impl->roundToDevicePixels(rect, roundingMode);

    return Direct2D::State::roundToDevicePixels(*platformContext(), rect);
}

void GraphicsContext::drawLineForText(const FloatRect& rect, bool printing, bool doubleLines, StrokeStyle strokeStyle)
{
    DashArray widths;
    widths.append(0);
    widths.append(rect.width());
    drawLinesForText(rect.location(), rect.height(), widths, printing, doubleLines, strokeStyle);
}

void GraphicsContext::drawLinesForText(const FloatPoint& point, float thickness, const DashArray& widths, bool printing, bool doubleUnderlines, StrokeStyle strokeStyle)
{
    if (paintingDisabled())
        return;

    if (!widths.size())
        return;

    if (m_impl) {
        m_impl->drawLinesForText(point, thickness, widths, printing, doubleUnderlines);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::drawLinesForText(*platformContext(), point, thickness, widths, printing, doubleUnderlines, m_state.strokeColor);
}

void GraphicsContext::setURLForRect(const URL& link, const FloatRect& destRect)
{
    if (paintingDisabled())
        return;

    if (m_impl) {
        WTFLogAlways("GraphicsContext::setURLForRect() is not yet compatible with recording contexts.");
        return; // FIXME for display lists.
    }

    notImplemented();
}

void GraphicsContext::setPlatformImageInterpolationQuality(InterpolationQuality mode)
{
    ASSERT(!paintingDisabled());

    D2D1_INTERPOLATION_MODE quality = D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;

    switch (mode) {
    case InterpolationDefault:
        quality = D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
        break;
    case InterpolationNone:
        quality = D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
        break;
    case InterpolationLow:
        quality = D2D1_INTERPOLATION_MODE_LINEAR;
        break;
    case InterpolationMedium:
        quality = D2D1_INTERPOLATION_MODE_CUBIC;
        break;
    case InterpolationHigh:
        quality = D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC;
        break;
    }
    // FIXME: SetInterpolationQuality(platformContext(), quality);
}

void GraphicsContext::setIsCALayerContext(bool isLayerContext)
{
    if (paintingDisabled())
        return;

    if (m_impl)
        return;

    // This function is probabaly not needed.
    notImplemented();
}

bool GraphicsContext::isCALayerContext() const
{
    if (paintingDisabled())
        return false;

    // FIXME
    if (m_impl)
        return false;

    // This function is probabaly not needed.
    notImplemented();
    return false;
}

void GraphicsContext::setIsAcceleratedContext(bool isAccelerated)
{
    if (paintingDisabled())
        return;

    // FIXME
    if (m_impl)
        return;

    notImplemented();
}

bool GraphicsContext::isAcceleratedContext() const
{
    if (!hasPlatformContext())
        return false;

    return Direct2D::State::isAcceleratedContext(*platformContext());
}

void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode)
{
    (void)mode;
    notImplemented();
}

void GraphicsContext::setPlatformStrokeColor(const Color& color)
{
    ASSERT(m_state.strokeColor == color);
    ASSERT(hasPlatformContext());
    platformContext()->m_solidStrokeBrush = brushWithColor(strokeColor());
}

void GraphicsContext::setPlatformStrokeThickness(float thickness)
{
    ASSERT(m_state.strokeThickness == thickness);
    m_data->setStrokeThickness(thickness);
}

void GraphicsContext::setPlatformFillColor(const Color& color)
{
    ASSERT(m_state.fillColor == color);
    ASSERT(hasPlatformContext());
    platformContext()->m_solidFillBrush = brushWithColor(fillColor());
}

void GraphicsContext::setPlatformShouldAntialias(bool enable)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);
    ASSERT(hasPlatformContext());
    Direct2D::State::setShouldAntialias(*platformContext(), enable);
}

void GraphicsContext::setPlatformShouldSmoothFonts(bool enable)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);

    auto fontSmoothingMode = enable ? D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE : D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
    platformContext()->renderTarget()->SetTextAntialiasMode(fontSmoothingMode);
}

void GraphicsContext::setPlatformAlpha(float alpha)
{
    if (paintingDisabled())
        return;

    ASSERT(m_state.alpha == alpha);
    m_data->setAlpha(alpha);
}

void GraphicsContext::setPlatformCompositeOperation(CompositeOperator compositeOperator, BlendMode blendMode)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);

    ASSERT(hasPlatformContext());
    Direct2D::State::setCompositeOperation(*platformContext(), compositeOperator, blendMode);
}

void GraphicsContext::platformApplyDeviceScaleFactor(float deviceScaleFactor)
{
    // This is a no-op for Direct2D.
}

void GraphicsContext::platformFillEllipse(const FloatRect& ellipse)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);

    if (m_state.fillGradient || m_state.fillPattern) {
        // FIXME: We should be able to fill ellipses with pattern/gradient brushes in D2D.
        fillEllipseAsPath(ellipse);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::fillEllipse(*platformContext(), ellipse, m_state.fillColor, m_state.strokeStyle, m_state.strokeColor, m_state.strokeThickness);
}

void GraphicsContext::platformStrokeEllipse(const FloatRect& ellipse)
{
    if (paintingDisabled())
        return;

    ASSERT(!m_impl);

    if (m_state.strokeGradient || m_state.strokePattern) {
        // FIXME: We should be able to stroke ellipses with pattern/gradient brushes in D2D.
        strokeEllipseAsPath(ellipse);
        return;
    }

    ASSERT(hasPlatformContext());
    Direct2D::drawEllipse(*platformContext(), ellipse, m_state.strokeStyle, m_state.strokeColor, m_state.strokeThickness);
}

}
