C++11 override should now be supported by all of {bots,Chrome,Android,Mozilla}
[platform/upstream/libSkiaSharp.git] / src / core / SkBlitter.h
1
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9
10 #ifndef SkBlitter_DEFINED
11 #define SkBlitter_DEFINED
12
13 #include "SkBitmap.h"
14 #include "SkBitmapProcShader.h"
15 #include "SkMask.h"
16 #include "SkMatrix.h"
17 #include "SkPaint.h"
18 #include "SkRefCnt.h"
19 #include "SkRegion.h"
20 #include "SkShader.h"
21 #include "SkSmallAllocator.h"
22
23 /** SkBlitter and its subclasses are responsible for actually writing pixels
24     into memory. Besides efficiency, they handle clipping and antialiasing.
25 */
26 class SkBlitter {
27 public:
28     virtual ~SkBlitter();
29
30     /// Blit a horizontal run of one or more pixels.
31     virtual void blitH(int x, int y, int width);
32     /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
33     /// zero-terminated run-length encoding of spans of constant alpha values.
34     virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
35                            const int16_t runs[]);
36
37     /// Blit a vertical run of pixels with a constant alpha value.
38     virtual void blitV(int x, int y, int height, SkAlpha alpha);
39     /// Blit a solid rectangle one or more pixels wide.
40     virtual void blitRect(int x, int y, int width, int height);
41     /** Blit a rectangle with one alpha-blended column on the left,
42         width (zero or more) opaque pixels, and one alpha-blended column
43         on the right.
44         The result will always be at least two pixels wide.
45     */
46     virtual void blitAntiRect(int x, int y, int width, int height,
47                               SkAlpha leftAlpha, SkAlpha rightAlpha);
48     /// Blit a pattern of pixels defined by a rectangle-clipped mask;
49     /// typically used for text.
50     virtual void blitMask(const SkMask&, const SkIRect& clip);
51
52     /** If the blitter just sets a single value for each pixel, return the
53         bitmap it draws into, and assign value. If not, return NULL and ignore
54         the value parameter.
55     */
56     virtual const SkBitmap* justAnOpaqueColor(uint32_t* value);
57
58     /**
59      *  Special method just to identify the null blitter, which is returned
60      *  from Choose() if the request cannot be fulfilled. Default impl
61      *  returns false.
62      */
63     virtual bool isNullBlitter() const;
64
65     /**
66      *  Special methods for SkShaderBlitter. On all other classes this is a no-op.
67      */
68     virtual bool resetShaderContext(const SkShader::ContextRec&);
69     virtual SkShader::Context* getShaderContext() const;
70
71     /**
72      * Special methods for blitters that can blit more than one row at a time.
73      * This function returns the number of rows that this blitter could optimally
74      * process at a time. It is still required to support blitting one scanline
75      * at a time.
76      */
77     virtual int requestRowsPreserved() const { return 1; }
78
79     /**
80      * This function allocates memory for the blitter that the blitter then owns.
81      * The memory can be used by the calling function at will, but it will be
82      * released when the blitter's destructor is called. This function returns
83      * NULL if no persistent memory is needed by the blitter.
84      */
85     virtual void* allocBlitMemory(size_t sz) {
86         return fBlitMemory.reset(sz, SkAutoMalloc::kReuse_OnShrink);
87     }
88
89     ///@name non-virtual helpers
90     void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
91     void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
92     void blitRegion(const SkRegion& clip);
93     ///@}
94
95     /** @name Factories
96         Return the correct blitter to use given the specified context.
97      */
98     static SkBlitter* Choose(const SkBitmap& device,
99                              const SkMatrix& matrix,
100                              const SkPaint& paint,
101                              SkTBlitterAllocator*,
102                              bool drawCoverage = false);
103
104     static SkBlitter* ChooseSprite(const SkBitmap& device,
105                                    const SkPaint&,
106                                    const SkBitmap& src,
107                                    int left, int top,
108                                    SkTBlitterAllocator*);
109     ///@}
110
111 protected:
112
113     SkAutoMalloc fBlitMemory;
114     
115 private:
116 };
117
118 /** This blitter silently never draws anything.
119 */
120 class SkNullBlitter : public SkBlitter {
121 public:
122     void blitH(int x, int y, int width) override;
123     virtual void blitAntiH(int x, int y, const SkAlpha[],
124                            const int16_t runs[]) override;
125     void blitV(int x, int y, int height, SkAlpha alpha) override;
126     void blitRect(int x, int y, int width, int height) override;
127     void blitMask(const SkMask&, const SkIRect& clip) override;
128     const SkBitmap* justAnOpaqueColor(uint32_t* value) override;
129     bool isNullBlitter() const override;
130 };
131
132 /** Wraps another (real) blitter, and ensures that the real blitter is only
133     called with coordinates that have been clipped by the specified clipRect.
134     This means the caller need not perform the clipping ahead of time.
135 */
136 class SkRectClipBlitter : public SkBlitter {
137 public:
138     void init(SkBlitter* blitter, const SkIRect& clipRect) {
139         SkASSERT(!clipRect.isEmpty());
140         fBlitter = blitter;
141         fClipRect = clipRect;
142     }
143
144     void blitH(int x, int y, int width) override;
145     virtual void blitAntiH(int x, int y, const SkAlpha[],
146                            const int16_t runs[]) override;
147     void blitV(int x, int y, int height, SkAlpha alpha) override;
148     void blitRect(int x, int y, int width, int height) override;
149     virtual void blitAntiRect(int x, int y, int width, int height,
150                      SkAlpha leftAlpha, SkAlpha rightAlpha) override;
151     void blitMask(const SkMask&, const SkIRect& clip) override;
152     const SkBitmap* justAnOpaqueColor(uint32_t* value) override;
153
154     int requestRowsPreserved() const override {
155         return fBlitter->requestRowsPreserved();
156     }
157
158     void* allocBlitMemory(size_t sz) override {
159         return fBlitter->allocBlitMemory(sz);
160     }
161
162 private:
163     SkBlitter*  fBlitter;
164     SkIRect     fClipRect;
165 };
166
167 /** Wraps another (real) blitter, and ensures that the real blitter is only
168     called with coordinates that have been clipped by the specified clipRgn.
169     This means the caller need not perform the clipping ahead of time.
170 */
171 class SkRgnClipBlitter : public SkBlitter {
172 public:
173     void init(SkBlitter* blitter, const SkRegion* clipRgn) {
174         SkASSERT(clipRgn && !clipRgn->isEmpty());
175         fBlitter = blitter;
176         fRgn = clipRgn;
177     }
178
179     void blitH(int x, int y, int width) override;
180     virtual void blitAntiH(int x, int y, const SkAlpha[],
181                            const int16_t runs[]) override;
182     void blitV(int x, int y, int height, SkAlpha alpha) override;
183     void blitRect(int x, int y, int width, int height) override;
184     virtual void blitAntiRect(int x, int y, int width, int height,
185                      SkAlpha leftAlpha, SkAlpha rightAlpha) override;
186     void blitMask(const SkMask&, const SkIRect& clip) override;
187     const SkBitmap* justAnOpaqueColor(uint32_t* value) override;
188
189     int requestRowsPreserved() const override {
190         return fBlitter->requestRowsPreserved();
191     }
192
193     void* allocBlitMemory(size_t sz) override {
194         return fBlitter->allocBlitMemory(sz);
195     }
196
197 private:
198     SkBlitter*      fBlitter;
199     const SkRegion* fRgn;
200 };
201
202 /** Factory to set up the appropriate most-efficient wrapper blitter
203     to apply a clip. Returns a pointer to a member, so lifetime must
204     be managed carefully.
205 */
206 class SkBlitterClipper {
207 public:
208     SkBlitter*  apply(SkBlitter* blitter, const SkRegion* clip,
209                       const SkIRect* bounds = NULL);
210
211 private:
212     SkNullBlitter       fNullBlitter;
213     SkRectClipBlitter   fRectBlitter;
214     SkRgnClipBlitter    fRgnBlitter;
215 };
216
217 #endif