SkAAClip.h revision 9d524f22bfde5dc3dc8f48e1be39bdebd3bb0304
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkAAClip_DEFINED
9#define SkAAClip_DEFINED
10
11#include "SkBlitter.h"
12#include "SkRegion.h"
13
14class SkAAClip {
15public:
16    SkAAClip();
17    SkAAClip(const SkAAClip&);
18    ~SkAAClip();
19
20    SkAAClip& operator=(const SkAAClip&);
21    friend bool operator==(const SkAAClip&, const SkAAClip&);
22    friend bool operator!=(const SkAAClip& a, const SkAAClip& b) {
23        return !(a == b);
24    }
25
26    void swap(SkAAClip&);
27
28    bool isEmpty() const { return nullptr == fRunHead; }
29    const SkIRect& getBounds() const { return fBounds; }
30
31    // Returns true iff the clip is not empty, and is just a hard-edged rect (no partial alpha).
32    // If true, getBounds() can be used in place of this clip.
33    bool isRect() const;
34
35    bool setEmpty();
36    bool setRect(const SkIRect&);
37    bool setRect(const SkRect&, bool doAA = true);
38    bool setPath(const SkPath&, const SkRegion* clip = nullptr, bool doAA = true);
39    bool setRegion(const SkRegion&);
40    bool set(const SkAAClip&);
41
42    bool op(const SkAAClip&, const SkAAClip&, SkRegion::Op);
43
44    // Helpers for op()
45    bool op(const SkIRect&, SkRegion::Op);
46    bool op(const SkRect&, SkRegion::Op, bool doAA);
47    bool op(const SkAAClip&, SkRegion::Op);
48
49    bool translate(int dx, int dy, SkAAClip* dst) const;
50    bool translate(int dx, int dy) {
51        return this->translate(dx, dy, this);
52    }
53
54    /**
55     *  Allocates a mask the size of the aaclip, and expands its data into
56     *  the mask, using kA8_Format
57     */
58    void copyToMask(SkMask*) const;
59
60    // called internally
61
62    bool quickContains(int left, int top, int right, int bottom) const;
63    bool quickContains(const SkIRect& r) const {
64        return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
65    }
66
67    const uint8_t* findRow(int y, int* lastYForRow = nullptr) const;
68    const uint8_t* findX(const uint8_t data[], int x, int* initialCount = nullptr) const;
69
70    class Iter;
71    struct RunHead;
72    struct YOffset;
73    class Builder;
74
75#ifdef SK_DEBUG
76    void validate() const;
77    void debug(bool compress_y=false) const;
78#else
79    void validate() const {}
80    void debug(bool compress_y=false) const {}
81#endif
82
83private:
84    SkIRect  fBounds;
85    RunHead* fRunHead;
86
87    void freeRuns();
88    bool trimBounds();
89    bool trimTopBottom();
90    bool trimLeftRight();
91
92    friend class Builder;
93    class BuilderBlitter;
94    friend class BuilderBlitter;
95};
96
97///////////////////////////////////////////////////////////////////////////////
98
99class SkAAClipBlitter : public SkBlitter {
100public:
101    SkAAClipBlitter() : fScanlineScratch(nullptr) {}
102    virtual ~SkAAClipBlitter();
103
104    void init(SkBlitter* blitter, const SkAAClip* aaclip) {
105        SkASSERT(aaclip && !aaclip->isEmpty());
106        fBlitter = blitter;
107        fAAClip = aaclip;
108        fAAClipBounds = aaclip->getBounds();
109    }
110
111    void blitH(int x, int y, int width) override;
112    void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
113    void blitV(int x, int y, int height, SkAlpha alpha) override;
114    void blitRect(int x, int y, int width, int height) override;
115    void blitMask(const SkMask&, const SkIRect& clip) override;
116    const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
117
118private:
119    SkBlitter*      fBlitter;
120    const SkAAClip* fAAClip;
121    SkIRect         fAAClipBounds;
122
123    // point into fScanlineScratch
124    int16_t*        fRuns;
125    SkAlpha*        fAA;
126
127    enum {
128        kSize = 32 * 32
129    };
130    SkAutoSMalloc<kSize> fGrayMaskScratch;  // used for blitMask
131    void* fScanlineScratch;  // enough for a mask at 32bit, or runs+aa
132
133    void ensureRunsAndAA();
134};
135
136#endif
137