|
1 /* |
|
2 * Copyright 2006 The Android Open Source Project |
|
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 SkCanvas_DEFINED |
|
9 #define SkCanvas_DEFINED |
|
10 |
|
11 #include "SkTypes.h" |
|
12 #include "SkBitmap.h" |
|
13 #include "SkDeque.h" |
|
14 #include "SkClipStack.h" |
|
15 #include "SkPaint.h" |
|
16 #include "SkRefCnt.h" |
|
17 #include "SkPath.h" |
|
18 #include "SkRegion.h" |
|
19 #include "SkXfermode.h" |
|
20 |
|
21 // if not defined, we always assume ClipToLayer for saveLayer() |
|
22 //#define SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
|
23 |
|
24 |
|
25 //#define SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG |
|
26 //#define SK_SUPPORT_LEGACY_GETCLIPTYPE |
|
27 //#define SK_SUPPORT_LEGACY_GETTOTALCLIP |
|
28 //#define SK_SUPPORT_LEGACY_GETTOPDEVICE |
|
29 |
|
30 class SkBounder; |
|
31 class SkBaseDevice; |
|
32 class SkDraw; |
|
33 class SkDrawFilter; |
|
34 class SkMetaData; |
|
35 class SkPicture; |
|
36 class SkRRect; |
|
37 class SkSurface; |
|
38 class SkSurface_Base; |
|
39 class GrContext; |
|
40 class GrRenderTarget; |
|
41 |
|
42 /** \class SkCanvas |
|
43 |
|
44 A Canvas encapsulates all of the state about drawing into a device (bitmap). |
|
45 This includes a reference to the device itself, and a stack of matrix/clip |
|
46 values. For any given draw call (e.g. drawRect), the geometry of the object |
|
47 being drawn is transformed by the concatenation of all the matrices in the |
|
48 stack. The transformed geometry is clipped by the intersection of all of |
|
49 the clips in the stack. |
|
50 |
|
51 While the Canvas holds the state of the drawing device, the state (style) |
|
52 of the object being drawn is held by the Paint, which is provided as a |
|
53 parameter to each of the draw() methods. The Paint holds attributes such as |
|
54 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns), |
|
55 etc. |
|
56 */ |
|
57 class SK_API SkCanvas : public SkRefCnt { |
|
58 public: |
|
59 SK_DECLARE_INST_COUNT(SkCanvas) |
|
60 |
|
61 /** |
|
62 * Attempt to allocate an offscreen raster canvas, matching the ImageInfo. |
|
63 * On success, return a new canvas that will draw into that offscreen. |
|
64 * |
|
65 * The caller can access the pixels after drawing into this canvas by |
|
66 * calling readPixels() or peekPixels(). |
|
67 * |
|
68 * If the requested ImageInfo is opaque (either the colortype is |
|
69 * intrinsically opaque like RGB_565, or the info's alphatype is kOpaque) |
|
70 * then the pixel memory may be uninitialized. Otherwise, the pixel memory |
|
71 * will be initialized to 0, which is interpreted as transparent. |
|
72 * |
|
73 * On failure, return NULL. This can fail for several reasons: |
|
74 * 1. the memory allocation failed (e.g. request is too large) |
|
75 * 2. invalid ImageInfo (e.g. negative dimensions) |
|
76 * 3. unsupported ImageInfo for a canvas |
|
77 * - kUnknown_SkColorType, kIndex_8_SkColorType |
|
78 * - kIgnore_SkAlphaType |
|
79 * - this list is not complete, so others may also be unsupported |
|
80 * |
|
81 * Note: it is valid to request a supported ImageInfo, but with zero |
|
82 * dimensions. |
|
83 */ |
|
84 static SkCanvas* NewRaster(const SkImageInfo&); |
|
85 |
|
86 static SkCanvas* NewRasterN32(int width, int height) { |
|
87 return NewRaster(SkImageInfo::MakeN32Premul(width, height)); |
|
88 } |
|
89 |
|
90 /** |
|
91 * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the |
|
92 * specified pixels. To access the pixels after drawing to them, the caller should call |
|
93 * flush() or call peekPixels(...). |
|
94 * |
|
95 * On failure, return NULL. This can fail for several reasons: |
|
96 * 1. invalid ImageInfo (e.g. negative dimensions) |
|
97 * 2. unsupported ImageInfo for a canvas |
|
98 * - kUnknown_SkColorType, kIndex_8_SkColorType |
|
99 * - kIgnore_SkAlphaType |
|
100 * - this list is not complete, so others may also be unsupported |
|
101 * |
|
102 * Note: it is valid to request a supported ImageInfo, but with zero |
|
103 * dimensions. |
|
104 */ |
|
105 static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t); |
|
106 |
|
107 static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) { |
|
108 return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes); |
|
109 } |
|
110 |
|
111 /** |
|
112 * Creates an empty canvas with no backing device/pixels, and zero |
|
113 * dimensions. |
|
114 */ |
|
115 SkCanvas(); |
|
116 |
|
117 /** |
|
118 * Creates a canvas of the specified dimensions, but explicitly not backed |
|
119 * by any device/pixels. Typically this use used by subclasses who handle |
|
120 * the draw calls in some other way. |
|
121 */ |
|
122 SkCanvas(int width, int height); |
|
123 |
|
124 /** Construct a canvas with the specified device to draw into. |
|
125 |
|
126 @param device Specifies a device for the canvas to draw into. |
|
127 */ |
|
128 explicit SkCanvas(SkBaseDevice* device); |
|
129 |
|
130 /** Construct a canvas with the specified bitmap to draw into. |
|
131 @param bitmap Specifies a bitmap for the canvas to draw into. Its |
|
132 structure are copied to the canvas. |
|
133 */ |
|
134 explicit SkCanvas(const SkBitmap& bitmap); |
|
135 virtual ~SkCanvas(); |
|
136 |
|
137 SkMetaData& getMetaData(); |
|
138 |
|
139 /** |
|
140 * Return ImageInfo for this canvas. If the canvas is not backed by pixels |
|
141 * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. |
|
142 */ |
|
143 SkImageInfo imageInfo() const; |
|
144 |
|
145 /////////////////////////////////////////////////////////////////////////// |
|
146 |
|
147 /** |
|
148 * Trigger the immediate execution of all pending draw operations. |
|
149 */ |
|
150 void flush(); |
|
151 |
|
152 /** |
|
153 * Gets the size of the base or root layer in global canvas coordinates. The |
|
154 * origin of the base layer is always (0,0). The current drawable area may be |
|
155 * smaller (due to clipping or saveLayer). |
|
156 */ |
|
157 SkISize getBaseLayerSize() const; |
|
158 |
|
159 /** |
|
160 * DEPRECATED: call getBaseLayerSize |
|
161 */ |
|
162 SkISize getDeviceSize() const { return this->getBaseLayerSize(); } |
|
163 |
|
164 /** |
|
165 * DEPRECATED. |
|
166 * Return the canvas' device object, which may be null. The device holds |
|
167 * the bitmap of the pixels that the canvas draws into. The reference count |
|
168 * of the returned device is not changed by this call. |
|
169 */ |
|
170 SkBaseDevice* getDevice() const; |
|
171 |
|
172 /** |
|
173 * saveLayer() can create another device (which is later drawn onto |
|
174 * the previous device). getTopDevice() returns the top-most device current |
|
175 * installed. Note that this can change on other calls like save/restore, |
|
176 * so do not access this device after subsequent canvas calls. |
|
177 * The reference count of the device is not changed. |
|
178 * |
|
179 * @param updateMatrixClip If this is true, then before the device is |
|
180 * returned, we ensure that its has been notified about the current |
|
181 * matrix and clip. Note: this happens automatically when the device |
|
182 * is drawn to, but is optional here, as there is a small perf hit |
|
183 * sometimes. |
|
184 */ |
|
185 #ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE |
|
186 private: |
|
187 #endif |
|
188 SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const; |
|
189 public: |
|
190 |
|
191 /** |
|
192 * Create a new surface matching the specified info, one that attempts to |
|
193 * be maximally compatible when used with this canvas. |
|
194 */ |
|
195 SkSurface* newSurface(const SkImageInfo&); |
|
196 |
|
197 /** |
|
198 * Return the GPU context of the device that is associated with the canvas. |
|
199 * For a canvas with non-GPU device, NULL is returned. |
|
200 */ |
|
201 GrContext* getGrContext(); |
|
202 |
|
203 /////////////////////////////////////////////////////////////////////////// |
|
204 |
|
205 /** |
|
206 * If the canvas has writable pixels in its top layer (and is not recording to a picture |
|
207 * or other non-raster target) and has direct access to its pixels (i.e. they are in |
|
208 * local RAM) return the address of those pixels, and if not null, |
|
209 * return the ImageInfo and rowBytes. The returned address is only valid |
|
210 * while the canvas object is in scope and unchanged. Any API calls made on |
|
211 * canvas (or its parent surface if any) will invalidate the |
|
212 * returned address (and associated information). |
|
213 * |
|
214 * On failure, returns NULL and the info and rowBytes parameters are |
|
215 * ignored. |
|
216 */ |
|
217 void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes); |
|
218 |
|
219 /** |
|
220 * If the canvas has readable pixels in its base layer (and is not recording to a picture |
|
221 * or other non-raster target) and has direct access to its pixels (i.e. they are in |
|
222 * local RAM) return the const-address of those pixels, and if not null, |
|
223 * return the ImageInfo and rowBytes. The returned address is only valid |
|
224 * while the canvas object is in scope and unchanged. Any API calls made on |
|
225 * canvas (or its parent surface if any) will invalidate the |
|
226 * returned address (and associated information). |
|
227 * |
|
228 * On failure, returns NULL and the info and rowBytes parameters are |
|
229 * ignored. |
|
230 */ |
|
231 const void* peekPixels(SkImageInfo* info, size_t* rowBytes); |
|
232 |
|
233 /** |
|
234 * This enum can be used with read/writePixels to perform a pixel ops to or |
|
235 * from an 8888 config other than Skia's native config (SkPMColor). There |
|
236 * are three byte orders supported: native, BGRA, and RGBA. Each has a |
|
237 * premultiplied and unpremultiplied variant. |
|
238 * |
|
239 * Components of a 8888 pixel can be packed/unpacked from a 32bit word using |
|
240 * either byte offsets or shift values. Byte offsets are endian-invariant |
|
241 * while shifts are not. BGRA and RGBA configs are defined by byte |
|
242 * orderings. The native config is defined by shift values (SK_A32_SHIFT, |
|
243 * ..., SK_B32_SHIFT). |
|
244 */ |
|
245 enum Config8888 { |
|
246 /** |
|
247 * Skia's native order specified by: |
|
248 * SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT |
|
249 * |
|
250 * kNative_Premul_Config8888 is equivalent to SkPMColor |
|
251 * kNative_Unpremul_Config8888 has the same component order as SkPMColor |
|
252 * but is not premultiplied. |
|
253 */ |
|
254 kNative_Premul_Config8888, |
|
255 kNative_Unpremul_Config8888, |
|
256 /** |
|
257 * low byte to high byte: B, G, R, A. |
|
258 */ |
|
259 kBGRA_Premul_Config8888, |
|
260 kBGRA_Unpremul_Config8888, |
|
261 /** |
|
262 * low byte to high byte: R, G, B, A. |
|
263 */ |
|
264 kRGBA_Premul_Config8888, |
|
265 kRGBA_Unpremul_Config8888 |
|
266 }; |
|
267 |
|
268 /** |
|
269 * On success (returns true), copy the canvas pixels into the bitmap. |
|
270 * On failure, the bitmap parameter is left unchanged and false is |
|
271 * returned. |
|
272 * |
|
273 * The canvas' pixels are converted to the bitmap's config. The only |
|
274 * supported config is kARGB_8888_Config, though this is likely to be |
|
275 * relaxed in the future. The meaning of config kARGB_8888_Config is |
|
276 * modified by the enum param config8888. The default value interprets |
|
277 * kARGB_8888_Config as SkPMColor |
|
278 * |
|
279 * If the bitmap has pixels already allocated, the canvas pixels will be |
|
280 * written there. If not, bitmap->allocPixels() will be called |
|
281 * automatically. If the bitmap is backed by a texture readPixels will |
|
282 * fail. |
|
283 * |
|
284 * The actual pixels written is the intersection of the canvas' bounds, and |
|
285 * the rectangle formed by the bitmap's width,height and the specified x,y. |
|
286 * If bitmap pixels extend outside of that intersection, they will not be |
|
287 * modified. |
|
288 * |
|
289 * Other failure conditions: |
|
290 * * If the canvas is backed by a non-raster device (e.g. PDF) then |
|
291 * readPixels will fail. |
|
292 * * If bitmap is texture-backed then readPixels will fail. (This may be |
|
293 * relaxed in the future.) |
|
294 * |
|
295 * Example that reads the entire canvas into a bitmap using the native |
|
296 * SkPMColor: |
|
297 * SkISize size = canvas->getDeviceSize(); |
|
298 * bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, |
|
299 * size.fHeight); |
|
300 * if (canvas->readPixels(bitmap, 0, 0)) { |
|
301 * // use the pixels |
|
302 * } |
|
303 */ |
|
304 bool readPixels(SkBitmap* bitmap, |
|
305 int x, int y, |
|
306 Config8888 config8888 = kNative_Premul_Config8888); |
|
307 |
|
308 /** |
|
309 * DEPRECATED: This will be removed as soon as webkit is no longer relying |
|
310 * on it. The bitmap is resized to the intersection of srcRect and the |
|
311 * canvas bounds. New pixels are always allocated on success. Bitmap is |
|
312 * unmodified on failure. |
|
313 */ |
|
314 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); |
|
315 |
|
316 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG |
|
317 /** |
|
318 * DEPRECATED |
|
319 * Similar to draw sprite, this method will copy the pixels in bitmap onto |
|
320 * the canvas, with the top/left corner specified by (x, y). The canvas' |
|
321 * pixel values are completely replaced: there is no blending. |
|
322 * |
|
323 * Currently if bitmap is backed by a texture this is a no-op. This may be |
|
324 * relaxed in the future. |
|
325 * |
|
326 * If the bitmap has config kARGB_8888_Config then the config8888 param |
|
327 * will determines how the pixel valuess are intepreted. If the bitmap is |
|
328 * not kARGB_8888_Config then this parameter is ignored. |
|
329 * |
|
330 * Note: If you are recording drawing commands on this canvas to |
|
331 * SkPicture, writePixels() is ignored! |
|
332 */ |
|
333 void writePixels(const SkBitmap& bitmap, int x, int y, Config8888 config8888); |
|
334 #endif |
|
335 |
|
336 /** |
|
337 * This method affects the pixels in the base-layer, and operates in pixel coordinates, |
|
338 * ignoring the matrix and clip. |
|
339 * |
|
340 * The specified ImageInfo and (x,y) offset specifies a rectangle: target. |
|
341 * |
|
342 * target.setXYWH(x, y, info.width(), info.height()); |
|
343 * |
|
344 * Target is intersected with the bounds of the base-layer. If this intersection is not empty, |
|
345 * then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes |
|
346 * and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src |
|
347 * pixels, performing any colortype/alphatype transformations needed (in the case where the |
|
348 * src and dst have different colortypes or alphatypes). |
|
349 * |
|
350 * This call can fail, returning false, for several reasons: |
|
351 * - If the src colortype/alphatype cannot be converted to the canvas' types |
|
352 * - If this canvas is not backed by pixels (e.g. picture or PDF) |
|
353 */ |
|
354 bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y); |
|
355 |
|
356 /** |
|
357 * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap |
|
358 * is just wrapping a texture, returns false and does nothing. |
|
359 */ |
|
360 bool writePixels(const SkBitmap& bitmap, int x, int y); |
|
361 |
|
362 /////////////////////////////////////////////////////////////////////////// |
|
363 |
|
364 enum SaveFlags { |
|
365 /** save the matrix state, restoring it on restore() */ |
|
366 kMatrix_SaveFlag = 0x01, |
|
367 /** save the clip state, restoring it on restore() */ |
|
368 kClip_SaveFlag = 0x02, |
|
369 /** the layer needs to support per-pixel alpha */ |
|
370 kHasAlphaLayer_SaveFlag = 0x04, |
|
371 /** the layer needs to support 8-bits per color component */ |
|
372 kFullColorLayer_SaveFlag = 0x08, |
|
373 /** |
|
374 * the layer should clip against the bounds argument |
|
375 * |
|
376 * if SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG is undefined, this is treated as always on. |
|
377 */ |
|
378 kClipToLayer_SaveFlag = 0x10, |
|
379 |
|
380 // helper masks for common choices |
|
381 kMatrixClip_SaveFlag = 0x03, |
|
382 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
|
383 kARGB_NoClipLayer_SaveFlag = 0x0F, |
|
384 #endif |
|
385 kARGB_ClipLayer_SaveFlag = 0x1F |
|
386 }; |
|
387 |
|
388 /** This call saves the current matrix, clip, and drawFilter, and pushes a |
|
389 copy onto a private stack. Subsequent calls to translate, scale, |
|
390 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all |
|
391 operate on this copy. |
|
392 When the balancing call to restore() is made, the previous matrix, clip, |
|
393 and drawFilter are restored. |
|
394 @param flags The flags govern what portion of the Matrix/Clip/drawFilter |
|
395 state the save (and matching restore) effect. For example, |
|
396 if only kMatrix is specified, then only the matrix state |
|
397 will be pushed and popped. Likewise for the clip if kClip |
|
398 is specified. However, the drawFilter is always affected |
|
399 by calls to save/restore. |
|
400 @return The value to pass to restoreToCount() to balance this save() |
|
401 */ |
|
402 int save(SaveFlags flags = kMatrixClip_SaveFlag); |
|
403 |
|
404 /** This behaves the same as save(), but in addition it allocates an |
|
405 offscreen bitmap. All drawing calls are directed there, and only when |
|
406 the balancing call to restore() is made is that offscreen transfered to |
|
407 the canvas (or the previous layer). |
|
408 @param bounds (may be null) This rect, if non-null, is used as a hint to |
|
409 limit the size of the offscreen, and thus drawing may be |
|
410 clipped to it, though that clipping is not guaranteed to |
|
411 happen. If exact clipping is desired, use clipRect(). |
|
412 @param paint (may be null) This is copied, and is applied to the |
|
413 offscreen when restore() is called |
|
414 @param flags LayerFlags |
|
415 @return The value to pass to restoreToCount() to balance this save() |
|
416 */ |
|
417 int saveLayer(const SkRect* bounds, const SkPaint* paint, |
|
418 SaveFlags flags = kARGB_ClipLayer_SaveFlag); |
|
419 |
|
420 /** This behaves the same as save(), but in addition it allocates an |
|
421 offscreen bitmap. All drawing calls are directed there, and only when |
|
422 the balancing call to restore() is made is that offscreen transfered to |
|
423 the canvas (or the previous layer). |
|
424 @param bounds (may be null) This rect, if non-null, is used as a hint to |
|
425 limit the size of the offscreen, and thus drawing may be |
|
426 clipped to it, though that clipping is not guaranteed to |
|
427 happen. If exact clipping is desired, use clipRect(). |
|
428 @param alpha This is applied to the offscreen when restore() is called. |
|
429 @param flags LayerFlags |
|
430 @return The value to pass to restoreToCount() to balance this save() |
|
431 */ |
|
432 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, |
|
433 SaveFlags flags = kARGB_ClipLayer_SaveFlag); |
|
434 |
|
435 /** This call balances a previous call to save(), and is used to remove all |
|
436 modifications to the matrix/clip/drawFilter state since the last save |
|
437 call. |
|
438 It is an error to call restore() more times than save() was called. |
|
439 */ |
|
440 void restore(); |
|
441 |
|
442 /** Returns the number of matrix/clip states on the SkCanvas' private stack. |
|
443 This will equal # save() calls - # restore() calls + 1. The save count on |
|
444 a new canvas is 1. |
|
445 */ |
|
446 int getSaveCount() const; |
|
447 |
|
448 /** Efficient way to pop any calls to save() that happened after the save |
|
449 count reached saveCount. It is an error for saveCount to be greater than |
|
450 getSaveCount(). To pop all the way back to the initial matrix/clip context |
|
451 pass saveCount == 1. |
|
452 @param saveCount The number of save() levels to restore from |
|
453 */ |
|
454 void restoreToCount(int saveCount); |
|
455 |
|
456 /** Returns true if drawing is currently going to a layer (from saveLayer) |
|
457 * rather than to the root device. |
|
458 */ |
|
459 virtual bool isDrawingToLayer() const; |
|
460 |
|
461 /** Preconcat the current matrix with the specified translation |
|
462 @param dx The distance to translate in X |
|
463 @param dy The distance to translate in Y |
|
464 returns true if the operation succeeded (e.g. did not overflow) |
|
465 */ |
|
466 bool translate(SkScalar dx, SkScalar dy); |
|
467 |
|
468 /** Preconcat the current matrix with the specified scale. |
|
469 @param sx The amount to scale in X |
|
470 @param sy The amount to scale in Y |
|
471 returns true if the operation succeeded (e.g. did not overflow) |
|
472 */ |
|
473 bool scale(SkScalar sx, SkScalar sy); |
|
474 |
|
475 /** Preconcat the current matrix with the specified rotation. |
|
476 @param degrees The amount to rotate, in degrees |
|
477 returns true if the operation succeeded (e.g. did not overflow) |
|
478 */ |
|
479 bool rotate(SkScalar degrees); |
|
480 |
|
481 /** Preconcat the current matrix with the specified skew. |
|
482 @param sx The amount to skew in X |
|
483 @param sy The amount to skew in Y |
|
484 returns true if the operation succeeded (e.g. did not overflow) |
|
485 */ |
|
486 bool skew(SkScalar sx, SkScalar sy); |
|
487 |
|
488 /** Preconcat the current matrix with the specified matrix. |
|
489 @param matrix The matrix to preconcatenate with the current matrix |
|
490 @return true if the operation succeeded (e.g. did not overflow) |
|
491 */ |
|
492 bool concat(const SkMatrix& matrix); |
|
493 |
|
494 /** Replace the current matrix with a copy of the specified matrix. |
|
495 @param matrix The matrix that will be copied into the current matrix. |
|
496 */ |
|
497 void setMatrix(const SkMatrix& matrix); |
|
498 |
|
499 /** Helper for setMatrix(identity). Sets the current matrix to identity. |
|
500 */ |
|
501 void resetMatrix(); |
|
502 |
|
503 /** |
|
504 * Modify the current clip with the specified rectangle. |
|
505 * @param rect The rect to combine with the current clip |
|
506 * @param op The region op to apply to the current clip |
|
507 * @param doAntiAlias true if the clip should be antialiased |
|
508 */ |
|
509 void clipRect(const SkRect& rect, |
|
510 SkRegion::Op op = SkRegion::kIntersect_Op, |
|
511 bool doAntiAlias = false); |
|
512 |
|
513 /** |
|
514 * Modify the current clip with the specified SkRRect. |
|
515 * @param rrect The rrect to combine with the current clip |
|
516 * @param op The region op to apply to the current clip |
|
517 * @param doAntiAlias true if the clip should be antialiased |
|
518 */ |
|
519 void clipRRect(const SkRRect& rrect, |
|
520 SkRegion::Op op = SkRegion::kIntersect_Op, |
|
521 bool doAntiAlias = false); |
|
522 |
|
523 /** |
|
524 * Modify the current clip with the specified path. |
|
525 * @param path The path to combine with the current clip |
|
526 * @param op The region op to apply to the current clip |
|
527 * @param doAntiAlias true if the clip should be antialiased |
|
528 */ |
|
529 void clipPath(const SkPath& path, |
|
530 SkRegion::Op op = SkRegion::kIntersect_Op, |
|
531 bool doAntiAlias = false); |
|
532 |
|
533 /** EXPERIMENTAL -- only used for testing |
|
534 Set to false to force clips to be hard, even if doAntiAlias=true is |
|
535 passed to clipRect or clipPath. |
|
536 */ |
|
537 void setAllowSoftClip(bool allow) { |
|
538 fAllowSoftClip = allow; |
|
539 } |
|
540 |
|
541 /** EXPERIMENTAL -- only used for testing |
|
542 Set to simplify clip stack using path ops. |
|
543 */ |
|
544 void setAllowSimplifyClip(bool allow) { |
|
545 fAllowSimplifyClip = allow; |
|
546 } |
|
547 |
|
548 /** Modify the current clip with the specified region. Note that unlike |
|
549 clipRect() and clipPath() which transform their arguments by the current |
|
550 matrix, clipRegion() assumes its argument is already in device |
|
551 coordinates, and so no transformation is performed. |
|
552 @param deviceRgn The region to apply to the current clip |
|
553 @param op The region op to apply to the current clip |
|
554 */ |
|
555 void clipRegion(const SkRegion& deviceRgn, |
|
556 SkRegion::Op op = SkRegion::kIntersect_Op); |
|
557 |
|
558 /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the |
|
559 specified region. This does not intersect or in any other way account |
|
560 for the existing clip region. |
|
561 @param deviceRgn The region to copy into the current clip. |
|
562 */ |
|
563 void setClipRegion(const SkRegion& deviceRgn) { |
|
564 this->clipRegion(deviceRgn, SkRegion::kReplace_Op); |
|
565 } |
|
566 |
|
567 /** Return true if the specified rectangle, after being transformed by the |
|
568 current matrix, would lie completely outside of the current clip. Call |
|
569 this to check if an area you intend to draw into is clipped out (and |
|
570 therefore you can skip making the draw calls). |
|
571 @param rect the rect to compare with the current clip |
|
572 @return true if the rect (transformed by the canvas' matrix) does not |
|
573 intersect with the canvas' clip |
|
574 */ |
|
575 bool quickReject(const SkRect& rect) const; |
|
576 |
|
577 /** Return true if the specified path, after being transformed by the |
|
578 current matrix, would lie completely outside of the current clip. Call |
|
579 this to check if an area you intend to draw into is clipped out (and |
|
580 therefore you can skip making the draw calls). Note, for speed it may |
|
581 return false even if the path itself might not intersect the clip |
|
582 (i.e. the bounds of the path intersects, but the path does not). |
|
583 @param path The path to compare with the current clip |
|
584 @return true if the path (transformed by the canvas' matrix) does not |
|
585 intersect with the canvas' clip |
|
586 */ |
|
587 bool quickReject(const SkPath& path) const; |
|
588 |
|
589 /** Return true if the horizontal band specified by top and bottom is |
|
590 completely clipped out. This is a conservative calculation, meaning |
|
591 that it is possible that if the method returns false, the band may still |
|
592 in fact be clipped out, but the converse is not true. If this method |
|
593 returns true, then the band is guaranteed to be clipped out. |
|
594 @param top The top of the horizontal band to compare with the clip |
|
595 @param bottom The bottom of the horizontal and to compare with the clip |
|
596 @return true if the horizontal band is completely clipped out (i.e. does |
|
597 not intersect the current clip) |
|
598 */ |
|
599 bool quickRejectY(SkScalar top, SkScalar bottom) const { |
|
600 SkASSERT(top <= bottom); |
|
601 |
|
602 #ifndef SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT |
|
603 // TODO: add a hasPerspective method similar to getLocalClipBounds. This |
|
604 // would cache the SkMatrix::hasPerspective result. Alternatively, have |
|
605 // the MC stack just set a hasPerspective boolean as it is updated. |
|
606 if (this->getTotalMatrix().hasPerspective()) { |
|
607 // TODO: consider implementing some half-plane test between the |
|
608 // two Y planes and the device-bounds (i.e., project the top and |
|
609 // bottom Y planes and then determine if the clip bounds is completely |
|
610 // outside either one). |
|
611 return false; |
|
612 } |
|
613 #endif |
|
614 |
|
615 const SkRect& clipR = this->getLocalClipBounds(); |
|
616 // In the case where the clip is empty and we are provided with a |
|
617 // negative top and positive bottom parameter then this test will return |
|
618 // false even though it will be clipped. We have chosen to exclude that |
|
619 // check as it is rare and would result double the comparisons. |
|
620 return top >= clipR.fBottom || bottom <= clipR.fTop; |
|
621 } |
|
622 |
|
623 /** Return the bounds of the current clip (in local coordinates) in the |
|
624 bounds parameter, and return true if it is non-empty. This can be useful |
|
625 in a way similar to quickReject, in that it tells you that drawing |
|
626 outside of these bounds will be clipped out. |
|
627 */ |
|
628 virtual bool getClipBounds(SkRect* bounds) const; |
|
629 |
|
630 /** Return the bounds of the current clip, in device coordinates; returns |
|
631 true if non-empty. Maybe faster than getting the clip explicitly and |
|
632 then taking its bounds. |
|
633 */ |
|
634 virtual bool getClipDeviceBounds(SkIRect* bounds) const; |
|
635 |
|
636 |
|
637 /** Fill the entire canvas' bitmap (restricted to the current clip) with the |
|
638 specified ARGB color, using the specified mode. |
|
639 @param a the alpha component (0..255) of the color to fill the canvas |
|
640 @param r the red component (0..255) of the color to fill the canvas |
|
641 @param g the green component (0..255) of the color to fill the canvas |
|
642 @param b the blue component (0..255) of the color to fill the canvas |
|
643 @param mode the mode to apply the color in (defaults to SrcOver) |
|
644 */ |
|
645 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, |
|
646 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); |
|
647 |
|
648 /** Fill the entire canvas' bitmap (restricted to the current clip) with the |
|
649 specified color and mode. |
|
650 @param color the color to draw with |
|
651 @param mode the mode to apply the color in (defaults to SrcOver) |
|
652 */ |
|
653 void drawColor(SkColor color, |
|
654 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); |
|
655 |
|
656 /** |
|
657 * This erases the entire drawing surface to the specified color, |
|
658 * irrespective of the clip. It does not blend with the previous pixels, |
|
659 * but always overwrites them. |
|
660 * |
|
661 * It is roughly equivalent to the following: |
|
662 * canvas.save(); |
|
663 * canvas.clipRect(hugeRect, kReplace_Op); |
|
664 * paint.setColor(color); |
|
665 * paint.setXfermodeMode(kSrc_Mode); |
|
666 * canvas.drawPaint(paint); |
|
667 * canvas.restore(); |
|
668 * though it is almost always much more efficient. |
|
669 */ |
|
670 virtual void clear(SkColor); |
|
671 |
|
672 /** |
|
673 * Fill the entire canvas' bitmap (restricted to the current clip) with the |
|
674 * specified paint. |
|
675 * @param paint The paint used to fill the canvas |
|
676 */ |
|
677 virtual void drawPaint(const SkPaint& paint); |
|
678 |
|
679 enum PointMode { |
|
680 /** drawPoints draws each point separately */ |
|
681 kPoints_PointMode, |
|
682 /** drawPoints draws each pair of points as a line segment */ |
|
683 kLines_PointMode, |
|
684 /** drawPoints draws the array of points as a polygon */ |
|
685 kPolygon_PointMode |
|
686 }; |
|
687 |
|
688 /** Draw a series of points, interpreted based on the PointMode mode. For |
|
689 all modes, the count parameter is interpreted as the total number of |
|
690 points. For kLine mode, count/2 line segments are drawn. |
|
691 For kPoint mode, each point is drawn centered at its coordinate, and its |
|
692 size is specified by the paint's stroke-width. It draws as a square, |
|
693 unless the paint's cap-type is round, in which the points are drawn as |
|
694 circles. |
|
695 For kLine mode, each pair of points is drawn as a line segment, |
|
696 respecting the paint's settings for cap/join/width. |
|
697 For kPolygon mode, the entire array is drawn as a series of connected |
|
698 line segments. |
|
699 Note that, while similar, kLine and kPolygon modes draw slightly |
|
700 differently than the equivalent path built with a series of moveto, |
|
701 lineto calls, in that the path will draw all of its contours at once, |
|
702 with no interactions if contours intersect each other (think XOR |
|
703 xfermode). drawPoints always draws each element one at a time. |
|
704 @param mode PointMode specifying how to draw the array of points. |
|
705 @param count The number of points in the array |
|
706 @param pts Array of points to draw |
|
707 @param paint The paint used to draw the points |
|
708 */ |
|
709 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], |
|
710 const SkPaint& paint); |
|
711 |
|
712 /** Helper method for drawing a single point. See drawPoints() for a more |
|
713 details. |
|
714 */ |
|
715 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint); |
|
716 |
|
717 /** Draws a single pixel in the specified color. |
|
718 @param x The X coordinate of which pixel to draw |
|
719 @param y The Y coordiante of which pixel to draw |
|
720 @param color The color to draw |
|
721 */ |
|
722 void drawPoint(SkScalar x, SkScalar y, SkColor color); |
|
723 |
|
724 /** Draw a line segment with the specified start and stop x,y coordinates, |
|
725 using the specified paint. NOTE: since a line is always "framed", the |
|
726 paint's Style is ignored. |
|
727 @param x0 The x-coordinate of the start point of the line |
|
728 @param y0 The y-coordinate of the start point of the line |
|
729 @param x1 The x-coordinate of the end point of the line |
|
730 @param y1 The y-coordinate of the end point of the line |
|
731 @param paint The paint used to draw the line |
|
732 */ |
|
733 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, |
|
734 const SkPaint& paint); |
|
735 |
|
736 /** Draw the specified rectangle using the specified paint. The rectangle |
|
737 will be filled or stroked based on the Style in the paint. |
|
738 @param rect The rect to be drawn |
|
739 @param paint The paint used to draw the rect |
|
740 */ |
|
741 virtual void drawRect(const SkRect& rect, const SkPaint& paint); |
|
742 |
|
743 /** Draw the specified rectangle using the specified paint. The rectangle |
|
744 will be filled or framed based on the Style in the paint. |
|
745 @param rect The rect to be drawn |
|
746 @param paint The paint used to draw the rect |
|
747 */ |
|
748 void drawIRect(const SkIRect& rect, const SkPaint& paint) { |
|
749 SkRect r; |
|
750 r.set(rect); // promotes the ints to scalars |
|
751 this->drawRect(r, paint); |
|
752 } |
|
753 |
|
754 /** Draw the specified rectangle using the specified paint. The rectangle |
|
755 will be filled or framed based on the Style in the paint. |
|
756 @param left The left side of the rectangle to be drawn |
|
757 @param top The top side of the rectangle to be drawn |
|
758 @param right The right side of the rectangle to be drawn |
|
759 @param bottom The bottom side of the rectangle to be drawn |
|
760 @param paint The paint used to draw the rect |
|
761 */ |
|
762 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right, |
|
763 SkScalar bottom, const SkPaint& paint); |
|
764 |
|
765 /** Draw the specified oval using the specified paint. The oval will be |
|
766 filled or framed based on the Style in the paint. |
|
767 @param oval The rectangle bounds of the oval to be drawn |
|
768 @param paint The paint used to draw the oval |
|
769 */ |
|
770 virtual void drawOval(const SkRect& oval, const SkPaint&); |
|
771 |
|
772 /** |
|
773 * Draw the specified RRect using the specified paint The rrect will be filled or stroked |
|
774 * based on the Style in the paint. |
|
775 * |
|
776 * @param rrect The round-rect to draw |
|
777 * @param paint The paint used to draw the round-rect |
|
778 */ |
|
779 virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint); |
|
780 |
|
781 /** |
|
782 * Draw the annulus formed by the outer and inner rrects. The results |
|
783 * are undefined if the outer does not contain the inner. |
|
784 */ |
|
785 void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&); |
|
786 |
|
787 /** Draw the specified circle using the specified paint. If radius is <= 0, |
|
788 then nothing will be drawn. The circle will be filled |
|
789 or framed based on the Style in the paint. |
|
790 @param cx The x-coordinate of the center of the cirle to be drawn |
|
791 @param cy The y-coordinate of the center of the cirle to be drawn |
|
792 @param radius The radius of the cirle to be drawn |
|
793 @param paint The paint used to draw the circle |
|
794 */ |
|
795 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, |
|
796 const SkPaint& paint); |
|
797 |
|
798 /** Draw the specified arc, which will be scaled to fit inside the |
|
799 specified oval. If the sweep angle is >= 360, then the oval is drawn |
|
800 completely. Note that this differs slightly from SkPath::arcTo, which |
|
801 treats the sweep angle mod 360. |
|
802 @param oval The bounds of oval used to define the shape of the arc |
|
803 @param startAngle Starting angle (in degrees) where the arc begins |
|
804 @param sweepAngle Sweep angle (in degrees) measured clockwise |
|
805 @param useCenter true means include the center of the oval. For filling |
|
806 this will draw a wedge. False means just use the arc. |
|
807 @param paint The paint used to draw the arc |
|
808 */ |
|
809 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, |
|
810 bool useCenter, const SkPaint& paint); |
|
811 |
|
812 /** Draw the specified round-rect using the specified paint. The round-rect |
|
813 will be filled or framed based on the Style in the paint. |
|
814 @param rect The rectangular bounds of the roundRect to be drawn |
|
815 @param rx The x-radius of the oval used to round the corners |
|
816 @param ry The y-radius of the oval used to round the corners |
|
817 @param paint The paint used to draw the roundRect |
|
818 */ |
|
819 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, |
|
820 const SkPaint& paint); |
|
821 |
|
822 /** Draw the specified path using the specified paint. The path will be |
|
823 filled or framed based on the Style in the paint. |
|
824 @param path The path to be drawn |
|
825 @param paint The paint used to draw the path |
|
826 */ |
|
827 virtual void drawPath(const SkPath& path, const SkPaint& paint); |
|
828 |
|
829 /** Draw the specified bitmap, with its top/left corner at (x,y), using the |
|
830 specified paint, transformed by the current matrix. Note: if the paint |
|
831 contains a maskfilter that generates a mask which extends beyond the |
|
832 bitmap's original width/height, then the bitmap will be drawn as if it |
|
833 were in a Shader with CLAMP mode. Thus the color outside of the original |
|
834 width/height will be the edge color replicated. |
|
835 |
|
836 If a shader is present on the paint it will be ignored, except in the |
|
837 case where the bitmap is kA8_Config. In that case, the color is |
|
838 generated by the shader. |
|
839 |
|
840 @param bitmap The bitmap to be drawn |
|
841 @param left The position of the left side of the bitmap being drawn |
|
842 @param top The position of the top side of the bitmap being drawn |
|
843 @param paint The paint used to draw the bitmap, or NULL |
|
844 */ |
|
845 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, |
|
846 const SkPaint* paint = NULL); |
|
847 |
|
848 enum DrawBitmapRectFlags { |
|
849 kNone_DrawBitmapRectFlag = 0x0, |
|
850 /** |
|
851 * When filtering is enabled, allow the color samples outside of |
|
852 * the src rect (but still in the src bitmap) to bleed into the |
|
853 * drawn portion |
|
854 */ |
|
855 kBleed_DrawBitmapRectFlag = 0x1, |
|
856 }; |
|
857 |
|
858 /** Draw the specified bitmap, with the specified matrix applied (before the |
|
859 canvas' matrix is applied). |
|
860 @param bitmap The bitmap to be drawn |
|
861 @param src Optional: specify the subset of the bitmap to be drawn |
|
862 @param dst The destination rectangle where the scaled/translated |
|
863 image will be drawn |
|
864 @param paint The paint used to draw the bitmap, or NULL |
|
865 */ |
|
866 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, |
|
867 const SkRect& dst, |
|
868 const SkPaint* paint = NULL, |
|
869 DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag); |
|
870 |
|
871 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, |
|
872 const SkPaint* paint = NULL) { |
|
873 this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag); |
|
874 } |
|
875 |
|
876 void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc, |
|
877 const SkRect& dst, const SkPaint* paint = NULL, |
|
878 DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) { |
|
879 SkRect realSrcStorage; |
|
880 SkRect* realSrcPtr = NULL; |
|
881 if (isrc) { |
|
882 realSrcStorage.set(*isrc); |
|
883 realSrcPtr = &realSrcStorage; |
|
884 } |
|
885 this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags); |
|
886 } |
|
887 |
|
888 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, |
|
889 const SkPaint* paint = NULL); |
|
890 |
|
891 /** |
|
892 * Draw the bitmap stretched differentially to fit into dst. |
|
893 * center is a rect within the bitmap, and logically divides the bitmap |
|
894 * into 9 sections (3x3). For example, if the middle pixel of a [5x5] |
|
895 * bitmap is the "center", then the center-rect should be [2, 2, 3, 3]. |
|
896 * |
|
897 * If the dst is >= the bitmap size, then... |
|
898 * - The 4 corners are not stretched at all. |
|
899 * - The sides are stretched in only one axis. |
|
900 * - The center is stretched in both axes. |
|
901 * Else, for each axis where dst < bitmap, |
|
902 * - The corners shrink proportionally |
|
903 * - The sides (along the shrink axis) and center are not drawn |
|
904 */ |
|
905 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, |
|
906 const SkRect& dst, const SkPaint* paint = NULL); |
|
907 |
|
908 /** Draw the specified bitmap, with its top/left corner at (x,y), |
|
909 NOT transformed by the current matrix. Note: if the paint |
|
910 contains a maskfilter that generates a mask which extends beyond the |
|
911 bitmap's original width/height, then the bitmap will be drawn as if it |
|
912 were in a Shader with CLAMP mode. Thus the color outside of the original |
|
913 width/height will be the edge color replicated. |
|
914 @param bitmap The bitmap to be drawn |
|
915 @param left The position of the left side of the bitmap being drawn |
|
916 @param top The position of the top side of the bitmap being drawn |
|
917 @param paint The paint used to draw the bitmap, or NULL |
|
918 */ |
|
919 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, |
|
920 const SkPaint* paint = NULL); |
|
921 |
|
922 /** Draw the text, with origin at (x,y), using the specified paint. |
|
923 The origin is interpreted based on the Align setting in the paint. |
|
924 @param text The text to be drawn |
|
925 @param byteLength The number of bytes to read from the text parameter |
|
926 @param x The x-coordinate of the origin of the text being drawn |
|
927 @param y The y-coordinate of the origin of the text being drawn |
|
928 @param paint The paint used for the text (e.g. color, size, style) |
|
929 */ |
|
930 virtual void drawText(const void* text, size_t byteLength, SkScalar x, |
|
931 SkScalar y, const SkPaint& paint); |
|
932 |
|
933 /** Draw the text, with each character/glyph origin specified by the pos[] |
|
934 array. The origin is interpreted by the Align setting in the paint. |
|
935 @param text The text to be drawn |
|
936 @param byteLength The number of bytes to read from the text parameter |
|
937 @param pos Array of positions, used to position each character |
|
938 @param paint The paint used for the text (e.g. color, size, style) |
|
939 */ |
|
940 virtual void drawPosText(const void* text, size_t byteLength, |
|
941 const SkPoint pos[], const SkPaint& paint); |
|
942 |
|
943 /** Draw the text, with each character/glyph origin specified by the x |
|
944 coordinate taken from the xpos[] array, and the y from the constY param. |
|
945 The origin is interpreted by the Align setting in the paint. |
|
946 @param text The text to be drawn |
|
947 @param byteLength The number of bytes to read from the text parameter |
|
948 @param xpos Array of x-positions, used to position each character |
|
949 @param constY The shared Y coordinate for all of the positions |
|
950 @param paint The paint used for the text (e.g. color, size, style) |
|
951 */ |
|
952 virtual void drawPosTextH(const void* text, size_t byteLength, |
|
953 const SkScalar xpos[], SkScalar constY, |
|
954 const SkPaint& paint); |
|
955 |
|
956 /** Draw the text, with origin at (x,y), using the specified paint, along |
|
957 the specified path. The paint's Align setting determins where along the |
|
958 path to start the text. |
|
959 @param text The text to be drawn |
|
960 @param byteLength The number of bytes to read from the text parameter |
|
961 @param path The path the text should follow for its baseline |
|
962 @param hOffset The distance along the path to add to the text's |
|
963 starting position |
|
964 @param vOffset The distance above(-) or below(+) the path to |
|
965 position the text |
|
966 @param paint The paint used for the text |
|
967 */ |
|
968 void drawTextOnPathHV(const void* text, size_t byteLength, |
|
969 const SkPath& path, SkScalar hOffset, |
|
970 SkScalar vOffset, const SkPaint& paint); |
|
971 |
|
972 /** Draw the text, with origin at (x,y), using the specified paint, along |
|
973 the specified path. The paint's Align setting determins where along the |
|
974 path to start the text. |
|
975 @param text The text to be drawn |
|
976 @param byteLength The number of bytes to read from the text parameter |
|
977 @param path The path the text should follow for its baseline |
|
978 @param matrix (may be null) Applied to the text before it is |
|
979 mapped onto the path |
|
980 @param paint The paint used for the text |
|
981 */ |
|
982 virtual void drawTextOnPath(const void* text, size_t byteLength, |
|
983 const SkPath& path, const SkMatrix* matrix, |
|
984 const SkPaint& paint); |
|
985 |
|
986 /** PRIVATE / EXPERIMENTAL -- do not call |
|
987 Perform back-end analysis/optimization of a picture. This may attach |
|
988 optimization data to the picture which can be used by a later |
|
989 drawPicture call. |
|
990 @param picture The recorded drawing commands to analyze/optimize |
|
991 */ |
|
992 void EXPERIMENTAL_optimize(SkPicture* picture); |
|
993 |
|
994 /** Draw the picture into this canvas. This method effective brackets the |
|
995 playback of the picture's draw calls with save/restore, so the state |
|
996 of this canvas will be unchanged after this call. |
|
997 @param picture The recorded drawing commands to playback into this |
|
998 canvas. |
|
999 */ |
|
1000 virtual void drawPicture(SkPicture& picture); |
|
1001 |
|
1002 enum VertexMode { |
|
1003 kTriangles_VertexMode, |
|
1004 kTriangleStrip_VertexMode, |
|
1005 kTriangleFan_VertexMode |
|
1006 }; |
|
1007 |
|
1008 /** Draw the array of vertices, interpreted as triangles (based on mode). |
|
1009 @param vmode How to interpret the array of vertices |
|
1010 @param vertexCount The number of points in the vertices array (and |
|
1011 corresponding texs and colors arrays if non-null) |
|
1012 @param vertices Array of vertices for the mesh |
|
1013 @param texs May be null. If not null, specifies the coordinate |
|
1014 in _texture_ space (not uv space) for each vertex. |
|
1015 @param colors May be null. If not null, specifies a color for each |
|
1016 vertex, to be interpolated across the triangle. |
|
1017 @param xmode Used if both texs and colors are present. In this |
|
1018 case the colors are combined with the texture using mode, |
|
1019 before being drawn using the paint. If mode is null, then |
|
1020 kModulate_Mode is used. |
|
1021 @param indices If not null, array of indices to reference into the |
|
1022 vertex (texs, colors) array. |
|
1023 @param indexCount number of entries in the indices array (if not null) |
|
1024 @param paint Specifies the shader/texture if present. |
|
1025 */ |
|
1026 virtual void drawVertices(VertexMode vmode, int vertexCount, |
|
1027 const SkPoint vertices[], const SkPoint texs[], |
|
1028 const SkColor colors[], SkXfermode* xmode, |
|
1029 const uint16_t indices[], int indexCount, |
|
1030 const SkPaint& paint); |
|
1031 |
|
1032 /** Send a blob of data to the canvas. |
|
1033 For canvases that draw, this call is effectively a no-op, as the data |
|
1034 is not parsed, but just ignored. However, this call exists for |
|
1035 subclasses like SkPicture's recording canvas, that can store the data |
|
1036 and then play it back later (via another call to drawData). |
|
1037 */ |
|
1038 virtual void drawData(const void* data, size_t length) { |
|
1039 // do nothing. Subclasses may do something with the data |
|
1040 } |
|
1041 |
|
1042 /** Add comments. beginCommentGroup/endCommentGroup open/close a new group. |
|
1043 Each comment added via addComment is notionally attached to its |
|
1044 enclosing group. Top-level comments simply belong to no group. |
|
1045 */ |
|
1046 virtual void beginCommentGroup(const char* description) { |
|
1047 // do nothing. Subclasses may do something |
|
1048 } |
|
1049 virtual void addComment(const char* kywd, const char* value) { |
|
1050 // do nothing. Subclasses may do something |
|
1051 } |
|
1052 virtual void endCommentGroup() { |
|
1053 // do nothing. Subclasses may do something |
|
1054 } |
|
1055 |
|
1056 /** |
|
1057 * With this call the client asserts that subsequent draw operations (up to the |
|
1058 * matching popCull()) are fully contained within the given bounding box. The assertion |
|
1059 * is not enforced, but the information might be used to quick-reject command blocks, |
|
1060 * so an incorrect bounding box may result in incomplete rendering. |
|
1061 */ |
|
1062 void pushCull(const SkRect& cullRect) { |
|
1063 ++fCullCount; |
|
1064 this->onPushCull(cullRect); |
|
1065 } |
|
1066 |
|
1067 /** |
|
1068 * Terminates the current culling block, and restores the previous one (if any). |
|
1069 */ |
|
1070 void popCull() { |
|
1071 if (fCullCount > 0) { |
|
1072 --fCullCount; |
|
1073 this->onPopCull(); |
|
1074 } |
|
1075 } |
|
1076 ////////////////////////////////////////////////////////////////////////// |
|
1077 |
|
1078 /** Get the current bounder object. |
|
1079 The bounder's reference count is unchaged. |
|
1080 @return the canva's bounder (or NULL). |
|
1081 */ |
|
1082 SkBounder* getBounder() const { return fBounder; } |
|
1083 |
|
1084 /** Set a new bounder (or NULL). |
|
1085 Pass NULL to clear any previous bounder. |
|
1086 As a convenience, the parameter passed is also returned. |
|
1087 If a previous bounder exists, its reference count is decremented. |
|
1088 If bounder is not NULL, its reference count is incremented. |
|
1089 @param bounder the new bounder (or NULL) to be installed in the canvas |
|
1090 @return the set bounder object |
|
1091 */ |
|
1092 virtual SkBounder* setBounder(SkBounder* bounder); |
|
1093 |
|
1094 /** Get the current filter object. The filter's reference count is not |
|
1095 affected. The filter is saved/restored, just like the matrix and clip. |
|
1096 @return the canvas' filter (or NULL). |
|
1097 */ |
|
1098 SkDrawFilter* getDrawFilter() const; |
|
1099 |
|
1100 /** Set the new filter (or NULL). Pass NULL to clear any existing filter. |
|
1101 As a convenience, the parameter is returned. If an existing filter |
|
1102 exists, its refcnt is decrement. If the new filter is not null, its |
|
1103 refcnt is incremented. The filter is saved/restored, just like the |
|
1104 matrix and clip. |
|
1105 @param filter the new filter (or NULL) |
|
1106 @return the new filter |
|
1107 */ |
|
1108 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); |
|
1109 |
|
1110 ////////////////////////////////////////////////////////////////////////// |
|
1111 |
|
1112 /** |
|
1113 * Return true if the current clip is empty (i.e. nothing will draw). |
|
1114 * Note: this is not always a free call, so it should not be used |
|
1115 * more often than necessary. However, once the canvas has computed this |
|
1116 * result, subsequent calls will be cheap (until the clip state changes, |
|
1117 * which can happen on any clip..() or restore() call. |
|
1118 */ |
|
1119 virtual bool isClipEmpty() const; |
|
1120 |
|
1121 /** |
|
1122 * Returns true if the current clip is just a (non-empty) rectangle. |
|
1123 * Returns false if the clip is empty, or if it is complex. |
|
1124 */ |
|
1125 virtual bool isClipRect() const; |
|
1126 |
|
1127 /** Return the current matrix on the canvas. |
|
1128 This does not account for the translate in any of the devices. |
|
1129 @return The current matrix on the canvas. |
|
1130 */ |
|
1131 const SkMatrix& getTotalMatrix() const; |
|
1132 |
|
1133 #ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE |
|
1134 enum ClipType { |
|
1135 kEmpty_ClipType = 0, |
|
1136 kRect_ClipType, |
|
1137 kComplex_ClipType |
|
1138 }; |
|
1139 /** Returns a description of the total clip; may be cheaper than |
|
1140 getting the clip and querying it directly. |
|
1141 */ |
|
1142 virtual ClipType getClipType() const; |
|
1143 #endif |
|
1144 |
|
1145 #ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP |
|
1146 /** DEPRECATED -- need to move this guy to private/friend |
|
1147 * Return the current device clip (concatenation of all clip calls). |
|
1148 * This does not account for the translate in any of the devices. |
|
1149 * @return the current device clip (concatenation of all clip calls). |
|
1150 */ |
|
1151 const SkRegion& getTotalClip() const; |
|
1152 #endif |
|
1153 |
|
1154 /** Return the clip stack. The clip stack stores all the individual |
|
1155 * clips organized by the save/restore frame in which they were |
|
1156 * added. |
|
1157 * @return the current clip stack ("list" of individual clip elements) |
|
1158 */ |
|
1159 const SkClipStack* getClipStack() const { |
|
1160 return &fClipStack; |
|
1161 } |
|
1162 |
|
1163 class ClipVisitor { |
|
1164 public: |
|
1165 virtual ~ClipVisitor(); |
|
1166 virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0; |
|
1167 virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0; |
|
1168 virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0; |
|
1169 }; |
|
1170 |
|
1171 /** |
|
1172 * Replays the clip operations, back to front, that have been applied to |
|
1173 * the canvas, calling the appropriate method on the visitor for each |
|
1174 * clip. All clips have already been transformed into device space. |
|
1175 */ |
|
1176 void replayClips(ClipVisitor*) const; |
|
1177 |
|
1178 /////////////////////////////////////////////////////////////////////////// |
|
1179 |
|
1180 /** After calling saveLayer(), there can be any number of devices that make |
|
1181 up the top-most drawing area. LayerIter can be used to iterate through |
|
1182 those devices. Note that the iterator is only valid until the next API |
|
1183 call made on the canvas. Ownership of all pointers in the iterator stays |
|
1184 with the canvas, so none of them should be modified or deleted. |
|
1185 */ |
|
1186 class SK_API LayerIter /*: SkNoncopyable*/ { |
|
1187 public: |
|
1188 /** Initialize iterator with canvas, and set values for 1st device */ |
|
1189 LayerIter(SkCanvas*, bool skipEmptyClips); |
|
1190 ~LayerIter(); |
|
1191 |
|
1192 /** Return true if the iterator is done */ |
|
1193 bool done() const { return fDone; } |
|
1194 /** Cycle to the next device */ |
|
1195 void next(); |
|
1196 |
|
1197 // These reflect the current device in the iterator |
|
1198 |
|
1199 SkBaseDevice* device() const; |
|
1200 const SkMatrix& matrix() const; |
|
1201 const SkRegion& clip() const; |
|
1202 const SkPaint& paint() const; |
|
1203 int x() const; |
|
1204 int y() const; |
|
1205 |
|
1206 private: |
|
1207 // used to embed the SkDrawIter object directly in our instance, w/o |
|
1208 // having to expose that class def to the public. There is an assert |
|
1209 // in our constructor to ensure that fStorage is large enough |
|
1210 // (though needs to be a compile-time-assert!). We use intptr_t to work |
|
1211 // safely with 32 and 64 bit machines (to ensure the storage is enough) |
|
1212 intptr_t fStorage[32]; |
|
1213 class SkDrawIter* fImpl; // this points at fStorage |
|
1214 SkPaint fDefaultPaint; |
|
1215 bool fDone; |
|
1216 }; |
|
1217 |
|
1218 // don't call |
|
1219 const SkRegion& internal_private_getTotalClip() const; |
|
1220 // don't call |
|
1221 void internal_private_getTotalClipAsPath(SkPath*) const; |
|
1222 // don't call |
|
1223 GrRenderTarget* internal_private_accessTopLayerRenderTarget(); |
|
1224 |
|
1225 protected: |
|
1226 // default impl defers to getDevice()->newSurface(info) |
|
1227 virtual SkSurface* onNewSurface(const SkImageInfo&); |
|
1228 |
|
1229 // default impl defers to its device |
|
1230 virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes); |
|
1231 virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes); |
|
1232 |
|
1233 // Subclass save/restore notifiers. |
|
1234 // Overriders should call the corresponding INHERITED method up the inheritance chain. |
|
1235 // willSaveLayer()'s return value may suppress full layer allocation. |
|
1236 enum SaveLayerStrategy { |
|
1237 kFullLayer_SaveLayerStrategy, |
|
1238 kNoLayer_SaveLayerStrategy |
|
1239 }; |
|
1240 virtual void willSave(SaveFlags); |
|
1241 virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags); |
|
1242 virtual void willRestore(); |
|
1243 |
|
1244 virtual void didTranslate(SkScalar, SkScalar); |
|
1245 virtual void didScale(SkScalar, SkScalar); |
|
1246 virtual void didRotate(SkScalar); |
|
1247 virtual void didSkew(SkScalar, SkScalar); |
|
1248 virtual void didConcat(const SkMatrix&); |
|
1249 virtual void didSetMatrix(const SkMatrix&); |
|
1250 |
|
1251 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); |
|
1252 |
|
1253 enum ClipEdgeStyle { |
|
1254 kHard_ClipEdgeStyle, |
|
1255 kSoft_ClipEdgeStyle |
|
1256 }; |
|
1257 |
|
1258 virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle); |
|
1259 virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle); |
|
1260 virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle); |
|
1261 virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op); |
|
1262 |
|
1263 // Returns the canvas to be used by DrawIter. Default implementation |
|
1264 // returns this. Subclasses that encapsulate an indirect canvas may |
|
1265 // need to overload this method. The impl must keep track of this, as it |
|
1266 // is not released or deleted by the caller. |
|
1267 virtual SkCanvas* canvasForDrawIter(); |
|
1268 |
|
1269 // Clip rectangle bounds. Called internally by saveLayer. |
|
1270 // returns false if the entire rectangle is entirely clipped out |
|
1271 // If non-NULL, The imageFilter parameter will be used to expand the clip |
|
1272 // and offscreen bounds for any margin required by the filter DAG. |
|
1273 bool clipRectBounds(const SkRect* bounds, SaveFlags flags, |
|
1274 SkIRect* intersection, |
|
1275 const SkImageFilter* imageFilter = NULL); |
|
1276 |
|
1277 // Called by child classes that override clipPath and clipRRect to only |
|
1278 // track fast conservative clip bounds, rather than exact clips. |
|
1279 void updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op, |
|
1280 bool inverseFilled); |
|
1281 |
|
1282 // notify our surface (if we have one) that we are about to draw, so it |
|
1283 // can perform copy-on-write or invalidate any cached images |
|
1284 void predrawNotify(); |
|
1285 |
|
1286 virtual void onPushCull(const SkRect& cullRect); |
|
1287 virtual void onPopCull(); |
|
1288 |
|
1289 private: |
|
1290 class MCRec; |
|
1291 |
|
1292 SkClipStack fClipStack; |
|
1293 SkDeque fMCStack; |
|
1294 // points to top of stack |
|
1295 MCRec* fMCRec; |
|
1296 // the first N recs that can fit here mean we won't call malloc |
|
1297 uint32_t fMCRecStorage[32]; |
|
1298 |
|
1299 SkBounder* fBounder; |
|
1300 int fSaveLayerCount; // number of successful saveLayer calls |
|
1301 int fCullCount; // number of active culls |
|
1302 |
|
1303 SkMetaData* fMetaData; |
|
1304 |
|
1305 SkSurface_Base* fSurfaceBase; |
|
1306 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; } |
|
1307 void setSurfaceBase(SkSurface_Base* sb) { |
|
1308 fSurfaceBase = sb; |
|
1309 } |
|
1310 friend class SkSurface_Base; |
|
1311 friend class SkSurface_Gpu; |
|
1312 |
|
1313 bool fDeviceCMDirty; // cleared by updateDeviceCMCache() |
|
1314 void updateDeviceCMCache(); |
|
1315 |
|
1316 friend class SkDrawIter; // needs setupDrawForLayerDevice() |
|
1317 friend class AutoDrawLooper; |
|
1318 friend class SkLua; // needs top layer size and offset |
|
1319 friend class SkDeferredDevice; // needs getTopDevice() |
|
1320 |
|
1321 SkBaseDevice* createLayerDevice(const SkImageInfo&); |
|
1322 |
|
1323 SkBaseDevice* init(SkBaseDevice*); |
|
1324 |
|
1325 /** |
|
1326 * DEPRECATED |
|
1327 * |
|
1328 * Specify a device for this canvas to draw into. If it is not null, its |
|
1329 * reference count is incremented. If the canvas was already holding a |
|
1330 * device, its reference count is decremented. The new device is returned. |
|
1331 */ |
|
1332 SkBaseDevice* setRootDevice(SkBaseDevice* device); |
|
1333 |
|
1334 /** |
|
1335 * Gets the size/origin of the top level layer in global canvas coordinates. We don't want this |
|
1336 * to be public because it exposes decisions about layer sizes that are internal to the canvas. |
|
1337 */ |
|
1338 SkISize getTopLayerSize() const; |
|
1339 SkIPoint getTopLayerOrigin() const; |
|
1340 |
|
1341 // internal methods are not virtual, so they can safely be called by other |
|
1342 // canvas apis, without confusing subclasses (like SkPictureRecording) |
|
1343 void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint); |
|
1344 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, |
|
1345 const SkRect& dst, const SkPaint* paint, |
|
1346 DrawBitmapRectFlags flags); |
|
1347 void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, |
|
1348 const SkRect& dst, const SkPaint* paint); |
|
1349 void internalDrawPaint(const SkPaint& paint); |
|
1350 int internalSaveLayer(const SkRect* bounds, const SkPaint* paint, |
|
1351 SaveFlags, bool justForImageFilter, SaveLayerStrategy strategy); |
|
1352 void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*); |
|
1353 |
|
1354 // shared by save() and saveLayer() |
|
1355 int internalSave(SaveFlags flags); |
|
1356 void internalRestore(); |
|
1357 static void DrawRect(const SkDraw& draw, const SkPaint& paint, |
|
1358 const SkRect& r, SkScalar textSize); |
|
1359 static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, |
|
1360 const char text[], size_t byteLength, |
|
1361 SkScalar x, SkScalar y); |
|
1362 |
|
1363 /* These maintain a cache of the clip bounds in local coordinates, |
|
1364 (converted to 2s-compliment if floats are slow). |
|
1365 */ |
|
1366 mutable SkRect fCachedLocalClipBounds; |
|
1367 mutable bool fCachedLocalClipBoundsDirty; |
|
1368 bool fAllowSoftClip; |
|
1369 bool fAllowSimplifyClip; |
|
1370 |
|
1371 const SkRect& getLocalClipBounds() const { |
|
1372 if (fCachedLocalClipBoundsDirty) { |
|
1373 if (!this->getClipBounds(&fCachedLocalClipBounds)) { |
|
1374 fCachedLocalClipBounds.setEmpty(); |
|
1375 } |
|
1376 fCachedLocalClipBoundsDirty = false; |
|
1377 } |
|
1378 return fCachedLocalClipBounds; |
|
1379 } |
|
1380 |
|
1381 class AutoValidateClip : ::SkNoncopyable { |
|
1382 public: |
|
1383 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) { |
|
1384 fCanvas->validateClip(); |
|
1385 } |
|
1386 ~AutoValidateClip() { fCanvas->validateClip(); } |
|
1387 |
|
1388 private: |
|
1389 const SkCanvas* fCanvas; |
|
1390 }; |
|
1391 |
|
1392 #ifdef SK_DEBUG |
|
1393 void validateClip() const; |
|
1394 #else |
|
1395 void validateClip() const {} |
|
1396 #endif |
|
1397 |
|
1398 typedef SkRefCnt INHERITED; |
|
1399 }; |
|
1400 |
|
1401 /** Stack helper class to automatically call restoreToCount() on the canvas |
|
1402 when this object goes out of scope. Use this to guarantee that the canvas |
|
1403 is restored to a known state. |
|
1404 */ |
|
1405 class SkAutoCanvasRestore : SkNoncopyable { |
|
1406 public: |
|
1407 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) { |
|
1408 if (fCanvas) { |
|
1409 fSaveCount = canvas->getSaveCount(); |
|
1410 if (doSave) { |
|
1411 canvas->save(); |
|
1412 } |
|
1413 } |
|
1414 } |
|
1415 ~SkAutoCanvasRestore() { |
|
1416 if (fCanvas) { |
|
1417 fCanvas->restoreToCount(fSaveCount); |
|
1418 } |
|
1419 } |
|
1420 |
|
1421 /** |
|
1422 * Perform the restore now, instead of waiting for the destructor. Will |
|
1423 * only do this once. |
|
1424 */ |
|
1425 void restore() { |
|
1426 if (fCanvas) { |
|
1427 fCanvas->restoreToCount(fSaveCount); |
|
1428 fCanvas = NULL; |
|
1429 } |
|
1430 } |
|
1431 |
|
1432 private: |
|
1433 SkCanvas* fCanvas; |
|
1434 int fSaveCount; |
|
1435 }; |
|
1436 #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore) |
|
1437 |
|
1438 /** Stack helper class to automatically open and close a comment block |
|
1439 */ |
|
1440 class SkAutoCommentBlock : SkNoncopyable { |
|
1441 public: |
|
1442 SkAutoCommentBlock(SkCanvas* canvas, const char* description) { |
|
1443 fCanvas = canvas; |
|
1444 if (NULL != fCanvas) { |
|
1445 fCanvas->beginCommentGroup(description); |
|
1446 } |
|
1447 } |
|
1448 |
|
1449 ~SkAutoCommentBlock() { |
|
1450 if (NULL != fCanvas) { |
|
1451 fCanvas->endCommentGroup(); |
|
1452 } |
|
1453 } |
|
1454 |
|
1455 private: |
|
1456 SkCanvas* fCanvas; |
|
1457 }; |
|
1458 #define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock) |
|
1459 |
|
1460 /** |
|
1461 * If the caller wants read-only access to the pixels in a canvas, it can just |
|
1462 * call canvas->peekPixels(), since that is the fastest way to "peek" at the |
|
1463 * pixels on a raster-backed canvas. |
|
1464 * |
|
1465 * If the canvas has pixels, but they are not readily available to the CPU |
|
1466 * (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will |
|
1467 * succeed (though be slower, since it will return a copy of the pixels). |
|
1468 * |
|
1469 * SkAutoROCanvasPixels encapsulates these two techniques, trying first to call |
|
1470 * peekPixels() (for performance), but if that fails, calling readPixels() and |
|
1471 * storing the copy locally. |
|
1472 * |
|
1473 * The caller must respect the restrictions associated with peekPixels(), since |
|
1474 * that may have been called: The returned information is invalidated if... |
|
1475 * - any API is called on the canvas (or its parent surface if present) |
|
1476 * - the canvas goes out of scope |
|
1477 */ |
|
1478 class SkAutoROCanvasPixels : SkNoncopyable { |
|
1479 public: |
|
1480 SkAutoROCanvasPixels(SkCanvas* canvas); |
|
1481 |
|
1482 // returns NULL on failure |
|
1483 const void* addr() const { return fAddr; } |
|
1484 |
|
1485 // undefined if addr() == NULL |
|
1486 size_t rowBytes() const { return fRowBytes; } |
|
1487 |
|
1488 // undefined if addr() == NULL |
|
1489 const SkImageInfo& info() const { return fInfo; } |
|
1490 |
|
1491 // helper that, if returns true, installs the pixels into the bitmap. Note |
|
1492 // that the bitmap may reference the address returned by peekPixels(), so |
|
1493 // the caller must respect the restrictions associated with peekPixels(). |
|
1494 bool asROBitmap(SkBitmap*) const; |
|
1495 |
|
1496 private: |
|
1497 SkBitmap fBitmap; // used if peekPixels() fails |
|
1498 const void* fAddr; // NULL on failure |
|
1499 SkImageInfo fInfo; |
|
1500 size_t fRowBytes; |
|
1501 }; |
|
1502 |
|
1503 #endif |