/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkAAClip_DEFINED
#define SkAAClip_DEFINED

#include "SkAutoMalloc.h"
#include "SkBlitter.h"
#include "SkRegion.h"

class SkAAClip {
public:
    SkAAClip();
    SkAAClip(const SkAAClip&);
    ~SkAAClip();

    SkAAClip& operator=(const SkAAClip&);
    friend bool operator==(const SkAAClip&, const SkAAClip&);
    friend bool operator!=(const SkAAClip& a, const SkAAClip& b) {
        return !(a == b);
    }

    void swap(SkAAClip&);

    bool isEmpty() const { return nullptr == fRunHead; }
    const SkIRect& getBounds() const { return fBounds; }

    // Returns true iff the clip is not empty, and is just a hard-edged rect (no partial alpha).
    // If true, getBounds() can be used in place of this clip.
    bool isRect() const;

    bool setEmpty();
    bool setRect(const SkIRect&);
    bool setRect(const SkRect&, bool doAA = true);
    bool setPath(const SkPath&, const SkRegion* clip = nullptr, bool doAA = true);
    bool setRegion(const SkRegion&);
    bool set(const SkAAClip&);

    bool op(const SkAAClip&, const SkAAClip&, SkRegion::Op);

    // Helpers for op()
    bool op(const SkIRect&, SkRegion::Op);
    bool op(const SkRect&, SkRegion::Op, bool doAA);
    bool op(const SkAAClip&, SkRegion::Op);

    bool translate(int dx, int dy, SkAAClip* dst) const;
    bool translate(int dx, int dy) {
        return this->translate(dx, dy, this);
    }

    /**
     *  Allocates a mask the size of the aaclip, and expands its data into
     *  the mask, using kA8_Format
     */
    void copyToMask(SkMask*) const;

    // called internally

    bool quickContains(int left, int top, int right, int bottom) const;
    bool quickContains(const SkIRect& r) const {
        return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
    }

    const uint8_t* findRow(int y, int* lastYForRow = nullptr) const;
    const uint8_t* findX(const uint8_t data[], int x, int* initialCount = nullptr) const;

    class Iter;
    struct RunHead;
    struct YOffset;
    class Builder;

#ifdef SK_DEBUG
    void validate() const;
    void debug(bool compress_y=false) const;
#else
    void validate() const {}
    void debug(bool compress_y=false) const {}
#endif

private:
    SkIRect  fBounds;
    RunHead* fRunHead;

    void freeRuns();
    bool trimBounds();
    bool trimTopBottom();
    bool trimLeftRight();

    friend class Builder;
    class BuilderBlitter;
    friend class BuilderBlitter;
};

///////////////////////////////////////////////////////////////////////////////

class SkAAClipBlitter : public SkBlitter {
public:
    SkAAClipBlitter() : fScanlineScratch(nullptr) {}
    ~SkAAClipBlitter() override;

    void init(SkBlitter* blitter, const SkAAClip* aaclip) {
        SkASSERT(aaclip && !aaclip->isEmpty());
        fBlitter = blitter;
        fAAClip = aaclip;
        fAAClipBounds = aaclip->getBounds();
    }

    void blitH(int x, int y, int width) override;
    void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
    void blitV(int x, int y, int height, SkAlpha alpha) override;
    void blitRect(int x, int y, int width, int height) override;
    void blitMask(const SkMask&, const SkIRect& clip) override;
    const SkPixmap* justAnOpaqueColor(uint32_t* value) override;

private:
    SkBlitter*      fBlitter;
    const SkAAClip* fAAClip;
    SkIRect         fAAClipBounds;

    // point into fScanlineScratch
    int16_t*        fRuns;
    SkAlpha*        fAA;

    enum {
        kSize = 32 * 32
    };
    SkAutoSMalloc<kSize> fGrayMaskScratch;  // used for blitMask
    void* fScanlineScratch;  // enough for a mask at 32bit, or runs+aa

    void ensureRunsAndAA();
};

#endif
