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