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