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