Line data Source code
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 "SkBlendMode.h"
12 : #include "SkClipOp.h"
13 : #include "SkDeque.h"
14 : #include "SkPaint.h"
15 : #include "SkRasterHandleAllocator.h"
16 : #include "SkSurfaceProps.h"
17 : #include "SkLights.h"
18 : #include "../private/SkShadowParams.h"
19 :
20 : class GrContext;
21 : class GrRenderTargetContext;
22 : class SkBaseDevice;
23 : class SkBitmap;
24 : #ifdef SK_SUPPORT_OBSOLETE_REPLAYCLIP
25 : class SkCanvasClipVisitor;
26 : #endif
27 : class SkClipStack;
28 : class SkData;
29 : class SkDraw;
30 : class SkDrawable;
31 : class SkDrawFilter;
32 : class SkImage;
33 : class SkImageFilter;
34 : class SkMetaData;
35 : class SkPath;
36 : class SkPicture;
37 : class SkPixmap;
38 : class SkRasterClip;
39 : class SkRegion;
40 : class SkRRect;
41 : struct SkRSXform;
42 : class SkSurface;
43 : class SkSurface_Base;
44 : class SkTextBlob;
45 : class SkVertices;
46 :
47 : /** \class SkCanvas
48 :
49 : A Canvas encapsulates all of the state about drawing into a device (bitmap).
50 : This includes a reference to the device itself, and a stack of matrix/clip
51 : values. For any given draw call (e.g. drawRect), the geometry of the object
52 : being drawn is transformed by the concatenation of all the matrices in the
53 : stack. The transformed geometry is clipped by the intersection of all of
54 : the clips in the stack.
55 :
56 : While the Canvas holds the state of the drawing device, the state (style)
57 : of the object being drawn is held by the Paint, which is provided as a
58 : parameter to each of the draw() methods. The Paint holds attributes such as
59 : color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
60 : etc.
61 : */
62 : class SK_API SkCanvas : SkNoncopyable {
63 : enum PrivateSaveLayerFlags {
64 : kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31,
65 : };
66 :
67 : public:
68 : /**
69 : * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
70 : * specified pixels. To access the pixels after drawing to them, the caller should call
71 : * flush() or call peekPixels(...).
72 : *
73 : * On failure, return NULL. This can fail for several reasons:
74 : * 1. invalid ImageInfo (e.g. negative dimensions)
75 : * 2. unsupported ImageInfo for a canvas
76 : * - kUnknown_SkColorType, kIndex_8_SkColorType
77 : * - kUnknown_SkAlphaType
78 : * - this list is not complete, so others may also be unsupported
79 : *
80 : * Note: it is valid to request a supported ImageInfo, but with zero
81 : * dimensions.
82 : */
83 : static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo&, void*, size_t);
84 :
85 : static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
86 : size_t rowBytes) {
87 : return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
88 : }
89 :
90 : /**
91 : * Creates an empty canvas with no backing device/pixels, and zero
92 : * dimensions.
93 : */
94 : SkCanvas();
95 :
96 : /**
97 : * Creates a canvas of the specified dimensions, but explicitly not backed
98 : * by any device/pixels. Typically this use used by subclasses who handle
99 : * the draw calls in some other way.
100 : */
101 : SkCanvas(int width, int height, const SkSurfaceProps* = NULL);
102 :
103 : /** Construct a canvas with the specified device to draw into.
104 :
105 : @param device Specifies a device for the canvas to draw into.
106 : */
107 : explicit SkCanvas(SkBaseDevice* device);
108 :
109 : /** Construct a canvas with the specified bitmap to draw into.
110 : @param bitmap Specifies a bitmap for the canvas to draw into. Its
111 : structure are copied to the canvas.
112 : */
113 : explicit SkCanvas(const SkBitmap& bitmap);
114 :
115 : #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
116 : enum class ColorBehavior {
117 : kLegacy,
118 : };
119 :
120 : /**
121 : * Android framework only constructor.
122 : * Allows the creation of a legacy SkCanvas even though the |bitmap|
123 : * and its pixel ref may have an SkColorSpace.
124 : */
125 : SkCanvas(const SkBitmap& bitmap, ColorBehavior);
126 : #endif
127 :
128 : /** Construct a canvas with the specified bitmap to draw into.
129 : @param bitmap Specifies a bitmap for the canvas to draw into. Its
130 : structure are copied to the canvas.
131 : @param props New canvas surface properties.
132 : */
133 : SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
134 :
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 : * If the canvas is backed by pixels (cpu or gpu), this writes a copy of the SurfaceProps
147 : * for the canvas to the location supplied by the caller, and returns true. Otherwise,
148 : * return false and leave the supplied props unchanged.
149 : */
150 : bool getProps(SkSurfaceProps*) const;
151 :
152 : ///////////////////////////////////////////////////////////////////////////
153 :
154 : /**
155 : * Trigger the immediate execution of all pending draw operations. For the GPU
156 : * backend this will resolve all rendering to the GPU surface backing the
157 : * SkSurface that owns this canvas.
158 : */
159 : void flush();
160 :
161 : /**
162 : * Gets the size of the base or root layer in global canvas coordinates. The
163 : * origin of the base layer is always (0,0). The current drawable area may be
164 : * smaller (due to clipping or saveLayer).
165 : */
166 : virtual SkISize getBaseLayerSize() const;
167 :
168 : /**
169 : * Create a new surface matching the specified info, one that attempts to
170 : * be maximally compatible when used with this canvas. If there is no matching Surface type,
171 : * NULL is returned.
172 : *
173 : * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
174 : * inherits the properties of the surface that owns this canvas. If this canvas has no parent
175 : * surface, then the new surface is created with default properties.
176 : */
177 : sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps* = nullptr);
178 :
179 : /**
180 : * Return the GPU context of the device that is associated with the canvas.
181 : * For a canvas with non-GPU device, NULL is returned.
182 : */
183 : GrContext* getGrContext();
184 :
185 : ///////////////////////////////////////////////////////////////////////////
186 :
187 : /**
188 : * If the canvas has writable pixels in its top layer (and is not recording to a picture
189 : * or other non-raster target) and has direct access to its pixels (i.e. they are in
190 : * local RAM) return the address of those pixels, and if not null,
191 : * return the ImageInfo, rowBytes and origin. The returned address is only valid
192 : * while the canvas object is in scope and unchanged. Any API calls made on
193 : * canvas (or its parent surface if any) will invalidate the
194 : * returned address (and associated information).
195 : *
196 : * On failure, returns NULL and the info, rowBytes, and origin parameters are ignored.
197 : */
198 : void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
199 :
200 : SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
201 :
202 : /**
203 : * If the canvas has readable pixels in its base layer (and is not recording to a picture
204 : * or other non-raster target) and has direct access to its pixels (i.e. they are in
205 : * local RAM) return true, and if not null, return in the pixmap parameter information about
206 : * the pixels. The pixmap's pixel address is only valid
207 : * while the canvas object is in scope and unchanged. Any API calls made on
208 : * canvas (or its parent surface if any) will invalidate the pixel address
209 : * (and associated information).
210 : *
211 : * On failure, returns false and the pixmap parameter will be ignored.
212 : */
213 : bool peekPixels(SkPixmap*);
214 :
215 : /**
216 : * Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes),
217 : * converting them into the requested format (SkImageInfo). The base-layer pixels are read
218 : * starting at the specified (srcX,srcY) location in the coordinate system of the base-layer.
219 : *
220 : * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
221 : *
222 : * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
223 : *
224 : * srcR is intersected with the bounds of the base-layer. If this intersection is not empty,
225 : * then we have two sets of pixels (of equal size). Replace the dst pixels with the
226 : * corresponding src pixels, performing any colortype/alphatype transformations needed
227 : * (in the case where the src and dst have different colortypes or alphatypes).
228 : *
229 : * This call can fail, returning false, for several reasons:
230 : * - If srcR does not intersect the base-layer bounds.
231 : * - If the requested colortype/alphatype cannot be converted from the base-layer's types.
232 : * - If this canvas is not backed by pixels (e.g. picture or PDF)
233 : */
234 : bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
235 : int srcX, int srcY);
236 :
237 : /**
238 : * Helper for calling readPixels(info, ...). This call will check if bitmap has been allocated.
239 : * If not, it will attempt to call allocPixels(). If this fails, it will return false. If not,
240 : * it calls through to readPixels(info, ...) and returns its result.
241 : */
242 : bool readPixels(SkBitmap* bitmap, int srcX, int srcY);
243 :
244 : /**
245 : * Helper for allocating pixels and then calling readPixels(info, ...). The bitmap is resized
246 : * to the intersection of srcRect and the base-layer bounds. On success, pixels will be
247 : * allocated in bitmap and true returned. On failure, false is returned and bitmap will be
248 : * set to empty.
249 : */
250 : bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
251 :
252 : /**
253 : * This method affects the pixels in the base-layer, and operates in pixel coordinates,
254 : * ignoring the matrix and clip.
255 : *
256 : * The specified ImageInfo and (x,y) offset specifies a rectangle: target.
257 : *
258 : * target.setXYWH(x, y, info.width(), info.height());
259 : *
260 : * Target is intersected with the bounds of the base-layer. If this intersection is not empty,
261 : * then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes
262 : * and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src
263 : * pixels, performing any colortype/alphatype transformations needed (in the case where the
264 : * src and dst have different colortypes or alphatypes).
265 : *
266 : * This call can fail, returning false, for several reasons:
267 : * - If the src colortype/alphatype cannot be converted to the canvas' types
268 : * - If this canvas is not backed by pixels (e.g. picture or PDF)
269 : */
270 : bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
271 :
272 : /**
273 : * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap
274 : * is just wrapping a texture, returns false and does nothing.
275 : */
276 : bool writePixels(const SkBitmap& bitmap, int x, int y);
277 :
278 : ///////////////////////////////////////////////////////////////////////////
279 :
280 : /** This call saves the current matrix, clip, and drawFilter, and pushes a
281 : copy onto a private stack. Subsequent calls to translate, scale,
282 : rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
283 : operate on this copy.
284 : When the balancing call to restore() is made, the previous matrix, clip,
285 : and drawFilter are restored.
286 :
287 : @return The value to pass to restoreToCount() to balance this save()
288 : */
289 : int save();
290 :
291 : /** This behaves the same as save(), but in addition it allocates an
292 : offscreen bitmap. All drawing calls are directed there, and only when
293 : the balancing call to restore() is made is that offscreen transfered to
294 : the canvas (or the previous layer).
295 : @param bounds (may be null) This rect, if non-null, is used as a hint to
296 : limit the size of the offscreen, and thus drawing may be
297 : clipped to it, though that clipping is not guaranteed to
298 : happen. If exact clipping is desired, use clipRect().
299 : @param paint (may be null) This is copied, and is applied to the
300 : offscreen when restore() is called
301 : @return The value to pass to restoreToCount() to balance this save()
302 : */
303 : int saveLayer(const SkRect* bounds, const SkPaint* paint);
304 : int saveLayer(const SkRect& bounds, const SkPaint* paint) {
305 : return this->saveLayer(&bounds, paint);
306 : }
307 :
308 : /**
309 : * Temporary name.
310 : * Will allow any requests for LCD text to be respected, so the caller must be careful to
311 : * only draw on top of opaque sections of the layer to get good results.
312 : */
313 : int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint);
314 :
315 : /** This behaves the same as save(), but in addition it allocates an
316 : offscreen bitmap. All drawing calls are directed there, and only when
317 : the balancing call to restore() is made is that offscreen transfered to
318 : the canvas (or the previous layer).
319 : @param bounds (may be null) This rect, if non-null, is used as a hint to
320 : limit the size of the offscreen, and thus drawing may be
321 : clipped to it, though that clipping is not guaranteed to
322 : happen. If exact clipping is desired, use clipRect().
323 : @param alpha This is applied to the offscreen when restore() is called.
324 : @return The value to pass to restoreToCount() to balance this save()
325 : */
326 : int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
327 :
328 : enum {
329 : kIsOpaque_SaveLayerFlag = 1 << 0,
330 : kPreserveLCDText_SaveLayerFlag = 1 << 1,
331 :
332 : /** initialize the new layer with the contents of the previous layer */
333 : kInitWithPrevious_SaveLayerFlag = 1 << 2,
334 :
335 : #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
336 : kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
337 : #endif
338 : };
339 : typedef uint32_t SaveLayerFlags;
340 :
341 : struct SaveLayerRec {
342 : SaveLayerRec()
343 : : fBounds(nullptr), fPaint(nullptr), fBackdrop(nullptr), fSaveLayerFlags(0)
344 : {}
345 22 : SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
346 22 : : fBounds(bounds)
347 : , fPaint(paint)
348 : , fBackdrop(nullptr)
349 22 : , fSaveLayerFlags(saveLayerFlags)
350 22 : {}
351 0 : SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
352 : SaveLayerFlags saveLayerFlags)
353 0 : : fBounds(bounds)
354 : , fPaint(paint)
355 : , fBackdrop(backdrop)
356 0 : , fSaveLayerFlags(saveLayerFlags)
357 0 : {}
358 :
359 : const SkRect* fBounds; // optional
360 : const SkPaint* fPaint; // optional
361 : const SkImageFilter* fBackdrop; // optional
362 : SaveLayerFlags fSaveLayerFlags;
363 : };
364 :
365 : int saveLayer(const SaveLayerRec&);
366 :
367 : /** This call balances a previous call to save(), and is used to remove all
368 : modifications to the matrix/clip/drawFilter state since the last save
369 : call.
370 : It is an error to call restore() more times than save() was called.
371 : */
372 : void restore();
373 :
374 : /** Returns the number of matrix/clip states on the SkCanvas' private stack.
375 : This will equal # save() calls - # restore() calls + 1. The save count on
376 : a new canvas is 1.
377 : */
378 : int getSaveCount() const;
379 :
380 : /** Efficient way to pop any calls to save() that happened after the save
381 : count reached saveCount. It is an error for saveCount to be greater than
382 : getSaveCount(). To pop all the way back to the initial matrix/clip context
383 : pass saveCount == 1.
384 : @param saveCount The number of save() levels to restore from
385 : */
386 : void restoreToCount(int saveCount);
387 :
388 : /** Preconcat the current matrix with the specified translation
389 : @param dx The distance to translate in X
390 : @param dy The distance to translate in Y
391 : */
392 : void translate(SkScalar dx, SkScalar dy);
393 :
394 : /** Preconcat the current matrix with the specified scale.
395 : @param sx The amount to scale in X
396 : @param sy The amount to scale in Y
397 : */
398 : void scale(SkScalar sx, SkScalar sy);
399 :
400 : /** Preconcat the current matrix with the specified rotation about the origin.
401 : @param degrees The amount to rotate, in degrees
402 : */
403 : void rotate(SkScalar degrees);
404 :
405 : /** Preconcat the current matrix with the specified rotation about a given point.
406 : @param degrees The amount to rotate, in degrees
407 : @param px The x coordinate of the point to rotate about.
408 : @param py The y coordinate of the point to rotate about.
409 : */
410 : void rotate(SkScalar degrees, SkScalar px, SkScalar py);
411 :
412 : /** Preconcat the current matrix with the specified skew.
413 : @param sx The amount to skew in X
414 : @param sy The amount to skew in Y
415 : */
416 : void skew(SkScalar sx, SkScalar sy);
417 :
418 : /** Preconcat the current matrix with the specified matrix.
419 : @param matrix The matrix to preconcatenate with the current matrix
420 : */
421 : void concat(const SkMatrix& matrix);
422 :
423 : /** Replace the current matrix with a copy of the specified matrix.
424 : @param matrix The matrix that will be copied into the current matrix.
425 : */
426 : void setMatrix(const SkMatrix& matrix);
427 :
428 : /** Helper for setMatrix(identity). Sets the current matrix to identity.
429 : */
430 : void resetMatrix();
431 :
432 : #ifdef SK_EXPERIMENTAL_SHADOWING
433 : /** Add the specified translation to the current draw depth of the canvas.
434 : @param z The distance to translate in Z.
435 : Negative into screen, positive out of screen.
436 : Without translation, the draw depth defaults to 0.
437 : */
438 : void translateZ(SkScalar z);
439 :
440 : /** Set the current set of lights in the canvas.
441 : @param lights The lights that we want the canvas to have.
442 : */
443 : void setLights(sk_sp<SkLights> lights);
444 :
445 : /** Returns the current set of lights the canvas uses
446 : */
447 : sk_sp<SkLights> getLights() const;
448 : #endif
449 :
450 : /**
451 : * Modify the current clip with the specified rectangle.
452 : * @param rect The rect to combine with the current clip
453 : * @param op The region op to apply to the current clip
454 : * @param doAntiAlias true if the clip should be antialiased
455 : */
456 : void clipRect(const SkRect& rect, SkClipOp, bool doAntiAlias);
457 0 : void clipRect(const SkRect& rect, SkClipOp op) {
458 0 : this->clipRect(rect, op, false);
459 0 : }
460 3 : void clipRect(const SkRect& rect, bool doAntiAlias = false) {
461 3 : this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
462 3 : }
463 :
464 : /**
465 : * Sets the max clip rectangle, which can be set by clipRect, clipRRect and
466 : * clipPath and intersect the current clip with the specified rect.
467 : * The max clip affects only future ops (it is not retroactive).
468 : * We DON'T record the clip restriction in pictures.
469 : * This is private API to be used only by Android framework.
470 : * @param rect The maximum allowed clip in device coordinates.
471 : * Empty rect means max clip is not enforced.
472 : */
473 : void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
474 :
475 : /**
476 : * Modify the current clip with the specified SkRRect.
477 : * @param rrect The rrect to combine with the current clip
478 : * @param op The region op to apply to the current clip
479 : * @param doAntiAlias true if the clip should be antialiased
480 : */
481 : void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
482 : void clipRRect(const SkRRect& rrect, SkClipOp op) {
483 : this->clipRRect(rrect, op, false);
484 : }
485 : void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
486 : this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
487 : }
488 :
489 : /**
490 : * Modify the current clip with the specified path.
491 : * @param path The path to combine with the current clip
492 : * @param op The region op to apply to the current clip
493 : * @param doAntiAlias true if the clip should be antialiased
494 : */
495 : void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
496 : void clipPath(const SkPath& path, SkClipOp op) {
497 : this->clipPath(path, op, false);
498 : }
499 : void clipPath(const SkPath& path, bool doAntiAlias = false) {
500 : this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
501 : }
502 :
503 : /** EXPERIMENTAL -- only used for testing
504 : Set to simplify clip stack using path ops.
505 : */
506 : void setAllowSimplifyClip(bool allow) {
507 : fAllowSimplifyClip = allow;
508 : }
509 :
510 : /** Modify the current clip with the specified region. Note that unlike
511 : clipRect() and clipPath() which transform their arguments by the current
512 : matrix, clipRegion() assumes its argument is already in device
513 : coordinates, and so no transformation is performed.
514 : @param deviceRgn The region to apply to the current clip
515 : @param op The region op to apply to the current clip
516 : */
517 : void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
518 :
519 : /** Return true if the specified rectangle, after being transformed by the
520 : current matrix, would lie completely outside of the current clip. Call
521 : this to check if an area you intend to draw into is clipped out (and
522 : therefore you can skip making the draw calls).
523 : @param rect the rect to compare with the current clip
524 : @return true if the rect (transformed by the canvas' matrix) does not
525 : intersect with the canvas' clip
526 : */
527 : bool quickReject(const SkRect& rect) const;
528 :
529 : /** Return true if the specified path, after being transformed by the
530 : current matrix, would lie completely outside of the current clip. Call
531 : this to check if an area you intend to draw into is clipped out (and
532 : therefore you can skip making the draw calls). Note, for speed it may
533 : return false even if the path itself might not intersect the clip
534 : (i.e. the bounds of the path intersects, but the path does not).
535 : @param path The path to compare with the current clip
536 : @return true if the path (transformed by the canvas' matrix) does not
537 : intersect with the canvas' clip
538 : */
539 : bool quickReject(const SkPath& path) const;
540 :
541 : /**
542 : * Return the bounds of the current clip in local coordinates. If the clip is empty,
543 : * return { 0, 0, 0, 0 }.
544 : */
545 0 : SkRect getLocalClipBounds() const { return this->onGetLocalClipBounds(); }
546 :
547 : /**
548 : * Returns true if the clip bounds are non-empty.
549 : */
550 : bool getLocalClipBounds(SkRect* bounds) const {
551 : *bounds = this->onGetLocalClipBounds();
552 : return !bounds->isEmpty();
553 : }
554 :
555 : /**
556 : * Return the bounds of the current clip in device coordinates. If the clip is empty,
557 : * return { 0, 0, 0, 0 }.
558 : */
559 22 : SkIRect getDeviceClipBounds() const { return this->onGetDeviceClipBounds(); }
560 :
561 : /**
562 : * Returns true if the clip bounds are non-empty.
563 : */
564 14 : bool getDeviceClipBounds(SkIRect* bounds) const {
565 14 : *bounds = this->onGetDeviceClipBounds();
566 14 : return !bounds->isEmpty();
567 : }
568 :
569 : /** Fill the entire canvas' bitmap (restricted to the current clip) with the
570 : specified color and mode.
571 : @param color the color to draw with
572 : @param mode the mode to apply the color in (defaults to SrcOver)
573 : */
574 : void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
575 :
576 : /**
577 : * Helper method for drawing a color in SRC mode, completely replacing all the pixels
578 : * in the current clip with this color.
579 : */
580 17 : void clear(SkColor color) {
581 17 : this->drawColor(color, SkBlendMode::kSrc);
582 17 : }
583 :
584 : /**
585 : * This makes the contents of the canvas undefined. Subsequent calls that
586 : * require reading the canvas contents will produce undefined results. Examples
587 : * include blending and readPixels. The actual implementation is backend-
588 : * dependent and one legal implementation is to do nothing. This method
589 : * ignores the current clip.
590 : *
591 : * This function should only be called if the caller intends to subsequently
592 : * draw to the canvas. The canvas may do real work at discard() time in order
593 : * to optimize performance on subsequent draws. Thus, if you call this and then
594 : * never draw to the canvas subsequently you may pay a perfomance penalty.
595 : */
596 : void discard() { this->onDiscard(); }
597 :
598 : /**
599 : * Fill the entire canvas (restricted to the current clip) with the
600 : * specified paint.
601 : * @param paint The paint used to fill the canvas
602 : */
603 : void drawPaint(const SkPaint& paint);
604 :
605 : enum PointMode {
606 : /** drawPoints draws each point separately */
607 : kPoints_PointMode,
608 : /** drawPoints draws each pair of points as a line segment */
609 : kLines_PointMode,
610 : /** drawPoints draws the array of points as a polygon */
611 : kPolygon_PointMode
612 : };
613 :
614 : /** Draw a series of points, interpreted based on the PointMode mode. For
615 : all modes, the count parameter is interpreted as the total number of
616 : points. For kLine mode, count/2 line segments are drawn.
617 : For kPoint mode, each point is drawn centered at its coordinate, and its
618 : size is specified by the paint's stroke-width. It draws as a square,
619 : unless the paint's cap-type is round, in which the points are drawn as
620 : circles.
621 : For kLine mode, each pair of points is drawn as a line segment,
622 : respecting the paint's settings for cap/join/width.
623 : For kPolygon mode, the entire array is drawn as a series of connected
624 : line segments.
625 : Note that, while similar, kLine and kPolygon modes draw slightly
626 : differently than the equivalent path built with a series of moveto,
627 : lineto calls, in that the path will draw all of its contours at once,
628 : with no interactions if contours intersect each other (think XOR
629 : xfermode). drawPoints always draws each element one at a time.
630 : @param mode PointMode specifying how to draw the array of points.
631 : @param count The number of points in the array
632 : @param pts Array of points to draw
633 : @param paint The paint used to draw the points
634 : */
635 : void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
636 :
637 : /** Helper method for drawing a single point. See drawPoints() for more details.
638 : */
639 : void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
640 :
641 : /** Draw a line segment with the specified start and stop x,y coordinates,
642 : using the specified paint. NOTE: since a line is always "framed", the
643 : paint's Style is ignored.
644 : @param x0 The x-coordinate of the start point of the line
645 : @param y0 The y-coordinate of the start point of the line
646 : @param x1 The x-coordinate of the end point of the line
647 : @param y1 The y-coordinate of the end point of the line
648 : @param paint The paint used to draw the line
649 : */
650 : void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
651 :
652 : /** Draw the specified rectangle using the specified paint. The rectangle
653 : will be filled or stroked based on the Style in the paint.
654 : @param rect The rect to be drawn
655 : @param paint The paint used to draw the rect
656 : */
657 : void drawRect(const SkRect& rect, const SkPaint& paint);
658 :
659 : /** Draw the specified rectangle using the specified paint. The rectangle
660 : will be filled or framed based on the Style in the paint.
661 : @param rect The rect to be drawn
662 : @param paint The paint used to draw the rect
663 : */
664 0 : void drawIRect(const SkIRect& rect, const SkPaint& paint) {
665 : SkRect r;
666 0 : r.set(rect); // promotes the ints to scalars
667 0 : this->drawRect(r, paint);
668 0 : }
669 :
670 : /** Draw the outline of the specified region using the specified paint.
671 : @param region The region to be drawn
672 : @param paint The paint used to draw the region
673 : */
674 : void drawRegion(const SkRegion& region, const SkPaint& paint);
675 :
676 : /** Draw the specified oval using the specified paint. The oval will be
677 : filled or framed based on the Style in the paint.
678 : @param oval The rectangle bounds of the oval to be drawn
679 : @param paint The paint used to draw the oval
680 : */
681 : void drawOval(const SkRect& oval, const SkPaint&);
682 :
683 : /**
684 : * Draw the specified RRect using the specified paint The rrect will be filled or stroked
685 : * based on the Style in the paint.
686 : *
687 : * @param rrect The round-rect to draw
688 : * @param paint The paint used to draw the round-rect
689 : */
690 : void drawRRect(const SkRRect& rrect, const SkPaint& paint);
691 :
692 : /**
693 : * Draw the annulus formed by the outer and inner rrects. The results
694 : * are undefined if the outer does not contain the inner.
695 : */
696 : void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&);
697 :
698 : /** Draw the specified circle using the specified paint. If radius is <= 0,
699 : then nothing will be drawn. The circle will be filled
700 : or framed based on the Style in the paint.
701 : @param cx The x-coordinate of the center of the cirle to be drawn
702 : @param cy The y-coordinate of the center of the cirle to be drawn
703 : @param radius The radius of the cirle to be drawn
704 : @param paint The paint used to draw the circle
705 : */
706 : void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
707 :
708 : /** Draw the specified arc, which will be scaled to fit inside the
709 : specified oval. Sweep angles are not treated as modulo 360 and thus can
710 : exceed a full sweep of the oval. Note that this differs slightly from
711 : SkPath::arcTo, which treats the sweep angle mod 360. If the oval is empty
712 : or the sweep angle is zero nothing is drawn. If useCenter is true the oval
713 : center is inserted into the implied path before the arc and the path is
714 : closed back to the, center forming a wedge. Otherwise, the implied path
715 : contains just the arc and is not closed.
716 : @param oval The bounds of oval used to define the shape of the arc.
717 : @param startAngle Starting angle (in degrees) where the arc begins
718 : @param sweepAngle Sweep angle (in degrees) measured clockwise.
719 : @param useCenter true means include the center of the oval.
720 : @param paint The paint used to draw the arc
721 : */
722 : void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
723 : bool useCenter, const SkPaint& paint);
724 :
725 : /** Draw the specified round-rect using the specified paint. The round-rect
726 : will be filled or framed based on the Style in the paint.
727 : @param rect The rectangular bounds of the roundRect to be drawn
728 : @param rx The x-radius of the oval used to round the corners
729 : @param ry The y-radius of the oval used to round the corners
730 : @param paint The paint used to draw the roundRect
731 : */
732 : void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
733 :
734 : /** Draw the specified path using the specified paint. The path will be
735 : filled or framed based on the Style in the paint.
736 : @param path The path to be drawn
737 : @param paint The paint used to draw the path
738 : */
739 : void drawPath(const SkPath& path, const SkPaint& paint);
740 :
741 : /** Draw the specified image, with its top/left corner at (x,y), using the
742 : specified paint, transformed by the current matrix.
743 :
744 : @param image The image to be drawn
745 : @param left The position of the left side of the image being drawn
746 : @param top The position of the top side of the image being drawn
747 : @param paint The paint used to draw the image, or NULL
748 : */
749 : void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL);
750 4 : void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
751 : const SkPaint* paint = NULL) {
752 4 : this->drawImage(image.get(), left, top, paint);
753 4 : }
754 :
755 : /**
756 : * Controls the behavior at the edge of the src-rect, when specified in drawImageRect,
757 : * trading off speed for exactness.
758 : *
759 : * When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around
760 : * the pixels in the image. If there is a src-rect specified, it is intended to restrict the
761 : * pixels that will be read. However, for performance reasons, some implementations may slow
762 : * down if they cannot read 1-pixel past the src-rect boundary at times.
763 : *
764 : * This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable.
765 : * If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect
766 : * must be strictly respected, the caller should pass kStrict.
767 : */
768 : enum SrcRectConstraint {
769 : /**
770 : * If kStrict is specified, the implementation must respect the src-rect
771 : * (if specified) strictly, and will never sample outside of those bounds during sampling
772 : * even when filtering. This may be slower than kFast.
773 : */
774 : kStrict_SrcRectConstraint,
775 :
776 : /**
777 : * If kFast is specified, the implementation may sample outside of the src-rect
778 : * (if specified) by half the width of filter. This allows greater flexibility
779 : * to the implementation and can make the draw much faster.
780 : */
781 : kFast_SrcRectConstraint,
782 : };
783 :
784 : /** Draw the specified image, scaling and translating so that it fills the specified
785 : * dst rect. If the src rect is non-null, only that subset of the image is transformed
786 : * and drawn.
787 : *
788 : * @param image The image to be drawn
789 : * @param src Optional: specify the subset of the image to be drawn
790 : * @param dst The destination rectangle where the scaled/translated
791 : * image will be drawn
792 : * @param paint The paint used to draw the image, or NULL
793 : * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
794 : */
795 : void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
796 : const SkPaint* paint,
797 : SrcRectConstraint constraint = kStrict_SrcRectConstraint);
798 : // variant that takes src SkIRect
799 : void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
800 : const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
801 : // variant that assumes src == image-bounds
802 : void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
803 : SrcRectConstraint = kStrict_SrcRectConstraint);
804 :
805 151 : void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
806 : const SkPaint* paint,
807 : SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
808 151 : this->drawImageRect(image.get(), src, dst, paint, constraint);
809 151 : }
810 0 : void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
811 : const SkPaint* paint, SrcRectConstraint cons = kStrict_SrcRectConstraint) {
812 0 : this->drawImageRect(image.get(), isrc, dst, paint, cons);
813 0 : }
814 0 : void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
815 : SrcRectConstraint cons = kStrict_SrcRectConstraint) {
816 0 : this->drawImageRect(image.get(), dst, paint, cons);
817 0 : }
818 :
819 : /**
820 : * Draw the image stretched differentially to fit into dst.
821 : * center is a rect within the image, and logically divides the image
822 : * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
823 : * image is the "center", then the center-rect should be [2, 2, 3, 3].
824 : *
825 : * If the dst is >= the image size, then...
826 : * - The 4 corners are not stretched at all.
827 : * - The sides are stretched in only one axis.
828 : * - The center is stretched in both axes.
829 : * Else, for each axis where dst < image,
830 : * - The corners shrink proportionally
831 : * - The sides (along the shrink axis) and center are not drawn
832 : */
833 : void drawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
834 : const SkPaint* paint = nullptr);
835 0 : void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
836 : const SkPaint* paint = nullptr) {
837 0 : this->drawImageNine(image.get(), center, dst, paint);
838 0 : }
839 :
840 : /** Draw the specified bitmap, with its top/left corner at (x,y), using the
841 : specified paint, transformed by the current matrix. Note: if the paint
842 : contains a maskfilter that generates a mask which extends beyond the
843 : bitmap's original width/height, then the bitmap will be drawn as if it
844 : were in a Shader with CLAMP mode. Thus the color outside of the original
845 : width/height will be the edge color replicated.
846 :
847 : If a shader is present on the paint it will be ignored, except in the
848 : case where the bitmap is kAlpha_8_SkColorType. In that case, the color is
849 : generated by the shader.
850 :
851 : @param bitmap The bitmap to be drawn
852 : @param left The position of the left side of the bitmap being drawn
853 : @param top The position of the top side of the bitmap being drawn
854 : @param paint The paint used to draw the bitmap, or NULL
855 : */
856 : void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
857 : const SkPaint* paint = NULL);
858 :
859 : /** Draw the specified bitmap, scaling and translating so that it fills the specified
860 : * dst rect. If the src rect is non-null, only that subset of the bitmap is transformed
861 : * and drawn.
862 : *
863 : * @param bitmap The bitmap to be drawn
864 : * @param src Optional: specify the subset of the bitmap to be drawn
865 : * @param dst The destination rectangle where the scaled/translated
866 : * bitmap will be drawn
867 : * @param paint The paint used to draw the bitmap, or NULL
868 : * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
869 : */
870 : void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
871 : const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
872 : // variant where src is SkIRect
873 : void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
874 : const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
875 : void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
876 : SrcRectConstraint = kStrict_SrcRectConstraint);
877 :
878 : /**
879 : * Draw the bitmap stretched or shrunk differentially to fit into dst.
880 : * center is a rect within the bitmap, and logically divides the bitmap
881 : * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
882 : * bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
883 : *
884 : * If the dst is >= the bitmap size, then...
885 : * - The 4 corners are not stretched at all.
886 : * - The sides are stretched in only one axis.
887 : * - The center is stretched in both axes.
888 : * Else, for each axis where dst < bitmap,
889 : * - The corners shrink proportionally
890 : * - The sides (along the shrink axis) and center are not drawn
891 : */
892 : void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
893 : const SkPaint* paint = NULL);
894 :
895 : /**
896 : * Specifies coordinates to divide a bitmap into (xCount*yCount) rects.
897 : *
898 : * If the lattice divs or bounds are invalid, the entire lattice
899 : * struct will be ignored on the draw call.
900 : */
901 : struct Lattice {
902 : enum Flags : uint8_t {
903 : // If set, indicates that we should not draw corresponding rect.
904 : kTransparent_Flags = 1 << 0,
905 : };
906 :
907 : // An array of x-coordinates that divide the bitmap vertically.
908 : // These must be unique, increasing, and in the set [fBounds.fLeft, fBounds.fRight).
909 : // Does not have ownership.
910 : const int* fXDivs;
911 :
912 : // An array of y-coordinates that divide the bitmap horizontally.
913 : // These must be unique, increasing, and in the set [fBounds.fTop, fBounds.fBottom).
914 : // Does not have ownership.
915 : const int* fYDivs;
916 :
917 : // If non-null, the length of this array must be equal to
918 : // (fXCount + 1) * (fYCount + 1). Note that we allow the first rect
919 : // in each direction to be empty (ex: fXDivs[0] = fBounds.fLeft).
920 : // In this case, the caller still must specify a flag (as a placeholder)
921 : // for these empty rects.
922 : // The flags correspond to the rects in the lattice, first moving
923 : // left to right and then top to bottom.
924 : const Flags* fFlags;
925 :
926 : // The number of fXDivs.
927 : int fXCount;
928 :
929 : // The number of fYDivs.
930 : int fYCount;
931 :
932 : // The bound to draw from. Must be contained by the src that is being drawn,
933 : // non-empty, and non-inverted.
934 : // If nullptr, the bounds are the entire src.
935 : const SkIRect* fBounds;
936 : };
937 :
938 : /**
939 : * Draw the bitmap stretched or shrunk differentially to fit into dst.
940 : *
941 : * Moving horizontally across the bitmap, alternating rects will be "scalable"
942 : * (in the x-dimension) to fit into dst or must be left "fixed". The first rect
943 : * is treated as "fixed", but it's possible to specify an empty first rect by
944 : * making lattice.fXDivs[0] = 0.
945 : *
946 : * The scale factor for all "scalable" rects will be the same, and may be greater
947 : * than or less than 1 (meaning we can stretch or shrink). If the number of
948 : * "fixed" pixels is greater than the width of the dst, we will collapse all of
949 : * the "scalable" regions and appropriately downscale the "fixed" regions.
950 : *
951 : * The same interpretation also applies to the y-dimension.
952 : */
953 : void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
954 : const SkPaint* paint = nullptr);
955 : void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
956 : const SkPaint* paint = nullptr);
957 :
958 : /** Draw the text, with origin at (x,y), using the specified paint.
959 : The origin is interpreted based on the Align setting in the paint.
960 : @param text The text to be drawn
961 : @param byteLength The number of bytes to read from the text parameter
962 : @param x The x-coordinate of the origin of the text being drawn
963 : @param y The y-coordinate of the origin of the text being drawn
964 : @param paint The paint used for the text (e.g. color, size, style)
965 : */
966 : void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
967 : const SkPaint& paint);
968 :
969 : /** Draw the text, with each character/glyph origin specified by the pos[]
970 : array. The origin is interpreted by the Align setting in the paint.
971 : @param text The text to be drawn
972 : @param byteLength The number of bytes to read from the text parameter
973 : @param pos Array of positions, used to position each character
974 : @param paint The paint used for the text (e.g. color, size, style)
975 : */
976 : void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
977 : const SkPaint& paint);
978 :
979 : /** Draw the text, with each character/glyph origin specified by the x
980 : coordinate taken from the xpos[] array, and the y from the constY param.
981 : The origin is interpreted by the Align setting in the paint.
982 : @param text The text to be drawn
983 : @param byteLength The number of bytes to read from the text parameter
984 : @param xpos Array of x-positions, used to position each character
985 : @param constY The shared Y coordinate for all of the positions
986 : @param paint The paint used for the text (e.g. color, size, style)
987 : */
988 : void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
989 : const SkPaint& paint);
990 :
991 : /** Draw the text, with origin at (x,y), using the specified paint, along
992 : the specified path. The paint's Align setting determins where along the
993 : path to start the text.
994 : @param text The text to be drawn
995 : @param byteLength The number of bytes to read from the text parameter
996 : @param path The path the text should follow for its baseline
997 : @param hOffset The distance along the path to add to the text's
998 : starting position
999 : @param vOffset The distance above(-) or below(+) the path to
1000 : position the text
1001 : @param paint The paint used for the text
1002 : */
1003 : void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
1004 : SkScalar vOffset, const SkPaint& paint);
1005 :
1006 : /** Draw the text, with origin at (x,y), using the specified paint, along
1007 : the specified path. The paint's Align setting determins where along the
1008 : path to start the text.
1009 : @param text The text to be drawn
1010 : @param byteLength The number of bytes to read from the text parameter
1011 : @param path The path the text should follow for its baseline
1012 : @param matrix (may be null) Applied to the text before it is
1013 : mapped onto the path
1014 : @param paint The paint used for the text
1015 : */
1016 : void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
1017 : const SkMatrix* matrix, const SkPaint& paint);
1018 :
1019 : /**
1020 : * Draw the text with each character/glyph individually transformed by its xform.
1021 : * If cullRect is not null, it is a conservative bounds of what will be drawn
1022 : * taking into account the xforms and the paint, and will be used to accelerate culling.
1023 : */
1024 : void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform[],
1025 : const SkRect* cullRect, const SkPaint& paint);
1026 :
1027 : /** Draw the text blob, offset by (x,y), using the specified paint.
1028 : @param blob The text blob to be drawn
1029 : @param x The x-offset of the text being drawn
1030 : @param y The y-offset of the text being drawn
1031 : @param paint The paint used for the text (e.g. color, size, style)
1032 : */
1033 : void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
1034 0 : void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
1035 0 : this->drawTextBlob(blob.get(), x, y, paint);
1036 0 : }
1037 :
1038 : /** Draw the picture into this canvas. This method effective brackets the
1039 : playback of the picture's draw calls with save/restore, so the state
1040 : of this canvas will be unchanged after this call.
1041 : @param picture The recorded drawing commands to playback into this
1042 : canvas.
1043 : */
1044 0 : void drawPicture(const SkPicture* picture) {
1045 0 : this->drawPicture(picture, NULL, NULL);
1046 0 : }
1047 : void drawPicture(const sk_sp<SkPicture>& picture) {
1048 : this->drawPicture(picture.get());
1049 : }
1050 :
1051 : /**
1052 : * Draw the picture into this canvas.
1053 : *
1054 : * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
1055 : * logically equivalent to
1056 : * save/concat/drawPicture/restore
1057 : *
1058 : * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
1059 : * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
1060 : * This is logically equivalent to
1061 : * saveLayer(paint)/drawPicture/restore
1062 : */
1063 : void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint);
1064 : void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint) {
1065 : this->drawPicture(picture.get(), matrix, paint);
1066 : }
1067 :
1068 : #ifdef SK_EXPERIMENTAL_SHADOWING
1069 : /**
1070 : * Draw the picture into this canvas, with shadows!
1071 : *
1072 : * We will use the canvas's lights along with the picture information (draw depths of
1073 : * objects, etc) to first create a set of shadowmaps for the light-picture pairs, and
1074 : * then use that set of shadowmaps to render the scene with shadows.
1075 : *
1076 : * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
1077 : * logically equivalent to
1078 : * save/concat/drawPicture/restore
1079 : *
1080 : * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
1081 : * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
1082 : * This is logically equivalent to
1083 : * saveLayer(paint)/drawPicture/restore
1084 : *
1085 : * We also support using variance shadow maps for blurred shadows; the user can specify
1086 : * what shadow mapping algorithm to use with params.
1087 : * - Variance Shadow Mapping works by storing both the depth and depth^2 in the shadow map.
1088 : * - Then, the shadow map can be blurred, and when reading from it, the fragment shader
1089 : * can calculate the variance of the depth at a position by doing E(x^2) - E(x)^2.
1090 : * - We can then use the depth variance and depth at a fragment to arrive at an upper bound
1091 : * of the probability that the current surface is shadowed by using Chebyshev's
1092 : * inequality, and then use that to shade the fragment.
1093 : *
1094 : * - There are a few problems with VSM.
1095 : * * Light Bleeding | Areas with high variance, such as near the edges of high up rects,
1096 : * will cause their shadow penumbras to overwrite otherwise solid
1097 : * shadows.
1098 : * * Shape Distortion | We can combat Light Bleeding by biasing the shadow (setting
1099 : * mostly shaded fragments to completely shaded) and increasing
1100 : * the minimum allowed variance. However, this warps and rounds
1101 : * out the shape of the shadow.
1102 : */
1103 : void drawShadowedPicture(const SkPicture*,
1104 : const SkMatrix* matrix,
1105 : const SkPaint* paint,
1106 : const SkShadowParams& params);
1107 : void drawShadowedPicture(const sk_sp<SkPicture>& picture,
1108 : const SkMatrix* matrix,
1109 : const SkPaint* paint,
1110 : const SkShadowParams& params) {
1111 : this->drawShadowedPicture(picture.get(), matrix, paint, params);
1112 : }
1113 : #endif
1114 :
1115 : /** Draw vertices from an immutable SkVertices object.
1116 :
1117 : @param vertices The mesh to draw.
1118 : @param mode Used if both texs and colors are present and paint has a
1119 : shader. In this case the colors are combined with the texture
1120 : using mode, before being drawn using the paint.
1121 : @param paint Specifies the shader/texture if present.
1122 : */
1123 : void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
1124 : void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
1125 :
1126 : /**
1127 : Draw a cubic coons patch
1128 :
1129 : @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
1130 : starting at the top left corner.
1131 : @param colors specifies the colors for the corners which will be bilerp across the patch,
1132 : their order is clockwise starting at the top left corner.
1133 : @param texCoords specifies the texture coordinates that will be bilerp across the patch,
1134 : their order is the same as the colors.
1135 : @param mode specifies how are the colors and the textures combined if both of them are
1136 : present.
1137 : @param paint Specifies the shader/texture if present.
1138 : */
1139 : void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
1140 : const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
1141 : void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
1142 : const SkPoint texCoords[4], const SkPaint& paint) {
1143 : this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
1144 : }
1145 :
1146 : /**
1147 : * Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the
1148 : * coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle
1149 : * into a quad.
1150 : *
1151 : * xform maps [0, 0, tex.width, tex.height] -> quad
1152 : *
1153 : * The color array is optional. When specified, each color modulates the pixels in its
1154 : * corresponding quad (via the specified SkBlendMode).
1155 : *
1156 : * The cullRect is optional. When specified, it must be a conservative bounds of all of the
1157 : * resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not
1158 : * intersect the current clip.
1159 : *
1160 : * The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter
1161 : * and blendmode are used to affect each of the quads.
1162 : */
1163 : void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
1164 : const SkColor colors[], int count, SkBlendMode, const SkRect* cullRect,
1165 : const SkPaint* paint);
1166 0 : void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
1167 : const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
1168 : const SkPaint* paint) {
1169 0 : this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
1170 0 : }
1171 : void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
1172 : const SkRect* cullRect, const SkPaint* paint) {
1173 : this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
1174 : }
1175 : void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
1176 : int count, const SkRect* cullRect, const SkPaint* paint) {
1177 : this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
1178 : cullRect, paint);
1179 : }
1180 :
1181 : /**
1182 : * Draw the contents of this drawable into the canvas. If the canvas is async
1183 : * (e.g. it is recording into a picture) then the drawable will be referenced instead,
1184 : * to have its draw() method called when the picture is finalized.
1185 : *
1186 : * If the intent is to force the contents of the drawable into this canvas immediately,
1187 : * then drawable->draw(canvas) may be called.
1188 : */
1189 : void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL);
1190 : void drawDrawable(SkDrawable*, SkScalar x, SkScalar y);
1191 :
1192 : /**
1193 : * Send an "annotation" to the canvas. The annotation is a key/value pair, where the key is
1194 : * a null-terminated utf8 string, and the value is a blob of data stored in an SkData
1195 : * (which may be null). The annotation is associated with the specified rectangle.
1196 : *
1197 : * The caller still retains its ownership of the data (if any).
1198 : *
1199 : * Note: on may canvas types, this information is ignored, but some canvases (e.g. recording
1200 : * a picture or drawing to a PDF document) will pass on this information.
1201 : */
1202 : void drawAnnotation(const SkRect&, const char key[], SkData* value);
1203 0 : void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
1204 0 : this->drawAnnotation(rect, key, value.get());
1205 0 : }
1206 :
1207 : //////////////////////////////////////////////////////////////////////////
1208 : #ifdef SK_INTERNAL
1209 : #ifndef SK_SUPPORT_LEGACY_DRAWFILTER
1210 : #define SK_SUPPORT_LEGACY_DRAWFILTER
1211 : #endif
1212 : #endif
1213 :
1214 : #ifdef SK_SUPPORT_LEGACY_DRAWFILTER
1215 : /** Get the current filter object. The filter's reference count is not
1216 : affected. The filter is saved/restored, just like the matrix and clip.
1217 : @return the canvas' filter (or NULL).
1218 : */
1219 : SK_ATTR_EXTERNALLY_DEPRECATED("getDrawFilter use is deprecated")
1220 : SkDrawFilter* getDrawFilter() const;
1221 :
1222 : /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
1223 : As a convenience, the parameter is returned. If an existing filter
1224 : exists, its refcnt is decrement. If the new filter is not null, its
1225 : refcnt is incremented. The filter is saved/restored, just like the
1226 : matrix and clip.
1227 : @param filter the new filter (or NULL)
1228 : @return the new filter
1229 : */
1230 : SK_ATTR_EXTERNALLY_DEPRECATED("setDrawFilter use is deprecated")
1231 : virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
1232 : #endif
1233 : //////////////////////////////////////////////////////////////////////////
1234 :
1235 : /**
1236 : * Return true if the current clip is empty (i.e. nothing will draw).
1237 : * Note: this is not always a free call, so it should not be used
1238 : * more often than necessary. However, once the canvas has computed this
1239 : * result, subsequent calls will be cheap (until the clip state changes,
1240 : * which can happen on any clip..() or restore() call.
1241 : */
1242 : virtual bool isClipEmpty() const;
1243 :
1244 : /**
1245 : * Returns true if the current clip is just a (non-empty) rectangle.
1246 : * Returns false if the clip is empty, or if it is complex.
1247 : */
1248 : virtual bool isClipRect() const;
1249 :
1250 : /** Return the current matrix on the canvas.
1251 : This does not account for the translate in any of the devices.
1252 : @return The current matrix on the canvas.
1253 : */
1254 : const SkMatrix& getTotalMatrix() const;
1255 :
1256 : #ifdef SK_SUPPORT_OBSOLETE_REPLAYCLIP
1257 : typedef SkCanvasClipVisitor ClipVisitor;
1258 : /**
1259 : * Replays the clip operations, back to front, that have been applied to
1260 : * the canvas, calling the appropriate method on the visitor for each
1261 : * clip. All clips have already been transformed into device space.
1262 : */
1263 : void replayClips(ClipVisitor*) const;
1264 : #endif
1265 :
1266 : ///////////////////////////////////////////////////////////////////////////
1267 :
1268 : // don't call
1269 : GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
1270 :
1271 : // don't call
1272 : static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
1273 : static bool Internal_Private_GetIgnoreSaveLayerBounds();
1274 : static void Internal_Private_SetTreatSpriteAsBitmap(bool);
1275 : static bool Internal_Private_GetTreatSpriteAsBitmap();
1276 :
1277 : // TEMP helpers until we switch virtual over to const& for src-rect
1278 : void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
1279 : const SkPaint* paint,
1280 : SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1281 : void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
1282 : const SkPaint* paint,
1283 : SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1284 :
1285 : // expose minimum amount of information necessary for transitional refactoring
1286 : /**
1287 : * Returns CTM and clip bounds, translated from canvas coordinates to top layer coordinates.
1288 : */
1289 : void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds);
1290 :
1291 : /**
1292 : * Returns the global clip as a region. If the clip contains AA, then only the bounds
1293 : * of the clip may be returned.
1294 : */
1295 : void temporary_internal_getRgnClip(SkRegion*);
1296 :
1297 : protected:
1298 : #ifdef SK_EXPERIMENTAL_SHADOWING
1299 : /** Returns the current (cumulative) draw depth of the canvas.
1300 : */
1301 : SkScalar getZ() const;
1302 :
1303 : sk_sp<SkLights> fLights;
1304 : #endif
1305 :
1306 : // default impl defers to getDevice()->newSurface(info)
1307 : virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
1308 :
1309 : // default impl defers to its device
1310 : virtual bool onPeekPixels(SkPixmap*);
1311 : virtual bool onAccessTopLayerPixels(SkPixmap*);
1312 : virtual SkImageInfo onImageInfo() const;
1313 : virtual bool onGetProps(SkSurfaceProps*) const;
1314 : virtual void onFlush();
1315 :
1316 : // Subclass save/restore notifiers.
1317 : // Overriders should call the corresponding INHERITED method up the inheritance chain.
1318 : // getSaveLayerStrategy()'s return value may suppress full layer allocation.
1319 : enum SaveLayerStrategy {
1320 : kFullLayer_SaveLayerStrategy,
1321 : kNoLayer_SaveLayerStrategy,
1322 : };
1323 :
1324 595 : virtual void willSave() {}
1325 : // Overriders should call the corresponding INHERITED method up the inheritance chain.
1326 22 : virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) {
1327 22 : return kFullLayer_SaveLayerStrategy;
1328 : }
1329 617 : virtual void willRestore() {}
1330 617 : virtual void didRestore() {}
1331 0 : virtual void didConcat(const SkMatrix&) {}
1332 2039 : virtual void didSetMatrix(const SkMatrix&) {}
1333 0 : virtual void didTranslate(SkScalar dx, SkScalar dy) {
1334 0 : this->didConcat(SkMatrix::MakeTrans(dx, dy));
1335 0 : }
1336 :
1337 : #ifdef SK_EXPERIMENTAL_SHADOWING
1338 : virtual void didTranslateZ(SkScalar) {}
1339 : #endif
1340 :
1341 : virtual SkRect onGetLocalClipBounds() const;
1342 : virtual SkIRect onGetDeviceClipBounds() const;
1343 :
1344 :
1345 : virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value);
1346 : virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
1347 :
1348 : virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
1349 : SkScalar y, const SkPaint& paint);
1350 :
1351 : virtual void onDrawPosText(const void* text, size_t byteLength,
1352 : const SkPoint pos[], const SkPaint& paint);
1353 :
1354 : virtual void onDrawPosTextH(const void* text, size_t byteLength,
1355 : const SkScalar xpos[], SkScalar constY,
1356 : const SkPaint& paint);
1357 :
1358 : virtual void onDrawTextOnPath(const void* text, size_t byteLength,
1359 : const SkPath& path, const SkMatrix* matrix,
1360 : const SkPaint& paint);
1361 : virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform[],
1362 : const SkRect* cullRect, const SkPaint& paint);
1363 :
1364 : virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
1365 : const SkPaint& paint);
1366 :
1367 : virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
1368 : const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
1369 :
1370 : virtual void onDrawDrawable(SkDrawable*, const SkMatrix*);
1371 :
1372 : virtual void onDrawPaint(const SkPaint&);
1373 : virtual void onDrawRect(const SkRect&, const SkPaint&);
1374 : virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
1375 : virtual void onDrawOval(const SkRect&, const SkPaint&);
1376 : virtual void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
1377 : const SkPaint&);
1378 : virtual void onDrawRRect(const SkRRect&, const SkPaint&);
1379 : virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&);
1380 : virtual void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&);
1381 : virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
1382 : int count, SkBlendMode, const SkRect* cull, const SkPaint*);
1383 : virtual void onDrawPath(const SkPath&, const SkPaint&);
1384 : virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
1385 : virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
1386 : SrcRectConstraint);
1387 : virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
1388 : const SkPaint*);
1389 : virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst,
1390 : const SkPaint*);
1391 :
1392 : virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*);
1393 : virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
1394 : SrcRectConstraint);
1395 : virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
1396 : const SkPaint*);
1397 : virtual void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst,
1398 : const SkPaint*);
1399 :
1400 : enum ClipEdgeStyle {
1401 : kHard_ClipEdgeStyle,
1402 : kSoft_ClipEdgeStyle
1403 : };
1404 :
1405 : virtual void onClipRect(const SkRect& rect, SkClipOp, ClipEdgeStyle);
1406 : virtual void onClipRRect(const SkRRect& rrect, SkClipOp, ClipEdgeStyle);
1407 : virtual void onClipPath(const SkPath& path, SkClipOp, ClipEdgeStyle);
1408 : virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp);
1409 :
1410 : virtual void onDiscard();
1411 :
1412 : virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
1413 :
1414 : #ifdef SK_EXPERIMENTAL_SHADOWING
1415 : virtual void onDrawShadowedPicture(const SkPicture*,
1416 : const SkMatrix*,
1417 : const SkPaint*,
1418 : const SkShadowParams& params);
1419 : #endif
1420 :
1421 : // Clip rectangle bounds. Called internally by saveLayer.
1422 : // returns false if the entire rectangle is entirely clipped out
1423 : // If non-NULL, The imageFilter parameter will be used to expand the clip
1424 : // and offscreen bounds for any margin required by the filter DAG.
1425 : bool clipRectBounds(const SkRect* bounds, SaveLayerFlags, SkIRect* intersection,
1426 : const SkImageFilter* imageFilter = NULL);
1427 :
1428 : private:
1429 : /** After calling saveLayer(), there can be any number of devices that make
1430 : up the top-most drawing area. LayerIter can be used to iterate through
1431 : those devices. Note that the iterator is only valid until the next API
1432 : call made on the canvas. Ownership of all pointers in the iterator stays
1433 : with the canvas, so none of them should be modified or deleted.
1434 : */
1435 : class LayerIter /*: SkNoncopyable*/ {
1436 : public:
1437 : /** Initialize iterator with canvas, and set values for 1st device */
1438 : LayerIter(SkCanvas*);
1439 : ~LayerIter();
1440 :
1441 : /** Return true if the iterator is done */
1442 : bool done() const { return fDone; }
1443 : /** Cycle to the next device */
1444 : void next();
1445 :
1446 : // These reflect the current device in the iterator
1447 :
1448 : SkBaseDevice* device() const;
1449 : const SkMatrix& matrix() const;
1450 : void clip(SkRegion*) const;
1451 : const SkPaint& paint() const;
1452 : int x() const;
1453 : int y() const;
1454 :
1455 : private:
1456 : // used to embed the SkDrawIter object directly in our instance, w/o
1457 : // having to expose that class def to the public. There is an assert
1458 : // in our constructor to ensure that fStorage is large enough
1459 : // (though needs to be a compile-time-assert!). We use intptr_t to work
1460 : // safely with 32 and 64 bit machines (to ensure the storage is enough)
1461 : intptr_t fStorage[32];
1462 : class SkDrawIter* fImpl; // this points at fStorage
1463 : SkPaint fDefaultPaint;
1464 : bool fDone;
1465 : };
1466 :
1467 : static bool BoundsAffectsClip(SaveLayerFlags);
1468 : static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags);
1469 :
1470 : static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
1471 : SkBaseDevice* dst, const SkIPoint& dstOrigin,
1472 : const SkMatrix& ctm);
1473 :
1474 : enum ShaderOverrideOpacity {
1475 : kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
1476 : kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
1477 : kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque
1478 : };
1479 :
1480 : // notify our surface (if we have one) that we are about to draw, so it
1481 : // can perform copy-on-write or invalidate any cached images
1482 : void predrawNotify(bool willOverwritesEntireSurface = false);
1483 : void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
1484 331 : void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
1485 331 : this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
1486 331 : : kNotOpaque_ShaderOverrideOpacity);
1487 331 : }
1488 :
1489 : public:
1490 : SkBaseDevice* getDevice() const;
1491 : SkBaseDevice* getTopDevice() const;
1492 : private:
1493 :
1494 : class MCRec;
1495 :
1496 : SkDeque fMCStack;
1497 : // points to top of stack
1498 : MCRec* fMCRec;
1499 : // the first N recs that can fit here mean we won't call malloc
1500 : enum {
1501 : kMCRecSize = 128, // most recent measurement
1502 : kMCRecCount = 32, // common depth for save/restores
1503 : kDeviceCMSize = 184, // most recent measurement
1504 : };
1505 : intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
1506 : intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
1507 :
1508 : const SkSurfaceProps fProps;
1509 :
1510 : int fSaveCount; // value returned by getSaveCount()
1511 :
1512 : SkMetaData* fMetaData;
1513 : std::unique_ptr<SkRasterHandleAllocator> fAllocator;
1514 :
1515 : SkSurface_Base* fSurfaceBase;
1516 452 : SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
1517 100 : void setSurfaceBase(SkSurface_Base* sb) {
1518 100 : fSurfaceBase = sb;
1519 100 : }
1520 : friend class SkSurface_Base;
1521 : friend class SkSurface_Gpu;
1522 :
1523 : SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
1524 :
1525 : void doSave();
1526 : void checkForDeferredSave();
1527 : void internalSetMatrix(const SkMatrix&);
1528 :
1529 : friend class SkDrawIter; // needs setupDrawForLayerDevice()
1530 : friend class AutoDrawLooper;
1531 : friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
1532 : friend class SkSurface_Raster; // needs getDevice()
1533 : friend class SkRecorder; // resetForNextPicture
1534 : friend class SkLiteRecorder; // resetForNextPicture
1535 : friend class SkNoDrawCanvas; // InitFlags
1536 : friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
1537 : friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
1538 : friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
1539 : friend class SkDeferredCanvas; // For use of resetForNextPicture
1540 : friend class SkOverdrawCanvas;
1541 : friend class SkRasterHandleAllocator;
1542 :
1543 : enum InitFlags {
1544 : kDefault_InitFlags = 0,
1545 : kConservativeRasterClip_InitFlag = 1 << 0,
1546 : };
1547 : SkCanvas(const SkIRect& bounds, InitFlags);
1548 : SkCanvas(SkBaseDevice* device, InitFlags);
1549 : SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
1550 : SkRasterHandleAllocator::Handle);
1551 :
1552 : void resetForNextPicture(const SkIRect& bounds);
1553 :
1554 : // needs gettotalclip()
1555 : friend class SkCanvasStateUtils;
1556 :
1557 : // call this each time we attach ourselves to a device
1558 : // - constructor
1559 : // - internalSaveLayer
1560 : void setupDevice(SkBaseDevice*);
1561 :
1562 : SkBaseDevice* init(SkBaseDevice*, InitFlags);
1563 :
1564 : /**
1565 : * Gets the bounds of the top level layer in global canvas coordinates. We don't want this
1566 : * to be public because it exposes decisions about layer sizes that are internal to the canvas.
1567 : */
1568 : SkIRect getTopLayerBounds() const;
1569 :
1570 : void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
1571 : const SkRect& dst, const SkPaint* paint,
1572 : SrcRectConstraint);
1573 : void internalDrawPaint(const SkPaint& paint);
1574 : void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
1575 : void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
1576 :
1577 : // shared by save() and saveLayer()
1578 : void internalSave();
1579 : void internalRestore();
1580 :
1581 : /*
1582 : * Returns true if drawing the specified rect (or all if it is null) with the specified
1583 : * paint (or default if null) would overwrite the entire root device of the canvas
1584 : * (i.e. the canvas' surface if it had one).
1585 : */
1586 : bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
1587 :
1588 : /**
1589 : * Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
1590 : */
1591 : bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
1592 :
1593 : /**
1594 : * Returns true if the clip (for any active layer) contains antialiasing.
1595 : * If the clip is empty, this will return false.
1596 : */
1597 : bool androidFramework_isClipAA() const;
1598 :
1599 : /**
1600 : * Keep track of the device clip bounds and if the matrix is scale-translate. This allows
1601 : * us to do a fast quick reject in the common case.
1602 : */
1603 : bool fIsScaleTranslate;
1604 : SkRect fDeviceClipBounds;
1605 :
1606 : bool fAllowSoftClip;
1607 : bool fAllowSimplifyClip;
1608 :
1609 : class AutoValidateClip : ::SkNoncopyable {
1610 : public:
1611 595 : explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
1612 595 : fCanvas->validateClip();
1613 595 : }
1614 595 : ~AutoValidateClip() { fCanvas->validateClip(); }
1615 :
1616 : private:
1617 : const SkCanvas* fCanvas;
1618 : };
1619 :
1620 : #ifdef SK_DEBUG
1621 : void validateClip() const;
1622 : #else
1623 : void validateClip() const {}
1624 : #endif
1625 :
1626 : typedef SkRefCnt INHERITED;
1627 : };
1628 :
1629 : /** Stack helper class to automatically call restoreToCount() on the canvas
1630 : when this object goes out of scope. Use this to guarantee that the canvas
1631 : is restored to a known state.
1632 : */
1633 : class SkAutoCanvasRestore : SkNoncopyable {
1634 : public:
1635 0 : SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
1636 0 : if (fCanvas) {
1637 0 : fSaveCount = canvas->getSaveCount();
1638 0 : if (doSave) {
1639 0 : canvas->save();
1640 : }
1641 : }
1642 0 : }
1643 0 : ~SkAutoCanvasRestore() {
1644 0 : if (fCanvas) {
1645 0 : fCanvas->restoreToCount(fSaveCount);
1646 : }
1647 0 : }
1648 :
1649 : /**
1650 : * Perform the restore now, instead of waiting for the destructor. Will
1651 : * only do this once.
1652 : */
1653 : void restore() {
1654 : if (fCanvas) {
1655 : fCanvas->restoreToCount(fSaveCount);
1656 : fCanvas = NULL;
1657 : }
1658 : }
1659 :
1660 : private:
1661 : SkCanvas* fCanvas;
1662 : int fSaveCount;
1663 : };
1664 : #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
1665 :
1666 : #ifdef SK_SUPPORT_OBSOLETE_REPLAYCLIP
1667 : class SkCanvasClipVisitor {
1668 : public:
1669 : virtual ~SkCanvasClipVisitor();
1670 : virtual void clipRect(const SkRect&, SkClipOp, bool antialias) = 0;
1671 : virtual void clipRRect(const SkRRect&, SkClipOp, bool antialias) = 0;
1672 : virtual void clipPath(const SkPath&, SkClipOp, bool antialias) = 0;
1673 : };
1674 : #endif
1675 :
1676 : #endif
|