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 "SkBlendMode.h" 12 #include "SkClipOp.h" 13 #include "SkDeque.h" 14 #include "SkPaint.h" 15 #include "SkRasterHandleAllocator.h" 16 #include "SkSurfaceProps.h" 17 #include "SkLights.h" 18 #include "../private/SkShadowParams.h" 19 20 class GrContext; 21 class GrRenderTargetContext; 22 class SkBaseDevice; 23 class SkBitmap; 24 class SkCanvasClipVisitor; 25 class SkClipStack; 26 class SkData; 27 class SkDraw; 28 class SkDrawable; 29 class SkDrawFilter; 30 class SkImage; 31 class SkImageFilter; 32 class SkMetaData; 33 class SkPath; 34 class SkPicture; 35 class SkPixmap; 36 class SkRasterClip; 37 class SkRegion; 38 class SkRRect; 39 struct SkRSXform; 40 class SkSurface; 41 class SkSurface_Base; 42 class SkTextBlob; 43 class SkVertices; 44 45 /** \class SkCanvas 46 47 A Canvas encapsulates all of the state about drawing into a device (bitmap). 48 This includes a reference to the device itself, and a stack of matrix/clip 49 values. For any given draw call (e.g. drawRect), the geometry of the object 50 being drawn is transformed by the concatenation of all the matrices in the 51 stack. The transformed geometry is clipped by the intersection of all of 52 the clips in the stack. 53 54 While the Canvas holds the state of the drawing device, the state (style) 55 of the object being drawn is held by the Paint, which is provided as a 56 parameter to each of the draw() methods. The Paint holds attributes such as 57 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns), 58 etc. 59 */ 60 class SK_API SkCanvas : SkNoncopyable { 61 enum PrivateSaveLayerFlags { 62 kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31, 63 }; 64 65 public: 66 /** 67 * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the 68 * specified pixels. To access the pixels after drawing to them, the caller should call 69 * flush() or call peekPixels(...). 70 * 71 * On failure, return NULL. This can fail for several reasons: 72 * 1. invalid ImageInfo (e.g. negative dimensions) 73 * 2. unsupported ImageInfo for a canvas 74 * - kUnknown_SkColorType, kIndex_8_SkColorType 75 * - kUnknown_SkAlphaType 76 * - this list is not complete, so others may also be unsupported 77 * 78 * Note: it is valid to request a supported ImageInfo, but with zero 79 * dimensions. 80 */ 81 static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo&, void*, size_t); 82 MakeRasterDirectN32(int width,int height,SkPMColor * pixels,size_t rowBytes)83 static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels, 84 size_t rowBytes) { 85 return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes); 86 } 87 88 /** 89 * Creates an empty canvas with no backing device/pixels, and zero 90 * dimensions. 91 */ 92 SkCanvas(); 93 94 /** 95 * Creates a canvas of the specified dimensions, but explicitly not backed 96 * by any device/pixels. Typically this use used by subclasses who handle 97 * the draw calls in some other way. 98 */ 99 SkCanvas(int width, int height, const SkSurfaceProps* = NULL); 100 101 /** Construct a canvas with the specified device to draw into. 102 103 @param device Specifies a device for the canvas to draw into. 104 */ 105 explicit SkCanvas(SkBaseDevice* device); 106 107 /** Construct a canvas with the specified bitmap to draw into. 108 @param bitmap Specifies a bitmap for the canvas to draw into. Its 109 structure are copied to the canvas. 110 */ 111 explicit SkCanvas(const SkBitmap& bitmap); 112 113 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 114 enum class ColorBehavior { 115 kLegacy, 116 }; 117 118 /** 119 * Android framework only constructor. 120 * Allows the creation of a legacy SkCanvas even though the |bitmap| 121 * and its pixel ref may have an SkColorSpace. 122 */ 123 SkCanvas(const SkBitmap& bitmap, ColorBehavior); 124 #endif 125 126 /** Construct a canvas with the specified bitmap to draw into. 127 @param bitmap Specifies a bitmap for the canvas to draw into. Its 128 structure are copied to the canvas. 129 @param props New canvas surface properties. 130 */ 131 SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props); 132 133 virtual ~SkCanvas(); 134 135 SkMetaData& getMetaData(); 136 137 /** 138 * Return ImageInfo for this canvas. If the canvas is not backed by pixels 139 * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. 140 */ 141 SkImageInfo imageInfo() const; 142 143 /** 144 * If the canvas is backed by pixels (cpu or gpu), this writes a copy of the SurfaceProps 145 * for the canvas to the location supplied by the caller, and returns true. Otherwise, 146 * return false and leave the supplied props unchanged. 147 */ 148 bool getProps(SkSurfaceProps*) const; 149 150 /////////////////////////////////////////////////////////////////////////// 151 152 /** 153 * Trigger the immediate execution of all pending draw operations. For the GPU 154 * backend this will resolve all rendering to the GPU surface backing the 155 * SkSurface that owns this canvas. 156 */ 157 void flush(); 158 159 /** 160 * Gets the size of the base or root layer in global canvas coordinates. The 161 * origin of the base layer is always (0,0). The current drawable area may be 162 * smaller (due to clipping or saveLayer). 163 */ 164 virtual SkISize getBaseLayerSize() const; 165 166 #ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 167 /** 168 * DEPRECATED: call getBaseLayerSize 169 */ getDeviceSize()170 SkISize getDeviceSize() const { return this->getBaseLayerSize(); } 171 #endif 172 173 /** 174 * Create a new surface matching the specified info, one that attempts to 175 * be maximally compatible when used with this canvas. If there is no matching Surface type, 176 * NULL is returned. 177 * 178 * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface 179 * inherits the properties of the surface that owns this canvas. If this canvas has no parent 180 * surface, then the new surface is created with default properties. 181 */ 182 sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps* = nullptr); 183 184 /** 185 * Return the GPU context of the device that is associated with the canvas. 186 * For a canvas with non-GPU device, NULL is returned. 187 */ 188 GrContext* getGrContext(); 189 190 /////////////////////////////////////////////////////////////////////////// 191 192 /** 193 * If the canvas has writable pixels in its top layer (and is not recording to a picture 194 * or other non-raster target) and has direct access to its pixels (i.e. they are in 195 * local RAM) return the address of those pixels, and if not null, 196 * return the ImageInfo, rowBytes and origin. The returned address is only valid 197 * while the canvas object is in scope and unchanged. Any API calls made on 198 * canvas (or its parent surface if any) will invalidate the 199 * returned address (and associated information). 200 * 201 * On failure, returns NULL and the info, rowBytes, and origin parameters are ignored. 202 */ 203 void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL); 204 205 SkRasterHandleAllocator::Handle accessTopRasterHandle() const; 206 207 /** 208 * If the canvas has readable pixels in its base layer (and is not recording to a picture 209 * or other non-raster target) and has direct access to its pixels (i.e. they are in 210 * local RAM) return true, and if not null, return in the pixmap parameter information about 211 * the pixels. The pixmap's pixel address is only valid 212 * while the canvas object is in scope and unchanged. Any API calls made on 213 * canvas (or its parent surface if any) will invalidate the pixel address 214 * (and associated information). 215 * 216 * On failure, returns false and the pixmap parameter will be ignored. 217 */ 218 bool peekPixels(SkPixmap*); 219 220 /** 221 * Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes), 222 * converting them into the requested format (SkImageInfo). The base-layer pixels are read 223 * starting at the specified (srcX,srcY) location in the coordinate system of the base-layer. 224 * 225 * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle 226 * 227 * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); 228 * 229 * srcR is intersected with the bounds of the base-layer. If this intersection is not empty, 230 * then we have two sets of pixels (of equal size). Replace the dst pixels with the 231 * corresponding src pixels, performing any colortype/alphatype transformations needed 232 * (in the case where the src and dst have different colortypes or alphatypes). 233 * 234 * This call can fail, returning false, for several reasons: 235 * - If srcR does not intersect the base-layer bounds. 236 * - If the requested colortype/alphatype cannot be converted from the base-layer's types. 237 * - If this canvas is not backed by pixels (e.g. picture or PDF) 238 */ 239 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 240 int srcX, int srcY); 241 242 /** 243 * Helper for calling readPixels(info, ...). This call will check if bitmap has been allocated. 244 * If not, it will attempt to call allocPixels(). If this fails, it will return false. If not, 245 * it calls through to readPixels(info, ...) and returns its result. 246 */ 247 bool readPixels(SkBitmap* bitmap, int srcX, int srcY); 248 249 /** 250 * Helper for allocating pixels and then calling readPixels(info, ...). The bitmap is resized 251 * to the intersection of srcRect and the base-layer bounds. On success, pixels will be 252 * allocated in bitmap and true returned. On failure, false is returned and bitmap will be 253 * set to empty. 254 */ 255 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); 256 257 /** 258 * This method affects the pixels in the base-layer, and operates in pixel coordinates, 259 * ignoring the matrix and clip. 260 * 261 * The specified ImageInfo and (x,y) offset specifies a rectangle: target. 262 * 263 * target.setXYWH(x, y, info.width(), info.height()); 264 * 265 * Target is intersected with the bounds of the base-layer. If this intersection is not empty, 266 * then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes 267 * and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src 268 * pixels, performing any colortype/alphatype transformations needed (in the case where the 269 * src and dst have different colortypes or alphatypes). 270 * 271 * This call can fail, returning false, for several reasons: 272 * - If the src colortype/alphatype cannot be converted to the canvas' types 273 * - If this canvas is not backed by pixels (e.g. picture or PDF) 274 */ 275 bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y); 276 277 /** 278 * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap 279 * is just wrapping a texture, returns false and does nothing. 280 */ 281 bool writePixels(const SkBitmap& bitmap, int x, int y); 282 283 /////////////////////////////////////////////////////////////////////////// 284 285 /** This call saves the current matrix, clip, and drawFilter, and pushes a 286 copy onto a private stack. Subsequent calls to translate, scale, 287 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all 288 operate on this copy. 289 When the balancing call to restore() is made, the previous matrix, clip, 290 and drawFilter are restored. 291 292 @return The value to pass to restoreToCount() to balance this save() 293 */ 294 int save(); 295 296 /** This behaves the same as save(), but in addition it allocates an 297 offscreen bitmap. All drawing calls are directed there, and only when 298 the balancing call to restore() is made is that offscreen transfered to 299 the canvas (or the previous layer). 300 @param bounds (may be null) This rect, if non-null, is used as a hint to 301 limit the size of the offscreen, and thus drawing may be 302 clipped to it, though that clipping is not guaranteed to 303 happen. If exact clipping is desired, use clipRect(). 304 @param paint (may be null) This is copied, and is applied to the 305 offscreen when restore() is called 306 @return The value to pass to restoreToCount() to balance this save() 307 */ 308 int saveLayer(const SkRect* bounds, const SkPaint* paint); saveLayer(const SkRect & bounds,const SkPaint * paint)309 int saveLayer(const SkRect& bounds, const SkPaint* paint) { 310 return this->saveLayer(&bounds, paint); 311 } 312 313 /** 314 * Temporary name. 315 * Will allow any requests for LCD text to be respected, so the caller must be careful to 316 * only draw on top of opaque sections of the layer to get good results. 317 */ 318 int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint); 319 320 /** This behaves the same as save(), but in addition it allocates an 321 offscreen bitmap. All drawing calls are directed there, and only when 322 the balancing call to restore() is made is that offscreen transfered to 323 the canvas (or the previous layer). 324 @param bounds (may be null) This rect, if non-null, is used as a hint to 325 limit the size of the offscreen, and thus drawing may be 326 clipped to it, though that clipping is not guaranteed to 327 happen. If exact clipping is desired, use clipRect(). 328 @param alpha This is applied to the offscreen when restore() is called. 329 @return The value to pass to restoreToCount() to balance this save() 330 */ 331 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha); 332 333 enum { 334 kIsOpaque_SaveLayerFlag = 1 << 0, 335 kPreserveLCDText_SaveLayerFlag = 1 << 1, 336 337 /** initialize the new layer with the contents of the previous layer */ 338 kInitWithPrevious_SaveLayerFlag = 1 << 2, 339 340 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 341 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag, 342 #endif 343 }; 344 typedef uint32_t SaveLayerFlags; 345 346 struct SaveLayerRec { SaveLayerRecSaveLayerRec347 SaveLayerRec() 348 : fBounds(nullptr), fPaint(nullptr), fBackdrop(nullptr), fSaveLayerFlags(0) 349 {} 350 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0) fBoundsSaveLayerRec351 : fBounds(bounds) 352 , fPaint(paint) 353 , fBackdrop(nullptr) 354 , fSaveLayerFlags(saveLayerFlags) 355 {} SaveLayerRecSaveLayerRec356 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop, 357 SaveLayerFlags saveLayerFlags) 358 : fBounds(bounds) 359 , fPaint(paint) 360 , fBackdrop(backdrop) 361 , fSaveLayerFlags(saveLayerFlags) 362 {} 363 364 const SkRect* fBounds; // optional 365 const SkPaint* fPaint; // optional 366 const SkImageFilter* fBackdrop; // optional 367 SaveLayerFlags fSaveLayerFlags; 368 }; 369 370 int saveLayer(const SaveLayerRec&); 371 372 /** This call balances a previous call to save(), and is used to remove all 373 modifications to the matrix/clip/drawFilter state since the last save 374 call. 375 It is an error to call restore() more times than save() was called. 376 */ 377 void restore(); 378 379 /** Returns the number of matrix/clip states on the SkCanvas' private stack. 380 This will equal # save() calls - # restore() calls + 1. The save count on 381 a new canvas is 1. 382 */ 383 int getSaveCount() const; 384 385 /** Efficient way to pop any calls to save() that happened after the save 386 count reached saveCount. It is an error for saveCount to be greater than 387 getSaveCount(). To pop all the way back to the initial matrix/clip context 388 pass saveCount == 1. 389 @param saveCount The number of save() levels to restore from 390 */ 391 void restoreToCount(int saveCount); 392 393 /** Preconcat the current matrix with the specified translation 394 @param dx The distance to translate in X 395 @param dy The distance to translate in Y 396 */ 397 void translate(SkScalar dx, SkScalar dy); 398 399 /** Preconcat the current matrix with the specified scale. 400 @param sx The amount to scale in X 401 @param sy The amount to scale in Y 402 */ 403 void scale(SkScalar sx, SkScalar sy); 404 405 /** Preconcat the current matrix with the specified rotation about the origin. 406 @param degrees The amount to rotate, in degrees 407 */ 408 void rotate(SkScalar degrees); 409 410 /** Preconcat the current matrix with the specified rotation about a given point. 411 @param degrees The amount to rotate, in degrees 412 @param px The x coordinate of the point to rotate about. 413 @param py The y coordinate of the point to rotate about. 414 */ 415 void rotate(SkScalar degrees, SkScalar px, SkScalar py); 416 417 /** Preconcat the current matrix with the specified skew. 418 @param sx The amount to skew in X 419 @param sy The amount to skew in Y 420 */ 421 void skew(SkScalar sx, SkScalar sy); 422 423 /** Preconcat the current matrix with the specified matrix. 424 @param matrix The matrix to preconcatenate with the current matrix 425 */ 426 void concat(const SkMatrix& matrix); 427 428 /** Replace the current matrix with a copy of the specified matrix. 429 @param matrix The matrix that will be copied into the current matrix. 430 */ 431 void setMatrix(const SkMatrix& matrix); 432 433 /** Helper for setMatrix(identity). Sets the current matrix to identity. 434 */ 435 void resetMatrix(); 436 437 #ifdef SK_EXPERIMENTAL_SHADOWING 438 /** Add the specified translation to the current draw depth of the canvas. 439 @param z The distance to translate in Z. 440 Negative into screen, positive out of screen. 441 Without translation, the draw depth defaults to 0. 442 */ 443 void translateZ(SkScalar z); 444 445 /** Set the current set of lights in the canvas. 446 @param lights The lights that we want the canvas to have. 447 */ 448 void setLights(sk_sp<SkLights> lights); 449 450 /** Returns the current set of lights the canvas uses 451 */ 452 sk_sp<SkLights> getLights() const; 453 #endif 454 455 /** 456 * Modify the current clip with the specified rectangle. 457 * @param rect The rect to combine with the current clip 458 * @param op The region op to apply to the current clip 459 * @param doAntiAlias true if the clip should be antialiased 460 */ 461 void clipRect(const SkRect& rect, SkClipOp, bool doAntiAlias); clipRect(const SkRect & rect,SkClipOp op)462 void clipRect(const SkRect& rect, SkClipOp op) { 463 this->clipRect(rect, op, false); 464 } 465 void clipRect(const SkRect& rect, bool doAntiAlias = false) { 466 this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias); 467 } 468 469 /** 470 * Sets the max clip rectangle, which can be set by clipRect, clipRRect and 471 * clipPath and intersect the current clip with the specified rect. 472 * The max clip affects only future ops (it is not retroactive). 473 * We DON'T record the clip restriction in pictures. 474 * This is private API to be used only by Android framework. 475 * @param rect The maximum allowed clip in device coordinates. 476 * Empty rect means max clip is not enforced. 477 */ 478 void androidFramework_setDeviceClipRestriction(const SkIRect& rect); 479 480 /** 481 * Modify the current clip with the specified SkRRect. 482 * @param rrect The rrect to combine with the current clip 483 * @param op The region op to apply to the current clip 484 * @param doAntiAlias true if the clip should be antialiased 485 */ 486 void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias); clipRRect(const SkRRect & rrect,SkClipOp op)487 void clipRRect(const SkRRect& rrect, SkClipOp op) { 488 this->clipRRect(rrect, op, false); 489 } 490 void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) { 491 this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias); 492 } 493 494 /** 495 * Modify the current clip with the specified path. 496 * @param path The path to combine with the current clip 497 * @param op The region op to apply to the current clip 498 * @param doAntiAlias true if the clip should be antialiased 499 */ 500 void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias); clipPath(const SkPath & path,SkClipOp op)501 void clipPath(const SkPath& path, SkClipOp op) { 502 this->clipPath(path, op, false); 503 } 504 void clipPath(const SkPath& path, bool doAntiAlias = false) { 505 this->clipPath(path, SkClipOp::kIntersect, doAntiAlias); 506 } 507 508 /** EXPERIMENTAL -- only used for testing 509 Set to simplify clip stack using path ops. 510 */ setAllowSimplifyClip(bool allow)511 void setAllowSimplifyClip(bool allow) { 512 fAllowSimplifyClip = allow; 513 } 514 515 /** Modify the current clip with the specified region. Note that unlike 516 clipRect() and clipPath() which transform their arguments by the current 517 matrix, clipRegion() assumes its argument is already in device 518 coordinates, and so no transformation is performed. 519 @param deviceRgn The region to apply to the current clip 520 @param op The region op to apply to the current clip 521 */ 522 void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect); 523 524 /** Return true if the specified rectangle, after being transformed by the 525 current matrix, would lie completely outside of the current clip. Call 526 this to check if an area you intend to draw into is clipped out (and 527 therefore you can skip making the draw calls). 528 @param rect the rect to compare with the current clip 529 @return true if the rect (transformed by the canvas' matrix) does not 530 intersect with the canvas' clip 531 */ 532 bool quickReject(const SkRect& rect) const; 533 534 /** Return true if the specified path, after being transformed by the 535 current matrix, would lie completely outside of the current clip. Call 536 this to check if an area you intend to draw into is clipped out (and 537 therefore you can skip making the draw calls). Note, for speed it may 538 return false even if the path itself might not intersect the clip 539 (i.e. the bounds of the path intersects, but the path does not). 540 @param path The path to compare with the current clip 541 @return true if the path (transformed by the canvas' matrix) does not 542 intersect with the canvas' clip 543 */ 544 bool quickReject(const SkPath& path) const; 545 546 /** 547 * Return the bounds of the current clip in local coordinates. If the clip is empty, 548 * return { 0, 0, 0, 0 }. 549 */ getLocalClipBounds()550 SkRect getLocalClipBounds() const { return this->onGetLocalClipBounds(); } 551 552 /** 553 * Returns true if the clip bounds are non-empty. 554 */ getLocalClipBounds(SkRect * bounds)555 bool getLocalClipBounds(SkRect* bounds) const { 556 *bounds = this->onGetLocalClipBounds(); 557 return !bounds->isEmpty(); 558 } 559 560 /** 561 * Return the bounds of the current clip in device coordinates. If the clip is empty, 562 * return { 0, 0, 0, 0 }. 563 */ getDeviceClipBounds()564 SkIRect getDeviceClipBounds() const { return this->onGetDeviceClipBounds(); } 565 566 /** 567 * Returns true if the clip bounds are non-empty. 568 */ getDeviceClipBounds(SkIRect * bounds)569 bool getDeviceClipBounds(SkIRect* bounds) const { 570 *bounds = this->onGetDeviceClipBounds(); 571 return !bounds->isEmpty(); 572 } 573 574 #ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 575 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 576 specified ARGB color, using the specified mode. 577 @param a the alpha component (0..255) of the color to fill the canvas 578 @param r the red component (0..255) of the color to fill the canvas 579 @param g the green component (0..255) of the color to fill the canvas 580 @param b the blue component (0..255) of the color to fill the canvas 581 @param mode the mode to apply the color in (defaults to SrcOver) 582 */ 583 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode = SkBlendMode::kSrcOver); 584 #endif 585 586 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 587 specified color and mode. 588 @param color the color to draw with 589 @param mode the mode to apply the color in (defaults to SrcOver) 590 */ 591 void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver); 592 593 /** 594 * Helper method for drawing a color in SRC mode, completely replacing all the pixels 595 * in the current clip with this color. 596 */ clear(SkColor color)597 void clear(SkColor color) { 598 this->drawColor(color, SkBlendMode::kSrc); 599 } 600 601 /** 602 * This makes the contents of the canvas undefined. Subsequent calls that 603 * require reading the canvas contents will produce undefined results. Examples 604 * include blending and readPixels. The actual implementation is backend- 605 * dependent and one legal implementation is to do nothing. This method 606 * ignores the current clip. 607 * 608 * This function should only be called if the caller intends to subsequently 609 * draw to the canvas. The canvas may do real work at discard() time in order 610 * to optimize performance on subsequent draws. Thus, if you call this and then 611 * never draw to the canvas subsequently you may pay a perfomance penalty. 612 */ discard()613 void discard() { this->onDiscard(); } 614 615 /** 616 * Fill the entire canvas (restricted to the current clip) with the 617 * specified paint. 618 * @param paint The paint used to fill the canvas 619 */ 620 void drawPaint(const SkPaint& paint); 621 622 enum PointMode { 623 /** drawPoints draws each point separately */ 624 kPoints_PointMode, 625 /** drawPoints draws each pair of points as a line segment */ 626 kLines_PointMode, 627 /** drawPoints draws the array of points as a polygon */ 628 kPolygon_PointMode 629 }; 630 631 /** Draw a series of points, interpreted based on the PointMode mode. For 632 all modes, the count parameter is interpreted as the total number of 633 points. For kLine mode, count/2 line segments are drawn. 634 For kPoint mode, each point is drawn centered at its coordinate, and its 635 size is specified by the paint's stroke-width. It draws as a square, 636 unless the paint's cap-type is round, in which the points are drawn as 637 circles. 638 For kLine mode, each pair of points is drawn as a line segment, 639 respecting the paint's settings for cap/join/width. 640 For kPolygon mode, the entire array is drawn as a series of connected 641 line segments. 642 Note that, while similar, kLine and kPolygon modes draw slightly 643 differently than the equivalent path built with a series of moveto, 644 lineto calls, in that the path will draw all of its contours at once, 645 with no interactions if contours intersect each other (think XOR 646 xfermode). drawPoints always draws each element one at a time. 647 @param mode PointMode specifying how to draw the array of points. 648 @param count The number of points in the array 649 @param pts Array of points to draw 650 @param paint The paint used to draw the points 651 */ 652 void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint); 653 654 /** Helper method for drawing a single point. See drawPoints() for more details. 655 */ 656 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint); 657 658 #ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 659 /** Draws a single pixel in the specified color. 660 @param x The X coordinate of which pixel to draw 661 @param y The Y coordiante of which pixel to draw 662 @param color The color to draw 663 */ 664 void drawPoint(SkScalar x, SkScalar y, SkColor color); 665 #endif 666 667 /** Draw a line segment with the specified start and stop x,y coordinates, 668 using the specified paint. NOTE: since a line is always "framed", the 669 paint's Style is ignored. 670 @param x0 The x-coordinate of the start point of the line 671 @param y0 The y-coordinate of the start point of the line 672 @param x1 The x-coordinate of the end point of the line 673 @param y1 The y-coordinate of the end point of the line 674 @param paint The paint used to draw the line 675 */ 676 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint); 677 678 /** Draw the specified rectangle using the specified paint. The rectangle 679 will be filled or stroked based on the Style in the paint. 680 @param rect The rect to be drawn 681 @param paint The paint used to draw the rect 682 */ 683 void drawRect(const SkRect& rect, const SkPaint& paint); 684 685 /** Draw the specified rectangle using the specified paint. The rectangle 686 will be filled or framed based on the Style in the paint. 687 @param rect The rect to be drawn 688 @param paint The paint used to draw the rect 689 */ drawIRect(const SkIRect & rect,const SkPaint & paint)690 void drawIRect(const SkIRect& rect, const SkPaint& paint) { 691 SkRect r; 692 r.set(rect); // promotes the ints to scalars 693 this->drawRect(r, paint); 694 } 695 696 #ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 697 /** Draw the specified rectangle using the specified paint. The rectangle 698 will be filled or framed based on the Style in the paint. 699 @param left The left side of the rectangle to be drawn 700 @param top The top side of the rectangle to be drawn 701 @param right The right side of the rectangle to be drawn 702 @param bottom The bottom side of the rectangle to be drawn 703 @param paint The paint used to draw the rect 704 */ 705 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right, 706 SkScalar bottom, const SkPaint& paint); 707 #endif 708 709 /** Draw the outline of the specified region using the specified paint. 710 @param region The region to be drawn 711 @param paint The paint used to draw the region 712 */ 713 void drawRegion(const SkRegion& region, const SkPaint& paint); 714 715 /** Draw the specified oval using the specified paint. The oval will be 716 filled or framed based on the Style in the paint. 717 @param oval The rectangle bounds of the oval to be drawn 718 @param paint The paint used to draw the oval 719 */ 720 void drawOval(const SkRect& oval, const SkPaint&); 721 722 /** 723 * Draw the specified RRect using the specified paint The rrect will be filled or stroked 724 * based on the Style in the paint. 725 * 726 * @param rrect The round-rect to draw 727 * @param paint The paint used to draw the round-rect 728 */ 729 void drawRRect(const SkRRect& rrect, const SkPaint& paint); 730 731 /** 732 * Draw the annulus formed by the outer and inner rrects. The results 733 * are undefined if the outer does not contain the inner. 734 */ 735 void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&); 736 737 /** Draw the specified circle using the specified paint. If radius is <= 0, 738 then nothing will be drawn. The circle will be filled 739 or framed based on the Style in the paint. 740 @param cx The x-coordinate of the center of the cirle to be drawn 741 @param cy The y-coordinate of the center of the cirle to be drawn 742 @param radius The radius of the cirle to be drawn 743 @param paint The paint used to draw the circle 744 */ 745 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint); 746 747 /** Draw the specified arc, which will be scaled to fit inside the 748 specified oval. Sweep angles are not treated as modulo 360 and thus can 749 exceed a full sweep of the oval. Note that this differs slightly from 750 SkPath::arcTo, which treats the sweep angle mod 360. If the oval is empty 751 or the sweep angle is zero nothing is drawn. If useCenter is true the oval 752 center is inserted into the implied path before the arc and the path is 753 closed back to the, center forming a wedge. Otherwise, the implied path 754 contains just the arc and is not closed. 755 @param oval The bounds of oval used to define the shape of the arc. 756 @param startAngle Starting angle (in degrees) where the arc begins 757 @param sweepAngle Sweep angle (in degrees) measured clockwise. 758 @param useCenter true means include the center of the oval. 759 @param paint The paint used to draw the arc 760 */ 761 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 762 bool useCenter, const SkPaint& paint); 763 764 /** Draw the specified round-rect using the specified paint. The round-rect 765 will be filled or framed based on the Style in the paint. 766 @param rect The rectangular bounds of the roundRect to be drawn 767 @param rx The x-radius of the oval used to round the corners 768 @param ry The y-radius of the oval used to round the corners 769 @param paint The paint used to draw the roundRect 770 */ 771 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint); 772 773 /** Draw the specified path using the specified paint. The path will be 774 filled or framed based on the Style in the paint. 775 @param path The path to be drawn 776 @param paint The paint used to draw the path 777 */ 778 void drawPath(const SkPath& path, const SkPaint& paint); 779 780 /** Draw the specified image, with its top/left corner at (x,y), using the 781 specified paint, transformed by the current matrix. 782 783 @param image The image to be drawn 784 @param left The position of the left side of the image being drawn 785 @param top The position of the top side of the image being drawn 786 @param paint The paint used to draw the image, or NULL 787 */ 788 void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL); 789 void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, 790 const SkPaint* paint = NULL) { 791 this->drawImage(image.get(), left, top, paint); 792 } 793 794 /** 795 * Controls the behavior at the edge of the src-rect, when specified in drawImageRect, 796 * trading off speed for exactness. 797 * 798 * When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around 799 * the pixels in the image. If there is a src-rect specified, it is intended to restrict the 800 * pixels that will be read. However, for performance reasons, some implementations may slow 801 * down if they cannot read 1-pixel past the src-rect boundary at times. 802 * 803 * This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable. 804 * If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect 805 * must be strictly respected, the caller should pass kStrict. 806 */ 807 enum SrcRectConstraint { 808 /** 809 * If kStrict is specified, the implementation must respect the src-rect 810 * (if specified) strictly, and will never sample outside of those bounds during sampling 811 * even when filtering. This may be slower than kFast. 812 */ 813 kStrict_SrcRectConstraint, 814 815 /** 816 * If kFast is specified, the implementation may sample outside of the src-rect 817 * (if specified) by half the width of filter. This allows greater flexibility 818 * to the implementation and can make the draw much faster. 819 */ 820 kFast_SrcRectConstraint, 821 }; 822 823 /** Draw the specified image, scaling and translating so that it fills the specified 824 * dst rect. If the src rect is non-null, only that subset of the image is transformed 825 * and drawn. 826 * 827 * @param image The image to be drawn 828 * @param src Optional: specify the subset of the image to be drawn 829 * @param dst The destination rectangle where the scaled/translated 830 * image will be drawn 831 * @param paint The paint used to draw the image, or NULL 832 * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect. 833 */ 834 void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 835 const SkPaint* paint, 836 SrcRectConstraint constraint = kStrict_SrcRectConstraint); 837 // variant that takes src SkIRect 838 void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 839 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); 840 // variant that assumes src == image-bounds 841 void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 842 SrcRectConstraint = kStrict_SrcRectConstraint); 843 844 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst, 845 const SkPaint* paint, 846 SrcRectConstraint constraint = kStrict_SrcRectConstraint) { 847 this->drawImageRect(image.get(), src, dst, paint, constraint); 848 } 849 void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst, 850 const SkPaint* paint, SrcRectConstraint cons = kStrict_SrcRectConstraint) { 851 this->drawImageRect(image.get(), isrc, dst, paint, cons); 852 } 853 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint, 854 SrcRectConstraint cons = kStrict_SrcRectConstraint) { 855 this->drawImageRect(image.get(), dst, paint, cons); 856 } 857 858 /** 859 * Draw the image stretched differentially to fit into dst. 860 * center is a rect within the image, and logically divides the image 861 * into 9 sections (3x3). For example, if the middle pixel of a [5x5] 862 * image is the "center", then the center-rect should be [2, 2, 3, 3]. 863 * 864 * If the dst is >= the image size, then... 865 * - The 4 corners are not stretched at all. 866 * - The sides are stretched in only one axis. 867 * - The center is stretched in both axes. 868 * Else, for each axis where dst < image, 869 * - The corners shrink proportionally 870 * - The sides (along the shrink axis) and center are not drawn 871 */ 872 void drawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, 873 const SkPaint* paint = nullptr); 874 void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst, 875 const SkPaint* paint = nullptr) { 876 this->drawImageNine(image.get(), center, dst, paint); 877 } 878 879 /** Draw the specified bitmap, with its top/left corner at (x,y), using the 880 specified paint, transformed by the current matrix. Note: if the paint 881 contains a maskfilter that generates a mask which extends beyond the 882 bitmap's original width/height, then the bitmap will be drawn as if it 883 were in a Shader with CLAMP mode. Thus the color outside of the original 884 width/height will be the edge color replicated. 885 886 If a shader is present on the paint it will be ignored, except in the 887 case where the bitmap is kAlpha_8_SkColorType. In that case, the color is 888 generated by the shader. 889 890 @param bitmap The bitmap to be drawn 891 @param left The position of the left side of the bitmap being drawn 892 @param top The position of the top side of the bitmap being drawn 893 @param paint The paint used to draw the bitmap, or NULL 894 */ 895 void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 896 const SkPaint* paint = NULL); 897 898 /** Draw the specified bitmap, scaling and translating so that it fills the specified 899 * dst rect. If the src rect is non-null, only that subset of the bitmap is transformed 900 * and drawn. 901 * 902 * @param bitmap The bitmap to be drawn 903 * @param src Optional: specify the subset of the bitmap to be drawn 904 * @param dst The destination rectangle where the scaled/translated 905 * bitmap will be drawn 906 * @param paint The paint used to draw the bitmap, or NULL 907 * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect. 908 */ 909 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 910 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); 911 // variant where src is SkIRect 912 void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 913 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); 914 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 915 SrcRectConstraint = kStrict_SrcRectConstraint); 916 917 /** 918 * Draw the bitmap stretched or shrunk differentially to fit into dst. 919 * center is a rect within the bitmap, and logically divides the bitmap 920 * into 9 sections (3x3). For example, if the middle pixel of a [5x5] 921 * bitmap is the "center", then the center-rect should be [2, 2, 3, 3]. 922 * 923 * If the dst is >= the bitmap size, then... 924 * - The 4 corners are not stretched at all. 925 * - The sides are stretched in only one axis. 926 * - The center is stretched in both axes. 927 * Else, for each axis where dst < bitmap, 928 * - The corners shrink proportionally 929 * - The sides (along the shrink axis) and center are not drawn 930 */ 931 void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 932 const SkPaint* paint = NULL); 933 934 /** 935 * Specifies coordinates to divide a bitmap into (xCount*yCount) rects. 936 * 937 * If the lattice divs or bounds are invalid, the entire lattice 938 * struct will be ignored on the draw call. 939 */ 940 struct Lattice { 941 enum Flags : uint8_t { 942 // If set, indicates that we should not draw corresponding rect. 943 kTransparent_Flags = 1 << 0, 944 }; 945 946 // An array of x-coordinates that divide the bitmap vertically. 947 // These must be unique, increasing, and in the set [fBounds.fLeft, fBounds.fRight). 948 // Does not have ownership. 949 const int* fXDivs; 950 951 // An array of y-coordinates that divide the bitmap horizontally. 952 // These must be unique, increasing, and in the set [fBounds.fTop, fBounds.fBottom). 953 // Does not have ownership. 954 const int* fYDivs; 955 956 // If non-null, the length of this array must be equal to 957 // (fXCount + 1) * (fYCount + 1). Note that we allow the first rect 958 // in each direction to be empty (ex: fXDivs[0] = fBounds.fLeft). 959 // In this case, the caller still must specify a flag (as a placeholder) 960 // for these empty rects. 961 // The flags correspond to the rects in the lattice, first moving 962 // left to right and then top to bottom. 963 const Flags* fFlags; 964 965 // The number of fXDivs. 966 int fXCount; 967 968 // The number of fYDivs. 969 int fYCount; 970 971 // The bound to draw from. Must be contained by the src that is being drawn, 972 // non-empty, and non-inverted. 973 // If nullptr, the bounds are the entire src. 974 const SkIRect* fBounds; 975 }; 976 977 /** 978 * Draw the bitmap stretched or shrunk differentially to fit into dst. 979 * 980 * Moving horizontally across the bitmap, alternating rects will be "scalable" 981 * (in the x-dimension) to fit into dst or must be left "fixed". The first rect 982 * is treated as "fixed", but it's possible to specify an empty first rect by 983 * making lattice.fXDivs[0] = 0. 984 * 985 * The scale factor for all "scalable" rects will be the same, and may be greater 986 * than or less than 1 (meaning we can stretch or shrink). If the number of 987 * "fixed" pixels is greater than the width of the dst, we will collapse all of 988 * the "scalable" regions and appropriately downscale the "fixed" regions. 989 * 990 * The same interpretation also applies to the y-dimension. 991 */ 992 void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 993 const SkPaint* paint = nullptr); 994 void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 995 const SkPaint* paint = nullptr); 996 997 /** Draw the text, with origin at (x,y), using the specified paint. 998 The origin is interpreted based on the Align setting in the paint. 999 @param text The text to be drawn 1000 @param byteLength The number of bytes to read from the text parameter 1001 @param x The x-coordinate of the origin of the text being drawn 1002 @param y The y-coordinate of the origin of the text being drawn 1003 @param paint The paint used for the text (e.g. color, size, style) 1004 */ 1005 void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 1006 const SkPaint& paint); 1007 1008 /** Draw the text, with each character/glyph origin specified by the pos[] 1009 array. The origin is interpreted by the Align setting in the paint. 1010 @param text The text to be drawn 1011 @param byteLength The number of bytes to read from the text parameter 1012 @param pos Array of positions, used to position each character 1013 @param paint The paint used for the text (e.g. color, size, style) 1014 */ 1015 void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 1016 const SkPaint& paint); 1017 1018 /** Draw the text, with each character/glyph origin specified by the x 1019 coordinate taken from the xpos[] array, and the y from the constY param. 1020 The origin is interpreted by the Align setting in the paint. 1021 @param text The text to be drawn 1022 @param byteLength The number of bytes to read from the text parameter 1023 @param xpos Array of x-positions, used to position each character 1024 @param constY The shared Y coordinate for all of the positions 1025 @param paint The paint used for the text (e.g. color, size, style) 1026 */ 1027 void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, 1028 const SkPaint& paint); 1029 1030 /** Draw the text, with origin at (x,y), using the specified paint, along 1031 the specified path. The paint's Align setting determins where along the 1032 path to start the text. 1033 @param text The text to be drawn 1034 @param byteLength The number of bytes to read from the text parameter 1035 @param path The path the text should follow for its baseline 1036 @param hOffset The distance along the path to add to the text's 1037 starting position 1038 @param vOffset The distance above(-) or below(+) the path to 1039 position the text 1040 @param paint The paint used for the text 1041 */ 1042 void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset, 1043 SkScalar vOffset, const SkPaint& paint); 1044 1045 /** Draw the text, with origin at (x,y), using the specified paint, along 1046 the specified path. The paint's Align setting determins where along the 1047 path to start the text. 1048 @param text The text to be drawn 1049 @param byteLength The number of bytes to read from the text parameter 1050 @param path The path the text should follow for its baseline 1051 @param matrix (may be null) Applied to the text before it is 1052 mapped onto the path 1053 @param paint The paint used for the text 1054 */ 1055 void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 1056 const SkMatrix* matrix, const SkPaint& paint); 1057 1058 /** 1059 * Draw the text with each character/glyph individually transformed by its xform. 1060 * If cullRect is not null, it is a conservative bounds of what will be drawn 1061 * taking into account the xforms and the paint, and will be used to accelerate culling. 1062 */ 1063 void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform[], 1064 const SkRect* cullRect, const SkPaint& paint); 1065 1066 /** Draw the text blob, offset by (x,y), using the specified paint. 1067 @param blob The text blob to be drawn 1068 @param x The x-offset of the text being drawn 1069 @param y The y-offset of the text being drawn 1070 @param paint The paint used for the text (e.g. color, size, style) 1071 */ 1072 void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint); drawTextBlob(const sk_sp<SkTextBlob> & blob,SkScalar x,SkScalar y,const SkPaint & paint)1073 void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) { 1074 this->drawTextBlob(blob.get(), x, y, paint); 1075 } 1076 1077 /** Draw the picture into this canvas. This method effective brackets the 1078 playback of the picture's draw calls with save/restore, so the state 1079 of this canvas will be unchanged after this call. 1080 @param picture The recorded drawing commands to playback into this 1081 canvas. 1082 */ drawPicture(const SkPicture * picture)1083 void drawPicture(const SkPicture* picture) { 1084 this->drawPicture(picture, NULL, NULL); 1085 } drawPicture(const sk_sp<SkPicture> & picture)1086 void drawPicture(const sk_sp<SkPicture>& picture) { 1087 this->drawPicture(picture.get()); 1088 } 1089 1090 /** 1091 * Draw the picture into this canvas. 1092 * 1093 * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is 1094 * logically equivalent to 1095 * save/concat/drawPicture/restore 1096 * 1097 * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's 1098 * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. 1099 * This is logically equivalent to 1100 * saveLayer(paint)/drawPicture/restore 1101 */ 1102 void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint); drawPicture(const sk_sp<SkPicture> & picture,const SkMatrix * matrix,const SkPaint * paint)1103 void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint) { 1104 this->drawPicture(picture.get(), matrix, paint); 1105 } 1106 1107 #ifdef SK_EXPERIMENTAL_SHADOWING 1108 /** 1109 * Draw the picture into this canvas, with shadows! 1110 * 1111 * We will use the canvas's lights along with the picture information (draw depths of 1112 * objects, etc) to first create a set of shadowmaps for the light-picture pairs, and 1113 * then use that set of shadowmaps to render the scene with shadows. 1114 * 1115 * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is 1116 * logically equivalent to 1117 * save/concat/drawPicture/restore 1118 * 1119 * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's 1120 * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. 1121 * This is logically equivalent to 1122 * saveLayer(paint)/drawPicture/restore 1123 * 1124 * We also support using variance shadow maps for blurred shadows; the user can specify 1125 * what shadow mapping algorithm to use with params. 1126 * - Variance Shadow Mapping works by storing both the depth and depth^2 in the shadow map. 1127 * - Then, the shadow map can be blurred, and when reading from it, the fragment shader 1128 * can calculate the variance of the depth at a position by doing E(x^2) - E(x)^2. 1129 * - We can then use the depth variance and depth at a fragment to arrive at an upper bound 1130 * of the probability that the current surface is shadowed by using Chebyshev's 1131 * inequality, and then use that to shade the fragment. 1132 * 1133 * - There are a few problems with VSM. 1134 * * Light Bleeding | Areas with high variance, such as near the edges of high up rects, 1135 * will cause their shadow penumbras to overwrite otherwise solid 1136 * shadows. 1137 * * Shape Distortion | We can combat Light Bleeding by biasing the shadow (setting 1138 * mostly shaded fragments to completely shaded) and increasing 1139 * the minimum allowed variance. However, this warps and rounds 1140 * out the shape of the shadow. 1141 */ 1142 void drawShadowedPicture(const SkPicture*, 1143 const SkMatrix* matrix, 1144 const SkPaint* paint, 1145 const SkShadowParams& params); drawShadowedPicture(const sk_sp<SkPicture> & picture,const SkMatrix * matrix,const SkPaint * paint,const SkShadowParams & params)1146 void drawShadowedPicture(const sk_sp<SkPicture>& picture, 1147 const SkMatrix* matrix, 1148 const SkPaint* paint, 1149 const SkShadowParams& params) { 1150 this->drawShadowedPicture(picture.get(), matrix, paint, params); 1151 } 1152 #endif 1153 1154 enum VertexMode { 1155 kTriangles_VertexMode, 1156 kTriangleStrip_VertexMode, 1157 kTriangleFan_VertexMode 1158 }; 1159 1160 /** Draw the array of vertices, interpreted as triangles (based on mode). 1161 1162 If both textures and vertex-colors are NULL, it strokes hairlines with 1163 the paint's color. This behavior is a useful debugging mode to visualize 1164 the mesh. 1165 1166 @param vmode How to interpret the array of vertices 1167 @param vertexCount The number of points in the vertices array (and 1168 corresponding texs and colors arrays if non-null) 1169 @param vertices Array of vertices for the mesh 1170 @param texs May be null. If not null, specifies the coordinate 1171 in _texture_ space (not uv space) for each vertex. 1172 @param colors May be null. If not null, specifies a color for each 1173 vertex, to be interpolated across the triangle. 1174 @param mode Used if both texs and colors are present and paint has a 1175 shader. In this case the colors are combined with the texture 1176 using mode, before being drawn using the paint. 1177 @param indices If not null, array of indices to reference into the 1178 vertex (texs, colors) array. 1179 @param indexCount number of entries in the indices array (if not null) 1180 @param paint Specifies the shader/texture if present. 1181 */ 1182 void drawVertices(VertexMode vmode, int vertexCount, 1183 const SkPoint vertices[], const SkPoint texs[], 1184 const SkColor colors[], SkBlendMode mode, 1185 const uint16_t indices[], int indexCount, 1186 const SkPaint& paint); drawVertices(VertexMode vmode,int vertexCount,const SkPoint vertices[],const SkPoint texs[],const SkColor colors[],const uint16_t indices[],int indexCount,const SkPaint & paint)1187 void drawVertices(VertexMode vmode, int vertexCount, 1188 const SkPoint vertices[], const SkPoint texs[], 1189 const SkColor colors[], const uint16_t indices[], int indexCount, 1190 const SkPaint& paint) { 1191 this->drawVertices(vmode, vertexCount, vertices, texs, colors, SkBlendMode::kModulate, 1192 indices, indexCount, paint); 1193 } 1194 1195 /** Draw vertices from an immutable SkVertices object. 1196 1197 @param vertices The mesh to draw. 1198 @param mode Used if both texs and colors are present and paint has a 1199 shader. In this case the colors are combined with the texture 1200 using mode, before being drawn using the paint. 1201 @param paint Specifies the shader/texture if present. 1202 */ 1203 void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint); 1204 void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint); 1205 1206 /** 1207 Draw a cubic coons patch 1208 1209 @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order 1210 starting at the top left corner. 1211 @param colors specifies the colors for the corners which will be bilerp across the patch, 1212 their order is clockwise starting at the top left corner. 1213 @param texCoords specifies the texture coordinates that will be bilerp across the patch, 1214 their order is the same as the colors. 1215 @param mode specifies how are the colors and the textures combined if both of them are 1216 present. 1217 @param paint Specifies the shader/texture if present. 1218 */ 1219 void drawPatch(const SkPoint cubics[12], const SkColor colors[4], 1220 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint); drawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],const SkPaint & paint)1221 void drawPatch(const SkPoint cubics[12], const SkColor colors[4], 1222 const SkPoint texCoords[4], const SkPaint& paint) { 1223 this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint); 1224 } 1225 1226 /** 1227 * Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the 1228 * coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle 1229 * into a quad. 1230 * 1231 * xform maps [0, 0, tex.width, tex.height] -> quad 1232 * 1233 * The color array is optional. When specified, each color modulates the pixels in its 1234 * corresponding quad (via the specified SkBlendMode). 1235 * 1236 * The cullRect is optional. When specified, it must be a conservative bounds of all of the 1237 * resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not 1238 * intersect the current clip. 1239 * 1240 * The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter 1241 * and blendmode are used to affect each of the quads. 1242 */ 1243 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 1244 const SkColor colors[], int count, SkBlendMode, const SkRect* cullRect, 1245 const SkPaint* paint); 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)1246 void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[], 1247 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect, 1248 const SkPaint* paint) { 1249 this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint); 1250 } drawAtlas(const SkImage * atlas,const SkRSXform xform[],const SkRect tex[],int count,const SkRect * cullRect,const SkPaint * paint)1251 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count, 1252 const SkRect* cullRect, const SkPaint* paint) { 1253 this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint); 1254 } drawAtlas(const sk_sp<SkImage> & atlas,const SkRSXform xform[],const SkRect tex[],int count,const SkRect * cullRect,const SkPaint * paint)1255 void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[], 1256 int count, const SkRect* cullRect, const SkPaint* paint) { 1257 this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst, 1258 cullRect, paint); 1259 } 1260 1261 /** 1262 * Draw the contents of this drawable into the canvas. If the canvas is async 1263 * (e.g. it is recording into a picture) then the drawable will be referenced instead, 1264 * to have its draw() method called when the picture is finalized. 1265 * 1266 * If the intent is to force the contents of the drawable into this canvas immediately, 1267 * then drawable->draw(canvas) may be called. 1268 */ 1269 void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL); 1270 void drawDrawable(SkDrawable*, SkScalar x, SkScalar y); 1271 1272 /** 1273 * Send an "annotation" to the canvas. The annotation is a key/value pair, where the key is 1274 * a null-terminated utf8 string, and the value is a blob of data stored in an SkData 1275 * (which may be null). The annotation is associated with the specified rectangle. 1276 * 1277 * The caller still retains its ownership of the data (if any). 1278 * 1279 * Note: on may canvas types, this information is ignored, but some canvases (e.g. recording 1280 * a picture or drawing to a PDF document) will pass on this information. 1281 */ 1282 void drawAnnotation(const SkRect&, const char key[], SkData* value); drawAnnotation(const SkRect & rect,const char key[],const sk_sp<SkData> & value)1283 void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) { 1284 this->drawAnnotation(rect, key, value.get()); 1285 } 1286 1287 ////////////////////////////////////////////////////////////////////////// 1288 #ifdef SK_INTERNAL 1289 #ifndef SK_SUPPORT_LEGACY_DRAWFILTER 1290 #define SK_SUPPORT_LEGACY_DRAWFILTER 1291 #endif 1292 #endif 1293 1294 #ifdef SK_SUPPORT_LEGACY_DRAWFILTER 1295 /** Get the current filter object. The filter's reference count is not 1296 affected. The filter is saved/restored, just like the matrix and clip. 1297 @return the canvas' filter (or NULL). 1298 */ 1299 SK_ATTR_EXTERNALLY_DEPRECATED("getDrawFilter use is deprecated") 1300 SkDrawFilter* getDrawFilter() const; 1301 1302 /** Set the new filter (or NULL). Pass NULL to clear any existing filter. 1303 As a convenience, the parameter is returned. If an existing filter 1304 exists, its refcnt is decrement. If the new filter is not null, its 1305 refcnt is incremented. The filter is saved/restored, just like the 1306 matrix and clip. 1307 @param filter the new filter (or NULL) 1308 @return the new filter 1309 */ 1310 SK_ATTR_EXTERNALLY_DEPRECATED("setDrawFilter use is deprecated") 1311 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); 1312 #endif 1313 ////////////////////////////////////////////////////////////////////////// 1314 1315 /** 1316 * Return true if the current clip is empty (i.e. nothing will draw). 1317 * Note: this is not always a free call, so it should not be used 1318 * more often than necessary. However, once the canvas has computed this 1319 * result, subsequent calls will be cheap (until the clip state changes, 1320 * which can happen on any clip..() or restore() call. 1321 */ 1322 virtual bool isClipEmpty() const; 1323 1324 /** 1325 * Returns true if the current clip is just a (non-empty) rectangle. 1326 * Returns false if the clip is empty, or if it is complex. 1327 */ 1328 virtual bool isClipRect() const; 1329 1330 /** Return the current matrix on the canvas. 1331 This does not account for the translate in any of the devices. 1332 @return The current matrix on the canvas. 1333 */ 1334 const SkMatrix& getTotalMatrix() const; 1335 1336 typedef SkCanvasClipVisitor ClipVisitor; 1337 /** 1338 * Replays the clip operations, back to front, that have been applied to 1339 * the canvas, calling the appropriate method on the visitor for each 1340 * clip. All clips have already been transformed into device space. 1341 */ 1342 void replayClips(ClipVisitor*) const; 1343 1344 /////////////////////////////////////////////////////////////////////////// 1345 1346 // don't call 1347 GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext(); 1348 1349 // don't call 1350 static void Internal_Private_SetIgnoreSaveLayerBounds(bool); 1351 static bool Internal_Private_GetIgnoreSaveLayerBounds(); 1352 static void Internal_Private_SetTreatSpriteAsBitmap(bool); 1353 static bool Internal_Private_GetTreatSpriteAsBitmap(); 1354 1355 // TEMP helpers until we switch virtual over to const& for src-rect 1356 void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1357 const SkPaint* paint, 1358 SrcRectConstraint constraint = kStrict_SrcRectConstraint); 1359 void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1360 const SkPaint* paint, 1361 SrcRectConstraint constraint = kStrict_SrcRectConstraint); 1362 1363 // expose minimum amount of information necessary for transitional refactoring 1364 /** 1365 * Returns CTM and clip bounds, translated from canvas coordinates to top layer coordinates. 1366 */ 1367 void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds); 1368 1369 /** 1370 * Returns the global clip as a region. If the clip contains AA, then only the bounds 1371 * of the clip may be returned. 1372 */ 1373 void temporary_internal_getRgnClip(SkRegion*); 1374 1375 protected: 1376 #ifdef SK_EXPERIMENTAL_SHADOWING 1377 /** Returns the current (cumulative) draw depth of the canvas. 1378 */ 1379 SkScalar getZ() const; 1380 1381 sk_sp<SkLights> fLights; 1382 #endif 1383 1384 // default impl defers to getDevice()->newSurface(info) 1385 virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&); 1386 1387 // default impl defers to its device 1388 virtual bool onPeekPixels(SkPixmap*); 1389 virtual bool onAccessTopLayerPixels(SkPixmap*); 1390 virtual SkImageInfo onImageInfo() const; 1391 virtual bool onGetProps(SkSurfaceProps*) const; 1392 virtual void onFlush(); 1393 1394 // Subclass save/restore notifiers. 1395 // Overriders should call the corresponding INHERITED method up the inheritance chain. 1396 // getSaveLayerStrategy()'s return value may suppress full layer allocation. 1397 enum SaveLayerStrategy { 1398 kFullLayer_SaveLayerStrategy, 1399 kNoLayer_SaveLayerStrategy, 1400 }; 1401 willSave()1402 virtual void willSave() {} 1403 // Overriders should call the corresponding INHERITED method up the inheritance chain. getSaveLayerStrategy(const SaveLayerRec &)1404 virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) { 1405 return kFullLayer_SaveLayerStrategy; 1406 } willRestore()1407 virtual void willRestore() {} didRestore()1408 virtual void didRestore() {} didConcat(const SkMatrix &)1409 virtual void didConcat(const SkMatrix&) {} didSetMatrix(const SkMatrix &)1410 virtual void didSetMatrix(const SkMatrix&) {} didTranslate(SkScalar dx,SkScalar dy)1411 virtual void didTranslate(SkScalar dx, SkScalar dy) { 1412 this->didConcat(SkMatrix::MakeTrans(dx, dy)); 1413 } 1414 1415 #ifdef SK_EXPERIMENTAL_SHADOWING didTranslateZ(SkScalar)1416 virtual void didTranslateZ(SkScalar) {} 1417 #endif 1418 1419 virtual SkRect onGetLocalClipBounds() const; 1420 virtual SkIRect onGetDeviceClipBounds() const; 1421 1422 1423 virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value); 1424 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); 1425 1426 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, 1427 SkScalar y, const SkPaint& paint); 1428 1429 virtual void onDrawPosText(const void* text, size_t byteLength, 1430 const SkPoint pos[], const SkPaint& paint); 1431 1432 virtual void onDrawPosTextH(const void* text, size_t byteLength, 1433 const SkScalar xpos[], SkScalar constY, 1434 const SkPaint& paint); 1435 1436 virtual void onDrawTextOnPath(const void* text, size_t byteLength, 1437 const SkPath& path, const SkMatrix* matrix, 1438 const SkPaint& paint); 1439 virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform[], 1440 const SkRect* cullRect, const SkPaint& paint); 1441 1442 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 1443 const SkPaint& paint); 1444 1445 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 1446 const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint); 1447 1448 virtual void onDrawDrawable(SkDrawable*, const SkMatrix*); 1449 1450 virtual void onDrawPaint(const SkPaint&); 1451 virtual void onDrawRect(const SkRect&, const SkPaint&); 1452 virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint); 1453 virtual void onDrawOval(const SkRect&, const SkPaint&); 1454 virtual void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, 1455 const SkPaint&); 1456 virtual void onDrawRRect(const SkRRect&, const SkPaint&); 1457 virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&); 1458 virtual void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&); 1459 virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], 1460 int count, SkBlendMode, const SkRect* cull, const SkPaint*); 1461 virtual void onDrawPath(const SkPath&, const SkPaint&); 1462 virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*); 1463 virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*, 1464 SrcRectConstraint); 1465 virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, 1466 const SkPaint*); 1467 virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, 1468 const SkPaint*); 1469 1470 virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*); 1471 virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, 1472 SrcRectConstraint); 1473 virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, 1474 const SkPaint*); 1475 virtual void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst, 1476 const SkPaint*); 1477 1478 enum ClipEdgeStyle { 1479 kHard_ClipEdgeStyle, 1480 kSoft_ClipEdgeStyle 1481 }; 1482 1483 virtual void onClipRect(const SkRect& rect, SkClipOp, ClipEdgeStyle); 1484 virtual void onClipRRect(const SkRRect& rrect, SkClipOp, ClipEdgeStyle); 1485 virtual void onClipPath(const SkPath& path, SkClipOp, ClipEdgeStyle); 1486 virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp); 1487 1488 virtual void onDiscard(); 1489 1490 virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); 1491 1492 #ifdef SK_EXPERIMENTAL_SHADOWING 1493 virtual void onDrawShadowedPicture(const SkPicture*, 1494 const SkMatrix*, 1495 const SkPaint*, 1496 const SkShadowParams& params); 1497 #endif 1498 1499 // Clip rectangle bounds. Called internally by saveLayer. 1500 // returns false if the entire rectangle is entirely clipped out 1501 // If non-NULL, The imageFilter parameter will be used to expand the clip 1502 // and offscreen bounds for any margin required by the filter DAG. 1503 bool clipRectBounds(const SkRect* bounds, SaveLayerFlags, SkIRect* intersection, 1504 const SkImageFilter* imageFilter = NULL); 1505 1506 private: 1507 /** After calling saveLayer(), there can be any number of devices that make 1508 up the top-most drawing area. LayerIter can be used to iterate through 1509 those devices. Note that the iterator is only valid until the next API 1510 call made on the canvas. Ownership of all pointers in the iterator stays 1511 with the canvas, so none of them should be modified or deleted. 1512 */ 1513 class LayerIter /*: SkNoncopyable*/ { 1514 public: 1515 /** Initialize iterator with canvas, and set values for 1st device */ 1516 LayerIter(SkCanvas*); 1517 ~LayerIter(); 1518 1519 /** Return true if the iterator is done */ done()1520 bool done() const { return fDone; } 1521 /** Cycle to the next device */ 1522 void next(); 1523 1524 // These reflect the current device in the iterator 1525 1526 SkBaseDevice* device() const; 1527 const SkMatrix& matrix() const; 1528 void clip(SkRegion*) const; 1529 const SkPaint& paint() const; 1530 int x() const; 1531 int y() const; 1532 1533 private: 1534 // used to embed the SkDrawIter object directly in our instance, w/o 1535 // having to expose that class def to the public. There is an assert 1536 // in our constructor to ensure that fStorage is large enough 1537 // (though needs to be a compile-time-assert!). We use intptr_t to work 1538 // safely with 32 and 64 bit machines (to ensure the storage is enough) 1539 intptr_t fStorage[32]; 1540 class SkDrawIter* fImpl; // this points at fStorage 1541 SkPaint fDefaultPaint; 1542 bool fDone; 1543 }; 1544 1545 static bool BoundsAffectsClip(SaveLayerFlags); 1546 static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags); 1547 1548 static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1549 SkBaseDevice* dst, const SkIPoint& dstOrigin, 1550 const SkMatrix& ctm); 1551 1552 enum ShaderOverrideOpacity { 1553 kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image) 1554 kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque 1555 kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque 1556 }; 1557 1558 // notify our surface (if we have one) that we are about to draw, so it 1559 // can perform copy-on-write or invalidate any cached images 1560 void predrawNotify(bool willOverwritesEntireSurface = false); 1561 void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity); predrawNotify(const SkRect * rect,const SkPaint * paint,bool shaderOverrideIsOpaque)1562 void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) { 1563 this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity 1564 : kNotOpaque_ShaderOverrideOpacity); 1565 } 1566 1567 SkBaseDevice* getDevice() const; 1568 SkBaseDevice* getTopDevice() const; 1569 1570 class MCRec; 1571 1572 SkDeque fMCStack; 1573 // points to top of stack 1574 MCRec* fMCRec; 1575 // the first N recs that can fit here mean we won't call malloc 1576 enum { 1577 kMCRecSize = 128, // most recent measurement 1578 kMCRecCount = 32, // common depth for save/restores 1579 kDeviceCMSize = 184, // most recent measurement 1580 }; 1581 intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)]; 1582 intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)]; 1583 1584 const SkSurfaceProps fProps; 1585 1586 int fSaveCount; // value returned by getSaveCount() 1587 1588 SkMetaData* fMetaData; 1589 std::unique_ptr<SkRasterHandleAllocator> fAllocator; 1590 1591 SkSurface_Base* fSurfaceBase; getSurfaceBase()1592 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; } setSurfaceBase(SkSurface_Base * sb)1593 void setSurfaceBase(SkSurface_Base* sb) { 1594 fSurfaceBase = sb; 1595 } 1596 friend class SkSurface_Base; 1597 friend class SkSurface_Gpu; 1598 1599 SkIRect fClipRestrictionRect = SkIRect::MakeEmpty(); 1600 1601 void doSave(); 1602 void checkForDeferredSave(); 1603 void internalSetMatrix(const SkMatrix&); 1604 1605 friend class SkDrawIter; // needs setupDrawForLayerDevice() 1606 friend class AutoDrawLooper; 1607 friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip 1608 friend class SkSurface_Raster; // needs getDevice() 1609 friend class SkRecorder; // resetForNextPicture 1610 friend class SkLiteRecorder; // resetForNextPicture 1611 friend class SkNoDrawCanvas; // InitFlags 1612 friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags) 1613 friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>) 1614 friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags 1615 friend class SkDeferredCanvas; // For use of resetForNextPicture 1616 friend class SkOverdrawCanvas; 1617 friend class SkRasterHandleAllocator; 1618 1619 enum InitFlags { 1620 kDefault_InitFlags = 0, 1621 kConservativeRasterClip_InitFlag = 1 << 0, 1622 }; 1623 SkCanvas(const SkIRect& bounds, InitFlags); 1624 SkCanvas(SkBaseDevice* device, InitFlags); 1625 SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>, 1626 SkRasterHandleAllocator::Handle); 1627 1628 void resetForNextPicture(const SkIRect& bounds); 1629 1630 // needs gettotalclip() 1631 friend class SkCanvasStateUtils; 1632 1633 // call this each time we attach ourselves to a device 1634 // - constructor 1635 // - internalSaveLayer 1636 void setupDevice(SkBaseDevice*); 1637 1638 SkBaseDevice* init(SkBaseDevice*, InitFlags); 1639 1640 /** 1641 * Gets the bounds of the top level layer in global canvas coordinates. We don't want this 1642 * to be public because it exposes decisions about layer sizes that are internal to the canvas. 1643 */ 1644 SkIRect getTopLayerBounds() const; 1645 1646 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 1647 const SkRect& dst, const SkPaint* paint, 1648 SrcRectConstraint); 1649 void internalDrawPaint(const SkPaint& paint); 1650 void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy); 1651 void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*); 1652 1653 // shared by save() and saveLayer() 1654 void internalSave(); 1655 void internalRestore(); 1656 1657 /* 1658 * Returns true if drawing the specified rect (or all if it is null) with the specified 1659 * paint (or default if null) would overwrite the entire root device of the canvas 1660 * (i.e. the canvas' surface if it had one). 1661 */ 1662 bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const; 1663 1664 /** 1665 * Returns true if the paint's imagefilter can be invoked directly, without needed a layer. 1666 */ 1667 bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&); 1668 1669 /** 1670 * Returns true if the clip (for any active layer) contains antialiasing. 1671 * If the clip is empty, this will return false. 1672 */ 1673 bool androidFramework_isClipAA() const; 1674 1675 /** 1676 * Keep track of the device clip bounds and if the matrix is scale-translate. This allows 1677 * us to do a fast quick reject in the common case. 1678 */ 1679 bool fIsScaleTranslate; 1680 SkRect fDeviceClipBounds; 1681 1682 bool fAllowSoftClip; 1683 bool fAllowSimplifyClip; 1684 1685 class AutoValidateClip : ::SkNoncopyable { 1686 public: AutoValidateClip(SkCanvas * canvas)1687 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) { 1688 fCanvas->validateClip(); 1689 } ~AutoValidateClip()1690 ~AutoValidateClip() { fCanvas->validateClip(); } 1691 1692 private: 1693 const SkCanvas* fCanvas; 1694 }; 1695 1696 #ifdef SK_DEBUG 1697 void validateClip() const; 1698 #else validateClip()1699 void validateClip() const {} 1700 #endif 1701 1702 typedef SkRefCnt INHERITED; 1703 }; 1704 1705 /** Stack helper class to automatically call restoreToCount() on the canvas 1706 when this object goes out of scope. Use this to guarantee that the canvas 1707 is restored to a known state. 1708 */ 1709 class SkAutoCanvasRestore : SkNoncopyable { 1710 public: SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)1711 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) { 1712 if (fCanvas) { 1713 fSaveCount = canvas->getSaveCount(); 1714 if (doSave) { 1715 canvas->save(); 1716 } 1717 } 1718 } ~SkAutoCanvasRestore()1719 ~SkAutoCanvasRestore() { 1720 if (fCanvas) { 1721 fCanvas->restoreToCount(fSaveCount); 1722 } 1723 } 1724 1725 /** 1726 * Perform the restore now, instead of waiting for the destructor. Will 1727 * only do this once. 1728 */ restore()1729 void restore() { 1730 if (fCanvas) { 1731 fCanvas->restoreToCount(fSaveCount); 1732 fCanvas = NULL; 1733 } 1734 } 1735 1736 private: 1737 SkCanvas* fCanvas; 1738 int fSaveCount; 1739 }; 1740 #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore) 1741 1742 class SkCanvasClipVisitor { 1743 public: 1744 virtual ~SkCanvasClipVisitor(); 1745 virtual void clipRect(const SkRect&, SkClipOp, bool antialias) = 0; 1746 virtual void clipRRect(const SkRRect&, SkClipOp, bool antialias) = 0; 1747 virtual void clipPath(const SkPath&, SkClipOp, bool antialias) = 0; 1748 }; 1749 1750 #endif 1751