1/*
2 * Copyright 2013 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 SkBitmapDevice_DEFINED
9#define SkBitmapDevice_DEFINED
10
11#include "SkBitmap.h"
12#include "SkCanvas.h"
13#include "SkColor.h"
14#include "SkDevice.h"
15#include "SkImageInfo.h"
16#include "SkPixelRef.h"
17#include "SkRasterClip.h"
18#include "SkRasterClipStack.h"
19#include "SkRect.h"
20#include "SkScalar.h"
21#include "SkSize.h"
22#include "SkSurfaceProps.h"
23
24class SkImageFilterCache;
25class SkMatrix;
26class SkPaint;
27class SkPath;
28class SkPixelRef;
29class SkPixmap;
30class SkRasterHandleAllocator;
31class SkRRect;
32class SkSurface;
33struct SkPoint;
34
35///////////////////////////////////////////////////////////////////////////////
36class SK_API SkBitmapDevice : public SkBaseDevice {
37public:
38    /**
39     *  Construct a new device with the specified bitmap as its backend. It is
40     *  valid for the bitmap to have no pixels associated with it. In that case,
41     *  any drawing to this device will have no effect.
42     */
43    SkBitmapDevice(const SkBitmap& bitmap);
44
45    /**
46     * Create a new device along with its requisite pixel memory using
47     * default SkSurfaceProps (i.e., kLegacyFontHost_InitType-style).
48     * Note: this entry point is slated for removal - no one should call it.
49     */
50    static SkBitmapDevice* Create(const SkImageInfo& info);
51
52    /**
53     *  Construct a new device with the specified bitmap as its backend. It is
54     *  valid for the bitmap to have no pixels associated with it. In that case,
55     *  any drawing to this device will have no effect.
56     */
57    SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps,
58                   void* externalHandle = nullptr);
59
60    static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&,
61                                  SkRasterHandleAllocator* = nullptr);
62
63protected:
64    bool onShouldDisableLCD(const SkPaint&) const override;
65    void* getRasterHandle() const override { return fRasterHandle; }
66
67    /** These are called inside the per-device-layer loop for each draw call.
68     When these are called, we have already applied any saveLayer operations,
69     and are handling any looping from the paint, and any effects from the
70     DrawFilter.
71     */
72    void drawPaint(const SkPaint& paint) override;
73    void drawPoints(SkCanvas::PointMode mode, size_t count,
74                            const SkPoint[], const SkPaint& paint) override;
75    void drawRect(const SkRect& r, const SkPaint& paint) override;
76    void drawOval(const SkRect& oval, const SkPaint& paint) override;
77    void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
78
79    /**
80     *  If pathIsMutable, then the implementation is allowed to cast path to a
81     *  non-const pointer and modify it in place (as an optimization). Canvas
82     *  may do this to implement helpers such as drawOval, by placing a temp
83     *  path on the stack to hold the representation of the oval.
84     *
85     *  If prePathMatrix is not null, it should logically be applied before any
86     *  stroking or other effects. If there are no effects on the paint that
87     *  affect the geometry/rasterization, then the pre matrix can just be
88     *  pre-concated with the current matrix.
89     */
90    void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
91                          bool pathIsMutable) override;
92    void drawBitmap(const SkBitmap&, SkScalar x, SkScalar y, const SkPaint&) override;
93    void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override;
94
95    /**
96     *  The default impl. will create a bitmap-shader from the bitmap,
97     *  and call drawRect with it.
98     */
99    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&,
100                        const SkPaint&, SkCanvas::SrcRectConstraint) override;
101
102    /**
103     *  Does not handle text decoration.
104     *  Decorations (underline and stike-thru) will be handled by SkCanvas.
105     */
106    void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
107                  const SkPaint&) override;
108    void drawPosText(const void* text, size_t len, const SkScalar pos[],
109                     int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
110    void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
111    void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
112
113    ///////////////////////////////////////////////////////////////////////////
114
115    void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
116                     SkImage*, const SkMatrix&) override;
117    sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
118    sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
119    sk_sp<SkSpecialImage> snapSpecial() override;
120
121    ///////////////////////////////////////////////////////////////////////////
122
123    bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) override;
124    bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) override;
125    bool onPeekPixels(SkPixmap*) override;
126    bool onAccessPixels(SkPixmap*) override;
127
128    void onSave() override;
129    void onRestore() override;
130    void onClipRect(const SkRect& rect, SkClipOp, bool aa) override;
131    void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override;
132    void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
133    void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
134    void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
135    bool onClipIsAA() const override;
136    void onAsRgnClip(SkRegion*) const override;
137    void validateDevBounds(const SkIRect& r) override;
138    ClipType onGetClipType() const override;
139
140private:
141    friend class SkCanvas;
142    friend struct DeviceCM; //for setMatrixClip
143    friend class SkDraw;
144    friend class SkDrawIter;
145    friend class SkDeviceFilteredPaint;
146    friend class SkSurface_Raster;
147    friend class SkThreadedBMPDevice; // to copy fRCStack
148
149    class BDDraw;
150
151    // used to change the backend's pixels (and possibly config/rowbytes)
152    // but cannot change the width/height, so there should be no change to
153    // any clip information.
154    void replaceBitmapBackendForRasterSurface(const SkBitmap&) override;
155
156    SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
157
158    sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
159
160    SkImageFilterCache* getImageFilterCache() override;
161
162    SkBitmap    fBitmap;
163    void*       fRasterHandle = nullptr;
164    SkRasterClipStack  fRCStack;
165
166    typedef SkBaseDevice INHERITED;
167};
168
169#endif // SkBitmapDevice_DEFINED
170