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