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