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