// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BaseRenderingContext2D_h
#define BaseRenderingContext2D_h

#include "bindings/core/v8/UnionTypesCore.h"
#include "bindings/modules/v8/UnionTypesModules.h"
#include "modules/ModulesExport.h"
#include "modules/canvas2d/CanvasGradient.h"
#include "modules/canvas2d/CanvasPathMethods.h"
#include "modules/canvas2d/CanvasRenderingContext2DState.h"
#include "modules/canvas2d/CanvasStyle.h"
#include "third_party/skia/include/core/SkCanvas.h"

namespace blink {

class CanvasImageSource;
class Color;
class Image;
class ImageBuffer;
class Path2D;
class SVGMatrixTearOff;

typedef HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmap CanvasImageSourceUnion;

class MODULES_EXPORT BaseRenderingContext2D : public WillBeGarbageCollectedMixin, public CanvasPathMethods {
    WTF_MAKE_NONCOPYABLE(BaseRenderingContext2D);
public:
    ~BaseRenderingContext2D() override;

    void strokeStyle(StringOrCanvasGradientOrCanvasPattern&) const;
    void setStrokeStyle(const StringOrCanvasGradientOrCanvasPattern&);

    void fillStyle(StringOrCanvasGradientOrCanvasPattern&) const;
    void setFillStyle(const StringOrCanvasGradientOrCanvasPattern&);

    double lineWidth() const;
    void setLineWidth(double);

    String lineCap() const;
    void setLineCap(const String&);

    String lineJoin() const;
    void setLineJoin(const String&);

    double miterLimit() const;
    void setMiterLimit(double);

    const Vector<double>& getLineDash() const;
    void setLineDash(const Vector<double>&);

    double lineDashOffset() const;
    void setLineDashOffset(double);

    double shadowOffsetX() const;
    void setShadowOffsetX(double);

    double shadowOffsetY() const;
    void setShadowOffsetY(double);

    double shadowBlur() const;
    void setShadowBlur(double);

    String shadowColor() const;
    void setShadowColor(const String&);

    double globalAlpha() const;
    void setGlobalAlpha(double);

    String globalCompositeOperation() const;
    void setGlobalCompositeOperation(const String&);

    String filter() const;
    void setFilter(const String&);

    void save();
    void restore();

    PassRefPtrWillBeRawPtr<SVGMatrixTearOff> currentTransform() const;
    void setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMatrixTearOff>);

    void scale(double sx, double sy);
    void rotate(double angleInRadians);
    void translate(double tx, double ty);
    void transform(double m11, double m12, double m21, double m22, double dx, double dy);
    void setTransform(double m11, double m12, double m21, double m22, double dx, double dy);
    void resetTransform();

    void beginPath();

    void fill(const String& winding = "nonzero");
    void fill(Path2D*, const String& winding = "nonzero");
    void stroke();
    void stroke(Path2D*);
    void clip(const String& winding = "nonzero");
    void clip(Path2D*, const String& winding = "nonzero");

    bool isPointInPath(const double x, const double y, const String& winding = "nonzero");
    bool isPointInPath(Path2D*, const double x, const double y, const String& winding = "nonzero");
    bool isPointInStroke(const double x, const double y);
    bool isPointInStroke(Path2D*, const double x, const double y);

    void clearRect(double x, double y, double width, double height);
    void fillRect(double x, double y, double width, double height);
    void strokeRect(double x, double y, double width, double height);

    void drawImage(const CanvasImageSourceUnion&, double x, double y, ExceptionState&);
    void drawImage(const CanvasImageSourceUnion&, double x, double y, double width, double height, ExceptionState&);
    void drawImage(const CanvasImageSourceUnion&, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh, ExceptionState&);
    void drawImage(CanvasImageSource*, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh, ExceptionState&);

    CanvasGradient* createLinearGradient(double x0, double y0, double x1, double y1);
    CanvasGradient* createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1, ExceptionState&);
    CanvasPattern* createPattern(const CanvasImageSourceUnion&, const String& repetitionType, ExceptionState&);

    ImageData* createImageData(ImageData*) const;
    ImageData* createImageData(double width, double height, ExceptionState&) const;
    ImageData* getImageData(double sx, double sy, double sw, double sh, ExceptionState&) const;
    void putImageData(ImageData*, double dx, double dy, ExceptionState&);
    void putImageData(ImageData*, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, ExceptionState&);

    bool imageSmoothingEnabled() const;
    void setImageSmoothingEnabled(bool);
    String imageSmoothingQuality() const;
    void setImageSmoothingQuality(const String&);

    virtual bool originClean() const = 0;
    virtual void setOriginTainted() = 0;
    virtual bool wouldTaintOrigin(CanvasImageSource*) = 0;

    virtual int width() const = 0;
    virtual int height() const = 0;

    virtual bool hasImageBuffer() const = 0;
    virtual ImageBuffer* imageBuffer() const = 0;

    virtual bool parseColorOrCurrentColor(Color&, const String& colorString) const = 0;

    virtual SkCanvas* drawingCanvas() const = 0;
    virtual SkCanvas* existingDrawingCanvas() const = 0;
    virtual void disableDeferral(DisableDeferralReason) = 0;

    virtual AffineTransform baseTransform() const = 0;

    virtual void didDraw(const SkIRect& dirtyRect) = 0;

    virtual bool stateHasFilter() = 0;
    virtual SkImageFilter* stateGetFilter() = 0;

    virtual void validateStateStack() = 0;

    virtual bool hasAlpha() const = 0;

    virtual bool isContextLost() const = 0;

    DECLARE_VIRTUAL_TRACE();

