Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 */
8 #ifndef SkCanvas_DEFINED
9 #define SkCanvas_DEFINED
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"
21 // if not defined, we always assume ClipToLayer for saveLayer()
22 //#define SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
25 //#define SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
26 //#define SK_SUPPORT_LEGACY_GETCLIPTYPE
27 //#define SK_SUPPORT_LEGACY_GETTOTALCLIP
28 //#define SK_SUPPORT_LEGACY_GETTOPDEVICE
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;
42 /** \class SkCanvas
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.
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)
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&);
86 static SkCanvas* NewRasterN32(int width, int height) {
87 return NewRaster(SkImageInfo::MakeN32Premul(width, height));
88 }
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);
107 static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) {
108 return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
109 }
111 /**
112 * Creates an empty canvas with no backing device/pixels, and zero
113 * dimensions.
114 */
115 SkCanvas();
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);
124 /** Construct a canvas with the specified device to draw into.
126 @param device Specifies a device for the canvas to draw into.
127 */
128 explicit SkCanvas(SkBaseDevice* device);
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();
137 SkMetaData& getMetaData();
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;
145 ///////////////////////////////////////////////////////////////////////////
147 /**
148 * Trigger the immediate execution of all pending draw operations.
149 */
150 void flush();
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;
159 /**
160 * DEPRECATED: call getBaseLayerSize
161 */
162 SkISize getDeviceSize() const { return this->getBaseLayerSize(); }
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;
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:
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&);
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();
203 ///////////////////////////////////////////////////////////////////////////
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);
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);
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 };
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);
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);
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
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);
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);
362 ///////////////////////////////////////////////////////////////////////////
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,
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 };
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);
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);
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);
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();
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;
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);
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;
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);
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);
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);
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);
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);
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);
499 /** Helper for setMatrix(identity). Sets the current matrix to identity.
500 */
501 void resetMatrix();
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);
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);
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);
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 }
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 }
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);
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 }
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;
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;
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);
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
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 }
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;
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;
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);
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);
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);
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);
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 };
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);
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);
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);
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);
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);
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 }
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);
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&);
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);
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&);
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);
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);
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);
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);
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.
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.
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);
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 };
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);
871 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
872 const SkPaint* paint = NULL) {
873 this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
874 }
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 }
888 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
889 const SkPaint* paint = NULL);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1002 enum VertexMode {
1003 kTriangles_VertexMode,
1004 kTriangleStrip_VertexMode,
1005 kTriangleFan_VertexMode
1006 };
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);
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 }
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 }
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 }
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 //////////////////////////////////////////////////////////////////////////
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; }
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);
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;
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);
1110 //////////////////////////////////////////////////////////////////////////
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;
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;
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;
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
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
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 }
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 };
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;
1178 ///////////////////////////////////////////////////////////////////////////
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();
1192 /** Return true if the iterator is done */
1193 bool done() const { return fDone; }
1194 /** Cycle to the next device */
1195 void next();
1197 // These reflect the current device in the iterator
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;
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 };
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();
1225 protected:
1226 // default impl defers to getDevice()->newSurface(info)
1227 virtual SkSurface* onNewSurface(const SkImageInfo&);
1229 // default impl defers to its device
1230 virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes);
1231 virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes);
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();
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&);
1251 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
1253 enum ClipEdgeStyle {
1254 kHard_ClipEdgeStyle,
1255 kSoft_ClipEdgeStyle
1256 };
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);
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();
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);
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);
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();
1286 virtual void onPushCull(const SkRect& cullRect);
1287 virtual void onPopCull();
1289 private:
1290 class MCRec;
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];
1299 SkBounder* fBounder;
1300 int fSaveLayerCount; // number of successful saveLayer calls
1301 int fCullCount; // number of active culls
1303 SkMetaData* fMetaData;
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;
1313 bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
1314 void updateDeviceCMCache();
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()
1321 SkBaseDevice* createLayerDevice(const SkImageInfo&);
1323 SkBaseDevice* init(SkBaseDevice*);
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);
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;
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*);
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);
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;
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 }
1381 class AutoValidateClip : ::SkNoncopyable {
1382 public:
1383 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
1384 fCanvas->validateClip();
1385 }
1386 ~AutoValidateClip() { fCanvas->validateClip(); }
1388 private:
1389 const SkCanvas* fCanvas;
1390 };
1392 #ifdef SK_DEBUG
1393 void validateClip() const;
1394 #else
1395 void validateClip() const {}
1396 #endif
1398 typedef SkRefCnt INHERITED;
1399 };
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 }
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 }
1432 private:
1433 SkCanvas* fCanvas;
1434 int fSaveCount;
1435 };
1436 #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
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 }
1449 ~SkAutoCommentBlock() {
1450 if (NULL != fCanvas) {
1451 fCanvas->endCommentGroup();
1452 }
1453 }
1455 private:
1456 SkCanvas* fCanvas;
1457 };
1458 #define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock)
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);
1482 // returns NULL on failure
1483 const void* addr() const { return fAddr; }
1485 // undefined if addr() == NULL
1486 size_t rowBytes() const { return fRowBytes; }
1488 // undefined if addr() == NULL
1489 const SkImageInfo& info() const { return fInfo; }
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;
1496 private:
1497 SkBitmap fBitmap; // used if peekPixels() fails
1498 const void* fAddr; // NULL on failure
1499 SkImageInfo fInfo;
1500 size_t fRowBytes;
1501 };
1503 #endif