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