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