1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkCanvas_DEFINED 11 #define SkCanvas_DEFINED 12 13 #include "SkTypes.h" 14 #include "SkBitmap.h" 15 #include "SkDeque.h" 16 #include "SkClipStack.h" 17 #include "SkPaint.h" 18 #include "SkRefCnt.h" 19 #include "SkPath.h" 20 #include "SkRegion.h" 21 #include "SkScalarCompare.h" 22 #include "SkXfermode.h" 23 24 class SkBounder; 25 class SkDevice; 26 class SkDraw; 27 class SkDrawFilter; 28 class SkPicture; 29 30 /** \class SkCanvas 31 32 A Canvas encapsulates all of the state about drawing into a device (bitmap). 33 This includes a reference to the device itself, and a stack of matrix/clip 34 values. For any given draw call (e.g. drawRect), the geometry of the object 35 being drawn is transformed by the concatenation of all the matrices in the 36 stack. The transformed geometry is clipped by the intersection of all of 37 the clips in the stack. 38 39 While the Canvas holds the state of the drawing device, the state (style) 40 of the object being drawn is held by the Paint, which is provided as a 41 parameter to each of the draw() methods. The Paint holds attributes such as 42 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns), 43 etc. 44 */ 45 class SK_API SkCanvas : public SkRefCnt { 46 public: 47 SkCanvas(); 48 49 /** Construct a canvas with the specified device to draw into. 50 51 @param device Specifies a device for the canvas to draw into. 52 */ 53 explicit SkCanvas(SkDevice* device); 54 55 /** Deprecated - Construct a canvas with the specified bitmap to draw into. 56 @param bitmap Specifies a bitmap for the canvas to draw into. Its 57 structure are copied to the canvas. 58 */ 59 explicit SkCanvas(const SkBitmap& bitmap); 60 virtual ~SkCanvas(); 61 62 /////////////////////////////////////////////////////////////////////////// 63 64 /** 65 * Trigger the immediate execution of all pending draw operations. 66 */ 67 void flush(); 68 69 /** 70 * Return the width/height of the underlying device. The current drawable 71 * area may be small (due to clipping or saveLayer). For a canvas with 72 * no device, 0,0 will be returned. 73 */ 74 SkISize getDeviceSize() const; 75 76 /** Return the canvas' device object, which may be null. The device holds 77 the bitmap of the pixels that the canvas draws into. The reference count 78 of the returned device is not changed by this call. 79 */ 80 SkDevice* getDevice() const; 81 82 /** Specify a device for this canvas to draw into. If it is not null, its 83 reference count is incremented. If the canvas was already holding a 84 device, its reference count is decremented. The new device is returned. 85 */ 86 virtual SkDevice* setDevice(SkDevice* device); 87 88 /** 89 * saveLayer() can create another device (which is later drawn onto 90 * the previous device). getTopDevice() returns the top-most device current 91 * installed. Note that this can change on other calls like save/restore, 92 * so do not access this device after subsequent canvas calls. 93 * The reference count of the device is not changed. 94 */ 95 SkDevice* getTopDevice() const; 96 97 /** 98 * Create a new raster device and make it current. This also returns 99 * the new device. 100 */ 101 SkDevice* setBitmapDevice(const SkBitmap& bitmap); 102 103 /** 104 * Shortcut for getDevice()->createCompatibleDevice(...). 105 * If getDevice() == NULL, this method does nothing, and returns NULL. 106 */ 107 SkDevice* createCompatibleDevice(SkBitmap::Config config, 108 int width, int height, 109 bool isOpaque); 110 111 /////////////////////////////////////////////////////////////////////////// 112 113 /** 114 * This enum can be used with read/writePixels to perform a pixel ops to or 115 * from an 8888 config other than Skia's native config (SkPMColor). There 116 * are three byte orders supported: native, BGRA, and RGBA. Each has a 117 * premultiplied and unpremultiplied variant. 118 * 119 * Components of a 8888 pixel can be packed/unpacked from a 32bit word using 120 * either byte offsets or shift values. Byte offsets are endian-invariant 121 * while shifts are not. BGRA and RGBA configs are defined by byte 122 * orderings. The native config is defined by shift values (SK_A32_SHIFT, 123 * ..., SK_B32_SHIFT). 124 */ 125 enum Config8888 { 126 /** 127 * Skia's native order specified by: 128 * SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT 129 * 130 * kNative_Premul_Config8888 is equivalent to SkPMColor 131 * kNative_Unpremul_Config8888 has the same component order as SkPMColor 132 * but is not premultiplied. 133 */ 134 kNative_Premul_Config8888, 135 kNative_Unpremul_Config8888, 136 /** 137 * low byte to high byte: B, G, R, A. 138 */ 139 kBGRA_Premul_Config8888, 140 kBGRA_Unpremul_Config8888, 141 /** 142 * low byte to high byte: R, G, B, A. 143 */ 144 kRGBA_Premul_Config8888, 145 kRGBA_Unpremul_Config8888, 146 }; 147 148 /** 149 * On success (returns true), copy the canvas pixels into the bitmap. 150 * On failure, the bitmap parameter is left unchanged and false is 151 * returned. 152 * 153 * The canvas' pixels are converted to the bitmap's config. The only 154 * supported config is kARGB_8888_Config, though this is likely to be 155 * relaxed in the future. The meaning of config kARGB_8888_Config is 156 * modified by the enum param config8888. The default value interprets 157 * kARGB_8888_Config as SkPMColor 158 * 159 * If the bitmap has pixels already allocated, the canvas pixels will be 160 * written there. If not, bitmap->allocPixels() will be called 161 * automatically. If the bitmap is backed by a texture readPixels will 162 * fail. 163 * 164 * The actual pixels written is the intersection of the canvas' bounds, and 165 * the rectangle formed by the bitmap's width,height and the specified x,y. 166 * If bitmap pixels extend outside of that intersection, they will not be 167 * modified. 168 * 169 * Other failure conditions: 170 * * If the canvas is backed by a non-raster device (e.g. PDF) then 171 * readPixels will fail. 172 * * If bitmap is texture-backed then readPixels will fail. (This may be 173 * relaxed in the future.) 174 * 175 * Example that reads the entire canvas into a bitmap using the native 176 * SkPMColor: 177 * SkISize size = canvas->getDeviceSize(); 178 * bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, 179 * size.fHeight); 180 * if (canvas->readPixels(bitmap, 0, 0)) { 181 * // use the pixels 182 * } 183 */ 184 bool readPixels(SkBitmap* bitmap, 185 int x, int y, 186 Config8888 config8888 = kNative_Premul_Config8888); 187 188 /** 189 * DEPRECATED: This will be removed as soon as webkit is no longer relying 190 * on it. The bitmap is resized to the intersection of srcRect and the 191 * canvas bounds. New pixels are always allocated on success. Bitmap is 192 * unmodified on failure. 193 */ 194 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); 195 196 /** 197 * Similar to draw sprite, this method will copy the pixels in bitmap onto 198 * the canvas, with the top/left corner specified by (x, y). The canvas' 199 * pixel values are completely replaced: there is no blending. 200 * 201 * Currently if bitmap is backed by a texture this is a no-op. This may be 202 * relaxed in the future. 203 * 204 * If the bitmap has config kARGB_8888_Config then the config8888 param 205 * will determines how the pixel valuess are intepreted. If the bitmap is 206 * not kARGB_8888_Config then this parameter is ignored. 207 * 208 * Note: If you are recording drawing commands on this canvas to 209 * SkPicture, writePixels() is ignored! 210 */ 211 void writePixels(const SkBitmap& bitmap, 212 int x, int y, 213 Config8888 config8888 = kNative_Premul_Config8888); 214 215 /////////////////////////////////////////////////////////////////////////// 216 217 enum SaveFlags { 218 /** save the matrix state, restoring it on restore() */ 219 kMatrix_SaveFlag = 0x01, 220 /** save the clip state, restoring it on restore() */ 221 kClip_SaveFlag = 0x02, 222 /** the layer needs to support per-pixel alpha */ 223 kHasAlphaLayer_SaveFlag = 0x04, 224 /** the layer needs to support 8-bits per color component */ 225 kFullColorLayer_SaveFlag = 0x08, 226 /** the layer should clip against the bounds argument */ 227 kClipToLayer_SaveFlag = 0x10, 228 229 // helper masks for common choices 230 kMatrixClip_SaveFlag = 0x03, 231 kARGB_NoClipLayer_SaveFlag = 0x0F, 232 kARGB_ClipLayer_SaveFlag = 0x1F 233 }; 234 235 /** This call saves the current matrix, clip, and drawFilter, and pushes a 236 copy onto a private stack. Subsequent calls to translate, scale, 237 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all 238 operate on this copy. 239 When the balancing call to restore() is made, the previous matrix, clip, 240 and drawFilter are restored. 241 @return The value to pass to restoreToCount() to balance this save() 242 */ 243 virtual int save(SaveFlags flags = kMatrixClip_SaveFlag); 244 245 /** This behaves the same as save(), but in addition it allocates an 246 offscreen bitmap. All drawing calls are directed there, and only when 247 the balancing call to restore() is made is that offscreen transfered to 248 the canvas (or the previous layer). 249 @param bounds (may be null) This rect, if non-null, is used as a hint to 250 limit the size of the offscreen, and thus drawing may be 251 clipped to it, though that clipping is not guaranteed to 252 happen. If exact clipping is desired, use clipRect(). 253 @param paint (may be null) This is copied, and is applied to the 254 offscreen when restore() is called 255 @param flags LayerFlags 256 @return The value to pass to restoreToCount() to balance this save() 257 */ 258 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, 259 SaveFlags flags = kARGB_ClipLayer_SaveFlag); 260 261 /** This behaves the same as save(), but in addition it allocates an 262 offscreen bitmap. All drawing calls are directed there, and only when 263 the balancing call to restore() is made is that offscreen transfered to 264 the canvas (or the previous layer). 265 @param bounds (may be null) This rect, if non-null, is used as a hint to 266 limit the size of the offscreen, and thus drawing may be 267 clipped to it, though that clipping is not guaranteed to 268 happen. If exact clipping is desired, use clipRect(). 269 @param alpha This is applied to the offscreen when restore() is called. 270 @param flags LayerFlags 271 @return The value to pass to restoreToCount() to balance this save() 272 */ 273 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 274 SaveFlags flags = kARGB_ClipLayer_SaveFlag); 275 276 /** This call balances a previous call to save(), and is used to remove all 277 modifications to the matrix/clip/drawFilter state since the last save 278 call. 279 It is an error to call restore() more times than save() was called. 280 */ 281 virtual void restore(); 282 283 /** Returns the number of matrix/clip states on the SkCanvas' private stack. 284 This will equal # save() calls - # restore() calls. 285 */ 286 int getSaveCount() const; 287 288 /** Efficient way to pop any calls to save() that happened after the save 289 count reached saveCount. It is an error for saveCount to be less than 290 getSaveCount() 291 @param saveCount The number of save() levels to restore from 292 */ 293 void restoreToCount(int saveCount); 294 295 /** Returns true if drawing is currently going to a layer (from saveLayer) 296 * rather than to the root device. 297 */ 298 virtual bool isDrawingToLayer() const; 299 300 /** Preconcat the current matrix with the specified translation 301 @param dx The distance to translate in X 302 @param dy The distance to translate in Y 303 returns true if the operation succeeded (e.g. did not overflow) 304 */ 305 virtual bool translate(SkScalar dx, SkScalar dy); 306 307 /** Preconcat the current matrix with the specified scale. 308 @param sx The amount to scale in X 309 @param sy The amount to scale in Y 310 returns true if the operation succeeded (e.g. did not overflow) 311 */ 312 virtual bool scale(SkScalar sx, SkScalar sy); 313 314 /** Preconcat the current matrix with the specified rotation. 315 @param degrees The amount to rotate, in degrees 316 returns true if the operation succeeded (e.g. did not overflow) 317 */ 318 virtual bool rotate(SkScalar degrees); 319 320 /** Preconcat the current matrix with the specified skew. 321 @param sx The amount to skew in X 322 @param sy The amount to skew in Y 323 returns true if the operation succeeded (e.g. did not overflow) 324 */ 325 virtual bool skew(SkScalar sx, SkScalar sy); 326 327 /** Preconcat the current matrix with the specified matrix. 328 @param matrix The matrix to preconcatenate with the current matrix 329 @return true if the operation succeeded (e.g. did not overflow) 330 */ 331 virtual bool concat(const SkMatrix& matrix); 332 333 /** Replace the current matrix with a copy of the specified matrix. 334 @param matrix The matrix that will be copied into the current matrix. 335 */ 336 virtual void setMatrix(const SkMatrix& matrix); 337 338 /** Helper for setMatrix(identity). Sets the current matrix to identity. 339 */ 340 void resetMatrix(); 341 342 /** Modify the current clip with the specified rectangle. 343 @param rect The rect to intersect with the current clip 344 @param op The region op to apply to the current clip 345 @return true if the canvas' clip is non-empty 346 */ 347 virtual bool clipRect(const SkRect& rect, 348 SkRegion::Op op = SkRegion::kIntersect_Op, 349 bool doAntiAlias = false); 350 351 /** Modify the current clip with the specified path. 352 @param path The path to apply to the current clip 353 @param op The region op to apply to the current clip 354 @return true if the canvas' new clip is non-empty 355 */ 356 virtual bool clipPath(const SkPath& path, 357 SkRegion::Op op = SkRegion::kIntersect_Op, 358 bool doAntiAlias = false); 359 360 /** Modify the current clip with the specified region. Note that unlike 361 clipRect() and clipPath() which transform their arguments by the current 362 matrix, clipRegion() assumes its argument is already in device 363 coordinates, and so no transformation is performed. 364 @param deviceRgn The region to apply to the current clip 365 @param op The region op to apply to the current clip 366 @return true if the canvas' new clip is non-empty 367 */ 368 virtual bool clipRegion(const SkRegion& deviceRgn, 369 SkRegion::Op op = SkRegion::kIntersect_Op); 370 371 /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the 372 specified region. This does not intersect or in any other way account 373 for the existing clip region. 374 @param deviceRgn The region to copy into the current clip. 375 @return true if the new clip region is non-empty 376 */ setClipRegion(const SkRegion & deviceRgn)377 bool setClipRegion(const SkRegion& deviceRgn) { 378 return this->clipRegion(deviceRgn, SkRegion::kReplace_Op); 379 } 380 381 /** Enum describing how to treat edges when performing quick-reject tests 382 of a geometry against the current clip. Treating them as antialiased 383 (kAA_EdgeType) will take into account the extra pixels that may be drawn 384 if the edge does not lie exactly on a device pixel boundary (after being 385 transformed by the current matrix). 386 */ 387 enum EdgeType { 388 /** Treat the edges as B&W (not antialiased) for the purposes of testing 389 against the current clip 390 */ 391 kBW_EdgeType, 392 /** Treat the edges as antialiased for the purposes of testing 393 against the current clip 394 */ 395 kAA_EdgeType 396 }; 397 398 /** Return true if the specified rectangle, after being transformed by the 399 current matrix, would lie completely outside of the current clip. Call 400 this to check if an area you intend to draw into is clipped out (and 401 therefore you can skip making the draw calls). 402 @param rect the rect to compare with the current clip 403 @param et specifies how to treat the edges (see EdgeType) 404 @return true if the rect (transformed by the canvas' matrix) does not 405 intersect with the canvas' clip 406 */ 407 bool quickReject(const SkRect& rect, EdgeType et) const; 408 409 /** Return true if the specified path, after being transformed by the 410 current matrix, would lie completely outside of the current clip. Call 411 this to check if an area you intend to draw into is clipped out (and 412 therefore you can skip making the draw calls). Note, for speed it may 413 return false even if the path itself might not intersect the clip 414 (i.e. the bounds of the path intersects, but the path does not). 415 @param path The path to compare with the current clip 416 @param et specifies how to treat the edges (see EdgeType) 417 @return true if the path (transformed by the canvas' matrix) does not 418 intersect with the canvas' clip 419 */ 420 bool quickReject(const SkPath& path, EdgeType et) const; 421 422 /** Return true if the horizontal band specified by top and bottom is 423 completely clipped out. This is a conservative calculation, meaning 424 that it is possible that if the method returns false, the band may still 425 in fact be clipped out, but the converse is not true. If this method 426 returns true, then the band is guaranteed to be clipped out. 427 @param top The top of the horizontal band to compare with the clip 428 @param bottom The bottom of the horizontal and to compare with the clip 429 @return true if the horizontal band is completely clipped out (i.e. does 430 not intersect the current clip) 431 */ quickRejectY(SkScalar top,SkScalar bottom,EdgeType et)432 bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const { 433 SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom)); 434 const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et); 435 // In the case where the clip is empty and we are provided with a 436 // negative top and positive bottom parameter then this test will return 437 // false even though it will be clipped. We have chosen to exclude that 438 // check as it is rare and would result double the comparisons. 439 return SkScalarToCompareType(top) >= clipR.fBottom 440 || SkScalarToCompareType(bottom) <= clipR.fTop; 441 } 442 443 /** Return the bounds of the current clip (in local coordinates) in the 444 bounds parameter, and return true if it is non-empty. This can be useful 445 in a way similar to quickReject, in that it tells you that drawing 446 outside of these bounds will be clipped out. 447 */ 448 bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const; 449 450 /** Return the bounds of the current clip, in device coordinates; returns 451 true if non-empty. Maybe faster than getting the clip explicitly and 452 then taking its bounds. 453 */ 454 bool getClipDeviceBounds(SkIRect* bounds) const; 455 456 457 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 458 specified ARGB color, using the specified mode. 459 @param a the alpha component (0..255) of the color to fill the canvas 460 @param r the red component (0..255) of the color to fill the canvas 461 @param g the green component (0..255) of the color to fill the canvas 462 @param b the blue component (0..255) of the color to fill the canvas 463 @param mode the mode to apply the color in (defaults to SrcOver) 464 */ 465 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 466 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); 467 468 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 469 specified color and mode. 470 @param color the color to draw with 471 @param mode the mode to apply the color in (defaults to SrcOver) 472 */ 473 void drawColor(SkColor color, 474 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); 475 476 /** 477 * This erases the entire drawing surface to the specified color, 478 * irrespective of the clip. It does not blend with the previous pixels, 479 * but always overwrites them. 480 * 481 * It is roughly equivalent to the following: 482 * canvas.save(); 483 * canvas.clipRect(hugeRect, kReplace_Op); 484 * paint.setColor(color); 485 * paint.setXfermodeMode(kSrc_Mode); 486 * canvas.drawPaint(paint); 487 * canvas.restore(); 488 * though it is almost always much more efficient. 489 */ 490 virtual void clear(SkColor); 491 492 /** 493 * Fill the entire canvas' bitmap (restricted to the current clip) with the 494 * specified paint. 495 * @param paint The paint used to fill the canvas 496 */ 497 virtual void drawPaint(const SkPaint& paint); 498 499 enum PointMode { 500 /** drawPoints draws each point separately */ 501 kPoints_PointMode, 502 /** drawPoints draws each pair of points as a line segment */ 503 kLines_PointMode, 504 /** drawPoints draws the array of points as a polygon */ 505 kPolygon_PointMode 506 }; 507 508 /** Draw a series of points, interpreted based on the PointMode mode. For 509 all modes, the count parameter is interpreted as the total number of 510 points. For kLine mode, count/2 line segments are drawn. 511 For kPoint mode, each point is drawn centered at its coordinate, and its 512 size is specified by the paint's stroke-width. It draws as a square, 513 unless the paint's cap-type is round, in which the points are drawn as 514 circles. 515 For kLine mode, each pair of points is drawn as a line segment, 516 respecting the paint's settings for cap/join/width. 517 For kPolygon mode, the entire array is drawn as a series of connected 518 line segments. 519 Note that, while similar, kLine and kPolygon modes draw slightly 520 differently than the equivalent path built with a series of moveto, 521 lineto calls, in that the path will draw all of its contours at once, 522 with no interactions if contours intersect each other (think XOR 523 xfermode). drawPoints always draws each element one at a time. 524 @param mode PointMode specifying how to draw the array of points. 525 @param count The number of points in the array 526 @param pts Array of points to draw 527 @param paint The paint used to draw the points 528 */ 529 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 530 const SkPaint& paint); 531 532 /** Helper method for drawing a single point. See drawPoints() for a more 533 details. 534 */ 535 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint); 536 537 /** Draws a single pixel in the specified color. 538 @param x The X coordinate of which pixel to draw 539 @param y The Y coordiante of which pixel to draw 540 @param color The color to draw 541 */ 542 void drawPoint(SkScalar x, SkScalar y, SkColor color); 543 544 /** Draw a line segment with the specified start and stop x,y coordinates, 545 using the specified paint. NOTE: since a line is always "framed", the 546 paint's Style is ignored. 547 @param x0 The x-coordinate of the start point of the line 548 @param y0 The y-coordinate of the start point of the line 549 @param x1 The x-coordinate of the end point of the line 550 @param y1 The y-coordinate of the end point of the line 551 @param paint The paint used to draw the line 552 */ 553 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 554 const SkPaint& paint); 555 556 /** Draw the specified rectangle using the specified paint. The rectangle 557 will be filled or stroked based on the Style in the paint. 558 @param rect The rect to be drawn 559 @param paint The paint used to draw the rect 560 */ 561 virtual void drawRect(const SkRect& rect, const SkPaint& paint); 562 563 /** Draw the specified rectangle using the specified paint. The rectangle 564 will be filled or framed based on the Style in the paint. 565 @param rect The rect to be drawn 566 @param paint The paint used to draw the rect 567 */ drawIRect(const SkIRect & rect,const SkPaint & paint)568 void drawIRect(const SkIRect& rect, const SkPaint& paint) 569 { 570 SkRect r; 571 r.set(rect); // promotes the ints to scalars 572 this->drawRect(r, paint); 573 } 574 575 /** Draw the specified rectangle using the specified paint. The rectangle 576 will be filled or framed based on the Style in the paint. 577 @param left The left side of the rectangle to be drawn 578 @param top The top side of the rectangle to be drawn 579 @param right The right side of the rectangle to be drawn 580 @param bottom The bottom side of the rectangle to be drawn 581 @param paint The paint used to draw the rect 582 */ 583 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right, 584 SkScalar bottom, const SkPaint& paint); 585 586 /** Draw the specified oval using the specified paint. The oval will be 587 filled or framed based on the Style in the paint. 588 @param oval The rectangle bounds of the oval to be drawn 589 @param paint The paint used to draw the oval 590 */ 591 void drawOval(const SkRect& oval, const SkPaint&); 592 593 /** Draw the specified circle using the specified paint. If radius is <= 0, 594 then nothing will be drawn. The circle will be filled 595 or framed based on the Style in the paint. 596 @param cx The x-coordinate of the center of the cirle to be drawn 597 @param cy The y-coordinate of the center of the cirle to be drawn 598 @param radius The radius of the cirle to be drawn 599 @param paint The paint used to draw the circle 600 */ 601 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 602 const SkPaint& paint); 603 604 /** Draw the specified arc, which will be scaled to fit inside the 605 specified oval. If the sweep angle is >= 360, then the oval is drawn 606 completely. Note that this differs slightly from SkPath::arcTo, which 607 treats the sweep angle mod 360. 608 @param oval The bounds of oval used to define the shape of the arc 609 @param startAngle Starting angle (in degrees) where the arc begins 610 @param sweepAngle Sweep angle (in degrees) measured clockwise 611 @param useCenter true means include the center of the oval. For filling 612 this will draw a wedge. False means just use the arc. 613 @param paint The paint used to draw the arc 614 */ 615 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 616 bool useCenter, const SkPaint& paint); 617 618 /** Draw the specified round-rect using the specified paint. The round-rect 619 will be filled or framed based on the Style in the paint. 620 @param rect The rectangular bounds of the roundRect to be drawn 621 @param rx The x-radius of the oval used to round the corners 622 @param ry The y-radius of the oval used to round the corners 623 @param paint The paint used to draw the roundRect 624 */ 625 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, 626 const SkPaint& paint); 627 628 /** Draw the specified path using the specified paint. The path will be 629 filled or framed based on the Style in the paint. 630 @param path The path to be drawn 631 @param paint The paint used to draw the path 632 */ 633 virtual void drawPath(const SkPath& path, const SkPaint& paint); 634 635 /** Draw the specified bitmap, with its top/left corner at (x,y), using the 636 specified paint, transformed by the current matrix. Note: if the paint 637 contains a maskfilter that generates a mask which extends beyond the 638 bitmap's original width/height, then the bitmap will be drawn as if it 639 were in a Shader with CLAMP mode. Thus the color outside of the original 640 width/height will be the edge color replicated. 641 @param bitmap The bitmap to be drawn 642 @param left The position of the left side of the bitmap being drawn 643 @param top The position of the top side of the bitmap being drawn 644 @param paint The paint used to draw the bitmap, or NULL 645 */ 646 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 647 const SkPaint* paint = NULL); 648 649 /** Draw the specified bitmap, with the specified matrix applied (before the 650 canvas' matrix is applied). 651 @param bitmap The bitmap to be drawn 652 @param src Optional: specify the subset of the bitmap to be drawn 653 @param dst The destination rectangle where the scaled/translated 654 image will be drawn 655 @param paint The paint used to draw the bitmap, or NULL 656 */ 657 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, 658 const SkRect& dst, const SkPaint* paint = NULL); 659 660 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, 661 const SkPaint* paint = NULL); 662 663 /** 664 * Draw the bitmap stretched differentially to fit into dst. 665 * center is a rect within the bitmap, and logically divides the bitmap 666 * into 9 sections (3x3). For example, if the middle pixel of a [5x5] 667 * bitmap is the "center", then the center-rect should be [2, 2, 3, 3]. 668 * 669 * If the dst is >= the bitmap size, then... 670 * - The 4 corners are not stretch at all. 671 * - The sides are stretch in only one axis. 672 * - The center is stretch in both axes. 673 * Else, for each axis where dst < bitmap, 674 * - The corners shrink proportionally 675 * - The sides (along the shrink axis) and center are not drawn 676 */ 677 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 678 const SkRect& dst, const SkPaint* paint = NULL); 679 680 /** Draw the specified bitmap, with its top/left corner at (x,y), 681 NOT transformed by the current matrix. Note: if the paint 682 contains a maskfilter that generates a mask which extends beyond the 683 bitmap's original width/height, then the bitmap will be drawn as if it 684 were in a Shader with CLAMP mode. Thus the color outside of the original 685 width/height will be the edge color replicated. 686 @param bitmap The bitmap to be drawn 687 @param left The position of the left side of the bitmap being drawn 688 @param top The position of the top side of the bitmap being drawn 689 @param paint The paint used to draw the bitmap, or NULL 690 */ 691 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 692 const SkPaint* paint = NULL); 693 694 /** Draw the text, with origin at (x,y), using the specified paint. 695 The origin is interpreted based on the Align setting in the paint. 696 @param text The text to be drawn 697 @param byteLength The number of bytes to read from the text parameter 698 @param x The x-coordinate of the origin of the text being drawn 699 @param y The y-coordinate of the origin of the text being drawn 700 @param paint The paint used for the text (e.g. color, size, style) 701 */ 702 virtual void drawText(const void* text, size_t byteLength, SkScalar x, 703 SkScalar y, const SkPaint& paint); 704 705 /** Draw the text, with each character/glyph origin specified by the pos[] 706 array. The origin is interpreted by the Align setting in the paint. 707 @param text The text to be drawn 708 @param byteLength The number of bytes to read from the text parameter 709 @param pos Array of positions, used to position each character 710 @param paint The paint used for the text (e.g. color, size, style) 711 */ 712 virtual void drawPosText(const void* text, size_t byteLength, 713 const SkPoint pos[], const SkPaint& paint); 714 715 /** Draw the text, with each character/glyph origin specified by the x 716 coordinate taken from the xpos[] array, and the y from the constY param. 717 The origin is interpreted by the Align setting in the paint. 718 @param text The text to be drawn 719 @param byteLength The number of bytes to read from the text parameter 720 @param xpos Array of x-positions, used to position each character 721 @param constY The shared Y coordinate for all of the positions 722 @param paint The paint used for the text (e.g. color, size, style) 723 */ 724 virtual void drawPosTextH(const void* text, size_t byteLength, 725 const SkScalar xpos[], SkScalar constY, 726 const SkPaint& paint); 727 728 /** Draw the text, with origin at (x,y), using the specified paint, along 729 the specified path. The paint's Align setting determins where along the 730 path to start the text. 731 @param text The text to be drawn 732 @param byteLength The number of bytes to read from the text parameter 733 @param path The path the text should follow for its baseline 734 @param hOffset The distance along the path to add to the text's 735 starting position 736 @param vOffset The distance above(-) or below(+) the path to 737 position the text 738 @param paint The paint used for the text 739 */ 740 void drawTextOnPathHV(const void* text, size_t byteLength, 741 const SkPath& path, SkScalar hOffset, 742 SkScalar vOffset, const SkPaint& paint); 743 744 /** Draw the text, with origin at (x,y), using the specified paint, along 745 the specified path. The paint's Align setting determins where along the 746 path to start the text. 747 @param text The text to be drawn 748 @param byteLength The number of bytes to read from the text parameter 749 @param path The path the text should follow for its baseline 750 @param matrix (may be null) Applied to the text before it is 751 mapped onto the path 752 @param paint The paint used for the text 753 */ 754 virtual void drawTextOnPath(const void* text, size_t byteLength, 755 const SkPath& path, const SkMatrix* matrix, 756 const SkPaint& paint); 757 758 #ifdef SK_BUILD_FOR_ANDROID 759 /** Draw the text on path, with each character/glyph origin specified by the pos[] 760 array. The origin is interpreted by the Align setting in the paint. 761 @param text The text to be drawn 762 @param byteLength The number of bytes to read from the text parameter 763 @param pos Array of positions, used to position each character 764 @param paint The paint used for the text (e.g. color, size, style) 765 @param path The path to draw on 766 @param matrix The canvas matrix 767 */ 768 void drawPosTextOnPath(const void* text, size_t byteLength, 769 const SkPoint pos[], const SkPaint& paint, 770 const SkPath& path, const SkMatrix* matrix); 771 #endif 772 773 /** Draw the picture into this canvas. This method effective brackets the 774 playback of the picture's draw calls with save/restore, so the state 775 of this canvas will be unchanged after this call. This contrasts with 776 the more immediate method SkPicture::draw(), which does not bracket 777 the canvas with save/restore, thus the canvas may be left in a changed 778 state after the call. 779 @param picture The recorded drawing commands to playback into this 780 canvas. 781 */ 782 virtual void drawPicture(SkPicture& picture); 783 784 enum VertexMode { 785 kTriangles_VertexMode, 786 kTriangleStrip_VertexMode, 787 kTriangleFan_VertexMode 788 }; 789 790 /** Draw the array of vertices, interpreted as triangles (based on mode). 791 @param vmode How to interpret the array of vertices 792 @param vertexCount The number of points in the vertices array (and 793 corresponding texs and colors arrays if non-null) 794 @param vertices Array of vertices for the mesh 795 @param texs May be null. If not null, specifies the coordinate 796 in texture space for each vertex. 797 @param colors May be null. If not null, specifies a color for each 798 vertex, to be interpolated across the triangle. 799 @param xmode Used if both texs and colors are present. In this 800 case the colors are combined with the texture using mode, 801 before being drawn using the paint. If mode is null, then 802 kMultiply_Mode is used. 803 @param indices If not null, array of indices to reference into the 804 vertex (texs, colors) array. 805 @param indexCount number of entries in the indices array (if not null) 806 @param paint Specifies the shader/texture if present. 807 */ 808 virtual void drawVertices(VertexMode vmode, int vertexCount, 809 const SkPoint vertices[], const SkPoint texs[], 810 const SkColor colors[], SkXfermode* xmode, 811 const uint16_t indices[], int indexCount, 812 const SkPaint& paint); 813 814 /** Send a blob of data to the canvas. 815 For canvases that draw, this call is effectively a no-op, as the data 816 is not parsed, but just ignored. However, this call exists for 817 subclasses like SkPicture's recording canvas, that can store the data 818 and then play it back later (via another call to drawData). 819 */ 820 virtual void drawData(const void* data, size_t length); 821 822 ////////////////////////////////////////////////////////////////////////// 823 824 /** Get the current bounder object. 825 The bounder's reference count is unchaged. 826 @return the canva's bounder (or NULL). 827 */ getBounder()828 SkBounder* getBounder() const { return fBounder; } 829 830 /** Set a new bounder (or NULL). 831 Pass NULL to clear any previous bounder. 832 As a convenience, the parameter passed is also returned. 833 If a previous bounder exists, its reference count is decremented. 834 If bounder is not NULL, its reference count is incremented. 835 @param bounder the new bounder (or NULL) to be installed in the canvas 836 @return the set bounder object 837 */ 838 virtual SkBounder* setBounder(SkBounder* bounder); 839 840 /** Get the current filter object. The filter's reference count is not 841 affected. The filter is saved/restored, just like the matrix and clip. 842 @return the canvas' filter (or NULL). 843 */ 844 SkDrawFilter* getDrawFilter() const; 845 846 /** Set the new filter (or NULL). Pass NULL to clear any existing filter. 847 As a convenience, the parameter is returned. If an existing filter 848 exists, its refcnt is decrement. If the new filter is not null, its 849 refcnt is incremented. The filter is saved/restored, just like the 850 matrix and clip. 851 @param filter the new filter (or NULL) 852 @return the new filter 853 */ 854 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); 855 856 ////////////////////////////////////////////////////////////////////////// 857 858 /** Return the current matrix on the canvas. 859 This does not account for the translate in any of the devices. 860 @return The current matrix on the canvas. 861 */ 862 const SkMatrix& getTotalMatrix() const; 863 864 enum ClipType { 865 kEmpty_ClipType = 0, 866 kRect_ClipType, 867 kComplex_ClipType 868 }; 869 870 /** Returns a description of the total clip; may be cheaper than 871 getting the clip and querying it directly. 872 */ 873 ClipType getClipType() const; 874 875 /** Return the current device clip (concatenation of all clip calls). 876 This does not account for the translate in any of the devices. 877 @return the current device clip (concatenation of all clip calls). 878 */ 879 const SkRegion& getTotalClip() const; 880 881 /** 882 * Return true if the current clip is non-empty. 883 * 884 * If bounds is not NULL, set it to the bounds of the current clip 885 * in global coordinates. 886 */ 887 bool getTotalClipBounds(SkIRect* bounds) const; 888 889 /** 890 * Return the current clipstack. This mirrors the result in getTotalClip() 891 * but is represented as a stack of geometric clips + region-ops. 892 */ 893 const SkClipStack& getTotalClipStack() const; 894 895 void setExternalMatrix(const SkMatrix* = NULL); 896 897 /////////////////////////////////////////////////////////////////////////// 898 899 /** After calling saveLayer(), there can be any number of devices that make 900 up the top-most drawing area. LayerIter can be used to iterate through 901 those devices. Note that the iterator is only valid until the next API 902 call made on the canvas. Ownership of all pointers in the iterator stays 903 with the canvas, so none of them should be modified or deleted. 904 */ 905 class SK_API LayerIter /*: SkNoncopyable*/ { 906 public: 907 /** Initialize iterator with canvas, and set values for 1st device */ 908 LayerIter(SkCanvas*, bool skipEmptyClips); 909 ~LayerIter(); 910 911 /** Return true if the iterator is done */ done()912 bool done() const { return fDone; } 913 /** Cycle to the next device */ 914 void next(); 915 916 // These reflect the current device in the iterator 917 918 SkDevice* device() const; 919 const SkMatrix& matrix() const; 920 const SkRegion& clip() const; 921 const SkPaint& paint() const; 922 int x() const; 923 int y() const; 924 925 private: 926 // used to embed the SkDrawIter object directly in our instance, w/o 927 // having to expose that class def to the public. There is an assert 928 // in our constructor to ensure that fStorage is large enough 929 // (though needs to be a compile-time-assert!). We use intptr_t to work 930 // safely with 32 and 64 bit machines (to ensure the storage is enough) 931 intptr_t fStorage[32]; 932 class SkDrawIter* fImpl; // this points at fStorage 933 SkPaint fDefaultPaint; 934 bool fDone; 935 }; 936 937 protected: 938 // Returns the canvas to be used by DrawIter. Default implementation 939 // returns this. Subclasses that encapsulate an indirect canvas may 940 // need to overload this method. The impl must keep track of this, as it 941 // is not released or deleted by the caller. 942 virtual SkCanvas* canvasForDrawIter(); 943 944 // all of the drawBitmap variants call this guy 945 virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*, 946 const SkMatrix&, const SkPaint& paint); 947 948 // Clip rectangle bounds. Called internally by saveLayer. 949 // returns false if the entire rectangle is entirely clipped out 950 bool clipRectBounds(const SkRect* bounds, SaveFlags flags, 951 SkIRect* intersection); 952 953 private: 954 class MCRec; 955 956 SkClipStack fClipStack; 957 SkDeque fMCStack; 958 // points to top of stack 959 MCRec* fMCRec; 960 // the first N recs that can fit here mean we won't call malloc 961 uint32_t fMCRecStorage[32]; 962 963 SkBounder* fBounder; 964 SkDevice* fLastDeviceToGainFocus; 965 int fLayerCount; // number of successful saveLayer calls 966 967 void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&, 968 const SkClipStack& clipStack); 969 970 bool fDeviceCMDirty; // cleared by updateDeviceCMCache() 971 void updateDeviceCMCache(); 972 973 friend class SkDrawIter; // needs setupDrawForLayerDevice() 974 975 SkDevice* createLayerDevice(SkBitmap::Config, int width, int height, 976 bool isOpaque); 977 978 SkDevice* init(SkDevice*); 979 980 // internal methods are not virtual, so they can safely be called by other 981 // canvas apis, without confusing subclasses (like SkPictureRecording) 982 void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m, 983 const SkPaint* paint); 984 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, 985 const SkRect& dst, const SkPaint* paint); 986 void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 987 const SkRect& dst, const SkPaint* paint); 988 void internalDrawPaint(const SkPaint& paint); 989 990 991 void drawDevice(SkDevice*, int x, int y, const SkPaint*); 992 // shared by save() and saveLayer() 993 int internalSave(SaveFlags flags); 994 void internalRestore(); 995 static void DrawRect(const SkDraw& draw, const SkPaint& paint, 996 const SkRect& r, SkScalar textSize); 997 static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 998 const char text[], size_t byteLength, 999 SkScalar x, SkScalar y); 1000 1001 /* These maintain a cache of the clip bounds in local coordinates, 1002 (converted to 2s-compliment if floats are slow). 1003 */ 1004 mutable SkRectCompareType fLocalBoundsCompareType; 1005 mutable bool fLocalBoundsCompareTypeDirty; 1006 1007 mutable SkRectCompareType fLocalBoundsCompareTypeBW; 1008 mutable bool fLocalBoundsCompareTypeDirtyBW; 1009 1010 /* Get the local clip bounds with an anti-aliased edge. 1011 */ getLocalClipBoundsCompareType()1012 const SkRectCompareType& getLocalClipBoundsCompareType() const { 1013 return getLocalClipBoundsCompareType(kAA_EdgeType); 1014 } 1015 getLocalClipBoundsCompareType(EdgeType et)1016 const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const { 1017 if (et == kAA_EdgeType) { 1018 if (fLocalBoundsCompareTypeDirty) { 1019 this->computeLocalClipBoundsCompareType(et); 1020 fLocalBoundsCompareTypeDirty = false; 1021 } 1022 return fLocalBoundsCompareType; 1023 } else { 1024 if (fLocalBoundsCompareTypeDirtyBW) { 1025 this->computeLocalClipBoundsCompareType(et); 1026 fLocalBoundsCompareTypeDirtyBW = false; 1027 } 1028 return fLocalBoundsCompareTypeBW; 1029 } 1030 } 1031 void computeLocalClipBoundsCompareType(EdgeType et) const; 1032 1033 SkMatrix fExternalMatrix, fExternalInverse; 1034 bool fUseExternalMatrix; 1035 1036 class AutoValidateClip : ::SkNoncopyable { 1037 public: AutoValidateClip(SkCanvas * canvas)1038 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) { 1039 fCanvas->validateClip(); 1040 } ~AutoValidateClip()1041 ~AutoValidateClip() { fCanvas->validateClip(); } 1042 1043 private: 1044 const SkCanvas* fCanvas; 1045 }; 1046 1047 #ifdef SK_DEBUG 1048 void validateClip() const; 1049 #else validateClip()1050 void validateClip() const {} 1051 #endif 1052 }; 1053 1054 /** Stack helper class to automatically call restoreToCount() on the canvas 1055 when this object goes out of scope. Use this to guarantee that the canvas 1056 is restored to a known state. 1057 */ 1058 class SkAutoCanvasRestore : SkNoncopyable { 1059 public: SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)1060 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) { 1061 SkASSERT(canvas); 1062 fSaveCount = canvas->getSaveCount(); 1063 if (doSave) { 1064 canvas->save(); 1065 } 1066 } ~SkAutoCanvasRestore()1067 ~SkAutoCanvasRestore() { 1068 fCanvas->restoreToCount(fSaveCount); 1069 } 1070 1071 private: 1072 SkCanvas* fCanvas; 1073 int fSaveCount; 1074 }; 1075 1076 #endif 1077