• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SkDevice_DEFINED
18 #define SkDevice_DEFINED
19 
20 #include "SkRefCnt.h"
21 #include "SkBitmap.h"
22 #include "SkCanvas.h"
23 #include "SkColor.h"
24 
25 class SkClipStack;
26 class SkDevice;
27 class SkDraw;
28 struct SkIRect;
29 class SkMatrix;
30 class SkMetaData;
31 class SkRegion;
32 
33 /** \class SkDeviceFactory
34 
35     Devices that extend SkDevice should also provide a SkDeviceFactory class
36     to pass into SkCanvas.  Doing so will eliminate the need to extend
37     SkCanvas as well.
38 */
39 class SK_API SkDeviceFactory : public SkRefCnt {
40 public:
41     SkDeviceFactory();
42     virtual ~SkDeviceFactory();
43     virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
44                                 int height, bool isOpaque, bool isLayer) = 0;
45 };
46 
47 class SkRasterDeviceFactory : public SkDeviceFactory {
48 public:
49     virtual SkDevice* newDevice(SkCanvas*, SkBitmap::Config, int width,
50                                 int height, bool isOpaque, bool isLayer);
51 };
52 
53 class SK_API SkDevice : public SkRefCnt {
54 public:
55     SkDevice(SkCanvas*);
56     /** Construct a new device, extracting the width/height/config/isOpaque values from
57         the bitmap. If transferPixelOwnership is true, and the bitmap claims to own its
58         own pixels (getOwnsPixels() == true), then transfer this responsibility to the
59         device, and call setOwnsPixels(false) on the bitmap.
60 
61         Subclasses may override the destructor, which is virtual, even though this class
62         doesn't have one. SkRefCnt does.
63 
64         @param bitmap   A copy of this bitmap is made and stored in the device
65     */
66     SkDevice(SkCanvas*, const SkBitmap& bitmap, bool forOffscreen);
67     virtual ~SkDevice();
68 
69     /**
70      *  Return the factory that will create this subclass of SkDevice.
71      *  The returned factory is cached by the device, and so its reference count
72      *  is not changed by this call.
73      */
74     SkDeviceFactory* getDeviceFactory();
75 
76     enum Capabilities {
77         kGL_Capability     = 0x1,  //!< mask indicating GL support
78         kVector_Capability = 0x2,  //!< mask indicating a vector representation
79         kAll_Capabilities  = 0x3
80     };
getDeviceCapabilities()81     virtual uint32_t getDeviceCapabilities() { return 0; }
82 
83     /** Return the width of the device (in pixels).
84     */
width()85     virtual int width() const { return fBitmap.width(); }
86     /** Return the height of the device (in pixels).
87     */
height()88     virtual int height() const { return fBitmap.height(); }
89 
90     /**
91      *  Return the device's origin: its offset in device coordinates from
92      *  the default origin in its canvas' matrix/clip
93      */
getOrigin()94     const SkIPoint& getOrigin() const { return fOrigin; }
95 
96     /** Return the bitmap config of the device's pixels
97     */
config()98     SkBitmap::Config config() const { return fBitmap.getConfig(); }
99     /** Returns true if the device's bitmap's config treats every pixels as
100         implicitly opaque.
101     */
isOpaque()102     bool isOpaque() const { return fBitmap.isOpaque(); }
103 
104     /** Return the bounds of the device
105     */
106     void getBounds(SkIRect* bounds) const;
107 
108     /** Return true if the specified rectangle intersects the bounds of the
109         device. If sect is not NULL and there is an intersection, sect returns
110         the intersection.
111     */
112     bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
113 
114     /** Return the bitmap associated with this device. Call this each time you need
115         to access the bitmap, as it notifies the subclass to perform any flushing
116         etc. before you examine the pixels.
117         @param changePixels set to true if the caller plans to change the pixels
118         @return the device's bitmap
119     */
120     const SkBitmap& accessBitmap(bool changePixels);
121 
122     /** Clears the entire device to the specified color (including alpha).
123      *  Ignores the clip.
124      */
125     virtual void clear(SkColor color);
126 
127     /**
128      * Deprecated name for clear.
129      */
eraseColor(SkColor eraseColor)130     void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
131 
132     /** Called when this device is installed into a Canvas. Balanaced by a call
133         to unlockPixels() when the device is removed from a Canvas.
134     */
135     virtual void lockPixels();
136     virtual void unlockPixels();
137 
138     /** Return the device's associated texture, or NULL. If returned, it may be
139         drawn into another device
140      */
accessTexture()141     virtual SkGpuTexture* accessTexture() { return NULL; }
142 
143     /**
144      *  Called with the correct matrix and clip before this device is drawn
145      *  to using those settings. If your subclass overrides this, be sure to
146      *  call through to the base class as well.
147      *
148      *  The clipstack is another view of the clip. It records the actual
149      *  geometry that went into building the region. It is present for devices
150      *  that want to parse it, but is not required: the region is a complete
151      *  picture of the current clip. (i.e. if you regionize all of the geometry
152      *  in the clipstack, you will arrive at an equivalent region to the one
153      *  passed in).
154     */
155     virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
156                                const SkClipStack&);
157 
158     /** Called when this device gains focus (i.e becomes the current device
159         for drawing).
160     */
gainFocus(SkCanvas *,const SkMatrix &,const SkRegion &,const SkClipStack &)161     virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
162                            const SkClipStack&) {}
163 
164     /** Causes any deferred drawing to the device to be completed.
165      */
flush()166     virtual void flush() {}
167 
168     /**
169      *  Copy the pixels from the device into bitmap. Returns true on success.
170      *  If false is returned, then the bitmap parameter is left unchanged.
171      *  The bitmap parameter is treated as output-only, and will be completely
172      *  overwritten (if the method returns true).
173      */
174     virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
175 
176     /**
177      *  Similar to draw sprite, this method will copy the pixels in bitmap onto
178      *  the device, with the top/left corner specified by (x, y). The pixel
179      *  values in the device are completely replaced: there is no blending.
180      */
181     virtual void writePixels(const SkBitmap& bitmap, int x, int y);
182 
183     /** These are called inside the per-device-layer loop for each draw call.
184      When these are called, we have already applied any saveLayer operations,
185      and are handling any looping from the paint, and any effects from the
186      DrawFilter.
187      */
188     virtual void drawPaint(const SkDraw&, const SkPaint& paint);
189     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
190                             const SkPoint[], const SkPaint& paint);
191     virtual void drawRect(const SkDraw&, const SkRect& r,
192                           const SkPaint& paint);
193     /**
194      *  If pathIsMutable, then the implementation is allowed to cast path to a
195      *  non-const pointer and modify it in place (as an optimization). Canvas
196      *  may do this to implement helpers such as drawOval, by placing a temp
197      *  path on the stack to hold the representation of the oval.
198      *
199      *  If prePathMatrix is not null, it should logically be applied before any
200      *  stroking or other effects. If there are no effects on the paint that
201      *  affect the geometry/rasterization, then the pre matrix can just be
202      *  pre-concated with the current matrix.
203      */
204     virtual void drawPath(const SkDraw&, const SkPath& path,
205                           const SkPaint& paint,
206                           const SkMatrix* prePathMatrix = NULL,
207                           bool pathIsMutable = false);
208     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
209                             const SkIRect* srcRectOrNull,
210                             const SkMatrix& matrix, const SkPaint& paint);
211     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
212                             int x, int y, const SkPaint& paint);
213     virtual void drawText(const SkDraw&, const void* text, size_t len,
214                           SkScalar x, SkScalar y, const SkPaint& paint);
215     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
216                              const SkScalar pos[], SkScalar constY,
217                              int scalarsPerPos, const SkPaint& paint);
218     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
219                                 const SkPath& path, const SkMatrix* matrix,
220                                 const SkPaint& paint);
221 #ifdef ANDROID
222     virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
223                                    const SkPoint pos[], const SkPaint& paint,
224                                    const SkPath& path, const SkMatrix* matrix);
225 #endif
226     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
227                               const SkPoint verts[], const SkPoint texs[],
228                               const SkColor colors[], SkXfermode* xmode,
229                               const uint16_t indices[], int indexCount,
230                               const SkPaint& paint);
231     virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
232                             const SkPaint&);
233 
234     ///////////////////////////////////////////////////////////////////////////
235 
236     SkMetaData& getMetaData();
237 
238     struct TextFlags {
239         uint32_t            fFlags;     // SkPaint::getFlags()
240         SkPaint::Hinting    fHinting;
241     };
242 
243     /**
244      *  Device may filter the text flags for drawing text here. If it wants to
245      *  make a change to the specified values, it should write them into the
246      *  textflags parameter (output) and return true. If the paint is fine as
247      *  is, then ignore the textflags parameter and return false.
248      *
249      *  The baseclass SkDevice filters based on its depth and blitters.
250      */
251     virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
252 
253 protected:
254     /**
255      *  subclasses must override this to return a new (or ref'd) instance of
256      *  a device factory that will create this subclass of device. This value
257      *  is cached, so it should get called at most once for a given instance.
258      */
259     virtual SkDeviceFactory* onNewDeviceFactory();
260 
261     /** Update as needed the pixel value in the bitmap, so that the caller can access
262         the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
263         must remain unchanged.
264     */
265     virtual void onAccessBitmap(SkBitmap*);
266 
getPixelRef()267     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
268     // just for subclasses, to assign a custom pixelref
setPixelRef(SkPixelRef * pr,size_t offset)269     SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
270         fBitmap.setPixelRef(pr, offset);
271         return pr;
272     }
273 
274 private:
275     friend class SkCanvas;
276     // just called by SkCanvas when built as a layer
setOrigin(int x,int y)277     void setOrigin(int x, int y) { fOrigin.set(x, y); }
278 
279     SkCanvas*   fCanvas;
280     SkBitmap    fBitmap;
281     SkIPoint    fOrigin;
282     SkMetaData* fMetaData;
283 
284     SkDeviceFactory* fCachedDeviceFactory;
285 };
286 
287 #endif
288