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

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com

source code of flutter_engine/third_party/skia/include/core/SkCanvas.h