|
1 |
|
2 /* |
|
3 * Copyright 2013 Google Inc. |
|
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 #ifndef SkBitmapDevice_DEFINED |
|
10 #define SkBitmapDevice_DEFINED |
|
11 |
|
12 #include "SkDevice.h" |
|
13 |
|
14 /////////////////////////////////////////////////////////////////////////////// |
|
15 class SK_API SkBitmapDevice : public SkBaseDevice { |
|
16 public: |
|
17 SK_DECLARE_INST_COUNT(SkBitmapDevice) |
|
18 |
|
19 /** |
|
20 * Construct a new device with the specified bitmap as its backend. It is |
|
21 * valid for the bitmap to have no pixels associated with it. In that case, |
|
22 * any drawing to this device will have no effect. |
|
23 */ |
|
24 SkBitmapDevice(const SkBitmap& bitmap); |
|
25 |
|
26 /** |
|
27 * Construct a new device with the specified bitmap as its backend. It is |
|
28 * valid for the bitmap to have no pixels associated with it. In that case, |
|
29 * any drawing to this device will have no effect. |
|
30 */ |
|
31 SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties); |
|
32 |
|
33 #ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG |
|
34 /** |
|
35 * Create a new raster device and have the pixels be automatically |
|
36 * allocated. The rowBytes of the device will be computed automatically |
|
37 * based on the config and the width. |
|
38 * |
|
39 * @param config The desired config for the pixels. If the request cannot |
|
40 * be met, the closest matching support config will be used. |
|
41 * @param width width (in pixels) of the device |
|
42 * @param height height (in pixels) of the device |
|
43 * @param isOpaque Set to true if it is known that all of the pixels will |
|
44 * be drawn to opaquely. Used as an accelerator when drawing |
|
45 * these pixels to another device. |
|
46 */ |
|
47 SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false); |
|
48 |
|
49 /** |
|
50 * Create a new raster device and have the pixels be automatically |
|
51 * allocated. The rowBytes of the device will be computed automatically |
|
52 * based on the config and the width. |
|
53 * |
|
54 * @param config The desired config for the pixels. If the request cannot |
|
55 * be met, the closest matching support config will be used. |
|
56 * @param width width (in pixels) of the device |
|
57 * @param height height (in pixels) of the device |
|
58 * @param isOpaque Set to true if it is known that all of the pixels will |
|
59 * be drawn to opaquely. Used as an accelerator when drawing |
|
60 * these pixels to another device. |
|
61 * @param deviceProperties Properties which affect compositing. |
|
62 */ |
|
63 SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque, |
|
64 const SkDeviceProperties& deviceProperties); |
|
65 #endif |
|
66 static SkBitmapDevice* Create(const SkImageInfo&, |
|
67 const SkDeviceProperties* = NULL); |
|
68 |
|
69 /** Return the width of the device (in pixels). |
|
70 */ |
|
71 virtual int width() const SK_OVERRIDE { return fBitmap.width(); } |
|
72 /** Return the height of the device (in pixels). |
|
73 */ |
|
74 virtual int height() const SK_OVERRIDE { return fBitmap.height(); } |
|
75 |
|
76 /** Returns true if the device's bitmap's config treats every pixels as |
|
77 implicitly opaque. |
|
78 */ |
|
79 virtual bool isOpaque() const SK_OVERRIDE { return fBitmap.isOpaque(); } |
|
80 |
|
81 /** Return the bitmap config of the device's pixels |
|
82 */ |
|
83 virtual SkBitmap::Config config() const SK_OVERRIDE { return fBitmap.config(); } |
|
84 |
|
85 virtual SkImageInfo imageInfo() const SK_OVERRIDE; |
|
86 |
|
87 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG |
|
88 /** |
|
89 * DEPRECATED: This will be made protected once WebKit stops using it. |
|
90 * Instead use Canvas' writePixels method. |
|
91 * |
|
92 * Similar to draw sprite, this method will copy the pixels in bitmap onto |
|
93 * the device, with the top/left corner specified by (x, y). The pixel |
|
94 * values in the device are completely replaced: there is no blending. |
|
95 * |
|
96 * Currently if bitmap is backed by a texture this is a no-op. This may be |
|
97 * relaxed in the future. |
|
98 * |
|
99 * If the bitmap has config kARGB_8888_Config then the config8888 param |
|
100 * will determines how the pixel valuess are intepreted. If the bitmap is |
|
101 * not kARGB_8888_Config then this parameter is ignored. |
|
102 */ |
|
103 virtual void writePixels(const SkBitmap& bitmap, int x, int y, |
|
104 SkCanvas::Config8888 config8888) SK_OVERRIDE; |
|
105 #endif |
|
106 /** |
|
107 * Return the device's associated gpu render target, or NULL. |
|
108 */ |
|
109 virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } |
|
110 |
|
111 protected: |
|
112 /** |
|
113 * Device may filter the text flags for drawing text here. If it wants to |
|
114 * make a change to the specified values, it should write them into the |
|
115 * textflags parameter (output) and return true. If the paint is fine as |
|
116 * is, then ignore the textflags parameter and return false. |
|
117 * |
|
118 * The baseclass SkDevice filters based on its depth and blitters. |
|
119 */ |
|
120 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE; |
|
121 |
|
122 /** Clears the entire device to the specified color (including alpha). |
|
123 * Ignores the clip. |
|
124 */ |
|
125 virtual void clear(SkColor color) SK_OVERRIDE; |
|
126 |
|
127 /** These are called inside the per-device-layer loop for each draw call. |
|
128 When these are called, we have already applied any saveLayer operations, |
|
129 and are handling any looping from the paint, and any effects from the |
|
130 DrawFilter. |
|
131 */ |
|
132 virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE; |
|
133 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, |
|
134 const SkPoint[], const SkPaint& paint) SK_OVERRIDE; |
|
135 virtual void drawRect(const SkDraw&, const SkRect& r, |
|
136 const SkPaint& paint) SK_OVERRIDE; |
|
137 virtual void drawOval(const SkDraw&, const SkRect& oval, |
|
138 const SkPaint& paint) SK_OVERRIDE; |
|
139 virtual void drawRRect(const SkDraw&, const SkRRect& rr, |
|
140 const SkPaint& paint) SK_OVERRIDE; |
|
141 |
|
142 /** |
|
143 * If pathIsMutable, then the implementation is allowed to cast path to a |
|
144 * non-const pointer and modify it in place (as an optimization). Canvas |
|
145 * may do this to implement helpers such as drawOval, by placing a temp |
|
146 * path on the stack to hold the representation of the oval. |
|
147 * |
|
148 * If prePathMatrix is not null, it should logically be applied before any |
|
149 * stroking or other effects. If there are no effects on the paint that |
|
150 * affect the geometry/rasterization, then the pre matrix can just be |
|
151 * pre-concated with the current matrix. |
|
152 */ |
|
153 virtual void drawPath(const SkDraw&, const SkPath& path, |
|
154 const SkPaint& paint, |
|
155 const SkMatrix* prePathMatrix = NULL, |
|
156 bool pathIsMutable = false) SK_OVERRIDE; |
|
157 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
|
158 const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE; |
|
159 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
|
160 int x, int y, const SkPaint& paint) SK_OVERRIDE; |
|
161 |
|
162 /** |
|
163 * The default impl. will create a bitmap-shader from the bitmap, |
|
164 * and call drawRect with it. |
|
165 */ |
|
166 virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, |
|
167 const SkRect* srcOrNull, const SkRect& dst, |
|
168 const SkPaint& paint, |
|
169 SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE; |
|
170 |
|
171 /** |
|
172 * Does not handle text decoration. |
|
173 * Decorations (underline and stike-thru) will be handled by SkCanvas. |
|
174 */ |
|
175 virtual void drawText(const SkDraw&, const void* text, size_t len, |
|
176 SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE; |
|
177 virtual void drawPosText(const SkDraw&, const void* text, size_t len, |
|
178 const SkScalar pos[], SkScalar constY, |
|
179 int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE; |
|
180 virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, |
|
181 const SkPath& path, const SkMatrix* matrix, |
|
182 const SkPaint& paint) SK_OVERRIDE; |
|
183 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, |
|
184 const SkPoint verts[], const SkPoint texs[], |
|
185 const SkColor colors[], SkXfermode* xmode, |
|
186 const uint16_t indices[], int indexCount, |
|
187 const SkPaint& paint) SK_OVERRIDE; |
|
188 /** The SkBaseDevice passed will be an SkBaseDevice which was returned by a call to |
|
189 onCreateDevice on this device with kSaveLayer_Usage. |
|
190 */ |
|
191 virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, |
|
192 const SkPaint&) SK_OVERRIDE; |
|
193 |
|
194 /////////////////////////////////////////////////////////////////////////// |
|
195 |
|
196 /** Update as needed the pixel value in the bitmap, so that the caller can |
|
197 access the pixels directly. Note: only the pixels field should be |
|
198 altered. The config/width/height/rowbytes must remain unchanged. |
|
199 @return the device contents as a bitmap |
|
200 */ |
|
201 virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE; |
|
202 |
|
203 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } |
|
204 // just for subclasses, to assign a custom pixelref |
|
205 SkPixelRef* setPixelRef(SkPixelRef* pr) { |
|
206 fBitmap.setPixelRef(pr); |
|
207 return pr; |
|
208 } |
|
209 |
|
210 /** |
|
211 * Implements readPixels API. The caller will ensure that: |
|
212 * 1. bitmap has pixel config kARGB_8888_Config. |
|
213 * 2. bitmap has pixels. |
|
214 * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is |
|
215 * contained in the device bounds. |
|
216 */ |
|
217 virtual bool onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) SK_OVERRIDE; |
|
218 virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE; |
|
219 virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes) SK_OVERRIDE; |
|
220 |
|
221 /** Called when this device is installed into a Canvas. Balanced by a call |
|
222 to unlockPixels() when the device is removed from a Canvas. |
|
223 */ |
|
224 virtual void lockPixels() SK_OVERRIDE; |
|
225 virtual void unlockPixels() SK_OVERRIDE; |
|
226 |
|
227 /** |
|
228 * Returns true if the device allows processing of this imagefilter. If |
|
229 * false is returned, then the filter is ignored. This may happen for |
|
230 * some subclasses that do not support pixel manipulations after drawing |
|
231 * has occurred (e.g. printing). The default implementation returns true. |
|
232 */ |
|
233 virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE; |
|
234 |
|
235 /** |
|
236 * Override and return true for filters that the device can handle |
|
237 * intrinsically. Doing so means that SkCanvas will pass-through this |
|
238 * filter to drawSprite and drawDevice (and potentially filterImage). |
|
239 * Returning false means the SkCanvas will have apply the filter itself, |
|
240 * and just pass the resulting image to the device. |
|
241 */ |
|
242 virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE; |
|
243 |
|
244 /** |
|
245 * Related (but not required) to canHandleImageFilter, this method returns |
|
246 * true if the device could apply the filter to the src bitmap and return |
|
247 * the result (and updates offset as needed). |
|
248 * If the device does not recognize or support this filter, |
|
249 * it just returns false and leaves result and offset unchanged. |
|
250 */ |
|
251 virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, |
|
252 SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; |
|
253 |
|
254 private: |
|
255 friend class SkCanvas; |
|
256 friend struct DeviceCM; //for setMatrixClip |
|
257 friend class SkDraw; |
|
258 friend class SkDrawIter; |
|
259 friend class SkDeviceFilteredPaint; |
|
260 friend class SkDeviceImageFilterProxy; |
|
261 |
|
262 friend class SkSurface_Raster; |
|
263 |
|
264 // used to change the backend's pixels (and possibly config/rowbytes) |
|
265 // but cannot change the width/height, so there should be no change to |
|
266 // any clip information. |
|
267 virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE; |
|
268 |
|
269 #ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG |
|
270 // in support of legacy constructors |
|
271 void init(SkBitmap::Config config, int width, int height, bool isOpaque); |
|
272 #endif |
|
273 |
|
274 virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; |
|
275 |
|
276 /** Causes any deferred drawing to the device to be completed. |
|
277 */ |
|
278 virtual void flush() SK_OVERRIDE {} |
|
279 |
|
280 virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; |
|
281 virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE; |
|
282 |
|
283 SkBitmap fBitmap; |
|
284 |
|
285 typedef SkBaseDevice INHERITED; |
|
286 }; |
|
287 |
|
288 #endif // SkBitmapDevice_DEFINED |