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