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