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 1459 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS 1460 /** Only for Stencil Culling use, Please do not use in other cases. 1461 Similar to DrawPath but with Stencil test, which will attempt 1462 to enable Stencil Test using CompareOp GREATER_OR_EQUAL. 1463 it will degenerate into DrawPath if Non-StencilCullingOp use stencil. 1464 */ 1465 void drawPathWithStencil(const SkPath& path, const SkPaint& paint, uint32_t stencilRef); 1466 1467 /** Only for Stencil Culling use, Please do not use in other cases. 1468 Similar to DrawImage but with Stencil test, which will attempt 1469 to enable Stencil Test using CompareOp GREATER_OR_EQUAL. 1470 it will degenerate into DrawImage if Non-StencilCullingOp use stencil. 1471 */ drawImageWithStencil(const sk_sp<SkImage> & image,SkScalar left,SkScalar top,const SkSamplingOptions & sampling,const SkPaint * paint,uint32_t stencilRef)1472 void drawImageWithStencil(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, 1473 const SkSamplingOptions& sampling, const SkPaint* paint, uint32_t stencilRef) { 1474 this->onDrawImage2WithStencil(image.get(), left, top, sampling, paint, stencilRef); 1475 } 1476 1477 /** Only for Stencil Culling use, Please do not use in other cases. 1478 Use stecnilVal to clear the specified area in stencil Buffer. 1479 it will do nothing if Non-StencilCullingOp use stencil. 1480 */ 1481 void clearStencil(const SkIRect& rect, uint32_t stencilVal); 1482 #endif 1483 drawImage(const SkImage * image,SkScalar left,SkScalar top)1484 void drawImage(const SkImage* image, SkScalar left, SkScalar top) { 1485 this->drawImage(image, left, top, SkSamplingOptions(), nullptr); 1486 } drawImage(const sk_sp<SkImage> & image,SkScalar left,SkScalar top)1487 void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top) { 1488 this->drawImage(image.get(), left, top, SkSamplingOptions(), nullptr); 1489 } 1490 1491 /** \enum SkCanvas::SrcRectConstraint 1492 SrcRectConstraint controls the behavior at the edge of source SkRect, 1493 provided to drawImageRect() when there is any filtering. If kStrict is set, 1494 then extra code is used to ensure it nevers samples outside of the src-rect. 1495 */ 1496 enum SrcRectConstraint { 1497 kStrict_SrcRectConstraint, //!< sample only inside bounds; slower 1498 kFast_SrcRectConstraint, //!< sample outside bounds; faster 1499 }; 1500 1501 void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkSamplingOptions&, 1502 const SkPaint* = nullptr); 1503 void drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y, 1504 const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) { 1505 this->drawImage(image.get(), x, y, sampling, paint); 1506 } 1507 void drawImageRect(const SkImage*, const SkRect& src, const SkRect& dst, 1508 const SkSamplingOptions&, const SkPaint*, SrcRectConstraint); 1509 void drawImageRect(const SkImage*, const SkRect& dst, const SkSamplingOptions&, 1510 const SkPaint* = nullptr); drawImageRect(const sk_sp<SkImage> & image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)1511 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst, 1512 const SkSamplingOptions& sampling, const SkPaint* paint, 1513 SrcRectConstraint constraint) { 1514 this->drawImageRect(image.get(), src, dst, sampling, paint, constraint); 1515 } 1516 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, 1517 const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) { 1518 this->drawImageRect(image.get(), dst, sampling, paint); 1519 } 1520 1521 /** Draws SkImage image stretched proportionally to fit into SkRect dst. 1522 SkIRect center divides the image into nine sections: four sides, four corners, and 1523 the center. Corners are unmodified or scaled down proportionately if their sides 1524 are larger than dst; center and four sides are scaled to fit remaining space, if any. 1525 1526 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint. 1527 1528 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and 1529 SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader. 1530 If paint contains SkMaskFilter, generate mask from image bounds. 1531 Any SkMaskFilter on paint is ignored as is paint anti-aliasing state. 1532 1533 If generated mask extends beyond image bounds, replicate image edge colors, just 1534 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set 1535 replicates the image edge color when it samples outside of its bounds. 1536 1537 @param image SkImage containing pixels, dimensions, and format 1538 @param center SkIRect edge of image corners and sides 1539 @param dst destination SkRect of image to draw to 1540 @param filter what technique to use when sampling the image 1541 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter, 1542 and so on; or nullptr 1543 */ 1544 void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 1545 SkFilterMode filter, const SkPaint* paint = nullptr); 1546 1547 /** \struct SkCanvas::Lattice 1548 SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid. 1549 Grid entries on even columns and even rows are fixed; these entries are 1550 always drawn at their original size if the destination is large enough. 1551 If the destination side is too small to hold the fixed entries, all fixed 1552 entries are proportionately scaled down to fit. 1553 The grid entries not on even columns and rows are scaled to fit the 1554 remaining space, if any. 1555 */ 1556 struct Lattice { 1557 1558 /** \enum SkCanvas::Lattice::RectType 1559 Optional setting per rectangular grid entry to make it transparent, 1560 or to fill the grid entry with a color. 1561 */ 1562 enum RectType : uint8_t { 1563 kDefault = 0, //!< draws SkBitmap into lattice rectangle 1564 kTransparent, //!< skips lattice rectangle by making it transparent 1565 kFixedColor, //!< draws one of fColors into lattice rectangle 1566 }; 1567 1568 const int* fXDivs; //!< x-axis values dividing bitmap 1569 const int* fYDivs; //!< y-axis values dividing bitmap 1570 const RectType* fRectTypes; //!< array of fill types 1571 int fXCount; //!< number of x-coordinates 1572 int fYCount; //!< number of y-coordinates 1573 const SkIRect* fBounds; //!< source bounds to draw from 1574 const SkColor* fColors; //!< array of colors 1575 }; 1576 1577 /** Draws SkImage image stretched proportionally to fit into SkRect dst. 1578 1579 SkCanvas::Lattice lattice divides image into a rectangular grid. 1580 Each intersection of an even-numbered row and column is fixed; 1581 fixed lattice elements never scale larger than their initial 1582 size and shrink proportionately when all fixed elements exceed the bitmap 1583 dimension. All other grid elements scale to fill the available space, if any. 1584 1585 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint. 1586 1587 If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and 1588 SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader. 1589 If paint contains SkMaskFilter, generate mask from image bounds. 1590 Any SkMaskFilter on paint is ignored as is paint anti-aliasing state. 1591 1592 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors, 1593 just as SkShader made from SkShader::MakeBitmapShader with 1594 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples 1595 outside of its bounds. 1596 1597 @param image SkImage containing pixels, dimensions, and format 1598 @param lattice division of bitmap into fixed and variable rectangles 1599 @param dst destination SkRect of image to draw to 1600 @param filter what technique to use when sampling the image 1601 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter, 1602 and so on; or nullptr 1603 */ 1604 void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 1605 SkFilterMode filter, const SkPaint* paint = nullptr); drawImageLattice(const SkImage * image,const Lattice & lattice,const SkRect & dst)1606 void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst) { 1607 this->drawImageLattice(image, lattice, dst, SkFilterMode::kNearest, nullptr); 1608 } 1609 1610 /** 1611 * Experimental. Controls anti-aliasing of each edge of images in an image-set. 1612 */ 1613 enum QuadAAFlags : unsigned { 1614 kLeft_QuadAAFlag = 0b0001, 1615 kTop_QuadAAFlag = 0b0010, 1616 kRight_QuadAAFlag = 0b0100, 1617 kBottom_QuadAAFlag = 0b1000, 1618 1619 kNone_QuadAAFlags = 0b0000, 1620 kAll_QuadAAFlags = 0b1111, 1621 }; 1622 1623 /** This is used by the experimental API below. */ 1624 struct SK_API ImageSetEntry { 1625 ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect, 1626 int matrixIndex, float alpha, unsigned aaFlags, bool hasClip); 1627 1628 ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect, 1629 float alpha, unsigned aaFlags); 1630 1631 ImageSetEntry(); 1632 ~ImageSetEntry(); 1633 ImageSetEntry(const ImageSetEntry&); 1634 ImageSetEntry& operator=(const ImageSetEntry&); 1635 1636 sk_sp<const SkImage> fImage; 1637 SkRect fSrcRect; 1638 SkRect fDstRect; 1639 int fMatrixIndex = -1; // Index into the preViewMatrices arg, or < 0 1640 float fAlpha = 1.f; 1641 unsigned fAAFlags = kNone_QuadAAFlags; // QuadAAFlags 1642 bool fHasClip = false; // True to use next 4 points in dstClip arg as quad 1643 }; 1644 1645 /** 1646 * This is an experimental API for the SkiaRenderer Chromium project, and its API will surely 1647 * evolve if it is not removed outright. 1648 * 1649 * This behaves very similarly to drawRect() combined with a clipPath() formed by clip 1650 * quadrilateral. 'rect' and 'clip' are in the same coordinate space. If 'clip' is null, then it 1651 * is as if the rectangle was not clipped (or, alternatively, clipped to itself). If not null, 1652 * then it must provide 4 points. 1653 * 1654 * In addition to combining the draw and clipping into one operation, this function adds the 1655 * additional capability of controlling each of the rectangle's edges anti-aliasing 1656 * independently. The edges of the clip will respect the per-edge AA flags. It is required that 1657 * 'clip' be contained inside 'rect'. In terms of mapping to edge labels, the 'clip' points 1658 * should be ordered top-left, top-right, bottom-right, bottom-left so that the edge between [0] 1659 * and [1] is "top", [1] and [2] is "right", [2] and [3] is "bottom", and [3] and [0] is "left". 1660 * This ordering matches SkRect::toQuad(). 1661 * 1662 * This API only draws solid color, filled rectangles so it does not accept a full SkPaint. 1663 */ 1664 void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags, 1665 const SkColor4f& color, SkBlendMode mode); experimental_DrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aaFlags,SkColor color,SkBlendMode mode)1666 void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags, 1667 SkColor color, SkBlendMode mode) { 1668 this->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, SkColor4f::FromColor(color), mode); 1669 } 1670 1671 /** 1672 * This is an bulk variant of experimental_DrawEdgeAAQuad() that renders 'cnt' textured quads. 1673 * For each entry, 'fDstRect' is rendered with its clip (determined by entry's 'fHasClip' and 1674 * the current index in 'dstClip'). The entry's fImage is applied to the destination rectangle 1675 * by sampling from 'fSrcRect' sub-image. The corners of 'fSrcRect' map to the corners of 1676 * 'fDstRect', just like in drawImageRect(), and they will be properly interpolated when 1677 * applying a clip. 1678 * 1679 * Like experimental_DrawEdgeAAQuad(), each entry can specify edge AA flags that apply to both 1680 * the destination rect and its clip. 1681 * 1682 * If provided, the 'dstClips' array must have length equal 4 * the number of entries with 1683 * fHasClip true. If 'dstClips' is null, every entry must have 'fHasClip' set to false. The 1684 * destination clip coordinates will be read consecutively with the image set entries, advancing 1685 * by 4 points every time an entry with fHasClip is passed. 1686 * 1687 * This entry point supports per-entry manipulations to the canvas's current matrix. If an 1688 * entry provides 'fMatrixIndex' >= 0, it will be drawn as if the canvas's CTM was 1689 * canvas->getTotalMatrix() * preViewMatrices[fMatrixIndex]. If 'fMatrixIndex' is less than 0, 1690 * the pre-view matrix transform is implicitly the identity, so it will be drawn using just the 1691 * current canvas matrix. The pre-view matrix modifies the canvas's view matrix, it does not 1692 * affect the local coordinates of each entry. 1693 * 1694 * An optional paint may be provided, which supports the same subset of features usable with 1695 * drawImageRect (i.e. assumed to be filled and no path effects). When a paint is provided, the 1696 * image set is drawn as if each image used the applied paint independently, so each is affected 1697 * by the image, color, and/or mask filter. 1698 */ 1699 void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt, 1700 const SkPoint dstClips[], const SkMatrix preViewMatrices[], 1701 const SkSamplingOptions&, const SkPaint* paint = nullptr, 1702 SrcRectConstraint constraint = kStrict_SrcRectConstraint); 1703 1704 /** Draws text, with origin at (x, y), using clip, SkMatrix, SkFont font, 1705 and SkPaint paint. 1706 1707 When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or 1708 SkTextEncoding::kUTF32, this function uses the default 1709 character-to-glyph mapping from the SkTypeface in font. It does not 1710 perform typeface fallback for characters not found in the SkTypeface. 1711 It does not perform kerning or other complex shaping; glyphs are 1712 positioned based on their default advances. 1713 1714 Text meaning depends on SkTextEncoding. 1715 1716 Text size is affected by SkMatrix and SkFont text size. Default text 1717 size is 12 point. 1718 1719 All elements of paint: SkPathEffect, SkMaskFilter, SkShader, 1720 SkColorFilter, and SkImageFilter; apply to text. By 1721 default, draws filled black glyphs. 1722 1723 @param text character code points or glyphs drawn 1724 @param byteLength byte length of text array 1725 @param encoding text encoding used in the text array 1726 @param x start of text on x-axis 1727 @param y start of text on y-axis 1728 @param font typeface, text size and so, used to describe the text 1729 @param paint blend, color, and so on, used to draw 1730 */ 1731 void drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding, 1732 SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint); 1733 1734 /** Draws null terminated string, with origin at (x, y), using clip, SkMatrix, 1735 SkFont font, and SkPaint paint. 1736 1737 This function uses the default character-to-glyph mapping from the 1738 SkTypeface in font. It does not perform typeface fallback for 1739 characters not found in the SkTypeface. It does not perform kerning; 1740 glyphs are positioned based on their default advances. 1741 1742 String str is encoded as UTF-8. 1743 1744 Text size is affected by SkMatrix and font text size. Default text 1745 size is 12 point. 1746 1747 All elements of paint: SkPathEffect, SkMaskFilter, SkShader, 1748 SkColorFilter, and SkImageFilter; apply to text. By 1749 default, draws filled black glyphs. 1750 1751 @param str character code points drawn, 1752 ending with a char value of zero 1753 @param x start of string on x-axis 1754 @param y start of string on y-axis 1755 @param font typeface, text size and so, used to describe the text 1756 @param paint blend, color, and so on, used to draw 1757 */ drawString(const char str[],SkScalar x,SkScalar y,const SkFont & font,const SkPaint & paint)1758 void drawString(const char str[], SkScalar x, SkScalar y, const SkFont& font, 1759 const SkPaint& paint) { 1760 this->drawSimpleText(str, strlen(str), SkTextEncoding::kUTF8, x, y, font, paint); 1761 } 1762 1763 /** Draws SkString, with origin at (x, y), using clip, SkMatrix, SkFont font, 1764 and SkPaint paint. 1765 1766 This function uses the default character-to-glyph mapping from the 1767 SkTypeface in font. It does not perform typeface fallback for 1768 characters not found in the SkTypeface. It does not perform kerning; 1769 glyphs are positioned based on their default advances. 1770 1771 SkString str is encoded as UTF-8. 1772 1773 Text size is affected by SkMatrix and SkFont text size. Default text 1774 size is 12 point. 1775 1776 All elements of paint: SkPathEffect, SkMaskFilter, SkShader, 1777 SkColorFilter, and SkImageFilter; apply to text. By 1778 default, draws filled black glyphs. 1779 1780 @param str character code points drawn, 1781 ending with a char value of zero 1782 @param x start of string on x-axis 1783 @param y start of string on y-axis 1784 @param font typeface, text size and so, used to describe the text 1785 @param paint blend, color, and so on, used to draw 1786 */ drawString(const SkString & str,SkScalar x,SkScalar y,const SkFont & font,const SkPaint & paint)1787 void drawString(const SkString& str, SkScalar x, SkScalar y, const SkFont& font, 1788 const SkPaint& paint) { 1789 this->drawSimpleText(str.c_str(), str.size(), SkTextEncoding::kUTF8, x, y, font, paint); 1790 } 1791 1792 /** Draws count glyphs, at positions relative to origin styled with font and paint with 1793 supporting utf8 and cluster information. 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 clusters array of size count of cluster information 1808 @param textByteCount size of the utf8text 1809 @param utf8text utf8text supporting information for the glyphs 1810 @param origin the origin of all the positions 1811 @param font typeface, text size and so, used to describe the text 1812 @param paint blend, color, and so on, used to draw 1813 */ 1814 void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[], 1815 const uint32_t clusters[], int textByteCount, const char utf8text[], 1816 SkPoint origin, const SkFont& font, const SkPaint& paint); 1817 1818 /** Draws count glyphs, at positions relative to origin styled with font and paint. 1819 1820 This function draw glyphs at the given positions relative to the given origin. 1821 It does not perform typeface fallback for glyphs not found in the SkTypeface in font. 1822 1823 The drawing obeys the current transform matrix and clipping. 1824 1825 All elements of paint: SkPathEffect, SkMaskFilter, SkShader, 1826 SkColorFilter, and SkImageFilter; apply to text. By 1827 default, draws filled black glyphs. 1828 1829 @param count number of glyphs to draw 1830 @param glyphs the array of glyphIDs to draw 1831 @param positions where to draw each glyph relative to origin 1832 @param origin the origin of all the positions 1833 @param font typeface, text size and so, used to describe the text 1834 @param paint blend, color, and so on, used to draw 1835 */ 1836 void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[], 1837 SkPoint origin, const SkFont& font, const SkPaint& paint); 1838 1839 /** Draws count glyphs, at positions relative to origin styled with font and paint. 1840 1841 This function draw glyphs using the given scaling and rotations. They are positioned 1842 relative to the given origin. It does not perform typeface fallback for glyphs not found 1843 in the SkTypeface in font. 1844 1845 The drawing obeys the current transform matrix and clipping. 1846 1847 All elements of paint: SkPathEffect, SkMaskFilter, SkShader, 1848 SkColorFilter, and SkImageFilter; apply to text. By 1849 default, draws filled black glyphs. 1850 1851 @param count number of glyphs to draw 1852 @param glyphs the array of glyphIDs to draw 1853 @param xforms where to draw and orient each glyph 1854 @param origin the origin of all the positions 1855 @param font typeface, text size and so, used to describe the text 1856 @param paint blend, color, and so on, used to draw 1857 */ 1858 void drawGlyphs(int count, const SkGlyphID glyphs[], const SkRSXform xforms[], 1859 SkPoint origin, const SkFont& font, 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: anti-alias, SkBlendMode, color including alpha, 1872 SkColorFilter, SkPaint dither, SkMaskFilter, SkPathEffect, SkShader, and 1873 SkPaint::Style; apply to blob. If SkPaint contains SkPaint::kStroke_Style: 1874 SkPaint miter limit, SkPaint::Cap, SkPaint::Join, and SkPaint stroke width; 1875 apply to SkPath created from blob. 1876 1877 @param blob glyphs, positions, and their paints' text size, typeface, and so on 1878 @param x horizontal offset applied to blob 1879 @param y vertical offset applied to blob 1880 @param paint blend, color, stroking, and so on, used to draw 1881 1882 example: https://fiddle.skia.org/c/@Canvas_drawTextBlob 1883 */ 1884 void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint); 1885 1886 /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint. 1887 1888 blob contains glyphs, their positions, and paint attributes specific to text: 1889 SkTypeface, SkPaint text size, SkPaint text scale x, 1890 SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold, 1891 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text, 1892 and SkPaint subpixel text. 1893 1894 SkTextEncoding must be set to SkTextEncoding::kGlyphID. 1895 1896 Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter, 1897 and SkImageFilter; apply to blob. 1898 1899 @param blob glyphs, positions, and their paints' text size, typeface, and so on 1900 @param x horizontal offset applied to blob 1901 @param y vertical offset applied to blob 1902 @param paint blend, color, stroking, and so on, used to draw 1903 */ drawTextBlob(const sk_sp<SkTextBlob> & blob,SkScalar x,SkScalar y,const SkPaint & paint)1904 void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) { 1905 this->drawTextBlob(blob.get(), x, y, paint); 1906 } 1907 1908 /** Draws HMSymbol at locate wih paint. 1909 @param symbol HMSymbol information 1910 @param locate draw locate 1911 @param paint blend, color, stroking, and so on, used to draw 1912 */ drawSymbol(const HMSymbolData & symbol,SkPoint locate,const SkPaint & paint)1913 void drawSymbol(const HMSymbolData& symbol, SkPoint locate, const SkPaint& paint) { 1914 this->onDrawSymbol(symbol, locate, paint); 1915 } 1916 1917 /** Draws SkPicture picture, using clip and SkMatrix. 1918 Clip and SkMatrix are unchanged by picture contents, as if 1919 save() was called before and restore() was called after drawPicture(). 1920 1921 SkPicture records a series of draw commands for later playback. 1922 1923 @param picture recorded drawing commands to play 1924 */ drawPicture(const SkPicture * picture)1925 void drawPicture(const SkPicture* picture) { 1926 this->drawPicture(picture, nullptr, nullptr); 1927 } 1928 1929 /** Draws SkPicture picture, using clip and SkMatrix. 1930 Clip and SkMatrix are unchanged by picture contents, as if 1931 save() was called before and restore() was called after drawPicture(). 1932 1933 SkPicture records a series of draw commands for later playback. 1934 1935 @param picture recorded drawing commands to play 1936 */ drawPicture(const sk_sp<SkPicture> & picture)1937 void drawPicture(const sk_sp<SkPicture>& picture) { 1938 this->drawPicture(picture.get()); 1939 } 1940 1941 /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with 1942 SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter, 1943 SkImageFilter, and SkBlendMode, if provided. 1944 1945 If paint is non-null, then the picture is always drawn into a temporary layer before 1946 actually landing on the canvas. Note that drawing into a layer can also change its 1947 appearance if there are any non-associative blendModes inside any of the pictures elements. 1948 1949 @param picture recorded drawing commands to play 1950 @param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr 1951 @param paint SkPaint to apply transparency, filtering, and so on; may be nullptr 1952 1953 example: https://fiddle.skia.org/c/@Canvas_drawPicture_3 1954 */ 1955 void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint); 1956 1957 /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with 1958 SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter, 1959 SkImageFilter, and SkBlendMode, if provided. 1960 1961 If paint is non-null, then the picture is always drawn into a temporary layer before 1962 actually landing on the canvas. Note that drawing into a layer can also change its 1963 appearance if there are any non-associative blendModes inside any of the pictures elements. 1964 1965 @param picture recorded drawing commands to play 1966 @param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr 1967 @param paint SkPaint to apply transparency, filtering, and so on; may be nullptr 1968 */ drawPicture(const sk_sp<SkPicture> & picture,const SkMatrix * matrix,const SkPaint * paint)1969 void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, 1970 const SkPaint* paint) { 1971 this->drawPicture(picture.get(), matrix, paint); 1972 } 1973 1974 /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix. 1975 If paint contains an SkShader and vertices does not contain texCoords, the shader 1976 is mapped using the vertices' positions. 1977 1978 If vertices colors are defined in vertices, and SkPaint paint contains SkShader, 1979 SkBlendMode mode combines vertices colors with SkShader. 1980 1981 SkMaskFilter and SkPathEffect on paint are ignored. 1982 1983 @param vertices triangle mesh to draw 1984 @param mode combines vertices colors with SkShader, if both are present 1985 @param paint specifies the SkShader, used as SkVertices texture; may be nullptr 1986 1987 example: https://fiddle.skia.org/c/@Canvas_drawVertices 1988 */ 1989 void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint); 1990 1991 /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend 1992 * parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter. 1993 */ drawVertices(const SkVertices * vertices,const SkPaint & paint)1994 void drawVertices(const SkVertices* vertices, const SkPaint& paint) { 1995 this->drawVertices(vertices, SkBlendMode::kModulate, paint); 1996 } 1997 1998 /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix. 1999 If paint contains an SkShader and vertices does not contain texCoords, the shader 2000 is mapped using the vertices' positions. 2001 2002 If vertices colors are defined in vertices, and SkPaint paint contains SkShader, 2003 SkBlendMode mode combines vertices colors with SkShader. 2004 2005 SkMaskFilter and SkPathEffect on paint are ignored. 2006 2007 @param vertices triangle mesh to draw 2008 @param mode combines vertices colors with SkShader, if both are present 2009 @param paint specifies the SkShader, used as SkVertices texture, may be nullptr 2010 2011 example: https://fiddle.skia.org/c/@Canvas_drawVertices_2 2012 */ 2013 void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint); 2014 2015 /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend 2016 * parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter. 2017 */ drawVertices(const sk_sp<SkVertices> & vertices,const SkPaint & paint)2018 void drawVertices(const sk_sp<SkVertices>& vertices, const SkPaint& paint) { 2019 this->drawVertices(vertices, SkBlendMode::kModulate, paint); 2020 } 2021 2022 /** Draws a Coons patch: the interpolation of four cubics with shared corners, 2023 associating a color, and optionally a texture SkPoint, with each corner. 2024 2025 Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter, 2026 alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated 2027 as Coons patch texture; SkBlendMode mode combines color colors and SkShader if 2028 both are provided. 2029 2030 SkPoint array cubics specifies four SkPath cubic starting at the top-left corner, 2031 in clockwise order, sharing every fourth point. The last SkPath cubic ends at the 2032 first point. 2033 2034 Color array color associates colors with corners in top-left, top-right, 2035 bottom-right, bottom-left order. 2036 2037 If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to 2038 corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is 2039 nullptr, SkShader is mapped using positions (derived from cubics). 2040 2041 SkMaskFilter and SkPathEffect on paint are ignored. 2042 2043 @param cubics SkPath cubic array, sharing common points 2044 @param colors color array, one for each corner 2045 @param texCoords SkPoint array of texture coordinates, mapping SkShader to corners; 2046 may be nullptr 2047 @param mode SkBlendMode for colors, and for SkShader if paint has one 2048 @param paint SkShader, SkColorFilter, SkBlendMode, used to draw 2049 */ 2050 void drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2051 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint); 2052 2053 /** Draws SkPath cubic Coons patch: the interpolation of four cubics with shared corners, 2054 associating a color, and optionally a texture SkPoint, with each corner. 2055 2056 Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter, 2057 alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated 2058 as Coons patch texture; SkBlendMode mode combines color colors and SkShader if 2059 both are provided. 2060 2061 SkPoint array cubics specifies four SkPath cubic starting at the top-left corner, 2062 in clockwise order, sharing every fourth point. The last SkPath cubic ends at the 2063 first point. 2064 2065 Color array color associates colors with corners in top-left, top-right, 2066 bottom-right, bottom-left order. 2067 2068 If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to 2069 corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is 2070 nullptr, SkShader is mapped using positions (derived from cubics). 2071 2072 SkMaskFilter and SkPathEffect on paint are ignored. 2073 2074 @param cubics SkPath cubic array, sharing common points 2075 @param colors color array, one for each corner 2076 @param texCoords SkPoint array of texture coordinates, mapping SkShader to corners; 2077 may be nullptr 2078 @param paint SkShader, SkColorFilter, SkBlendMode, used to draw 2079 */ drawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],const SkPaint & paint)2080 void drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2081 const SkPoint texCoords[4], const SkPaint& paint) { 2082 this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint); 2083 } 2084 2085 /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint. 2086 paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode 2087 to draw, if present. For each entry in the array, SkRect tex locates sprite in 2088 atlas, and SkRSXform xform transforms it into destination space. 2089 2090 SkMaskFilter and SkPathEffect on paint are ignored. 2091 2092 xform, tex, and colors if present, must contain count entries. 2093 Optional colors are applied for each sprite using SkBlendMode mode, treating 2094 sprite as source and colors as destination. 2095 Optional cullRect is a conservative bounds of all transformed sprites. 2096 If cullRect is outside of clip, canvas can skip drawing. 2097 2098 If atlas is nullptr, this draws nothing. 2099 2100 @param atlas SkImage containing sprites 2101 @param xform SkRSXform mappings for sprites in atlas 2102 @param tex SkRect locations of sprites in atlas 2103 @param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr 2104 @param count number of sprites to draw 2105 @param mode SkBlendMode combining colors and sprites 2106 @param sampling SkSamplingOptions used when sampling from the atlas image 2107 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr 2108 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr 2109 */ 2110 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 2111 const SkColor colors[], int count, SkBlendMode mode, 2112 const SkSamplingOptions& sampling, const SkRect* cullRect, const SkPaint* paint); 2113 2114 /** Draws SkDrawable drawable using clip and SkMatrix, concatenated with 2115 optional matrix. 2116 2117 If SkCanvas has an asynchronous implementation, as is the case 2118 when it is recording into SkPicture, then drawable will be referenced, 2119 so that SkDrawable::draw() can be called when the operation is finalized. To force 2120 immediate drawing, call SkDrawable::draw() instead. 2121 2122 @param drawable custom struct encapsulating drawing commands 2123 @param matrix transformation applied to drawing; may be nullptr 2124 2125 example: https://fiddle.skia.org/c/@Canvas_drawDrawable 2126 */ 2127 void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr); 2128 2129 /** Draws SkDrawable drawable using clip and SkMatrix, offset by (x, y). 2130 2131 If SkCanvas has an asynchronous implementation, as is the case 2132 when it is recording into SkPicture, then drawable will be referenced, 2133 so that SkDrawable::draw() can be called when the operation is finalized. To force 2134 immediate drawing, call SkDrawable::draw() instead. 2135 2136 @param drawable custom struct encapsulating drawing commands 2137 @param x offset into SkCanvas writable pixels on x-axis 2138 @param y offset into SkCanvas writable pixels on y-axis 2139 2140 example: https://fiddle.skia.org/c/@Canvas_drawDrawable_2 2141 */ 2142 void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y); 2143 2144 /** Associates SkRect on SkCanvas with an annotation; a key-value pair, where the key is 2145 a null-terminated UTF-8 string, and optional value is stored as SkData. 2146 2147 Only some canvas implementations, such as recording to SkPicture, or drawing to 2148 document PDF, use annotations. 2149 2150 @param rect SkRect extent of canvas to annotate 2151 @param key string used for lookup 2152 @param value data holding value stored in annotation 2153 2154 example: https://fiddle.skia.org/c/@Canvas_drawAnnotation_2 2155 */ 2156 void drawAnnotation(const SkRect& rect, const char key[], SkData* value); 2157 2158 /** Associates SkRect on SkCanvas when an annotation; a key-value pair, where the key is 2159 a null-terminated UTF-8 string, and optional value is stored as SkData. 2160 2161 Only some canvas implementations, such as recording to SkPicture, or drawing to 2162 document PDF, use annotations. 2163 2164 @param rect SkRect extent of canvas to annotate 2165 @param key string used for lookup 2166 @param value data holding value stored in annotation 2167 */ drawAnnotation(const SkRect & rect,const char key[],const sk_sp<SkData> & value)2168 void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) { 2169 this->drawAnnotation(rect, key, value.get()); 2170 } 2171 2172 /** Returns true if clip is empty; that is, nothing will draw. 2173 2174 May do work when called; it should not be called 2175 more often than needed. However, once called, subsequent calls perform no 2176 work until clip changes. 2177 2178 @return true if clip is empty 2179 2180 example: https://fiddle.skia.org/c/@Canvas_isClipEmpty 2181 */ 2182 virtual bool isClipEmpty() const; 2183 2184 /** Returns true if clip is SkRect and not empty. 2185 Returns false if the clip is empty, or if it is not SkRect. 2186 2187 @return true if clip is SkRect and not empty 2188 2189 example: https://fiddle.skia.org/c/@Canvas_isClipRect 2190 */ 2191 virtual bool isClipRect() const; 2192 2193 /** Returns the current transform from local coordinates to the 'device', which for most 2194 * purposes means pixels. 2195 * 2196 * @return transformation from local coordinates to device / pixels. 2197 */ 2198 SkM44 getLocalToDevice() const; 2199 2200 /** 2201 * Throws away the 3rd row and column in the matrix, so be warned. 2202 */ getLocalToDeviceAs3x3()2203 SkMatrix getLocalToDeviceAs3x3() const { 2204 return this->getLocalToDevice().asM33(); 2205 } 2206 2207 #ifdef SK_SUPPORT_LEGACY_GETTOTALMATRIX 2208 /** DEPRECATED 2209 * Legacy version of getLocalToDevice(), which strips away any Z information, and 2210 * just returns a 3x3 version. 2211 * 2212 * @return 3x3 version of getLocalToDevice() 2213 * 2214 * example: https://fiddle.skia.org/c/@Canvas_getTotalMatrix 2215 * example: https://fiddle.skia.org/c/@Clip 2216 */ 2217 SkMatrix getTotalMatrix() const; 2218 #endif 2219 2220 /////////////////////////////////////////////////////////////////////////// 2221 2222 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && SK_SUPPORT_GPU 2223 // These methods exist to support WebView in Android Framework. 2224 SkIRect topLayerBounds() const; 2225 GrBackendRenderTarget topLayerBackendRenderTarget() const; 2226 #endif 2227 2228 /** 2229 * Returns the global clip as a region. If the clip contains AA, then only the bounds 2230 * of the clip may be returned. 2231 */ 2232 void temporary_internal_getRgnClip(SkRegion* region); 2233 2234 void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&); 2235 2236 /** 2237 * Get the downSample Dimension when do drawBlurImage. 2238 * 2239 * @param blurArg parameter of blur. 2240 * @return {width, height}, if return {0, 0}, witch means something error. 2241 */ 2242 std::array<int, 2> CalcHpsBluredImageDimension(const SkBlurArg& blurArg); 2243 2244 /** 2245 * Draw SkImage image with Gaussian Blur algorithm by the separate X and Y sigma 2246 * onto destination canvas. The provided tile mode is used when blur kernel goes 2247 * outside the input image, by default SkTileMode::kDecal is used. 2248 * 2249 * @param image SkImage containing pixels, dimensions, and format. 2250 * @param blurArg parameter of blur. 2251 */ drawBlurImage(const SkImage * image,const SkBlurArg & blurArg)2252 bool drawBlurImage(const SkImage* image, const SkBlurArg& blurArg) 2253 { 2254 if (image == nullptr) { 2255 return false; 2256 } 2257 return this->onDrawBlurImage(image, blurArg); 2258 } 2259 2260 2261 protected: 2262 // default impl defers to getDevice()->newSurface(info) 2263 virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props); 2264 2265 // default impl defers to its device 2266 virtual bool onPeekPixels(SkPixmap* pixmap); 2267 virtual bool onAccessTopLayerPixels(SkPixmap* pixmap); 2268 virtual SkImageInfo onImageInfo() const; 2269 virtual bool onGetProps(SkSurfaceProps* props) const; 2270 virtual void onFlush(); 2271 2272 // Subclass save/restore notifiers. 2273 // Overriders should call the corresponding INHERITED method up the inheritance chain. 2274 // getSaveLayerStrategy()'s return value may suppress full layer allocation. 2275 enum SaveLayerStrategy { 2276 kFullLayer_SaveLayerStrategy, 2277 kNoLayer_SaveLayerStrategy, 2278 }; 2279 willSave()2280 virtual void willSave() {} 2281 // Overriders should call the corresponding INHERITED method up the inheritance chain. getSaveLayerStrategy(const SaveLayerRec &)2282 virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) { 2283 return kFullLayer_SaveLayerStrategy; 2284 } 2285 2286 // returns true if we should actually perform the saveBehind, or false if we should just save. onDoSaveBehind(const SkRect *)2287 virtual bool onDoSaveBehind(const SkRect*) { return true; } willRestore()2288 virtual void willRestore() {} didRestore()2289 virtual void didRestore() {} 2290 onMarkCTM(const char *)2291 virtual void onMarkCTM(const char*) {} didConcat44(const SkM44 &)2292 virtual void didConcat44(const SkM44&) {} didSetM44(const SkM44 &)2293 virtual void didSetM44(const SkM44&) {} didTranslate(SkScalar,SkScalar)2294 virtual void didTranslate(SkScalar, SkScalar) {} didScale(SkScalar,SkScalar)2295 virtual void didScale(SkScalar, SkScalar) {} 2296 2297 // NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to 2298 // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using 2299 // that mechanism will be required to implement the new function. 2300 virtual void onDrawPaint(const SkPaint& paint); 2301 virtual void onDrawBehind(const SkPaint& paint); 2302 virtual void onDrawRect(const SkRect& rect, const SkPaint& paint); 2303 virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint); 2304 virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint); 2305 virtual void onDrawOval(const SkRect& rect, const SkPaint& paint); 2306 virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, 2307 bool useCenter, const SkPaint& paint); 2308 virtual void onDrawPath(const SkPath& path, const SkPaint& paint); 2309 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS 2310 virtual void onDrawPathWithStencil(const SkPath& path, const SkPaint& paint, uint32_t stencilRef); 2311 virtual void onDrawImage2WithStencil(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&, 2312 const SkPaint*, uint32_t stencilRef); 2313 #endif 2314 virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint); 2315 2316 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 2317 const SkPaint& paint); 2318 onDrawSymbol(const HMSymbolData & symbol,SkPoint locate,const SkPaint & paint)2319 virtual void onDrawSymbol(const HMSymbolData& symbol, SkPoint locate, const SkPaint& paint) {} 2320 2321 virtual void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint); 2322 2323 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2324 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint); 2325 virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 2326 const SkPaint& paint); 2327 2328 virtual void onDrawImage2(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&, 2329 const SkPaint*); 2330 virtual void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst, 2331 const SkSamplingOptions&, const SkPaint*, SrcRectConstraint); 2332 virtual void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect& dst, 2333 SkFilterMode, const SkPaint*); 2334 virtual void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect src[], 2335 const SkColor[], int count, SkBlendMode, const SkSamplingOptions&, 2336 const SkRect* cull, const SkPaint*); 2337 virtual void onDrawEdgeAAImageSet2(const ImageSetEntry imageSet[], int count, 2338 const SkPoint dstClips[], const SkMatrix preViewMatrices[], 2339 const SkSamplingOptions&, const SkPaint*, 2340 SrcRectConstraint); 2341 2342 virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode, 2343 const SkPaint& paint); 2344 2345 virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value); 2346 virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&); 2347 2348 virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix); 2349 virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2350 const SkPaint* paint); 2351 2352 virtual void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags, 2353 const SkColor4f& color, SkBlendMode mode); 2354 2355 enum ClipEdgeStyle { 2356 kHard_ClipEdgeStyle, 2357 kSoft_ClipEdgeStyle 2358 }; 2359 2360 virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle); 2361 virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle); 2362 virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle); 2363 virtual void onClipShader(sk_sp<SkShader>, SkClipOp); 2364 virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op); 2365 virtual void onResetClip(); 2366 2367 virtual void onDiscard(); 2368 2369 virtual bool onDrawBlurImage(const SkImage* image, const SkBlurArg& blurArg); 2370 2371 private: 2372 2373 enum ShaderOverrideOpacity { 2374 kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image) 2375 kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque 2376 kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque 2377 }; 2378 2379 // notify our surface (if we have one) that we are about to draw, so it 2380 // can perform copy-on-write or invalidate any cached images 2381 // returns false if the copy failed 2382 bool SK_WARN_UNUSED_RESULT predrawNotify(bool willOverwritesEntireSurface = false); 2383 bool SK_WARN_UNUSED_RESULT predrawNotify(const SkRect*, const SkPaint*, ShaderOverrideOpacity); 2384 2385 enum class CheckForOverwrite : bool { 2386 kNo = false, 2387 kYes = true 2388 }; 2389 // call the appropriate predrawNotify and create a layer if needed. 2390 skstd::optional<AutoLayerForImageFilter> aboutToDraw( 2391 SkCanvas* canvas, 2392 const SkPaint& paint, 2393 const SkRect* rawBounds = nullptr, 2394 CheckForOverwrite = CheckForOverwrite::kNo, 2395 ShaderOverrideOpacity = kNone_ShaderOverrideOpacity); 2396 2397 // The bottom-most device in the stack, only changed by init(). Image properties and the final 2398 // canvas pixels are determined by this device. baseDevice()2399 SkBaseDevice* baseDevice() const { 2400 SkASSERT(fBaseDevice); 2401 return fBaseDevice.get(); 2402 } 2403 2404 // The top-most device in the stack, will change within saveLayer()'s. All drawing and clipping 2405 // operations should route to this device. 2406 SkBaseDevice* topDevice() const; 2407 2408 // Canvases maintain a sparse stack of layers, where the top-most layer receives the drawing, 2409 // clip, and matrix commands. There is a layer per call to saveLayer() using the 2410 // kFullLayer_SaveLayerStrategy. 2411 struct Layer { 2412 sk_sp<SkBaseDevice> fDevice; 2413 sk_sp<SkImageFilter> fImageFilter; // applied to layer *before* being drawn by paint 2414 SkPaint fPaint; 2415 bool fDiscard; 2416 2417 Layer(sk_sp<SkBaseDevice> device, sk_sp<SkImageFilter> imageFilter, const SkPaint& paint); 2418 }; 2419 2420 // Encapsulate state needed to restore from saveBehind() 2421 struct BackImage { 2422 sk_sp<SkSpecialImage> fImage; 2423 SkIPoint fLoc; 2424 }; 2425 2426 class MCRec { 2427 public: 2428 // If not null, this MCRec corresponds with the saveLayer() record that made the layer. 2429 // The base "layer" is not stored here, since it is stored inline in SkCanvas and has no 2430 // restoration behavior. 2431 std::unique_ptr<Layer> fLayer; 2432 2433 // This points to the device of the top-most layer (which may be lower in the stack), or 2434 // to the canvas's fBaseDevice. The MCRec does not own the device. 2435 SkBaseDevice* fDevice; 2436 2437 std::unique_ptr<BackImage> fBackImage; 2438 SkM44 fMatrix; 2439 int fDeferredSaveCount = 0; 2440 2441 MCRec(SkBaseDevice* device); 2442 MCRec(const MCRec* prev); 2443 ~MCRec(); 2444 2445 void newLayer(sk_sp<SkBaseDevice> layerDevice, 2446 sk_sp<SkImageFilter> filter, 2447 const SkPaint& restorePaint); 2448 2449 void reset(SkBaseDevice* device); 2450 }; 2451 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS 2452 void drawImageCommon(const SkImage* image, SkScalar x, SkScalar y, 2453 const SkSamplingOptions& sampling, const SkPaint* paint, 2454 bool useStencil, uint32_t stencilRef = 0); 2455 2456 void onDrawPathCommon(const SkPath& path, const SkPaint& paint, bool useStencil, uint32_t stencilRef = 0); 2457 #endif 2458 SkDeque fMCStack; 2459 // points to top of stack 2460 MCRec* fMCRec; 2461 2462 sk_sp<SkMarkerStack> fMarkerStack; 2463 2464 // the first N recs that can fit here mean we won't call malloc 2465 static constexpr int kMCRecSize = 96; // most recent measurement 2466 static constexpr int kMCRecCount = 32; // common depth for save/restores 2467 2468 intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)]; 2469 2470 // Installed via init() 2471 sk_sp<SkBaseDevice> fBaseDevice; 2472 const SkSurfaceProps fProps; 2473 2474 int fSaveCount; // value returned by getSaveCount() 2475 2476 std::unique_ptr<SkRasterHandleAllocator> fAllocator; 2477 2478 SkSurface_Base* fSurfaceBase; getSurfaceBase()2479 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; } setSurfaceBase(SkSurface_Base * sb)2480 void setSurfaceBase(SkSurface_Base* sb) { 2481 fSurfaceBase = sb; 2482 } 2483 friend class SkSurface_Base; 2484 friend class SkSurface_Gpu; 2485 2486 SkIRect fClipRestrictionRect = SkIRect::MakeEmpty(); 2487 int fClipRestrictionSaveCount = -1; 2488 2489 void doSave(); 2490 void checkForDeferredSave(); 2491 void internalSetMatrix(const SkM44&); 2492 2493 friend class SkAndroidFrameworkUtils; 2494 friend class SkCanvasPriv; // needs to expose android functions for testing outside android 2495 friend class AutoLayerForImageFilter; 2496 friend class SkSurface_Raster; // needs getDevice() 2497 friend class SkNoDrawCanvas; // needs resetForNextPicture() 2498 friend class SkNWayCanvas; 2499 friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>) 2500 friend class SkOverdrawCanvas; 2501 friend class SkRasterHandleAllocator; 2502 protected: 2503 // For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend) 2504 SkCanvas(const SkIRect& bounds); 2505 private: 2506 SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>, 2507 SkRasterHandleAllocator::Handle); 2508 2509 SkCanvas(SkCanvas&&) = delete; 2510 SkCanvas(const SkCanvas&) = delete; 2511 SkCanvas& operator=(SkCanvas&&) = delete; 2512 SkCanvas& operator=(const SkCanvas&) = delete; 2513 2514 /** Experimental 2515 * Saves the specified subset of the current pixels in the current layer, 2516 * and then clears those pixels to transparent black. 2517 * Restores the pixels on restore() by drawing them in SkBlendMode::kDstOver. 2518 * 2519 * @param subset conservative bounds of the area to be saved / restored. 2520 * @return depth of save state stack before this call was made. 2521 */ 2522 int only_axis_aligned_saveBehind(const SkRect* subset); 2523 2524 /** 2525 * Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle. 2526 * If there is no active saveBehind, then this draws nothing. 2527 */ 2528 void drawClippedToSaveBehind(const SkPaint&); 2529 2530 void resetForNextPicture(const SkIRect& bounds); 2531 2532 // needs gettotalclip() 2533 friend class SkCanvasStateUtils; 2534 2535 void init(sk_sp<SkBaseDevice>); 2536 2537 // All base onDrawX() functions should call this and skip drawing if it returns true. 2538 // If 'matrix' is non-null, it maps the paint's fast bounds before checking for quick rejection 2539 bool internalQuickReject(const SkRect& bounds, const SkPaint& paint, 2540 const SkMatrix* matrix = nullptr); 2541 2542 void internalDrawPaint(const SkPaint& paint); 2543 void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy); 2544 void internalSaveBehind(const SkRect*); 2545 2546 void internalConcat44(const SkM44&); 2547 2548 // shared by save() and saveLayer() 2549 void internalSave(); 2550 void internalRestore(); 2551 2552 enum class DeviceCompatibleWithFilter : bool { 2553 // Check the src device's local-to-device matrix for compatibility with the filter, and if 2554 // it is not compatible, introduce an intermediate image and transformation that allows the 2555 // filter to be evaluated on the modified src content. 2556 kUnknown = false, 2557 // Assume that the src device's local-to-device matrix is compatible with the filter. 2558 kYes = true 2559 }; 2560 /** 2561 * Filters the contents of 'src' and draws the result into 'dst'. The filter is evaluated 2562 * relative to the current canvas matrix, and src is drawn to dst using their relative transform 2563 * 'paint' is applied after the filter and must not have a mask or image filter of its own. 2564 * A null 'filter' behaves as if the identity filter were used. 2565 * 2566 * 'scaleFactor' is an extra uniform scale transform applied to downscale the 'src' image 2567 * before any filtering, or as part of the copy, and is then drawn with 1/scaleFactor to 'dst'. 2568 * Must be 1.0 if 'compat' is kYes (i.e. any scale factor has already been baked into the 2569 * relative transforms between the devices). 2570 */ 2571 void internalDrawDeviceWithFilter(SkBaseDevice* src, SkBaseDevice* dst, 2572 const SkImageFilter* filter, const SkPaint& paint, 2573 DeviceCompatibleWithFilter compat, 2574 SkScalar scaleFactor = 1.f); 2575 2576 /* 2577 * Returns true if drawing the specified rect (or all if it is null) with the specified 2578 * paint (or default if null) would overwrite the entire root device of the canvas 2579 * (i.e. the canvas' surface if it had one). 2580 */ 2581 bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const; 2582 2583 /** 2584 * Returns true if the paint's imagefilter can be invoked directly, without needed a layer. 2585 */ 2586 bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkSamplingOptions&, 2587 const SkPaint&); 2588 2589 /** 2590 * Returns true if the clip (for any active layer) contains antialiasing. 2591 * If the clip is empty, this will return false. 2592 */ 2593 bool androidFramework_isClipAA() const; 2594 2595 /** 2596 * Reset the clip to be wide-open (modulo any separately specified device clip restriction). 2597 * This operate within the save/restore clip stack so it can be undone by restoring to an 2598 * earlier save point. 2599 */ 2600 void internal_private_resetClip(); 2601 internal_private_asPaintFilterCanvas()2602 virtual SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const { return nullptr; } 2603 2604 // Keep track of the device clip bounds in the canvas' global space to reject draws before 2605 // invoking the top-level device. 2606 SkRect fQuickRejectBounds; 2607 2608 // Compute the clip's bounds based on all clipped SkDevice's reported device bounds transformed 2609 // into the canvas' global space. 2610 SkRect computeDeviceClipBounds(bool outsetForAA=true) const; 2611 2612 class AutoUpdateQRBounds; 2613 void validateClip() const; 2614 2615 std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder; 2616 2617 using INHERITED = SkRefCnt; 2618 }; 2619 2620 /** \class SkAutoCanvasRestore 2621 Stack helper class calls SkCanvas::restoreToCount when SkAutoCanvasRestore 2622 goes out of scope. Use this to guarantee that the canvas is restored to a known 2623 state. 2624 */ 2625 class SkAutoCanvasRestore { 2626 public: 2627 2628 /** Preserves SkCanvas::save() count. Optionally saves SkCanvas clip and SkCanvas matrix. 2629 2630 @param canvas SkCanvas to guard 2631 @param doSave call SkCanvas::save() 2632 @return utility to restore SkCanvas state on destructor 2633 */ SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)2634 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) { 2635 if (fCanvas) { 2636 fSaveCount = canvas->getSaveCount(); 2637 if (doSave) { 2638 canvas->save(); 2639 } 2640 } 2641 } 2642 2643 /** Restores SkCanvas to saved state. Destructor is called when container goes out of 2644 scope. 2645 */ ~SkAutoCanvasRestore()2646 ~SkAutoCanvasRestore() { 2647 if (fCanvas) { 2648 fCanvas->restoreToCount(fSaveCount); 2649 } 2650 } 2651 2652 /** Restores SkCanvas to saved state immediately. Subsequent calls and 2653 ~SkAutoCanvasRestore() have no effect. 2654 */ restore()2655 void restore() { 2656 if (fCanvas) { 2657 fCanvas->restoreToCount(fSaveCount); 2658 fCanvas = nullptr; 2659 } 2660 } 2661 2662 private: 2663 SkCanvas* fCanvas; 2664 int fSaveCount; 2665 2666 SkAutoCanvasRestore(SkAutoCanvasRestore&&) = delete; 2667 SkAutoCanvasRestore(const SkAutoCanvasRestore&) = delete; 2668 SkAutoCanvasRestore& operator=(SkAutoCanvasRestore&&) = delete; 2669 SkAutoCanvasRestore& operator=(const SkAutoCanvasRestore&) = delete; 2670 }; 2671 2672 #endif 2673