1 :
2 : /*
3 : * Copyright 2010 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 SkDevice_DEFINED
11 : #define SkDevice_DEFINED
12 :
13 : #include "SkRefCnt.h"
14 : #include "SkBitmap.h"
15 : #include "SkCanvas.h"
16 : #include "SkColor.h"
17 :
18 : class SkClipStack;
19 : class SkDraw;
20 : struct SkIRect;
21 : class SkMatrix;
22 : class SkMetaData;
23 : class SkRegion;
24 :
25 : // This is an opaque class, not interpreted by skia
26 : class SkGpuRenderTarget;
27 :
28 : class SK_API SkDevice : public SkRefCnt {
29 : public:
30 : /**
31 : * Construct a new device with the specified bitmap as its backend. It is
32 : * valid for the bitmap to have no pixels associated with it. In that case,
33 : * any drawing to this device will have no effect.
34 : */
35 : SkDevice(const SkBitmap& bitmap);
36 :
37 : /**
38 : * Create a new raster device and have the pixels be automatically
39 : * allocated. The rowBytes of the device will be computed automatically
40 : * based on the config and the width.
41 : *
42 : * @param config The desired config for the pixels. If the request cannot
43 : * be met, the closest matching support config will be used.
44 : * @param width width (in pixels) of the device
45 : * @param height height (in pixels) of the device
46 : * @param isOpaque Set to true if it is known that all of the pixels will
47 : * be drawn to opaquely. Used as an accelerator when drawing
48 : * these pixels to another device.
49 : */
50 : SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
51 :
52 : virtual ~SkDevice();
53 :
54 : /**
55 : * Creates a device that is of the same type as this device (e.g. SW-raster,
56 : * GPU, or PDF). The backing store for this device is created automatically
57 : * (e.g. offscreen pixels or FBO or whatever is appropriate).
58 : *
59 : * @param width width of the device to create
60 : * @param height height of the device to create
61 : * @param isOpaque performance hint, set to true if you know that you will
62 : * draw into this device such that all of the pixels will
63 : * be opaque.
64 : */
65 : SkDevice* createCompatibleDevice(SkBitmap::Config config,
66 : int width, int height,
67 : bool isOpaque);
68 :
69 : SkMetaData& getMetaData();
70 :
71 : enum Capabilities {
72 : kGL_Capability = 0x1, //!< mask indicating GL support
73 : kVector_Capability = 0x2, //!< mask indicating a vector representation
74 : kAll_Capabilities = 0x3
75 : };
76 0 : virtual uint32_t getDeviceCapabilities() { return 0; }
77 :
78 : /** Return the width of the device (in pixels).
79 : */
80 0 : virtual int width() const { return fBitmap.width(); }
81 : /** Return the height of the device (in pixels).
82 : */
83 0 : virtual int height() const { return fBitmap.height(); }
84 :
85 : /**
86 : * Return the bounds of the device in the coordinate space of the root
87 : * canvas. The root device will have its top-left at 0,0, but other devices
88 : * such as those associated with saveLayer may have a non-zero origin.
89 : */
90 : void getGlobalBounds(SkIRect* bounds) const;
91 :
92 : /** Returns true if the device's bitmap's config treats every pixels as
93 : implicitly opaque.
94 : */
95 : bool isOpaque() const { return fBitmap.isOpaque(); }
96 :
97 : /** Return the bitmap config of the device's pixels
98 : */
99 : SkBitmap::Config config() const { return fBitmap.getConfig(); }
100 :
101 : /** Return the bitmap associated with this device. Call this each time you need
102 : to access the bitmap, as it notifies the subclass to perform any flushing
103 : etc. before you examine the pixels.
104 : @param changePixels set to true if the caller plans to change the pixels
105 : @return the device's bitmap
106 : */
107 : const SkBitmap& accessBitmap(bool changePixels);
108 :
109 : /**
110 : * DEPRECATED: This will be made protected once WebKit stops using it.
111 : * Instead use Canvas' writePixels method.
112 : *
113 : * Similar to draw sprite, this method will copy the pixels in bitmap onto
114 : * the device, with the top/left corner specified by (x, y). The pixel
115 : * values in the device are completely replaced: there is no blending.
116 : *
117 : * Currently if bitmap is backed by a texture this is a no-op. This may be
118 : * relaxed in the future.
119 : *
120 : * If the bitmap has config kARGB_8888_Config then the config8888 param
121 : * will determines how the pixel valuess are intepreted. If the bitmap is
122 : * not kARGB_8888_Config then this parameter is ignored.
123 : */
124 : virtual void writePixels(const SkBitmap& bitmap, int x, int y,
125 : SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
126 :
127 : /**
128 : * Return the device's associated gpu render target, or NULL.
129 : */
130 0 : virtual SkGpuRenderTarget* accessRenderTarget() { return NULL; }
131 :
132 :
133 : /**
134 : * Return the device's origin: its offset in device coordinates from
135 : * the default origin in its canvas' matrix/clip
136 : */
137 0 : const SkIPoint& getOrigin() const { return fOrigin; }
138 :
139 : protected:
140 : enum Usage {
141 : kGeneral_Usage,
142 : kSaveLayer_Usage // <! internal use only
143 : };
144 :
145 : struct TextFlags {
146 : uint32_t fFlags; // SkPaint::getFlags()
147 : SkPaint::Hinting fHinting;
148 : };
149 :
150 : /**
151 : * Device may filter the text flags for drawing text here. If it wants to
152 : * make a change to the specified values, it should write them into the
153 : * textflags parameter (output) and return true. If the paint is fine as
154 : * is, then ignore the textflags parameter and return false.
155 : *
156 : * The baseclass SkDevice filters based on its depth and blitters.
157 : */
158 : virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
159 :
160 : /**
161 : * Called with the correct matrix and clip before this device is drawn
162 : * to using those settings. If your subclass overrides this, be sure to
163 : * call through to the base class as well.
164 : *
165 : * The clipstack is another view of the clip. It records the actual
166 : * geometry that went into building the region. It is present for devices
167 : * that want to parse it, but is not required: the region is a complete
168 : * picture of the current clip. (i.e. if you regionize all of the geometry
169 : * in the clipstack, you will arrive at an equivalent region to the one
170 : * passed in).
171 : */
172 : virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
173 : const SkClipStack&);
174 :
175 : /** Called when this device gains focus (i.e becomes the current device
176 : for drawing).
177 : */
178 0 : virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
179 0 : const SkClipStack&) {}
180 :
181 : /** Clears the entire device to the specified color (including alpha).
182 : * Ignores the clip.
183 : */
184 : virtual void clear(SkColor color);
185 :
186 : /**
187 : * Deprecated name for clear.
188 : */
189 : void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
190 :
191 : /** These are called inside the per-device-layer loop for each draw call.
192 : When these are called, we have already applied any saveLayer operations,
193 : and are handling any looping from the paint, and any effects from the
194 : DrawFilter.
195 : */
196 : virtual void drawPaint(const SkDraw&, const SkPaint& paint);
197 : virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
198 : const SkPoint[], const SkPaint& paint);
199 : virtual void drawRect(const SkDraw&, const SkRect& r,
200 : const SkPaint& paint);
201 : /**
202 : * If pathIsMutable, then the implementation is allowed to cast path to a
203 : * non-const pointer and modify it in place (as an optimization). Canvas
204 : * may do this to implement helpers such as drawOval, by placing a temp
205 : * path on the stack to hold the representation of the oval.
206 : *
207 : * If prePathMatrix is not null, it should logically be applied before any
208 : * stroking or other effects. If there are no effects on the paint that
209 : * affect the geometry/rasterization, then the pre matrix can just be
210 : * pre-concated with the current matrix.
211 : */
212 : virtual void drawPath(const SkDraw&, const SkPath& path,
213 : const SkPaint& paint,
214 : const SkMatrix* prePathMatrix = NULL,
215 : bool pathIsMutable = false);
216 : virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
217 : const SkIRect* srcRectOrNull,
218 : const SkMatrix& matrix, const SkPaint& paint);
219 : virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
220 : int x, int y, const SkPaint& paint);
221 : /**
222 : * Does not handle text decoration.
223 : * Decorations (underline and stike-thru) will be handled by SkCanvas.
224 : */
225 : virtual void drawText(const SkDraw&, const void* text, size_t len,
226 : SkScalar x, SkScalar y, const SkPaint& paint);
227 : virtual void drawPosText(const SkDraw&, const void* text, size_t len,
228 : const SkScalar pos[], SkScalar constY,
229 : int scalarsPerPos, const SkPaint& paint);
230 : virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
231 : const SkPath& path, const SkMatrix* matrix,
232 : const SkPaint& paint);
233 : #ifdef SK_BUILD_FOR_ANDROID
234 : virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
235 : const SkPoint pos[], const SkPaint& paint,
236 : const SkPath& path, const SkMatrix* matrix);
237 : #endif
238 : virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
239 : const SkPoint verts[], const SkPoint texs[],
240 : const SkColor colors[], SkXfermode* xmode,
241 : const uint16_t indices[], int indexCount,
242 : const SkPaint& paint);
243 : /** The SkDevice passed will be an SkDevice which was returned by a call to
244 : onCreateCompatibleDevice on this device with kSaveLayer_Usage.
245 : */
246 : virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
247 : const SkPaint&);
248 :
249 : /**
250 : * On success (returns true), copy the device pixels into the bitmap.
251 : * On failure, the bitmap parameter is left unchanged and false is
252 : * returned.
253 : *
254 : * The device's pixels are converted to the bitmap's config. The only
255 : * supported config is kARGB_8888_Config, though this is likely to be
256 : * relaxed in the future. The meaning of config kARGB_8888_Config is
257 : * modified by the enum param config8888. The default value interprets
258 : * kARGB_8888_Config as SkPMColor
259 : *
260 : * If the bitmap has pixels already allocated, the device pixels will be
261 : * written there. If not, bitmap->allocPixels() will be called
262 : * automatically. If the bitmap is backed by a texture readPixels will
263 : * fail.
264 : *
265 : * The actual pixels written is the intersection of the device's bounds,
266 : * and the rectangle formed by the bitmap's width,height and the specified
267 : * x,y. If bitmap pixels extend outside of that intersection, they will not
268 : * be modified.
269 : *
270 : * Other failure conditions:
271 : * * If the device is not a raster device (e.g. PDF) then readPixels will
272 : * fail.
273 : * * If bitmap is texture-backed then readPixels will fail. (This may be
274 : * relaxed in the future.)
275 : */
276 : bool readPixels(SkBitmap* bitmap,
277 : int x, int y,
278 : SkCanvas::Config8888 config8888);
279 :
280 : ///////////////////////////////////////////////////////////////////////////
281 :
282 : /** Update as needed the pixel value in the bitmap, so that the caller can access
283 : the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
284 : must remain unchanged.
285 : */
286 : virtual void onAccessBitmap(SkBitmap*);
287 :
288 : SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
289 : // just for subclasses, to assign a custom pixelref
290 : SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
291 : fBitmap.setPixelRef(pr, offset);
292 : return pr;
293 : }
294 :
295 : /**
296 : * Implements readPixels API. The caller will ensure that:
297 : * 1. bitmap has pixel config kARGB_8888_Config.
298 : * 2. bitmap has pixels.
299 : * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is
300 : * contained in the device bounds.
301 : */
302 : virtual bool onReadPixels(const SkBitmap& bitmap,
303 : int x, int y,
304 : SkCanvas::Config8888 config8888);
305 :
306 : /** Called when this device is installed into a Canvas. Balanaced by a call
307 : to unlockPixels() when the device is removed from a Canvas.
308 : */
309 : virtual void lockPixels();
310 : virtual void unlockPixels();
311 :
312 : /**
313 : * Override and return true for filters that the device handles
314 : * intrinsically. Returning false means call the filter.
315 : * Default impl returns false.
316 : */
317 : virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
318 : const SkMatrix& ctm,
319 : SkBitmap* result, SkIPoint* offset);
320 :
321 : // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
322 : // either is identical to kNative_Premul_Config8888. Otherwise, -1.
323 : static const SkCanvas::Config8888 kPMColorAlias;
324 :
325 : private:
326 : friend class SkCanvas;
327 : friend struct DeviceCM; //for setMatrixClip
328 : friend class SkDraw;
329 : friend class SkDrawIter;
330 : friend class SkDeviceFilteredPaint;
331 : friend class DeviceImageFilterProxy;
332 :
333 : // just called by SkCanvas when built as a layer
334 0 : void setOrigin(int x, int y) { fOrigin.set(x, y); }
335 : // just called by SkCanvas for saveLayer
336 : SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
337 : int width, int height,
338 : bool isOpaque);
339 :
340 : /**
341 : * Subclasses should override this to implement createCompatibleDevice.
342 : */
343 : virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
344 : int width, int height,
345 : bool isOpaque,
346 : Usage usage);
347 :
348 : /** Causes any deferred drawing to the device to be completed.
349 : */
350 0 : virtual void flush() {}
351 :
352 : SkBitmap fBitmap;
353 : SkIPoint fOrigin;
354 : SkMetaData* fMetaData;
355 : };
356 :
357 : #endif
|