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