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