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