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