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