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 "include/core/SkBlendMode.h"
12#include "include/core/SkClipOp.h"
13#include "include/core/SkColor.h"
14#include "include/core/SkFontTypes.h"
15#include "include/core/SkImageInfo.h"
16#include "include/core/SkM44.h"
17#include "include/core/SkMatrix.h"
18#include "include/core/SkPaint.h"
19#include "include/core/SkPoint.h"
20#include "include/core/SkRasterHandleAllocator.h"
21#include "include/core/SkRect.h"
22#include "include/core/SkRefCnt.h"
23#include "include/core/SkScalar.h"
24#include "include/core/SkSize.h"
25#include "include/core/SkString.h"
26#include "include/core/SkSurfaceProps.h"
27#include "include/core/SkTypes.h"
28#include "include/private/SkDeque.h"
29#include "include/private/SkMacros.h"
30
31#include <cstring>
32#include <memory>
33#include <vector>
34
35class GrContext;
36class GrRenderTargetContext;
37class SkBaseDevice;
38class SkBitmap;
39class SkData;
40class SkDrawable;
41struct SkDrawShadowRec;
42class SkFont;
43class SkGlyphRunBuilder;
44class SkImage;
45class SkImageFilter;
46class SkPaintFilterCanvas;
47class SkPath;
48class SkPicture;
49class SkPixmap;
50class SkRegion;
51class SkRRect;
52struct SkRSXform;
53class SkSurface;
54class SkSurface_Base;
55class SkTextBlob;
56class SkVertices;
57
58/** \class SkCanvas
59 SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
60 SkCanvas contains a stack of SkMatrix and clip values.
61
62 SkCanvas and SkPaint together provide the state to draw into SkSurface or SkBaseDevice.
63 Each SkCanvas draw call transforms the geometry of the object by the concatenation of all
64 SkMatrix values in the stack. The transformed geometry is clipped by the intersection
65 of all of clip values in the stack. The SkCanvas draw calls use SkPaint to supply drawing
66 state such as color, SkTypeface, text size, stroke width, SkShader and so on.
67
68 To draw to a pixel-based destination, create raster surface or GPU surface.
69 Request SkCanvas from SkSurface to obtain the interface to draw.
70 SkCanvas generated by raster surface draws to memory visible to the CPU.
71 SkCanvas generated by GPU surface uses Vulkan or OpenGL to draw to the GPU.
72
73 To draw to a document, obtain SkCanvas from SVG canvas, document PDF, or SkPictureRecorder.
74 SkDocument based SkCanvas and other SkCanvas subclasses reference SkBaseDevice describing the
75 destination.
76
77 SkCanvas can be constructed to draw to SkBitmap without first creating raster surface.
78 This approach may be deprecated in the future.
79*/
80class SK_API SkCanvas {
81 enum PrivateSaveLayerFlags {
82 kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31,
83 };
84
85public:
86
87 /** Allocates raster SkCanvas that will draw directly into pixels.
88
89 SkCanvas is returned if all parameters are valid.
90 Valid parameters include:
91 info dimensions are zero or positive;
92 info contains SkColorType and SkAlphaType supported by raster surface;
93 pixels is not nullptr;
94 rowBytes is zero or large enough to contain info width pixels of SkColorType.
95
96 Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
97 If rowBytes is greater than zero, it must be equal to or greater than
98 info width times bytes required for SkColorType.
99
100 Pixel buffer size should be info height times computed rowBytes.
101 Pixels are not initialized.
102 To access pixels after drawing, call flush() or peekPixels().
103
104 @param info width, height, SkColorType, SkAlphaType, SkColorSpace, of raster surface;
105 width, or height, or both, may be zero
106 @param pixels pointer to destination pixels buffer
107 @param rowBytes interval from one SkSurface row to the next, or zero
108 @param props LCD striping orientation and setting for device independent fonts;
109 may be nullptr
110 @return SkCanvas if all parameters are valid; otherwise, nullptr
111 */
112 static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
113 size_t rowBytes,
114 const SkSurfaceProps* props = nullptr);
115
116 /** Allocates raster SkCanvas specified by inline image specification. Subsequent SkCanvas
117 calls draw into pixels.
118 SkColorType is set to kN32_SkColorType.
119 SkAlphaType is set to kPremul_SkAlphaType.
120 To access pixels after drawing, call flush() or peekPixels().
121
122 SkCanvas is returned if all parameters are valid.
123 Valid parameters include:
124 width and height are zero or positive;
125 pixels is not nullptr;
126 rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
127
128 Pass zero for rowBytes to compute rowBytes from width and size of pixel.
129 If rowBytes is greater than zero, it must be equal to or greater than
130 width times bytes required for SkColorType.
131
132 Pixel buffer size should be height times rowBytes.
133
134 @param width pixel column count on raster surface created; must be zero or greater
135 @param height pixel row count on raster surface created; must be zero or greater
136 @param pixels pointer to destination pixels buffer; buffer size should be height
137 times rowBytes
138 @param rowBytes interval from one SkSurface row to the next, or zero
139 @return SkCanvas if all parameters are valid; otherwise, nullptr
140 */
141 static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
142 size_t rowBytes) {
143 return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
144 }
145
146 /** Creates an empty SkCanvas with no backing device or pixels, with
147 a width and height of zero.
148
149 @return empty SkCanvas
150
151 example: https://fiddle.skia.org/c/@Canvas_empty_constructor
152 */
153 SkCanvas();
154
155 /** Creates SkCanvas of the specified dimensions without a SkSurface.
156 Used by subclasses with custom implementations for draw member functions.
157
158 If props equals nullptr, SkSurfaceProps are created with
159 SkSurfaceProps::InitType settings, which choose the pixel striping
160 direction and order. Since a platform may dynamically change its direction when
161 the device is rotated, and since a platform may have multiple monitors with
162 different characteristics, it is best not to rely on this legacy behavior.
163
164 @param width zero or greater
165 @param height zero or greater
166 @param props LCD striping orientation and setting for device independent fonts;
167 may be nullptr
168 @return SkCanvas placeholder with dimensions
169
170 example: https://fiddle.skia.org/c/@Canvas_int_int_const_SkSurfaceProps_star
171 */
172 SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr);
173
174 /** Private. For internal use only.
175 */
176 explicit SkCanvas(sk_sp<SkBaseDevice> device);
177
178 /** Constructs a canvas that draws into bitmap.
179 Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed SkSurface.
180
181 SkBitmap is copied so that subsequently editing bitmap will not affect
182 constructed SkCanvas.
183
184 May be deprecated in the future.
185
186 @param bitmap width, height, SkColorType, SkAlphaType, and pixel
187 storage of raster surface
188 @return SkCanvas that can be used to draw into bitmap
189
190 example: https://fiddle.skia.org/c/@Canvas_copy_const_SkBitmap
191 */
192 explicit SkCanvas(const SkBitmap& bitmap);
193
194#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
195 /** Private.
196 */
197 enum class ColorBehavior {
198 kLegacy, //!< placeholder
199 };
200
201 /** Private. For use by Android framework only.
202
203 @param bitmap specifies a bitmap for the canvas to draw into
204 @param behavior specializes this constructor; value is unused
205 @return SkCanvas that can be used to draw into bitmap
206 */
207 SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior);
208#endif
209
210 /** Constructs a canvas that draws into bitmap.
211 Use props to match the device characteristics, like LCD striping.
212
213 bitmap is copied so that subsequently editing bitmap will not affect
214 constructed SkCanvas.
215
216 @param bitmap width, height, SkColorType, SkAlphaType,
217 and pixel storage of raster surface
218 @param props order and orientation of RGB striping; and whether to use
219 device independent fonts
220 @return SkCanvas that can be used to draw into bitmap
221
222 example: https://fiddle.skia.org/c/@Canvas_const_SkBitmap_const_SkSurfaceProps
223 */
224 SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
225
226 /** Draws saved layers, if any.
227 Frees up resources used by SkCanvas.
228
229 example: https://fiddle.skia.org/c/@Canvas_destructor
230 */
231 virtual ~SkCanvas();
232
233 /** Returns SkImageInfo for SkCanvas. If SkCanvas is not associated with raster surface or
234 GPU surface, returned SkColorType is set to kUnknown_SkColorType.
235
236 @return dimensions and SkColorType of SkCanvas
237
238 example: https://fiddle.skia.org/c/@Canvas_imageInfo
239 */
240 SkImageInfo imageInfo() const;
241
242 /** Copies SkSurfaceProps, if SkCanvas is associated with raster surface or
243 GPU surface, and returns true. Otherwise, returns false and leave props unchanged.
244
245 @param props storage for writable SkSurfaceProps
246 @return true if SkSurfaceProps was copied
247
248 example: https://fiddle.skia.org/c/@Canvas_getProps
249 */
250 bool getProps(SkSurfaceProps* props) const;
251
252 /** Triggers the immediate execution of all pending draw operations.
253 If SkCanvas is associated with GPU surface, resolves all pending GPU operations.
254 If SkCanvas is associated with raster surface, has no effect; raster draw
255 operations are never deferred.
256 */
257 void flush();
258
259 /** Gets the size of the base or root layer in global canvas coordinates. The
260 origin of the base layer is always (0,0). The area available for drawing may be
261 smaller (due to clipping or saveLayer).
262
263 @return integral width and height of base layer
264
265 example: https://fiddle.skia.org/c/@Canvas_getBaseLayerSize
266 */
267 virtual SkISize getBaseLayerSize() const;
268
269 /** Creates SkSurface matching info and props, and associates it with SkCanvas.
270 Returns nullptr if no match found.
271
272 If props is nullptr, matches SkSurfaceProps in SkCanvas. If props is nullptr and SkCanvas
273 does not have SkSurfaceProps, creates SkSurface with default SkSurfaceProps.
274
275 @param info width, height, SkColorType, SkAlphaType, and SkColorSpace
276 @param props SkSurfaceProps to match; may be nullptr to match SkCanvas
277 @return SkSurface matching info and props, or nullptr if no match is available
278
279 example: https://fiddle.skia.org/c/@Canvas_makeSurface
280 */
281 sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr);
282
283 /** Returns GPU context of the GPU surface associated with SkCanvas.
284
285 @return GPU context, if available; nullptr otherwise
286
287 example: https://fiddle.skia.org/c/@Canvas_getGrContext
288 */
289 virtual GrContext* getGrContext();
290
291 /** Sometimes a canvas is owned by a surface. If it is, getSurface() will return a bare
292 * pointer to that surface, else this will return nullptr.
293 */
294 SkSurface* getSurface() const;
295
296 /** Returns the pixel base address, SkImageInfo, rowBytes, and origin if the pixels
297 can be read directly. The returned address is only valid
298 while SkCanvas is in scope and unchanged. Any SkCanvas call or SkSurface call
299 may invalidate the returned address and other returned values.
300
301 If pixels are inaccessible, info, rowBytes, and origin are unchanged.
302
303 @param info storage for writable pixels' SkImageInfo; may be nullptr
304 @param rowBytes storage for writable pixels' row bytes; may be nullptr
305 @param origin storage for SkCanvas top layer origin, its top-left corner;
306 may be nullptr
307 @return address of pixels, or nullptr if inaccessible
308
309 example: https://fiddle.skia.org/c/@Canvas_accessTopLayerPixels_a
310 example: https://fiddle.skia.org/c/@Canvas_accessTopLayerPixels_b
311 */
312 void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr);
313
314 /** Returns custom context that tracks the SkMatrix and clip.
315
316 Use SkRasterHandleAllocator to blend Skia drawing with custom drawing, typically performed
317 by the host platform user interface. The custom context returned is generated by
318 SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
319 the drawing destination.
320
321 @return context of custom allocation
322
323 example: https://fiddle.skia.org/c/@Canvas_accessTopRasterHandle
324 */
325 SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
326
327 /** Returns true if SkCanvas has direct access to its pixels.
328
329 Pixels are readable when SkBaseDevice is raster. Pixels are not readable when SkCanvas
330 is returned from GPU surface, returned by SkDocument::beginPage, returned by
331 SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
332 like DebugCanvas.
333
334 pixmap is valid only while SkCanvas is in scope and unchanged. Any
335 SkCanvas or SkSurface call may invalidate the pixmap values.
336
337 @param pixmap storage for pixel state if pixels are readable; otherwise, ignored
338 @return true if SkCanvas has direct access to pixels
339
340 example: https://fiddle.skia.org/c/@Canvas_peekPixels
341 */
342 bool peekPixels(SkPixmap* pixmap);
343
344 /** Copies SkRect of pixels from SkCanvas into dstPixels. SkMatrix and clip are
345 ignored.
346
347 Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
348 Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
349 Copies each readable pixel intersecting both rectangles, without scaling,
350 converting to dstInfo.colorType() and dstInfo.alphaType() if required.
351
352 Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
353 Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
354 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
355 class like DebugCanvas.
356
357 The destination pixel storage must be allocated by the caller.
358
359 Pixel values are converted only if SkColorType and SkAlphaType
360 do not match. Only pixels within both source and destination rectangles
361 are copied. dstPixels contents outside SkRect intersection are unchanged.
362
363 Pass negative values for srcX or srcY to offset pixels across or down destination.
364
365 Does not copy, and returns false if:
366 - Source and destination rectangles do not intersect.
367 - SkCanvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
368 - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
369 - dstRowBytes is too small to contain one row of pixels.
370
371 @param dstInfo width, height, SkColorType, and SkAlphaType of dstPixels
372 @param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger
373 @param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger
374 @param srcX offset into readable pixels on x-axis; may be negative
375 @param srcY offset into readable pixels on y-axis; may be negative
376 @return true if pixels were copied
377 */
378 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
379 int srcX, int srcY);
380
381 /** Copies SkRect of pixels from SkCanvas into pixmap. SkMatrix and clip are
382 ignored.
383
384 Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
385 Destination SkRect corners are (0, 0) and (pixmap.width(), pixmap.height()).
386 Copies each readable pixel intersecting both rectangles, without scaling,
387 converting to pixmap.colorType() and pixmap.alphaType() if required.
388
389 Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
390 Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
391 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
392 class like DebugCanvas.
393
394 Caller must allocate pixel storage in pixmap if needed.
395
396 Pixel values are converted only if SkColorType and SkAlphaType
397 do not match. Only pixels within both source and destination SkRect
398 are copied. pixmap pixels contents outside SkRect intersection are unchanged.
399
400 Pass negative values for srcX or srcY to offset pixels across or down pixmap.
401
402 Does not copy, and returns false if:
403 - Source and destination rectangles do not intersect.
404 - SkCanvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType().
405 - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
406 - SkPixmap pixels could not be allocated.
407 - pixmap.rowBytes() is too small to contain one row of pixels.
408
409 @param pixmap storage for pixels copied from SkCanvas
410 @param srcX offset into readable pixels on x-axis; may be negative
411 @param srcY offset into readable pixels on y-axis; may be negative
412 @return true if pixels were copied
413
414 example: https://fiddle.skia.org/c/@Canvas_readPixels_2
415 */
416 bool readPixels(const SkPixmap& pixmap, int srcX, int srcY);
417
418 /** Copies SkRect of pixels from SkCanvas into bitmap. SkMatrix and clip are
419 ignored.
420
421 Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
422 Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
423 Copies each readable pixel intersecting both rectangles, without scaling,
424 converting to bitmap.colorType() and bitmap.alphaType() if required.
425
426 Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
427 Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
428 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
429 class like DebugCanvas.
430
431 Caller must allocate pixel storage in bitmap if needed.
432
433 SkBitmap values are converted only if SkColorType and SkAlphaType
434 do not match. Only pixels within both source and destination rectangles
435 are copied. SkBitmap pixels outside SkRect intersection are unchanged.
436
437 Pass negative values for srcX or srcY to offset pixels across or down bitmap.
438
439 Does not copy, and returns false if:
440 - Source and destination rectangles do not intersect.
441 - SkCanvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType().
442 - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
443 - bitmap pixels could not be allocated.
444 - bitmap.rowBytes() is too small to contain one row of pixels.
445
446 @param bitmap storage for pixels copied from SkCanvas
447 @param srcX offset into readable pixels on x-axis; may be negative
448 @param srcY offset into readable pixels on y-axis; may be negative
449 @return true if pixels were copied
450
451 example: https://fiddle.skia.org/c/@Canvas_readPixels_3
452 */
453 bool readPixels(const SkBitmap& bitmap, int srcX, int srcY);
454
455 /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
456 Source SkRect corners are (0, 0) and (info.width(), info.height()).
457 Destination SkRect corners are (x, y) and
458 (imageInfo().width(), imageInfo().height()).
459
460 Copies each readable pixel intersecting both rectangles, without scaling,
461 converting to imageInfo().colorType() and imageInfo().alphaType() if required.
462
463 Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
464 Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
465 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
466 class like DebugCanvas.
467
468 Pixel values are converted only if SkColorType and SkAlphaType
469 do not match. Only pixels within both source and destination rectangles
470 are copied. SkCanvas pixels outside SkRect intersection are unchanged.
471
472 Pass negative values for x or y to offset pixels to the left or
473 above SkCanvas pixels.
474
475 Does not copy, and returns false if:
476 - Source and destination rectangles do not intersect.
477 - pixels could not be converted to SkCanvas imageInfo().colorType() or
478 imageInfo().alphaType().
479 - SkCanvas pixels are not writable; for instance, SkCanvas is document-based.
480 - rowBytes is too small to contain one row of pixels.
481
482 @param info width, height, SkColorType, and SkAlphaType of pixels
483 @param pixels pixels to copy, of size info.height() times rowBytes, or larger
484 @param rowBytes size of one row of pixels; info.width() times pixel size, or larger
485 @param x offset into SkCanvas writable pixels on x-axis; may be negative
486 @param y offset into SkCanvas writable pixels on y-axis; may be negative
487 @return true if pixels were written to SkCanvas
488
489 example: https://fiddle.skia.org/c/@Canvas_writePixels
490 */
491 bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y);
492
493 /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
494 Source SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
495
496 Destination SkRect corners are (x, y) and
497 (imageInfo().width(), imageInfo().height()).
498
499 Copies each readable pixel intersecting both rectangles, without scaling,
500 converting to imageInfo().colorType() and imageInfo().alphaType() if required.
501
502 Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
503 Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
504 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
505 class like DebugCanvas.
506
507 Pixel values are converted only if SkColorType and SkAlphaType
508 do not match. Only pixels within both source and destination rectangles
509 are copied. SkCanvas pixels outside SkRect intersection are unchanged.
510
511 Pass negative values for x or y to offset pixels to the left or
512 above SkCanvas pixels.
513
514 Does not copy, and returns false if:
515 - Source and destination rectangles do not intersect.
516 - bitmap does not have allocated pixels.
517 - bitmap pixels could not be converted to SkCanvas imageInfo().colorType() or
518 imageInfo().alphaType().
519 - SkCanvas pixels are not writable; for instance, SkCanvas is document based.
520 - bitmap pixels are inaccessible; for instance, bitmap wraps a texture.
521
522 @param bitmap contains pixels copied to SkCanvas
523 @param x offset into SkCanvas writable pixels on x-axis; may be negative
524 @param y offset into SkCanvas writable pixels on y-axis; may be negative
525 @return true if pixels were written to SkCanvas
526
527 example: https://fiddle.skia.org/c/@Canvas_writePixels_2
528 example: https://fiddle.skia.org/c/@State_Stack_a
529 example: https://fiddle.skia.org/c/@State_Stack_b
530 */
531 bool writePixels(const SkBitmap& bitmap, int x, int y);
532
533 /** Saves SkMatrix and clip.
534 Calling restore() discards changes to SkMatrix and clip,
535 restoring the SkMatrix and clip to their state when save() was called.
536
537 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix(),
538 and resetMatrix(). Clip may be changed by clipRect(), clipRRect(), clipPath(), clipRegion().
539
540 Saved SkCanvas state is put on a stack; multiple calls to save() should be balance
541 by an equal number of calls to restore().
542
543 Call restoreToCount() with result to restore this and subsequent saves.
544
545 @return depth of saved stack
546
547 example: https://fiddle.skia.org/c/@Canvas_save
548 */
549 int save();
550
551 /** Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
552 Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.
553
554 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
555 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
556 clipPath(), clipRegion().
557
558 SkRect bounds suggests but does not define the SkBitmap size. To clip drawing to
559 a specific rectangle, use clipRect().
560
561 Optional SkPaint paint applies alpha, SkColorFilter, SkImageFilter, and
562 SkBlendMode when restore() is called.
563
564 Call restoreToCount() with returned value to restore this and subsequent saves.
565
566 @param bounds hint to limit the size of the layer; may be nullptr
567 @param paint graphics state for layer; may be nullptr
568 @return depth of saved stack
569
570 example: https://fiddle.skia.org/c/@Canvas_saveLayer
571 example: https://fiddle.skia.org/c/@Canvas_saveLayer_4
572 */
573 int saveLayer(const SkRect* bounds, const SkPaint* paint);
574
575 /** Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
576 Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.
577
578 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
579 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
580 clipPath(), clipRegion().
581
582 SkRect bounds suggests but does not define the layer size. To clip drawing to
583 a specific rectangle, use clipRect().
584
585 Optional SkPaint paint applies alpha, SkColorFilter, SkImageFilter, and
586 SkBlendMode when restore() is called.
587
588 Call restoreToCount() with returned value to restore this and subsequent saves.
589
590 @param bounds hint to limit the size of layer; may be nullptr
591 @param paint graphics state for layer; may be nullptr
592 @return depth of saved stack
593 */
594 int saveLayer(const SkRect& bounds, const SkPaint* paint) {
595 return this->saveLayer(&bounds, paint);
596 }
597
598 /** Saves SkMatrix and clip, and allocates SkBitmap for subsequent drawing.
599
600 Calling restore() discards changes to SkMatrix and clip,
601 and blends layer with alpha opacity onto prior layer.
602
603 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
604 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
605 clipPath(), clipRegion().
606
607 SkRect bounds suggests but does not define layer size. To clip drawing to
608 a specific rectangle, use clipRect().
609
610 alpha of zero is fully transparent, 255 is fully opaque.
611
612 Call restoreToCount() with returned value to restore this and subsequent saves.
613
614 @param bounds hint to limit the size of layer; may be nullptr
615 @param alpha opacity of layer
616 @return depth of saved stack
617
618 example: https://fiddle.skia.org/c/@Canvas_saveLayerAlpha
619 */
620 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
621
622 /** \enum SkCanvas::SaveLayerFlagsSet
623 SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
624 defining how layer allocated by saveLayer() operates. It may be set to zero,
625 kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
626 */
627 enum SaveLayerFlagsSet {
628 // kPreserveLCDText_SaveLayerFlag = 1 << 1, (no longer used)
629 kInitWithPrevious_SaveLayerFlag = 1 << 2, //!< initializes with previous contents
630 kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag =
631 1 << 3, //!< experimental: do not use
632 // instead of matching previous layer's colortype, use F16
633 kF16ColorType = 1 << 4,
634#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
635 kDontClipToLayer_Legacy_SaveLayerFlag =
636 kDontClipToLayer_PrivateSaveLayerFlag, //!< deprecated
637#endif
638 };
639
640 typedef uint32_t SaveLayerFlags;
641
642 /** \struct SkCanvas::SaveLayerRec
643 SaveLayerRec contains the state used to create the layer.
644 */
645 struct SaveLayerRec {
646
647 /** Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
648
649 @return empty SaveLayerRec
650 */
651 SaveLayerRec() {}
652
653 /** Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
654
655 @param bounds layer dimensions; may be nullptr
656 @param paint applied to layer when overlaying prior layer; may be nullptr
657 @param saveLayerFlags SaveLayerRec options to modify layer
658 @return SaveLayerRec with empty fBackdrop
659 */
660 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
661 : fBounds(bounds)
662 , fPaint(paint)
663 , fSaveLayerFlags(saveLayerFlags)
664 {}
665
666 /** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
667
668 @param bounds layer dimensions; may be nullptr
669 @param paint applied to layer when overlaying prior layer;
670 may be nullptr
671 @param backdrop If not null, this causes the current layer to be filtered by
672 backdrop, and then drawn into the new layer
673 (respecting the current clip).
674 If null, the new layer is initialized with transparent-black.
675 @param saveLayerFlags SaveLayerRec options to modify layer
676 @return SaveLayerRec fully specified
677 */
678 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
679 SaveLayerFlags saveLayerFlags)
680 : fBounds(bounds)
681 , fPaint(paint)
682 , fBackdrop(backdrop)
683 , fSaveLayerFlags(saveLayerFlags)
684 {}
685
686 /** Experimental. Not ready for general use.
687 Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
688 clipMatrix uses alpha channel of image, transformed by clipMatrix, to clip
689 layer when drawn to SkCanvas.
690
691 @param bounds layer dimensions; may be nullptr
692 @param paint graphics state applied to layer when overlaying prior
693 layer; may be nullptr
694 @param backdrop If not null, this causes the current layer to be filtered by
695 backdrop, and then drawn into the new layer
696 (respecting the current clip).
697 If null, the new layer is initialized with transparent-black.
698 @param clipMask clip applied to layer; may be nullptr
699 @param clipMatrix matrix applied to clipMask; may be nullptr to use
700 identity matrix
701 @param saveLayerFlags SaveLayerRec options to modify layer
702 @return SaveLayerRec fully specified
703 */
704 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
705 const SkImage* clipMask, const SkMatrix* clipMatrix,
706 SaveLayerFlags saveLayerFlags)
707 : fBounds(bounds)
708 , fPaint(paint)
709 , fBackdrop(backdrop)
710 , fClipMask(clipMask)
711 , fClipMatrix(clipMatrix)
712 , fSaveLayerFlags(saveLayerFlags)
713 {}
714
715 /** hints at layer size limit */
716 const SkRect* fBounds = nullptr;
717
718 /** modifies overlay */
719 const SkPaint* fPaint = nullptr;
720
721 /**
722 * If not null, this triggers the same initialization behavior as setting
723 * kInitWithPrevious_SaveLayerFlag on fSaveLayerFlags: the current layer is copied into
724 * the new layer, rather than initializing the new layer with transparent-black.
725 * This is then filtered by fBackdrop (respecting the current clip).
726 */
727 const SkImageFilter* fBackdrop = nullptr;
728
729 /** clips layer with mask alpha */
730 const SkImage* fClipMask = nullptr;
731
732 /** transforms mask alpha used to clip */
733 const SkMatrix* fClipMatrix = nullptr;
734
735 /** preserves LCD text, creates with prior layer contents */
736 SaveLayerFlags fSaveLayerFlags = 0;
737 };
738
739 /** Saves SkMatrix and clip, and allocates SkBitmap for subsequent drawing.
740
741 Calling restore() discards changes to SkMatrix and clip,
742 and blends SkBitmap with alpha opacity onto the prior layer.
743
744 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
745 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
746 clipPath(), clipRegion().
747
748 SaveLayerRec contains the state used to create the layer.
749
750 Call restoreToCount() with returned value to restore this and subsequent saves.
751
752 @param layerRec layer state
753 @return depth of save state stack before this call was made.
754
755 example: https://fiddle.skia.org/c/@Canvas_saveLayer_3
756 */
757 int saveLayer(const SaveLayerRec& layerRec);
758
759 /** Removes changes to SkMatrix and clip since SkCanvas state was
760 last saved. The state is removed from the stack.
761
762 Does nothing if the stack is empty.
763
764 example: https://fiddle.skia.org/c/@AutoCanvasRestore_restore
765
766 example: https://fiddle.skia.org/c/@Canvas_restore
767 */
768 void restore();
769
770 /** Returns the number of saved states, each containing: SkMatrix and clip.
771 Equals the number of save() calls less the number of restore() calls plus one.
772 The save count of a new canvas is one.
773
774 @return depth of save state stack
775
776 example: https://fiddle.skia.org/c/@Canvas_getSaveCount
777 */
778 int getSaveCount() const;
779
780 /** Restores state to SkMatrix and clip values when save(), saveLayer(),
781 saveLayerPreserveLCDTextRequests(), or saveLayerAlpha() returned saveCount.
782
783 Does nothing if saveCount is greater than state stack count.
784 Restores state to initial values if saveCount is less than or equal to one.
785
786 @param saveCount depth of state stack to restore
787
788 example: https://fiddle.skia.org/c/@Canvas_restoreToCount
789 */
790 void restoreToCount(int saveCount);
791
792 /** Translates SkMatrix by dx along the x-axis and dy along the y-axis.
793
794 Mathematically, replaces SkMatrix with a translation matrix
795 premultiplied with SkMatrix.
796
797 This has the effect of moving the drawing by (dx, dy) before transforming
798 the result with SkMatrix.
799
800 @param dx distance to translate on x-axis
801 @param dy distance to translate on y-axis
802
803 example: https://fiddle.skia.org/c/@Canvas_translate
804 */
805 void translate(SkScalar dx, SkScalar dy);
806
807 /** Scales SkMatrix by sx on the x-axis and sy on the y-axis.
808
809 Mathematically, replaces SkMatrix with a scale matrix
810 premultiplied with SkMatrix.
811
812 This has the effect of scaling the drawing by (sx, sy) before transforming
813 the result with SkMatrix.
814
815 @param sx amount to scale on x-axis
816 @param sy amount to scale on y-axis
817
818 example: https://fiddle.skia.org/c/@Canvas_scale
819 */
820 void scale(SkScalar sx, SkScalar sy);
821
822 /** Rotates SkMatrix by degrees. Positive degrees rotates clockwise.
823
824 Mathematically, replaces SkMatrix with a rotation matrix
825 premultiplied with SkMatrix.
826
827 This has the effect of rotating the drawing by degrees before transforming
828 the result with SkMatrix.
829
830 @param degrees amount to rotate, in degrees
831
832 example: https://fiddle.skia.org/c/@Canvas_rotate
833 */
834 void rotate(SkScalar degrees);
835
836 /** Rotates SkMatrix by degrees about a point at (px, py). Positive degrees rotates
837 clockwise.
838
839 Mathematically, constructs a rotation matrix; premultiplies the rotation matrix by
840 a translation matrix; then replaces SkMatrix with the resulting matrix
841 premultiplied with SkMatrix.
842
843 This has the effect of rotating the drawing about a given point before
844 transforming the result with SkMatrix.
845
846 @param degrees amount to rotate, in degrees
847 @param px x-axis value of the point to rotate about
848 @param py y-axis value of the point to rotate about
849
850 example: https://fiddle.skia.org/c/@Canvas_rotate_2
851 */
852 void rotate(SkScalar degrees, SkScalar px, SkScalar py);
853
854 /** Skews SkMatrix by sx on the x-axis and sy on the y-axis. A positive value of sx
855 skews the drawing right as y-axis values increase; a positive value of sy skews
856 the drawing down as x-axis values increase.
857
858 Mathematically, replaces SkMatrix with a skew matrix premultiplied with SkMatrix.
859
860 This has the effect of skewing the drawing by (sx, sy) before transforming
861 the result with SkMatrix.
862
863 @param sx amount to skew on x-axis
864 @param sy amount to skew on y-axis
865
866 example: https://fiddle.skia.org/c/@Canvas_skew
867 */
868 void skew(SkScalar sx, SkScalar sy);
869
870 /** Replaces SkMatrix with matrix premultiplied with existing SkMatrix.
871
872 This has the effect of transforming the drawn geometry by matrix, before
873 transforming the result with existing SkMatrix.
874
875 @param matrix matrix to premultiply with existing SkMatrix
876
877 example: https://fiddle.skia.org/c/@Canvas_concat
878 */
879 void concat(const SkMatrix& matrix);
880 void concat(const SkM44&);
881
882 typedef uint32_t MarkerID;
883
884 /**
885 * Record a marker (provided by caller) for the current CTM. This does not
886 * change anything about the ctm or clip, but does "note" this matrix value, so it can
887 * be referenced by custom effects (who access it by specifying the same id).
888 *
889 * Within a save frame, marking with the same id more than once just replaces the previous
890 * value. However, between save frames, marking with the same id does not lose the marker
891 * in the previous save frame. It is "visible" when the current save() is balanced with
892 * a restore().
893 *
894 * NOTE: id==0 is reserved.
895 */
896 void markCTM(MarkerID id);
897
898 bool findMarkedCTM(MarkerID id, SkM44*) const;
899
900 /** Replaces SkMatrix with matrix.
901 Unlike concat(), any prior matrix state is overwritten.
902
903 @param matrix matrix to copy, replacing existing SkMatrix
904
905 example: https://fiddle.skia.org/c/@Canvas_setMatrix
906 */
907 void setMatrix(const SkMatrix& matrix);
908
909 /** Sets SkMatrix to the identity matrix.
910 Any prior matrix state is overwritten.
911
912 example: https://fiddle.skia.org/c/@Canvas_resetMatrix
913 */
914 void resetMatrix();
915
916 /** Replaces clip with the intersection or difference of clip and rect,
917 with an aliased or anti-aliased clip edge. rect is transformed by SkMatrix
918 before it is combined with clip.
919
920 @param rect SkRect to combine with clip
921 @param op SkClipOp to apply to clip
922 @param doAntiAlias true if clip is to be anti-aliased
923
924 example: https://fiddle.skia.org/c/@Canvas_clipRect
925 */
926 void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias);
927
928 /** Replaces clip with the intersection or difference of clip and rect.
929 Resulting clip is aliased; pixels are fully contained by the clip.
930 rect is transformed by SkMatrix before it is combined with clip.
931
932 @param rect SkRect to combine with clip
933 @param op SkClipOp to apply to clip
934 */
935 void clipRect(const SkRect& rect, SkClipOp op) {
936 this->clipRect(rect, op, false);
937 }
938
939 /** Replaces clip with the intersection of clip and rect.
940 Resulting clip is aliased; pixels are fully contained by the clip.
941 rect is transformed by SkMatrix
942 before it is combined with clip.
943
944 @param rect SkRect to combine with clip
945 @param doAntiAlias true if clip is to be anti-aliased
946 */
947 void clipRect(const SkRect& rect, bool doAntiAlias = false) {
948 this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
949 }
950
951 /** Sets the maximum clip rectangle, which can be set by clipRect(), clipRRect() and
952 clipPath() and intersect the current clip with the specified rect.
953 The maximum clip affects only future clipping operations; it is not retroactive.
954 The clip restriction is not recorded in pictures.
955
956 Pass an empty rect to disable maximum clip.
957 This private API is for use by Android framework only.
958
959 @param rect maximum allowed clip in device coordinates
960 */
961 void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
962
963 /** Replaces clip with the intersection or difference of clip and rrect,
964 with an aliased or anti-aliased clip edge.
965 rrect is transformed by SkMatrix
966 before it is combined with clip.
967
968 @param rrect SkRRect to combine with clip
969 @param op SkClipOp to apply to clip
970 @param doAntiAlias true if clip is to be anti-aliased
971
972 example: https://fiddle.skia.org/c/@Canvas_clipRRect
973 */
974 void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
975
976 /** Replaces clip with the intersection or difference of clip and rrect.
977 Resulting clip is aliased; pixels are fully contained by the clip.
978 rrect is transformed by SkMatrix before it is combined with clip.
979
980 @param rrect SkRRect to combine with clip
981 @param op SkClipOp to apply to clip
982 */
983 void clipRRect(const SkRRect& rrect, SkClipOp op) {
984 this->clipRRect(rrect, op, false);
985 }
986
987 /** Replaces clip with the intersection of clip and rrect,
988 with an aliased or anti-aliased clip edge.
989 rrect is transformed by SkMatrix before it is combined with clip.
990
991 @param rrect SkRRect to combine with clip
992 @param doAntiAlias true if clip is to be anti-aliased
993 */
994 void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
995 this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
996 }
997
998 /** Replaces clip with the intersection or difference of clip and path,
999 with an aliased or anti-aliased clip edge. SkPath::FillType determines if path
1000 describes the area inside or outside its contours; and if path contour overlaps
1001 itself or another path contour, whether the overlaps form part of the area.
1002 path is transformed by SkMatrix before it is combined with clip.
1003
1004 @param path SkPath to combine with clip
1005 @param op SkClipOp to apply to clip
1006 @param doAntiAlias true if clip is to be anti-aliased
1007
1008 example: https://fiddle.skia.org/c/@Canvas_clipPath
1009 */
1010 void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
1011
1012 /** Replaces clip with the intersection or difference of clip and path.
1013 Resulting clip is aliased; pixels are fully contained by the clip.
1014 SkPath::FillType determines if path
1015 describes the area inside or outside its contours; and if path contour overlaps
1016 itself or another path contour, whether the overlaps form part of the area.
1017 path is transformed by SkMatrix
1018 before it is combined with clip.
1019
1020 @param path SkPath to combine with clip
1021 @param op SkClipOp to apply to clip
1022 */
1023 void clipPath(const SkPath& path, SkClipOp op) {
1024 this->clipPath(path, op, false);
1025 }
1026
1027 /** Replaces clip with the intersection of clip and path.
1028 Resulting clip is aliased; pixels are fully contained by the clip.
1029 SkPath::FillType determines if path
1030 describes the area inside or outside its contours; and if path contour overlaps
1031 itself or another path contour, whether the overlaps form part of the area.
1032 path is transformed by SkMatrix before it is combined with clip.
1033
1034 @param path SkPath to combine with clip
1035 @param doAntiAlias true if clip is to be anti-aliased
1036 */
1037 void clipPath(const SkPath& path, bool doAntiAlias = false) {
1038 this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
1039 }
1040
1041 void clipShader(sk_sp<SkShader>, SkClipOp = SkClipOp::kIntersect);
1042
1043 /** Replaces clip with the intersection or difference of clip and SkRegion deviceRgn.
1044 Resulting clip is aliased; pixels are fully contained by the clip.
1045 deviceRgn is unaffected by SkMatrix.
1046
1047 @param deviceRgn SkRegion to combine with clip
1048 @param op SkClipOp to apply to clip
1049
1050 example: https://fiddle.skia.org/c/@Canvas_clipRegion
1051 */
1052 void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
1053
1054 /** Returns true if SkRect rect, transformed by SkMatrix, can be quickly determined to be
1055 outside of clip. May return false even though rect is outside of clip.
1056
1057 Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
1058
1059 @param rect SkRect to compare with clip
1060 @return true if rect, transformed by SkMatrix, does not intersect clip
1061
1062 example: https://fiddle.skia.org/c/@Canvas_quickReject
1063 */
1064 bool quickReject(const SkRect& rect) const;
1065
1066 /** Returns true if path, transformed by SkMatrix, can be quickly determined to be
1067 outside of clip. May return false even though path is outside of clip.
1068
1069 Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
1070
1071 @param path SkPath to compare with clip
1072 @return true if path, transformed by SkMatrix, does not intersect clip
1073
1074 example: https://fiddle.skia.org/c/@Canvas_quickReject_2
1075 */
1076 bool quickReject(const SkPath& path) const;
1077
1078 /** Returns bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
1079 return SkRect::MakeEmpty, where all SkRect sides equal zero.
1080
1081 SkRect returned is outset by one to account for partial pixel coverage if clip
1082 is anti-aliased.
1083
1084 @return bounds of clip in local coordinates
1085
1086 example: https://fiddle.skia.org/c/@Canvas_getLocalClipBounds
1087 */
1088 SkRect getLocalClipBounds() const;
1089
1090 /** Returns bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
1091 return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
1092
1093 bounds is outset by one to account for partial pixel coverage if clip
1094 is anti-aliased.
1095
1096 @param bounds SkRect of clip in local coordinates
1097 @return true if clip bounds is not empty
1098 */
1099 bool getLocalClipBounds(SkRect* bounds) const {
1100 *bounds = this->getLocalClipBounds();
1101 return !bounds->isEmpty();
1102 }
1103
1104 /** Returns SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
1105 return SkRect::MakeEmpty, where all SkRect sides equal zero.
1106
1107 Unlike getLocalClipBounds(), returned SkIRect is not outset.
1108
1109 @return bounds of clip in SkBaseDevice coordinates
1110
1111 example: https://fiddle.skia.org/c/@Canvas_getDeviceClipBounds
1112 */
1113 SkIRect getDeviceClipBounds() const;
1114
1115 /** Returns SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
1116 return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
1117
1118 Unlike getLocalClipBounds(), bounds is not outset.
1119
1120 @param bounds SkRect of clip in device coordinates
1121 @return true if clip bounds is not empty
1122 */
1123 bool getDeviceClipBounds(SkIRect* bounds) const {
1124 *bounds = this->getDeviceClipBounds();
1125 return !bounds->isEmpty();
1126 }
1127
1128 /** Fills clip with color color.
1129 mode determines how ARGB is combined with destination.
1130
1131 @param color unpremultiplied ARGB
1132 @param mode SkBlendMode used to combine source color and destination
1133
1134 example: https://fiddle.skia.org/c/@Canvas_drawColor
1135 */
1136 void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
1137
1138 /** Fills clip with color color using SkBlendMode::kSrc.
1139 This has the effect of replacing all pixels contained by clip with color.
1140
1141 @param color unpremultiplied ARGB
1142 */
1143 void clear(SkColor color) {
1144 this->drawColor(color, SkBlendMode::kSrc);
1145 }
1146
1147 /** Makes SkCanvas contents undefined. Subsequent calls that read SkCanvas pixels,
1148 such as drawing with SkBlendMode, return undefined results. discard() does
1149 not change clip or SkMatrix.
1150
1151 discard() may do nothing, depending on the implementation of SkSurface or SkBaseDevice
1152 that created SkCanvas.
1153
1154 discard() allows optimized performance on subsequent draws by removing
1155 cached data associated with SkSurface or SkBaseDevice.
1156 It is not necessary to call discard() once done with SkCanvas;
1157 any cached data is deleted when owning SkSurface or SkBaseDevice is deleted.
1158 */
1159 void discard() { this->onDiscard(); }
1160
1161 /** Fills clip with SkPaint paint. SkPaint components SkMaskFilter, SkShader,
1162 SkColorFilter, SkImageFilter, and SkBlendMode affect drawing;
1163 SkPathEffect in paint is ignored.
1164
1165 @param paint graphics state used to fill SkCanvas
1166
1167 example: https://fiddle.skia.org/c/@Canvas_drawPaint
1168 */
1169 void drawPaint(const SkPaint& paint);
1170
1171 /** \enum SkCanvas::PointMode
1172 Selects if an array of points are drawn as discrete points, as lines, or as
1173 an open polygon.
1174 */
1175 enum PointMode {
1176 kPoints_PointMode, //!< draw each point separately
1177 kLines_PointMode, //!< draw each pair of points as a line segment
1178 kPolygon_PointMode, //!< draw the array of points as a open polygon
1179 };
1180
1181 /** Draws pts using clip, SkMatrix and SkPaint paint.
1182 count is the number of points; if count is less than one, has no effect.
1183 mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
1184
1185 If mode is kPoints_PointMode, the shape of point drawn depends on paint
1186 SkPaint::Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
1187 circle of diameter SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap
1188 or SkPaint::kButt_Cap, each point draws a square of width and height
1189 SkPaint stroke width.
1190
1191 If mode is kLines_PointMode, each pair of points draws a line segment.
1192 One line is drawn for every two points; each point is used once. If count is odd,
1193 the final point is ignored.
1194
1195 If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
1196 count minus one lines are drawn; the first and last point are used once.
1197
1198 Each line segment respects paint SkPaint::Cap and SkPaint stroke width.
1199 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1200
1201 Always draws each element one at a time; is not affected by
1202 SkPaint::Join, and unlike drawPath(), does not create a mask from all points
1203 and lines before drawing.
1204
1205 @param mode whether pts draws points or lines
1206 @param count number of points in the array
1207 @param pts array of points to draw
1208 @param paint stroke, blend, color, and so on, used to draw
1209
1210 example: https://fiddle.skia.org/c/@Canvas_drawPoints
1211 */
1212 void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
1213
1214 /** Draws point at (x, y) using clip, SkMatrix and SkPaint paint.
1215
1216 The shape of point drawn depends on paint SkPaint::Cap.
1217 If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
1218 SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
1219 draw a square of width and height SkPaint stroke width.
1220 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1221
1222 @param x left edge of circle or square
1223 @param y top edge of circle or square
1224 @param paint stroke, blend, color, and so on, used to draw
1225
1226 example: https://fiddle.skia.org/c/@Canvas_drawPoint
1227 */
1228 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
1229
1230 /** Draws point p using clip, SkMatrix and SkPaint paint.
1231
1232 The shape of point drawn depends on paint SkPaint::Cap.
1233 If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
1234 SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
1235 draw a square of width and height SkPaint stroke width.
1236 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1237
1238 @param p top-left edge of circle or square
1239 @param paint stroke, blend, color, and so on, used to draw
1240 */
1241 void drawPoint(SkPoint p, const SkPaint& paint) {
1242 this->drawPoint(p.x(), p.y(), paint);
1243 }
1244
1245 /** Draws line segment from (x0, y0) to (x1, y1) using clip, SkMatrix, and SkPaint paint.
1246 In paint: SkPaint stroke width describes the line thickness;
1247 SkPaint::Cap draws the end rounded or square;
1248 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1249
1250 @param x0 start of line segment on x-axis
1251 @param y0 start of line segment on y-axis
1252 @param x1 end of line segment on x-axis
1253 @param y1 end of line segment on y-axis
1254 @param paint stroke, blend, color, and so on, used to draw
1255
1256 example: https://fiddle.skia.org/c/@Canvas_drawLine
1257 */
1258 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
1259
1260 /** Draws line segment from p0 to p1 using clip, SkMatrix, and SkPaint paint.
1261 In paint: SkPaint stroke width describes the line thickness;
1262 SkPaint::Cap draws the end rounded or square;
1263 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1264
1265 @param p0 start of line segment
1266 @param p1 end of line segment
1267 @param paint stroke, blend, color, and so on, used to draw
1268 */
1269 void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint) {
1270 this->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
1271 }
1272
1273 /** Draws SkRect rect using clip, SkMatrix, and SkPaint paint.
1274 In paint: SkPaint::Style determines if rectangle is stroked or filled;
1275 if stroked, SkPaint stroke width describes the line thickness, and
1276 SkPaint::Join draws the corners rounded or square.
1277
1278 @param rect rectangle to draw
1279 @param paint stroke or fill, blend, color, and so on, used to draw
1280
1281 example: https://fiddle.skia.org/c/@Canvas_drawRect
1282 */
1283 void drawRect(const SkRect& rect, const SkPaint& paint);
1284
1285 /** Draws SkIRect rect using clip, SkMatrix, and SkPaint paint.
1286 In paint: SkPaint::Style determines if rectangle is stroked or filled;
1287 if stroked, SkPaint stroke width describes the line thickness, and
1288 SkPaint::Join draws the corners rounded or square.
1289
1290 @param rect rectangle to draw
1291 @param paint stroke or fill, blend, color, and so on, used to draw
1292 */
1293 void drawIRect(const SkIRect& rect, const SkPaint& paint) {
1294 SkRect r;
1295 r.set(rect); // promotes the ints to scalars
1296 this->drawRect(r, paint);
1297 }
1298
1299 /** Draws SkRegion region using clip, SkMatrix, and SkPaint paint.
1300 In paint: SkPaint::Style determines if rectangle is stroked or filled;
1301 if stroked, SkPaint stroke width describes the line thickness, and
1302 SkPaint::Join draws the corners rounded or square.
1303
1304 @param region region to draw
1305 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1306
1307 example: https://fiddle.skia.org/c/@Canvas_drawRegion
1308 */
1309 void drawRegion(const SkRegion& region, const SkPaint& paint);
1310
1311 /** Draws oval oval using clip, SkMatrix, and SkPaint.
1312 In paint: SkPaint::Style determines if oval is stroked or filled;
1313 if stroked, SkPaint stroke width describes the line thickness.
1314
1315 @param oval SkRect bounds of oval
1316 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1317
1318 example: https://fiddle.skia.org/c/@Canvas_drawOval
1319 */
1320 void drawOval(const SkRect& oval, const SkPaint& paint);
1321
1322 /** Draws SkRRect rrect using clip, SkMatrix, and SkPaint paint.
1323 In paint: SkPaint::Style determines if rrect is stroked or filled;
1324 if stroked, SkPaint stroke width describes the line thickness.
1325
1326 rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
1327 may have any combination of positive non-square radii for the four corners.
1328
1329 @param rrect SkRRect with up to eight corner radii to draw
1330 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1331
1332 example: https://fiddle.skia.org/c/@Canvas_drawRRect
1333 */
1334 void drawRRect(const SkRRect& rrect, const SkPaint& paint);
1335
1336 /** Draws SkRRect outer and inner
1337 using clip, SkMatrix, and SkPaint paint.
1338 outer must contain inner or the drawing is undefined.
1339 In paint: SkPaint::Style determines if SkRRect is stroked or filled;
1340 if stroked, SkPaint stroke width describes the line thickness.
1341 If stroked and SkRRect corner has zero length radii, SkPaint::Join can
1342 draw corners rounded or square.
1343
1344 GPU-backed platforms optimize drawing when both outer and inner are
1345 concave and outer contains inner. These platforms may not be able to draw
1346 SkPath built with identical data as fast.
1347
1348 @param outer SkRRect outer bounds to draw
1349 @param inner SkRRect inner bounds to draw
1350 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1351
1352 example: https://fiddle.skia.org/c/@Canvas_drawDRRect_a
1353 example: https://fiddle.skia.org/c/@Canvas_drawDRRect_b
1354 */
1355 void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
1356
1357 /** Draws circle at (cx, cy) with radius using clip, SkMatrix, and SkPaint paint.
1358 If radius is zero or less, nothing is drawn.
1359 In paint: SkPaint::Style determines if circle is stroked or filled;
1360 if stroked, SkPaint stroke width describes the line thickness.
1361
1362 @param cx circle center on the x-axis
1363 @param cy circle center on the y-axis
1364 @param radius half the diameter of circle
1365 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1366
1367 example: https://fiddle.skia.org/c/@Canvas_drawCircle
1368 */
1369 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
1370
1371 /** Draws circle at center with radius using clip, SkMatrix, and SkPaint paint.
1372 If radius is zero or less, nothing is drawn.
1373 In paint: SkPaint::Style determines if circle is stroked or filled;
1374 if stroked, SkPaint stroke width describes the line thickness.
1375
1376 @param center circle center
1377 @param radius half the diameter of circle
1378 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1379 */
1380 void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint) {
1381 this->drawCircle(center.x(), center.y(), radius, paint);
1382 }
1383
1384 /** Draws arc using clip, SkMatrix, and SkPaint paint.
1385
1386 Arc is part of oval bounded by oval, sweeping from startAngle to startAngle plus
1387 sweepAngle. startAngle and sweepAngle are in degrees.
1388
1389 startAngle of zero places start point at the right middle edge of oval.
1390 A positive sweepAngle places arc end point clockwise from start point;
1391 a negative sweepAngle places arc end point counterclockwise from start point.
1392 sweepAngle may exceed 360 degrees, a full circle.
1393 If useCenter is true, draw a wedge that includes lines from oval
1394 center to arc end points. If useCenter is false, draw arc between end points.
1395
1396 If SkRect oval is empty or sweepAngle is zero, nothing is drawn.
1397
1398 @param oval SkRect bounds of oval containing arc to draw
1399 @param startAngle angle in degrees where arc begins
1400 @param sweepAngle sweep angle in degrees; positive is clockwise
1401 @param useCenter if true, include the center of the oval
1402 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1403 */
1404 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
1405 bool useCenter, const SkPaint& paint);
1406
1407 /** Draws SkRRect bounded by SkRect rect, with corner radii (rx, ry) using clip,
1408 SkMatrix, and SkPaint paint.
1409
1410 In paint: SkPaint::Style determines if SkRRect is stroked or filled;
1411 if stroked, SkPaint stroke width describes the line thickness.
1412 If rx or ry are less than zero, they are treated as if they are zero.
1413 If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
1414 If rx and ry are zero, SkRRect is drawn as SkRect and if stroked is affected by
1415 SkPaint::Join.
1416
1417 @param rect SkRect bounds of SkRRect to draw
1418 @param rx axis length on x-axis of oval describing rounded corners
1419 @param ry axis length on y-axis of oval describing rounded corners
1420 @param paint stroke, blend, color, and so on, used to draw
1421
1422 example: https://fiddle.skia.org/c/@Canvas_drawRoundRect
1423 */
1424 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
1425
1426 /** Draws SkPath path using clip, SkMatrix, and SkPaint paint.
1427 SkPath contains an array of path contour, each of which may be open or closed.
1428
1429 In paint: SkPaint::Style determines if SkRRect is stroked or filled:
1430 if filled, SkPath::FillType determines whether path contour describes inside or
1431 outside of fill; if stroked, SkPaint stroke width describes the line thickness,
1432 SkPaint::Cap describes line ends, and SkPaint::Join describes how
1433 corners are drawn.
1434
1435 @param path SkPath to draw
1436 @param paint stroke, blend, color, and so on, used to draw
1437
1438 example: https://fiddle.skia.org/c/@Canvas_drawPath
1439 */
1440 void drawPath(const SkPath& path, const SkPaint& paint);
1441
1442 /** Draws SkImage image, with its top-left corner at (left, top),
1443 using clip, SkMatrix, and optional SkPaint paint.
1444
1445 This is equivalent to drawImageRect() using a dst rect at (x,y) with the
1446 same width and height of the image.
1447
1448 @param image uncompressed rectangular map of pixels
1449 @param left left side of image
1450 @param top top side of image
1451 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1452 and so on; or nullptr
1453 */
1454 void drawImage(const SkImage* image, SkScalar left, SkScalar top,
1455 const SkPaint* paint = nullptr);
1456
1457 /** Draws SkImage image, with its top-left corner at (left, top),
1458 using clip, SkMatrix, and optional SkPaint paint.
1459
1460 This is equivalent to drawImageRect() using a dst rect at (x,y) with the
1461 same width and height of the image.
1462
1463 @param image uncompressed rectangular map of pixels
1464 @param left left side of image
1465 @param top pop side of image
1466 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1467 and so on; or nullptr
1468 */
1469 void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
1470 const SkPaint* paint = nullptr) {
1471 this->drawImage(image.get(), left, top, paint);
1472 }
1473
1474 /** \enum SkCanvas::SrcRectConstraint
1475 SrcRectConstraint controls the behavior at the edge of source SkRect,
1476 provided to drawImageRect(), trading off speed for precision.
1477
1478 SkFilterQuality in SkPaint may sample multiple pixels in the image. Source SkRect
1479 restricts the bounds of pixels that may be read. SkFilterQuality may slow down if
1480 it cannot read outside the bounds, when sampling near the edge of source SkRect.
1481 SrcRectConstraint specifies whether an SkImageFilter is allowed to read pixels
1482 outside source SkRect.
1483 */
1484 enum SrcRectConstraint {
1485 kStrict_SrcRectConstraint, //!< sample only inside bounds; slower
1486 kFast_SrcRectConstraint, //!< sample outside bounds; faster
1487 };
1488
1489 /** Draws SkRect src of SkImage image, scaled and translated to fill SkRect dst.
1490 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1491
1492 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1493 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1494 If paint contains SkMaskFilter, generate mask from image bounds.
1495
1496 If generated mask extends beyond image bounds, replicate image edge colors, just
1497 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1498 replicates the image edge color when it samples outside of its bounds.
1499
1500 When using a shader or shader mask filter, its coordinate system is based on the
1501 current CTM, so will reflect the dst rect geometry and is equivalent to
1502 drawRect(dst). The src rect is only used to access the provided image.
1503
1504 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1505 sample within src; set to kFast_SrcRectConstraint allows sampling outside to
1506 improve performance.
1507
1508 @param image SkImage containing pixels, dimensions, and format
1509 @param src source SkRect of image to draw from
1510 @param dst destination SkRect of image to draw to
1511 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1512 and so on; or nullptr
1513 @param constraint filter strictly within src or draw faster
1514 */
1515 void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
1516 const SkPaint* paint,
1517 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1518
1519 /** Draws SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
1520 Note that isrc is on integer pixel boundaries; dst may include fractional
1521 boundaries. Additionally transform draw using clip, SkMatrix, and optional SkPaint
1522 paint.
1523
1524 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1525 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1526 If paint contains SkMaskFilter, generate mask from image bounds.
1527
1528 If generated mask extends beyond image bounds, replicate image edge colors, just
1529 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1530 replicates the image edge color when it samples outside of its bounds.
1531
1532 When using a shader or shader mask filter, its coordinate system is based on the
1533 current CTM, so will reflect the dst rect geometry and is equivalent to
1534 drawRect(dst). The src rect is only used to access the provided image.
1535
1536 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1537 sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
1538 improve performance.
1539
1540 @param image SkImage containing pixels, dimensions, and format
1541 @param isrc source SkIRect of image to draw from
1542 @param dst destination SkRect of image to draw to
1543 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1544 and so on; or nullptr
1545 @param constraint filter strictly within isrc or draw faster
1546 */
1547 void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
1548 const SkPaint* paint,
1549 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1550
1551 /** Draws SkImage image, scaled and translated to fill SkRect dst, using clip, SkMatrix,
1552 and optional SkPaint paint.
1553
1554 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1555 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1556 If paint contains SkMaskFilter, generate mask from image bounds.
1557
1558 If generated mask extends beyond image bounds, replicate image edge colors, just
1559 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1560 replicates the image edge color when it samples outside of its bounds.
1561
1562 When using a shader or shader mask filter, its coordinate system is based on the
1563 current CTM, so will reflect the dst rect geometry and is equivalent to
1564 drawRect(dst).
1565
1566 @param image SkImage containing pixels, dimensions, and format
1567 @param dst destination SkRect of image to draw to
1568 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1569 and so on; or nullptr
1570
1571 example: https://fiddle.skia.org/c/@Canvas_drawImageRect_3
1572 */
1573 void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint);
1574
1575 /** Draws SkRect src of SkImage image, scaled and translated to fill SkRect dst.
1576 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1577
1578 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1579 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1580 If paint contains SkMaskFilter, generate mask from image bounds.
1581
1582 If generated mask extends beyond image bounds, replicate image edge colors, just
1583 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1584 replicates the image edge color when it samples outside of its bounds.
1585
1586 When using a shader or shader mask filter, its coordinate system is based on the
1587 current CTM, so will reflect the dst rect geometry and is equivalent to
1588 drawRect(dst). The src rect is only used to access the provided image.
1589
1590 @param image SkImage containing pixels, dimensions, and format
1591 @param src source SkRect of image to draw from
1592 @param dst destination SkRect of image to draw to
1593 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1594 and so on; or nullptr
1595 @param constraint filter strictly within src or draw faster
1596 */
1597 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
1598 const SkPaint* paint,
1599 SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
1600 this->drawImageRect(image.get(), src, dst, paint, constraint);
1601 }
1602
1603 /** Draws SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
1604 isrc is on integer pixel boundaries; dst may include fractional boundaries.
1605 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1606
1607 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1608 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1609 If paint contains SkMaskFilter, generate mask from image bounds.
1610
1611 If generated mask extends beyond image bounds, replicate image edge colors, just
1612 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1613 replicates the image edge color when it samples outside of its bounds.
1614
1615 When using a shader or shader mask filter, its coordinate system is based on the
1616 current CTM, so will reflect the dst rect geometry and is equivalent to
1617 drawRect(dst). The src rect is only used to access the provided image.
1618
1619 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1620 sample within image; set to kFast_SrcRectConstraint allows sampling outside to
1621 improve performance.
1622
1623 @param image SkImage containing pixels, dimensions, and format
1624 @param isrc source SkIRect of image to draw from
1625 @param dst destination SkRect of image to draw to
1626 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1627 and so on; or nullptr
1628 @param constraint filter strictly within image or draw faster
1629 */
1630 void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
1631 const SkPaint* paint,
1632 SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
1633 this->drawImageRect(image.get(), isrc, dst, paint, constraint);
1634 }
1635
1636 /** Draws SkImage image, scaled and translated to fill SkRect dst,
1637 using clip, SkMatrix, and optional SkPaint paint.
1638
1639 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1640 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1641 If paint contains SkMaskFilter, generate mask from image bounds.
1642
1643 If generated mask extends beyond image bounds, replicate image edge colors, just
1644 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1645 replicates the image edge color when it samples outside of its bounds.
1646
1647 When using a shader or shader mask filter, its coordinate system is based on the
1648 current CTM, so will reflect the dst rect geometry and is equivalent to
1649 drawRect(dst).
1650
1651 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1652 sample within image; set to kFast_SrcRectConstraint allows sampling outside to
1653 improve performance.
1654
1655 @param image SkImage containing pixels, dimensions, and format
1656 @param dst destination SkRect of image to draw to
1657 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1658 and so on; or nullptr
1659 */
1660 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint) {
1661 this->drawImageRect(image.get(), dst, paint);
1662 }
1663
1664 /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1665 SkIRect center divides the image into nine sections: four sides, four corners, and
1666 the center. Corners are unmodified or scaled down proportionately if their sides
1667 are larger than dst; center and four sides are scaled to fit remaining space, if any.
1668
1669 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1670
1671 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1672 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1673 If paint contains SkMaskFilter, generate mask from image bounds. If paint
1674 SkFilterQuality set to kNone_SkFilterQuality, disable pixel filtering. For all
1675 other values of paint SkFilterQuality, use kLow_SkFilterQuality to filter pixels.
1676 Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1677
1678 If generated mask extends beyond image bounds, replicate image edge colors, just
1679 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1680 replicates the image edge color when it samples outside of its bounds.
1681
1682 @param image SkImage containing pixels, dimensions, and format
1683 @param center SkIRect edge of image corners and sides
1684 @param dst destination SkRect of image to draw to
1685 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1686 and so on; or nullptr
1687 */
1688 void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
1689 const SkPaint* paint = nullptr);
1690
1691 /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1692 SkIRect center divides the image into nine sections: four sides, four corners, and
1693 the center. Corners are not scaled, or scaled down proportionately if their sides
1694 are larger than dst; center and four sides are scaled to fit remaining space, if any.
1695
1696 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1697
1698 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1699 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1700 If paint contains SkMaskFilter, generate mask from image bounds. If paint
1701 SkFilterQuality set to kNone_SkFilterQuality, disable pixel filtering. For all
1702 other values of paint SkFilterQuality, use kLow_SkFilterQuality to filter pixels.
1703 Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1704
1705 If generated mask extends beyond image bounds, replicate image edge colors, just
1706 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1707 replicates the image edge color when it samples outside of its bounds.
1708
1709 @param image SkImage containing pixels, dimensions, and format
1710 @param center SkIRect edge of image corners and sides
1711 @param dst destination SkRect of image to draw to
1712 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1713 and so on; or nullptr
1714 */
1715 void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
1716 const SkPaint* paint = nullptr) {
1717 this->drawImageNine(image.get(), center, dst, paint);
1718 }
1719
1720 /** Draws SkBitmap bitmap, with its top-left corner at (left, top),
1721 using clip, SkMatrix, and optional SkPaint paint.
1722
1723 If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter,
1724 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1725 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1726
1727 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1728 just as SkShader made from SkShader::MakeBitmapShader with
1729 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1730 outside of its bounds.
1731
1732 @param bitmap SkBitmap containing pixels, dimensions, and format
1733 @param left left side of bitmap
1734 @param top top side of bitmap
1735 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1736 and so on; or nullptr
1737 */
1738 void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
1739 const SkPaint* paint = nullptr);
1740
1741 /** Draws SkRect src of SkBitmap bitmap, scaled and translated to fill SkRect dst.
1742 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1743
1744 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1745 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1746 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1747
1748 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1749 just as SkShader made from SkShader::MakeBitmapShader with
1750 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1751 outside of its bounds.
1752
1753 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1754 sample within src; set to kFast_SrcRectConstraint allows sampling outside to
1755 improve performance.
1756
1757 @param bitmap SkBitmap containing pixels, dimensions, and format
1758 @param src source SkRect of image to draw from
1759 @param dst destination SkRect of image to draw to
1760 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1761 and so on; or nullptr
1762 @param constraint filter strictly within src or draw faster
1763 */
1764 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
1765 const SkPaint* paint,
1766 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1767
1768 /** Draws SkIRect isrc of SkBitmap bitmap, scaled and translated to fill SkRect dst.
1769 isrc is on integer pixel boundaries; dst may include fractional boundaries.
1770 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1771
1772 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1773 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1774 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1775
1776 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1777 just as SkShader made from SkShader::MakeBitmapShader with
1778 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1779 outside of its bounds.
1780
1781 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1782 sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
1783 improve performance.
1784
1785 @param bitmap SkBitmap containing pixels, dimensions, and format
1786 @param isrc source SkIRect of image to draw from
1787 @param dst destination SkRect of image to draw to
1788 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1789 and so on; or nullptr
1790 @param constraint sample strictly within isrc, or draw faster
1791 */
1792 void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
1793 const SkPaint* paint,
1794 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1795
1796 /** Draws SkBitmap bitmap, scaled and translated to fill SkRect dst.
1797 bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
1798 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1799
1800 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1801 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1802 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1803
1804 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1805 just as SkShader made from SkShader::MakeBitmapShader with
1806 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1807 outside of its bounds.
1808
1809 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1810 sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
1811 improve performance.
1812
1813 @param bitmap SkBitmap containing pixels, dimensions, and format
1814 @param dst destination SkRect of image to draw to
1815 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1816 and so on; or nullptr
1817 @param constraint filter strictly within bitmap or draw faster
1818 */
1819 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
1820 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1821
1822 /** \struct SkCanvas::Lattice
1823 SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid.
1824 Grid entries on even columns and even rows are fixed; these entries are
1825 always drawn at their original size if the destination is large enough.
1826 If the destination side is too small to hold the fixed entries, all fixed
1827 entries are proportionately scaled down to fit.
1828 The grid entries not on even columns and rows are scaled to fit the
1829 remaining space, if any.
1830 */
1831 struct Lattice {
1832
1833 /** \enum SkCanvas::Lattice::RectType
1834 Optional setting per rectangular grid entry to make it transparent,
1835 or to fill the grid entry with a color.
1836 */
1837 enum RectType : uint8_t {
1838 kDefault = 0, //!< draws SkBitmap into lattice rectangle
1839 kTransparent, //!< skips lattice rectangle by making it transparent
1840 kFixedColor, //!< draws one of fColors into lattice rectangle
1841 };
1842
1843 const int* fXDivs; //!< x-axis values dividing bitmap
1844 const int* fYDivs; //!< y-axis values dividing bitmap
1845 const RectType* fRectTypes; //!< array of fill types
1846 int fXCount; //!< number of x-coordinates
1847 int fYCount; //!< number of y-coordinates
1848 const SkIRect* fBounds; //!< source bounds to draw from
1849 const SkColor* fColors; //!< array of colors
1850 };
1851
1852 /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1853
1854 SkCanvas::Lattice lattice divides image into a rectangular grid.
1855 Each intersection of an even-numbered row and column is fixed; like the corners
1856 of drawBitmapNine(), fixed lattice elements never scale larger than their initial
1857 size and shrink proportionately when all fixed elements exceed the bitmap
1858 dimension. All other grid elements scale to fill the available space, if any.
1859
1860 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1861
1862 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter,
1863 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1864 If paint contains SkMaskFilter, generate mask from image bounds. If paint
1865 SkFilterQuality set to kNone_SkFilterQuality, disable pixel filtering. For all
1866 other values of paint SkFilterQuality, use kLow_SkFilterQuality to filter pixels.
1867 Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1868
1869 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1870 just as SkShader made from SkShader::MakeBitmapShader with
1871 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1872 outside of its bounds.
1873
1874 @param image SkImage containing pixels, dimensions, and format
1875 @param lattice division of bitmap into fixed and variable rectangles
1876 @param dst destination SkRect of image to draw to
1877 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1878 and so on; or nullptr
1879 */
1880 void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
1881 const SkPaint* paint = nullptr);
1882
1883 /**
1884 * Experimental. Controls anti-aliasing of each edge of images in an image-set.
1885 */
1886 enum QuadAAFlags : unsigned {
1887 kLeft_QuadAAFlag = 0b0001,
1888 kTop_QuadAAFlag = 0b0010,
1889 kRight_QuadAAFlag = 0b0100,
1890 kBottom_QuadAAFlag = 0b1000,
1891
1892 kNone_QuadAAFlags = 0b0000,
1893 kAll_QuadAAFlags = 0b1111,
1894 };
1895
1896 /** This is used by the experimental API below. */
1897 struct SK_API ImageSetEntry {
1898 ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
1899 int matrixIndex, float alpha, unsigned aaFlags, bool hasClip);
1900
1901 ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
1902 float alpha, unsigned aaFlags);
1903
1904 ImageSetEntry();
1905 ~ImageSetEntry();
1906 ImageSetEntry(const ImageSetEntry&);
1907 ImageSetEntry& operator=(const ImageSetEntry&);
1908
1909 sk_sp<const SkImage> fImage;
1910 SkRect fSrcRect;
1911 SkRect fDstRect;
1912 int fMatrixIndex = -1; // Index into the preViewMatrices arg, or < 0
1913 float fAlpha = 1.f;
1914 unsigned fAAFlags = kNone_QuadAAFlags; // QuadAAFlags
1915 bool fHasClip = false; // True to use next 4 points in dstClip arg as quad
1916 };
1917
1918 /**
1919 * This is an experimental API for the SkiaRenderer Chromium project, and its API will surely
1920 * evolve if it is not removed outright.
1921 *
1922 * This behaves very similarly to drawRect() combined with a clipPath() formed by clip
1923 * quadrilateral. 'rect' and 'clip' are in the same coordinate space. If 'clip' is null, then it
1924 * is as if the rectangle was not clipped (or, alternatively, clipped to itself). If not null,
1925 * then it must provide 4 points.
1926 *
1927 * In addition to combining the draw and clipping into one operation, this function adds the
1928 * additional capability of controlling each of the rectangle's edges anti-aliasing
1929 * independently. The edges of the clip will respect the per-edge AA flags. It is required that
1930 * 'clip' be contained inside 'rect'. In terms of mapping to edge labels, the 'clip' points
1931 * should be ordered top-left, top-right, bottom-right, bottom-left so that the edge between [0]
1932 * and [1] is "top", [1] and [2] is "right", [2] and [3] is "bottom", and [3] and [0] is "left".
1933 * This ordering matches SkRect::toQuad().
1934 *
1935 * This API only draws solid color, filled rectangles so it does not accept a full SkPaint.
1936 */
1937 void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
1938 const SkColor4f& color, SkBlendMode mode);
1939 void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
1940 SkColor color, SkBlendMode mode) {
1941 this->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, SkColor4f::FromColor(color), mode);
1942 }
1943
1944 /**
1945 * This is an bulk variant of experimental_DrawEdgeAAQuad() that renders 'cnt' textured quads.
1946 * For each entry, 'fDstRect' is rendered with its clip (determined by entry's 'fHasClip' and
1947 * the current index in 'dstClip'). The entry's fImage is applied to the destination rectangle
1948 * by sampling from 'fSrcRect' sub-image. The corners of 'fSrcRect' map to the corners of
1949 * 'fDstRect', just like in drawImageRect(), and they will be properly interpolated when
1950 * applying a clip.
1951 *
1952 * Like experimental_DrawEdgeAAQuad(), each entry can specify edge AA flags that apply to both
1953 * the destination rect and its clip.
1954 *
1955 * If provided, the 'dstClips' array must have length equal 4 * the number of entries with
1956 * fHasClip true. If 'dstClips' is null, every entry must have 'fHasClip' set to false. The
1957 * destination clip coordinates will be read consecutively with the image set entries, advancing
1958 * by 4 points every time an entry with fHasClip is passed.
1959 *
1960 * This entry point supports per-entry manipulations to the canvas's current matrix. If an
1961 * entry provides 'fMatrixIndex' >= 0, it will be drawn as if the canvas's CTM was
1962 * canvas->getTotalMatrix() * preViewMatrices[fMatrixIndex]. If 'fMatrixIndex' is less than 0,
1963 * the pre-view matrix transform is implicitly the identity, so it will be drawn using just the
1964 * current canvas matrix. The pre-view matrix modifies the canvas's view matrix, it does not
1965 * affect the local coordinates of each entry.
1966 *
1967 * An optional paint may be provided, which supports the same subset of features usable with
1968 * drawImageRect (i.e. assumed to be filled and no path effects). When a paint is provided, the
1969 * image set is drawn as if each image used the applied paint independently, so each is affected
1970 * by the image, color, and/or mask filter.
1971 */
1972 void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
1973 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
1974 const SkPaint* paint = nullptr,
1975 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1976
1977 /** Draws text, with origin at (x, y), using clip, SkMatrix, SkFont font,
1978 and SkPaint paint.
1979
1980 When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
1981 SkTextEncoding::kUTF32, this function uses the default
1982 character-to-glyph mapping from the SkTypeface in font. It does not
1983 perform typeface fallback for characters not found in the SkTypeface.
1984 It does not perform kerning or other complex shaping; glyphs are
1985 positioned based on their default advances.
1986
1987 Text meaning depends on SkTextEncoding.
1988
1989 Text size is affected by SkMatrix and SkFont text size. Default text
1990 size is 12 point.
1991
1992 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1993 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By
1994 default, draws filled black glyphs.
1995
1996 @param text character code points or glyphs drawn
1997 @param byteLength byte length of text array
1998 @param encoding text encoding used in the text array
1999 @param x start of text on x-axis
2000 @param y start of text on y-axis
2001 @param font typeface, text size and so, used to describe the text
2002 @param paint blend, color, and so on, used to draw
2003 */
2004 void drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
2005 SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint);
2006
2007 /** Draws null terminated string, with origin at (x, y), using clip, SkMatrix,
2008 SkFont font, and SkPaint paint.
2009
2010 This function uses the default character-to-glyph mapping from the
2011 SkTypeface in font. It does not perform typeface fallback for
2012 characters not found in the SkTypeface. It does not perform kerning;
2013 glyphs are positioned based on their default advances.
2014
2015 String str is encoded as UTF-8.
2016
2017 Text size is affected by SkMatrix and font text size. Default text
2018 size is 12 point.
2019
2020 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
2021 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By
2022 default, draws filled black glyphs.
2023
2024 @param str character code points drawn,
2025 ending with a char value of zero
2026 @param x start of string on x-axis
2027 @param y start of string on y-axis
2028 @param font typeface, text size and so, used to describe the text
2029 @param paint blend, color, and so on, used to draw
2030 */
2031 void drawString(const char str[], SkScalar x, SkScalar y, const SkFont& font,
2032 const SkPaint& paint) {
2033 this->drawSimpleText(str, strlen(str), SkTextEncoding::kUTF8, x, y, font, paint);
2034 }
2035
2036 /** Draws SkString, with origin at (x, y), using clip, SkMatrix, SkFont font,
2037 and SkPaint paint.
2038
2039 This function uses the default character-to-glyph mapping from the
2040 SkTypeface in font. It does not perform typeface fallback for
2041 characters not found in the SkTypeface. It does not perform kerning;
2042 glyphs are positioned based on their default advances.
2043
2044 SkString str is encoded as UTF-8.
2045
2046 Text size is affected by SkMatrix and SkFont text size. Default text
2047 size is 12 point.
2048
2049 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
2050 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By
2051 default, draws filled black glyphs.
2052
2053 @param str character code points drawn,
2054 ending with a char value of zero
2055 @param x start of string on x-axis
2056 @param y start of string on y-axis
2057 @param font typeface, text size and so, used to describe the text
2058 @param paint blend, color, and so on, used to draw
2059 */
2060 void drawString(const SkString& str, SkScalar x, SkScalar y, const SkFont& font,
2061 const SkPaint& paint) {
2062 this->drawSimpleText(str.c_str(), str.size(), SkTextEncoding::kUTF8, x, y, font, paint);
2063 }
2064
2065 /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
2066
2067 blob contains glyphs, their positions, and paint attributes specific to text:
2068 SkTypeface, SkPaint text size, SkPaint text scale x,
2069 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
2070 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
2071 and SkPaint subpixel text.
2072
2073 SkTextEncoding must be set to SkTextEncoding::kGlyphID.
2074
2075 Elements of paint: anti-alias, SkBlendMode, color including alpha,
2076 SkColorFilter, SkPaint dither, SkDrawLooper, SkMaskFilter, SkPathEffect, SkShader, and
2077 SkPaint::Style; apply to blob. If SkPaint contains SkPaint::kStroke_Style:
2078 SkPaint miter limit, SkPaint::Cap, SkPaint::Join, and SkPaint stroke width;
2079 apply to SkPath created from blob.
2080
2081 @param blob glyphs, positions, and their paints' text size, typeface, and so on
2082 @param x horizontal offset applied to blob
2083 @param y vertical offset applied to blob
2084 @param paint blend, color, stroking, and so on, used to draw
2085
2086 example: https://fiddle.skia.org/c/@Canvas_drawTextBlob
2087 */
2088 void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
2089
2090 /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
2091
2092 blob contains glyphs, their positions, and paint attributes specific to text:
2093 SkTypeface, SkPaint text size, SkPaint text scale x,
2094 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
2095 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
2096 and SkPaint subpixel text.
2097
2098 SkTextEncoding must be set to SkTextEncoding::kGlyphID.
2099
2100 Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
2101 SkImageFilter, and SkDrawLooper; apply to blob.
2102
2103 @param blob glyphs, positions, and their paints' text size, typeface, and so on
2104 @param x horizontal offset applied to blob
2105 @param y vertical offset applied to blob
2106 @param paint blend, color, stroking, and so on, used to draw
2107 */
2108 void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
2109 this->drawTextBlob(blob.get(), x, y, paint);
2110 }
2111
2112 /** Draws SkPicture picture, using clip and SkMatrix.
2113 Clip and SkMatrix are unchanged by picture contents, as if
2114 save() was called before and restore() was called after drawPicture().
2115
2116 SkPicture records a series of draw commands for later playback.
2117
2118 @param picture recorded drawing commands to play
2119 */
2120 void drawPicture(const SkPicture* picture) {
2121 this->drawPicture(picture, nullptr, nullptr);
2122 }
2123
2124 /** Draws SkPicture picture, using clip and SkMatrix.
2125 Clip and SkMatrix are unchanged by picture contents, as if
2126 save() was called before and restore() was called after drawPicture().
2127
2128 SkPicture records a series of draw commands for later playback.
2129
2130 @param picture recorded drawing commands to play
2131 */
2132 void drawPicture(const sk_sp<SkPicture>& picture) {
2133 this->drawPicture(picture.get());
2134 }
2135
2136 /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
2137 SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
2138 SkImageFilter, and SkBlendMode, if provided.
2139
2140 matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
2141 paint use is equivalent to: saveLayer(), drawPicture(), restore().
2142
2143 @param picture recorded drawing commands to play
2144 @param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
2145 @param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
2146
2147 example: https://fiddle.skia.org/c/@Canvas_drawPicture_3
2148 */
2149 void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
2150
2151 /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
2152 SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
2153 SkImageFilter, and SkBlendMode, if provided.
2154
2155 matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
2156 paint use is equivalent to: saveLayer(), drawPicture(), restore().
2157
2158 @param picture recorded drawing commands to play
2159 @param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
2160 @param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
2161 */
2162 void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix,
2163 const SkPaint* paint) {
2164 this->drawPicture(picture.get(), matrix, paint);
2165 }
2166
2167 /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
2168 If vertices texs and vertices colors are defined in vertices, and SkPaint paint
2169 contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
2170
2171 @param vertices triangle mesh to draw
2172 @param mode combines vertices colors with SkShader, if both are present
2173 @param paint specifies the SkShader, used as SkVertices texture; may be nullptr
2174
2175 example: https://fiddle.skia.org/c/@Canvas_drawVertices
2176 */
2177 void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
2178
2179 /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
2180 * parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
2181 */
2182 void drawVertices(const SkVertices* vertices, const SkPaint& paint) {
2183 this->drawVertices(vertices, SkBlendMode::kModulate, paint);
2184 }
2185
2186 /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
2187 If vertices texs and vertices colors are defined in vertices, and SkPaint paint
2188 contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
2189
2190 @param vertices triangle mesh to draw
2191 @param mode combines vertices colors with SkShader, if both are present
2192 @param paint specifies the SkShader, used as SkVertices texture, may be nullptr
2193
2194 example: https://fiddle.skia.org/c/@Canvas_drawVertices_2
2195 */
2196 void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
2197
2198 /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
2199 * parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
2200 */
2201 void drawVertices(const sk_sp<SkVertices>& vertices, const SkPaint& paint) {
2202 this->drawVertices(vertices, SkBlendMode::kModulate, paint);
2203 }
2204
2205 /** Draws a Coons patch: the interpolation of four cubics with shared corners,
2206 associating a color, and optionally a texture SkPoint, with each corner.
2207
2208 Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
2209 alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
2210 as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
2211 both are provided.
2212
2213 SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2214 in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
2215 first point.
2216
2217 Color array color associates colors with corners in top-left, top-right,
2218 bottom-right, bottom-left order.
2219
2220 If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
2221 corners in top-left, top-right, bottom-right, bottom-left order.
2222
2223 @param cubics SkPath cubic array, sharing common points
2224 @param colors color array, one for each corner
2225 @param texCoords SkPoint array of texture coordinates, mapping SkShader to corners;
2226 may be nullptr
2227 @param mode SkBlendMode for colors, and for SkShader if paint has one
2228 @param paint SkShader, SkColorFilter, SkBlendMode, used to draw
2229 */
2230 void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2231 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
2232
2233 /** Draws SkPath cubic Coons patch: the interpolation of four cubics with shared corners,
2234 associating a color, and optionally a texture SkPoint, with each corner.
2235
2236 Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
2237 alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
2238 as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
2239 both are provided.
2240
2241 SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2242 in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
2243 first point.
2244
2245 Color array color associates colors with corners in top-left, top-right,
2246 bottom-right, bottom-left order.
2247
2248 If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
2249 corners in top-left, top-right, bottom-right, bottom-left order.
2250
2251 @param cubics SkPath cubic array, sharing common points
2252 @param colors color array, one for each corner
2253 @param texCoords SkPoint array of texture coordinates, mapping SkShader to corners;
2254 may be nullptr
2255 @param paint SkShader, SkColorFilter, SkBlendMode, used to draw
2256 */
2257 void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2258 const SkPoint texCoords[4], const SkPaint& paint) {
2259 this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
2260 }
2261
2262 /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
2263 paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
2264 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2265 atlas, and SkRSXform xform transforms it into destination space.
2266
2267 xform, text, and colors if present, must contain count entries.
2268 Optional colors are applied for each sprite using SkBlendMode mode, treating
2269 sprite as source and colors as destination.
2270 Optional cullRect is a conservative bounds of all transformed sprites.
2271 If cullRect is outside of clip, canvas can skip drawing.
2272
2273 If atlas is nullptr, this draws nothing.
2274
2275 @param atlas SkImage containing sprites
2276 @param xform SkRSXform mappings for sprites in atlas
2277 @param tex SkRect locations of sprites in atlas
2278 @param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr
2279 @param count number of sprites to draw
2280 @param mode SkBlendMode combining colors and sprites
2281 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2282 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
2283 */
2284 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
2285 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
2286 const SkPaint* paint);
2287
2288 /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
2289 paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
2290 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2291 atlas, and SkRSXform xform transforms it into destination space.
2292
2293 xform, text, and colors if present, must contain count entries.
2294 Optional colors is applied for each sprite using SkBlendMode.
2295 Optional cullRect is a conservative bounds of all transformed sprites.
2296 If cullRect is outside of clip, canvas can skip drawing.
2297
2298 @param atlas SkImage containing sprites
2299 @param xform SkRSXform mappings for sprites in atlas
2300 @param tex SkRect locations of sprites in atlas
2301 @param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr
2302 @param count number of sprites to draw
2303 @param mode SkBlendMode combining colors and sprites
2304 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2305 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
2306 */
2307 void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
2308 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
2309 const SkPaint* paint) {
2310 this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
2311 }
2312
2313 /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
2314 paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
2315 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2316 atlas, and SkRSXform xform transforms it into destination space.
2317
2318 xform and text must contain count entries.
2319 Optional cullRect is a conservative bounds of all transformed sprites.
2320 If cullRect is outside of clip, canvas can skip drawing.
2321
2322 @param atlas SkImage containing sprites
2323 @param xform SkRSXform mappings for sprites in atlas
2324 @param tex SkRect locations of sprites in atlas
2325 @param count number of sprites to draw
2326 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2327 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
2328 */
2329 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
2330 const SkRect* cullRect, const SkPaint* paint) {
2331 this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
2332 }
2333
2334 /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
2335 paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
2336 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2337 atlas, and SkRSXform xform transforms it into destination space.
2338
2339 xform and text must contain count entries.
2340 Optional cullRect is a conservative bounds of all transformed sprites.
2341 If cullRect is outside of clip, canvas can skip drawing.
2342
2343 @param atlas SkImage containing sprites
2344 @param xform SkRSXform mappings for sprites in atlas
2345 @param tex SkRect locations of sprites in atlas
2346 @param count number of sprites to draw
2347 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2348 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
2349 */
2350 void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
2351 int count, const SkRect* cullRect, const SkPaint* paint) {
2352 this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
2353 cullRect, paint);
2354 }
2355
2356 /** Draws SkDrawable drawable using clip and SkMatrix, concatenated with
2357 optional matrix.
2358
2359 If SkCanvas has an asynchronous implementation, as is the case
2360 when it is recording into SkPicture, then drawable will be referenced,
2361 so that SkDrawable::draw() can be called when the operation is finalized. To force
2362 immediate drawing, call SkDrawable::draw() instead.
2363
2364 @param drawable custom struct encapsulating drawing commands
2365 @param matrix transformation applied to drawing; may be nullptr
2366
2367 example: https://fiddle.skia.org/c/@Canvas_drawDrawable
2368 */
2369 void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr);
2370
2371 /** Draws SkDrawable drawable using clip and SkMatrix, offset by (x, y).
2372
2373 If SkCanvas has an asynchronous implementation, as is the case
2374 when it is recording into SkPicture, then drawable will be referenced,
2375 so that SkDrawable::draw() can be called when the operation is finalized. To force
2376 immediate drawing, call SkDrawable::draw() instead.
2377
2378 @param drawable custom struct encapsulating drawing commands
2379 @param x offset into SkCanvas writable pixels on x-axis
2380 @param y offset into SkCanvas writable pixels on y-axis
2381
2382 example: https://fiddle.skia.org/c/@Canvas_drawDrawable_2
2383 */
2384 void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);
2385
2386 /** Associates SkRect on SkCanvas with an annotation; a key-value pair, where the key is
2387 a null-terminated UTF-8 string, and optional value is stored as SkData.
2388
2389 Only some canvas implementations, such as recording to SkPicture, or drawing to
2390 document PDF, use annotations.
2391
2392 @param rect SkRect extent of canvas to annotate
2393 @param key string used for lookup
2394 @param value data holding value stored in annotation
2395
2396 example: https://fiddle.skia.org/c/@Canvas_drawAnnotation_2
2397 */
2398 void drawAnnotation(const SkRect& rect, const char key[], SkData* value);
2399
2400 /** Associates SkRect on SkCanvas when an annotation; a key-value pair, where the key is
2401 a null-terminated UTF-8 string, and optional value is stored as SkData.
2402
2403 Only some canvas implementations, such as recording to SkPicture, or drawing to
2404 document PDF, use annotations.
2405
2406 @param rect SkRect extent of canvas to annotate
2407 @param key string used for lookup
2408 @param value data holding value stored in annotation
2409 */
2410 void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
2411 this->drawAnnotation(rect, key, value.get());
2412 }
2413
2414 /** Returns true if clip is empty; that is, nothing will draw.
2415
2416 May do work when called; it should not be called
2417 more often than needed. However, once called, subsequent calls perform no
2418 work until clip changes.
2419
2420 @return true if clip is empty
2421
2422 example: https://fiddle.skia.org/c/@Canvas_isClipEmpty
2423 */
2424 virtual bool isClipEmpty() const;
2425
2426 /** Returns true if clip is SkRect and not empty.
2427 Returns false if the clip is empty, or if it is not SkRect.
2428
2429 @return true if clip is SkRect and not empty
2430
2431 example: https://fiddle.skia.org/c/@Canvas_isClipRect
2432 */
2433 virtual bool isClipRect() const;
2434
2435 /** Returns the current transform from local coordinates to the 'device', which for most
2436 * purposes means pixels.
2437 *
2438 * @return transformation from local coordinates to device / pixels.
2439 */
2440 SkM44 getLocalToDevice() const;
2441
2442 /** Legacy version of getLocalToDevice(), which strips away any Z information, and
2443 * just returns a 3x3 version.
2444 *
2445 * @return 3x3 version of getLocalToDevice()
2446 *
2447 * example: https://fiddle.skia.org/c/@Canvas_getTotalMatrix
2448 * example: https://fiddle.skia.org/c/@Clip
2449 */
2450 SkMatrix getTotalMatrix() const;
2451
2452 ///////////////////////////////////////////////////////////////////////////
2453
2454 // don't call
2455 virtual GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
2456 SkIRect internal_private_getTopLayerBounds() const { return getTopLayerBounds(); }
2457
2458 // TEMP helpers until we switch virtual over to const& for src-rect
2459 void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
2460 const SkPaint* paint,
2461 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
2462
2463 /**
2464 * Returns the global clip as a region. If the clip contains AA, then only the bounds
2465 * of the clip may be returned.
2466 */
2467 void temporary_internal_getRgnClip(SkRegion* region);
2468
2469 void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
2470
2471
2472protected:
2473 // default impl defers to getDevice()->newSurface(info)
2474 virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
2475
2476 // default impl defers to its device
2477 virtual bool onPeekPixels(SkPixmap* pixmap);
2478 virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
2479 virtual SkImageInfo onImageInfo() const;
2480 virtual bool onGetProps(SkSurfaceProps* props) const;
2481 virtual void onFlush();
2482
2483 // Subclass save/restore notifiers.
2484 // Overriders should call the corresponding INHERITED method up the inheritance chain.
2485 // getSaveLayerStrategy()'s return value may suppress full layer allocation.
2486 enum SaveLayerStrategy {
2487 kFullLayer_SaveLayerStrategy,
2488 kNoLayer_SaveLayerStrategy,
2489 };
2490
2491 virtual void willSave() {}
2492 // Overriders should call the corresponding INHERITED method up the inheritance chain.
2493 virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
2494 return kFullLayer_SaveLayerStrategy;
2495 }
2496
2497 // returns true if we should actually perform the saveBehind, or false if we should just save.
2498 virtual bool onDoSaveBehind(const SkRect*) { return true; }
2499 virtual void willRestore() {}
2500 virtual void didRestore() {}
2501
2502 virtual void onMarkCTM(MarkerID) {}
2503#ifdef SK_SUPPORT_LEGACY_DIDCONCAT44
2504 virtual void didConcat44(const SkScalar[]) {} // colMajor
2505#else
2506 virtual void didConcat44(const SkM44&) {}
2507#endif
2508 virtual void didConcat(const SkMatrix& ) {}
2509 virtual void didSetMatrix(const SkMatrix& ) {}
2510 virtual void didTranslate(SkScalar, SkScalar) {}
2511 virtual void didScale(SkScalar, SkScalar) {}
2512
2513 // NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to
2514 // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
2515 // that mechanism will be required to implement the new function.
2516 virtual void onDrawPaint(const SkPaint& paint);
2517 virtual void onDrawBehind(const SkPaint& paint);
2518 virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
2519 virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
2520 virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
2521 virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
2522 virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
2523 bool useCenter, const SkPaint& paint);
2524 virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
2525 virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
2526
2527 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
2528 const SkPaint& paint);
2529
2530 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
2531 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
2532 virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
2533 const SkPaint& paint);
2534
2535 virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
2536 const SkPaint& paint);
2537 virtual void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, const SkPaint* paint);
2538 virtual void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
2539 const SkPaint* paint, SrcRectConstraint constraint);
2540 virtual void onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
2541 const SkPaint* paint);
2542 virtual void onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
2543 const SkPaint* paint);
2544
2545 virtual void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
2546 const SkColor colors[], int count, SkBlendMode mode,
2547 const SkRect* cull, const SkPaint* paint);
2548
2549 virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
2550 virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
2551
2552 virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
2553 virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
2554 const SkPaint* paint);
2555
2556 virtual void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
2557 const SkColor4f& color, SkBlendMode mode);
2558 virtual void onDrawEdgeAAImageSet(const ImageSetEntry imageSet[], int count,
2559 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
2560 const SkPaint* paint, SrcRectConstraint constraint);
2561
2562 enum ClipEdgeStyle {
2563 kHard_ClipEdgeStyle,
2564 kSoft_ClipEdgeStyle
2565 };
2566
2567 virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
2568 virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
2569 virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
2570 virtual void onClipShader(sk_sp<SkShader>, SkClipOp);
2571 virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);
2572
2573 virtual void onDiscard();
2574
2575 // Clip rectangle bounds. Called internally by saveLayer.
2576 // returns false if the entire rectangle is entirely clipped out
2577 // If non-NULL, The imageFilter parameter will be used to expand the clip
2578 // and offscreen bounds for any margin required by the filter DAG.
2579 bool clipRectBounds(const SkRect* bounds, SaveLayerFlags flags, SkIRect* intersection,
2580 const SkImageFilter* imageFilter = nullptr);
2581
2582 SkBaseDevice* getTopDevice() const;
2583
2584private:
2585 /** After calling saveLayer(), there can be any number of devices that make
2586 up the top-most drawing area. LayerIter can be used to iterate through
2587 those devices. Note that the iterator is only valid until the next API
2588 call made on the canvas. Ownership of all pointers in the iterator stays
2589 with the canvas, so none of them should be modified or deleted.
2590 */
2591 class LayerIter /*: SkNoncopyable*/ {
2592 public:
2593 /** Initialize iterator with canvas, and set values for 1st device */
2594 LayerIter(SkCanvas*);
2595 ~LayerIter();
2596
2597 /** Return true if the iterator is done */
2598 bool done() const { return fDone; }
2599 /** Cycle to the next device */
2600 void next();
2601
2602 // These reflect the current device in the iterator
2603
2604 SkBaseDevice* device() const;
2605 const SkMatrix& matrix() const;
2606 SkIRect clipBounds() const;
2607 const SkPaint& paint() const;
2608 int x() const;
2609 int y() const;
2610
2611 private:
2612 // used to embed the SkDrawIter object directly in our instance, w/o
2613 // having to expose that class def to the public. There is an assert
2614 // in our constructor to ensure that fStorage is large enough
2615 // (though needs to be a compile-time-assert!). We use intptr_t to work
2616 // safely with 32 and 64 bit machines (to ensure the storage is enough)
2617 intptr_t fStorage[32];
2618 class SkDrawIter* fImpl; // this points at fStorage
2619 SkPaint fDefaultPaint;
2620 SkIPoint fDeviceOrigin;
2621 bool fDone;
2622 };
2623
2624 static bool BoundsAffectsClip(SaveLayerFlags);
2625
2626 static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
2627 SkBaseDevice* dst, const SkIPoint& dstOrigin,
2628 const SkMatrix& ctm);
2629
2630 enum ShaderOverrideOpacity {
2631 kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
2632 kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
2633 kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque
2634 };
2635
2636 // notify our surface (if we have one) that we are about to draw, so it
2637 // can perform copy-on-write or invalidate any cached images
2638 void predrawNotify(bool willOverwritesEntireSurface = false);
2639 void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
2640 void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
2641 this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
2642 : kNotOpaque_ShaderOverrideOpacity);
2643 }
2644
2645 SkBaseDevice* getDevice() const;
2646
2647 class MCRec;
2648
2649 SkDeque fMCStack;
2650 // points to top of stack
2651 MCRec* fMCRec;
2652
2653 struct MarkerRec {
2654 MCRec* fMCRec;
2655 SkM44 fMatrix;
2656 MarkerID fID;
2657 };
2658 std::vector<MarkerRec> fMarkerStack;
2659
2660 // the first N recs that can fit here mean we won't call malloc
2661 static constexpr int kMCRecSize = 128; // most recent measurement
2662 static constexpr int kMCRecCount = 32; // common depth for save/restores
2663 static constexpr int kDeviceCMSize = 224; // most recent measurement
2664
2665 intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
2666 intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
2667
2668 const SkSurfaceProps fProps;
2669
2670 int fSaveCount; // value returned by getSaveCount()
2671
2672 std::unique_ptr<SkRasterHandleAllocator> fAllocator;
2673
2674 SkSurface_Base* fSurfaceBase;
2675 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
2676 void setSurfaceBase(SkSurface_Base* sb) {
2677 fSurfaceBase = sb;
2678 }
2679 friend class SkSurface_Base;
2680 friend class SkSurface_Gpu;
2681
2682 SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
2683
2684 void doSave();
2685 void checkForDeferredSave();
2686 void internalSetMatrix(const SkMatrix&);
2687
2688 friend class SkAndroidFrameworkUtils;
2689 friend class SkCanvasPriv; // needs kDontClipToLayer_PrivateSaveLayerFlag
2690 friend class SkDrawIter; // needs setupDrawForLayerDevice()
2691 friend class AutoLayerForImageFilter;
2692 friend class SkSurface_Raster; // needs getDevice()
2693 friend class SkNoDrawCanvas; // needs resetForNextPicture()
2694 friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
2695 friend class SkOverdrawCanvas;
2696 friend class SkRasterHandleAllocator;
2697protected:
2698 // For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend)
2699 SkCanvas(const SkIRect& bounds);
2700private:
2701 SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
2702 SkRasterHandleAllocator::Handle);
2703
2704 SkCanvas(SkCanvas&&) = delete;
2705 SkCanvas(const SkCanvas&) = delete;
2706 SkCanvas& operator=(SkCanvas&&) = delete;
2707 SkCanvas& operator=(const SkCanvas&) = delete;
2708
2709 /** Experimental
2710 * Saves the specified subset of the current pixels in the current layer,
2711 * and then clears those pixels to transparent black.
2712 * Restores the pixels on restore() by drawing them in SkBlendMode::kDstOver.
2713 *
2714 * @param subset conservative bounds of the area to be saved / restored.
2715 * @return depth of save state stack before this call was made.
2716 */
2717 int only_axis_aligned_saveBehind(const SkRect* subset);
2718
2719 /**
2720 * Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle.
2721 * If there is no active saveBehind, then this draws nothing.
2722 */
2723 void drawClippedToSaveBehind(const SkPaint&);
2724
2725 void resetForNextPicture(const SkIRect& bounds);
2726
2727 // needs gettotalclip()
2728 friend class SkCanvasStateUtils;
2729
2730 // call this each time we attach ourselves to a device
2731 // - constructor
2732 // - internalSaveLayer
2733 void setupDevice(SkBaseDevice*);
2734
2735 void init(sk_sp<SkBaseDevice>);
2736
2737 /**
2738 * Gets the bounds of the top level layer in global canvas coordinates. We don't want this
2739 * to be public because it exposes decisions about layer sizes that are internal to the canvas.
2740 */
2741 SkIRect getTopLayerBounds() const;
2742
2743 void internalDrawPaint(const SkPaint& paint);
2744 void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
2745 void internalSaveBehind(const SkRect*);
2746 void internalDrawDevice(SkBaseDevice*, const SkPaint*, SkImage* clipImage,
2747 const SkMatrix& clipMatrix);
2748
2749 void internalConcat44(const SkM44&);
2750
2751 // shared by save() and saveLayer()
2752 void internalSave();
2753 void internalRestore();
2754
2755 /*
2756 * Returns true if drawing the specified rect (or all if it is null) with the specified
2757 * paint (or default if null) would overwrite the entire root device of the canvas
2758 * (i.e. the canvas' surface if it had one).
2759 */
2760 bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
2761
2762 /**
2763 * Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
2764 */
2765 bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
2766
2767 /**
2768 * Returns true if the clip (for any active layer) contains antialiasing.
2769 * If the clip is empty, this will return false.
2770 */
2771 bool androidFramework_isClipAA() const;
2772
2773 virtual SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const { return nullptr; }
2774
2775 /**
2776 * Keep track of the device clip bounds and if the matrix is scale-translate. This allows
2777 * us to do a fast quick reject in the common case.
2778 */
2779 bool fIsScaleTranslate;
2780 SkRect fDeviceClipBounds;
2781
2782 class AutoValidateClip {
2783 public:
2784 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
2785 fCanvas->validateClip();
2786 }
2787 ~AutoValidateClip() { fCanvas->validateClip(); }
2788
2789 private:
2790 const SkCanvas* fCanvas;
2791
2792 AutoValidateClip(AutoValidateClip&&) = delete;
2793 AutoValidateClip(const AutoValidateClip&) = delete;
2794 AutoValidateClip& operator=(AutoValidateClip&&) = delete;
2795 AutoValidateClip& operator=(const AutoValidateClip&) = delete;
2796 };
2797
2798#ifdef SK_DEBUG
2799 void validateClip() const;
2800#else
2801 void validateClip() const {}
2802#endif
2803
2804 std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder;
2805
2806 typedef SkRefCnt INHERITED;
2807};
2808
2809/** \class SkAutoCanvasRestore
2810 Stack helper class calls SkCanvas::restoreToCount when SkAutoCanvasRestore
2811 goes out of scope. Use this to guarantee that the canvas is restored to a known
2812 state.
2813*/
2814class SkAutoCanvasRestore {
2815public:
2816
2817 /** Preserves SkCanvas::save() count. Optionally saves SkCanvas clip and SkCanvas matrix.
2818
2819 @param canvas SkCanvas to guard
2820 @param doSave call SkCanvas::save()
2821 @return utility to restore SkCanvas state on destructor
2822 */
2823 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
2824 if (fCanvas) {
2825 fSaveCount = canvas->getSaveCount();
2826 if (doSave) {
2827 canvas->save();
2828 }
2829 }
2830 }
2831
2832 /** Restores SkCanvas to saved state. Destructor is called when container goes out of
2833 scope.
2834 */
2835 ~SkAutoCanvasRestore() {
2836 if (fCanvas) {
2837 fCanvas->restoreToCount(fSaveCount);
2838 }
2839 }
2840
2841 /** Restores SkCanvas to saved state immediately. Subsequent calls and
2842 ~SkAutoCanvasRestore() have no effect.
2843 */
2844 void restore() {
2845 if (fCanvas) {
2846 fCanvas->restoreToCount(fSaveCount);
2847 fCanvas = nullptr;
2848 }
2849 }
2850
2851private:
2852 SkCanvas* fCanvas;
2853 int fSaveCount;
2854
2855 SkAutoCanvasRestore(SkAutoCanvasRestore&&) = delete;
2856 SkAutoCanvasRestore(const SkAutoCanvasRestore&) = delete;
2857 SkAutoCanvasRestore& operator=(SkAutoCanvasRestore&&) = delete;
2858 SkAutoCanvasRestore& operator=(const SkAutoCanvasRestore&) = delete;
2859};
2860
2861// Private
2862#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
2863
2864#endif
2865