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