protected:
    BaseRenderingContext2D();

    CanvasRenderingContext2DState& modifiableState();
    const CanvasRenderingContext2DState& state() const { return *m_stateStack.last(); }

    bool computeDirtyRect(const FloatRect& localBounds, SkIRect*);
    bool computeDirtyRect(const FloatRect& localBounds, const SkIRect& transformedClipBounds, SkIRect*);

    template<typename DrawFunc, typename ContainsFunc>
    bool draw(const DrawFunc&, const ContainsFunc&, const SkRect& bounds, CanvasRenderingContext2DState::PaintType, CanvasRenderingContext2DState::ImageType = CanvasRenderingContext2DState::NoImage);

    void inflateStrokeRect(FloatRect&) const;

    enum DrawType {
        ClipFill, // Fill that is already known to cover the current clip
        UntransformedUnclippedFill
    };

    void checkOverdraw(const SkRect&, const SkPaint*, CanvasRenderingContext2DState::ImageType, DrawType);

    WillBeHeapVector<OwnPtrWillBeMember<CanvasRenderingContext2DState>> m_stateStack;
    AntiAliasingMode m_clipAntialiasing;

private:
    void realizeSaves();

    bool shouldDrawImageAntialiased(const FloatRect& destRect) const;

    void drawPathInternal(const Path&, CanvasRenderingContext2DState::PaintType, SkPath::FillType = SkPath::kWinding_FillType);
    void drawImageInternal(SkCanvas*, CanvasImageSource*, Image*, const FloatRect& srcRect, const FloatRect& dstRect, const SkPaint*);
    void clipInternal(const Path&, const String& windingRuleString);

    bool isPointInPathInternal(const Path&, const double x, const double y, const String& windingRuleString);
    bool isPointInStrokeInternal(const Path&, const double x, const double y);

    static bool isFullCanvasCompositeMode(SkXfermode::Mode);

    template<typename DrawFunc>
    void compositedDraw(const DrawFunc&, SkCanvas*, CanvasRenderingContext2DState::PaintType, CanvasRenderingContext2DState::ImageType);

    void clearCanvas();
    bool rectContainsTransformedRect(const FloatRect&, const SkIRect&) const;
};

template<typename DrawFunc, typename ContainsFunc>
bool BaseRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc& drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
{
    if (!state().isTransformInvertible())
        return false;

    SkIRect clipBounds;
    if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds))
        return false;

    // If gradient size is zero, then paint nothing.
    CanvasStyle* style = state().style(paintType);
    if (style) {
        CanvasGradient* gradient = style->canvasGradient();
        if (gradient && gradient->gradient()->isZeroSize())
            return false;
    }

    if (isFullCanvasCompositeMode(state().globalComposite()) || stateHasFilter()) {
        compositedDraw(drawFunc, drawingCanvas(), paintType, imageType);
        didDraw(clipBounds);
    } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
        clearCanvas(); // takes care of checkOverdraw()
        const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, imageType);
        drawFunc(drawingCanvas(), paint);
        didDraw(clipBounds);
    } else {
        SkIRect dirtyRect;
        if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
            const SkPaint* paint = state().getPaint(paintType, DrawShadowAndForeground, imageType);
            if (paintType != CanvasRenderingContext2DState::StrokePaintType && drawCoversClipBounds(clipBounds))
                checkOverdraw(bounds, paint, imageType, ClipFill);
            drawFunc(drawingCanvas(), paint);
            didDraw(dirtyRect);
        }
    }
    return true;
}

template<typename DrawFunc>
void BaseRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, SkCanvas* c, CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::ImageType imageType)
{
    SkImageFilter* filter = stateGetFilter();
    ASSERT(isFullCanvasCompositeMode(state().globalComposite()) || filter);
    SkMatrix ctm = c->getTotalMatrix();
    c->resetMatrix();
    SkPaint compositePaint;
    compositePaint.setXfermodeMode(state().globalComposite());
    if (state().shouldDrawShadows()) {
        // unroll into two independently composited passes if drawing shadows
        SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, imageType);
        int saveCount = c->getSaveCount();
        if (filter) {
            SkPaint filterPaint;
            filterPaint.setImageFilter(filter);
            // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
            // does not affect transparent black regions.
            c->saveLayer(nullptr, &shadowPaint);
            c->saveLayer(nullptr, &filterPaint);
            SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, imageType);
            c->setMatrix(ctm);
            drawFunc(c, &foregroundPaint);
        } else {
            ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
            c->saveLayer(nullptr, &compositePaint);
            shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
            c->setMatrix(ctm);
            drawFunc(c, &shadowPaint);
        }
        c->restoreToCount(saveCount);
    }

    compositePaint.setImageFilter(filter);
    // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
    // does not affect transparent black regions *and* !isFullCanvasCompositeMode
    c->saveLayer(nullptr, &compositePaint);
    SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, imageType);
    foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
    c->setMatrix(ctm);
    drawFunc(c, &foregroundPaint);
    c->restore();
    c->setMatrix(ctm);
}

} // namespace blink

#endif // BaseRenderingContext2D_h
