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 #ifdef SK_BUILD_FOR_ANDROID 34 namespace WebCore { 35 class RasterRenderer; 36 class GaneshRenderer; 37 } 38 #endif 39 40 /** \class SkCanvas 41 42 A Canvas encapsulates all of the state about drawing into a device (bitmap). 43 This includes a reference to the device itself, and a stack of matrix/clip 44 values. For any given draw call (e.g. drawRect), the geometry of the object 45 being drawn is transformed by the concatenation of all the matrices in the 46 stack. The transformed geometry is clipped by the intersection of all of 47 the clips in the stack. 48 49 While the Canvas holds the state of the drawing device, the state (style) 50 of the object being drawn is held by the Paint, which is provided as a 51 parameter to each of the draw() methods. The Paint holds attributes such as 52 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns), 53 etc. 54 */ 55 class SK_API SkCanvas : public SkRefCnt { 56 public: 57 SK_DECLARE_INST_COUNT(SkCanvas) 58 59 SkCanvas(); 60 61 /** Construct a canvas with the specified device to draw into. 62 63 @param device Specifies a device for the canvas to draw into. 64 */ 65 explicit SkCanvas(SkDevice* device); 66 67 /** Deprecated - Construct a canvas with the specified bitmap to draw into. 68 @param bitmap Specifies a bitmap for the canvas to draw into. Its 69 structure are copied to the canvas. 70 */ 71 explicit SkCanvas(const SkBitmap& bitmap); 72 virtual ~SkCanvas(); 73 74 SkMetaData& getMetaData(); 75 76 /////////////////////////////////////////////////////////////////////////// 77 78 /** 79 * Trigger the immediate execution of all pending draw operations. 80 */ 81 void flush(); 82 83 /** 84 * Return the width/height of the underlying device. The current drawable 85 * area may be small (due to clipping or saveLayer). For a canvas with 86 * no device, 0,0 will be returned. 87 */ 88 SkISize getDeviceSize() const; 89 90 /** Return the canvas' device object, which may be null. The device holds 91 the bitmap of the pixels that the canvas draws into. The reference count 92 of the returned device is not changed by this call. 93 */ 94 SkDevice* getDevice() const; 95 96 /** 97 * saveLayer() can create another device (which is later drawn onto 98 * the previous device). getTopDevice() returns the top-most device current 99 * installed. Note that this can change on other calls like save/restore, 100 * so do not access this device after subsequent canvas calls. 101 * The reference count of the device is not changed. 102 * 103 * @param updateMatrixClip If this is true, then before the device is 104 * returned, we ensure that its has been notified about the current 105 * matrix and clip. Note: this happens automatically when the device 106 * is drawn to, but is optional here, as there is a small perf hit 107 * sometimes. 108 */ 109 SkDevice* getTopDevice(bool updateMatrixClip = false) const; 110 111 /** 112 * Shortcut for getDevice()->createCompatibleDevice(...). 113 * If getDevice() == NULL, this method does nothing, and returns NULL. 114 */ 115 SkDevice* createCompatibleDevice(SkBitmap::Config config, 116 int width, int height, 117 bool isOpaque); 118 119 /////////////////////////////////////////////////////////////////////////// 120 121 /** 122 * This enum can be used with read/writePixels to perform a pixel ops to or 123 * from an 8888 config other than Skia's native config (SkPMColor). There 124 * are three byte orders supported: native, BGRA, and RGBA. Each has a 125 * premultiplied and unpremultiplied variant. 126 * 127 * Components of a 8888 pixel can be packed/unpacked from a 32bit word using 128 * either byte offsets or shift values. Byte offsets are endian-invariant 129 * while shifts are not. BGRA and RGBA configs are defined by byte 130 * orderings. The native config is defined by shift values (SK_A32_SHIFT, 131 * ..., SK_B32_SHIFT). 132 */ 133 enum Config8888 { 134 /** 135 * Skia's native order specified by: 136 * SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT 137 * 138 * kNative_Premul_Config8888 is equivalent to SkPMColor 139 * kNative_Unpremul_Config8888 has the same component order as SkPMColor 140 * but is not premultiplied. 141 */ 142 kNative_Premul_Config8888, 143 kNative_Unpremul_Config8888, 144 /** 145 * low byte to high byte: B, G, R, A. 146 */ 147 kBGRA_Premul_Config8888, 148 kBGRA_Unpremul_Config8888, 149 /** 150 * low byte to high byte: R, G, B, A. 151 */ 152 kRGBA_Premul_Config8888, 153 kRGBA_Unpremul_Config8888 154 }; 155 156 /** 157 * On success (returns true), copy the canvas pixels into the bitmap. 158 * On failure, the bitmap parameter is left unchanged and false is 159 * returned. 160 * 161 * The canvas' pixels are converted to the bitmap's config. The only 162 * supported config is kARGB_8888_Config, though this is likely to be 163 * relaxed in the future. The meaning of config kARGB_8888_Config is 164 * modified by the enum param config8888. The default value interprets 165 * kARGB_8888_Config as SkPMColor 166 * 167 * If the bitmap has pixels already allocated, the canvas pixels will be 168 * written there. If not, bitmap->allocPixels() will be called 169 * automatically. If the bitmap is backed by a texture readPixels will 170 * fail. 171 * 172 * The actual pixels written is the intersection of the canvas' bounds, and 173 * the rectangle formed by the bitmap's width,height and the specified x,y. 174 * If bitmap pixels extend outside of that intersection, they will not be 175 * modified. 176 * 177 * Other failure conditions: 178 * * If the canvas is backed by a non-raster device (e.g. PDF) then 179 * readPixels will fail. 180 * * If bitmap is texture-backed then readPixels will fail. (This may be 181 * relaxed in the future.) 182 * 183 * Example that reads the entire canvas into a bitmap using the native 184 * SkPMColor: 185 * SkISize size = canvas->getDeviceSize(); 186 * bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, 187 * size.fHeight); 188 * if (canvas->readPixels(bitmap, 0, 0)) { 189 * // use the pixels 190 * } 191 */ 192 bool readPixels(SkBitmap* bitmap, 193 int x, int y, 194 Config8888 config8888 = kNative_Premul_Config8888); 195 196 /** 197 * DEPRECATED: This will be removed as soon as webkit is no longer relying 198 * on it. The bitmap is resized to the intersection of srcRect and the 199 * canvas bounds. New pixels are always allocated on success. Bitmap is 200 * unmodified on failure. 201 */ 202 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); 203 204 /** 205 * Similar to draw sprite, this method will copy the pixels in bitmap onto 206 * the canvas, with the top/left corner specified by (x, y). The canvas' 207 * pixel values are completely replaced: there is no blending. 208 * 209 * Currently if bitmap is backed by a texture this is a no-op. This may be 210 * relaxed in the future. 211 * 212 * If the bitmap has config kARGB_8888_Config then the config8888 param 213 * will determines how the pixel valuess are intepreted. If the bitmap is 214 * not kARGB_8888_Config then this parameter is ignored. 215 * 216 * Note: If you are recording drawing commands on this canvas to 217 * SkPicture, writePixels() is ignored! 218 */ 219 void writePixels(const SkBitmap& bitmap, 220 int x, int y, 221 Config8888 config8888 = kNative_Premul_Config8888); 222 223 /////////////////////////////////////////////////////////////////////////// 224 225 enum SaveFlags { 226 /** save the matrix state, restoring it on restore() */ 227 kMatrix_SaveFlag = 0x01, 228 /** save the clip state, restoring it on restore() */ 229 kClip_SaveFlag = 0x02, 230 /** the layer needs to support per-pixel alpha */ 231 kHasAlphaLayer_SaveFlag = 0x04, 232 /** the layer needs to support 8-bits per color component */ 233 kFullColorLayer_SaveFlag = 0x08, 234 /** the layer should clip against the bounds argument */ 235 kClipToLayer_SaveFlag = 0x10, 236 237 // helper masks for common choices 238 kMatrixClip_SaveFlag = 0x03, 239 kARGB_NoClipLayer_SaveFlag = 0x0F, 240 kARGB_ClipLayer_SaveFlag = 0x1F 241 }; 242 243 /** This call saves the current matrix, clip, and drawFilter, and pushes a 244 copy onto a private stack. Subsequent calls to translate, scale, 245 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all 246 operate on this copy. 247 When the balancing call to restore() is made, the previous matrix, clip, 248 and drawFilter are restored. 249 @return The value to pass to restoreToCount() to balance this save() 250 */ 251 virtual int save(SaveFlags flags = kMatrixClip_SaveFlag); 252 253 /** This behaves the same as save(), but in addition it allocates an 254 offscreen bitmap. All drawing calls are directed there, and only when 255 the balancing call to restore() is made is that offscreen transfered to 256 the canvas (or the previous layer). 257 @param bounds (may be null) This rect, if non-null, is used as a hint to 258 limit the size of the offscreen, and thus drawing may be 259 clipped to it, though that clipping is not guaranteed to 260 happen. If exact clipping is desired, use clipRect(). 261 @param paint (may be null) This is copied, and is applied to the 262 offscreen when restore() is called 263 @param flags LayerFlags 264 @return The value to pass to restoreToCount() to balance this save() 265 */ 266 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, 267 SaveFlags flags = kARGB_ClipLayer_SaveFlag); 268 269 /** This behaves the same as save(), but in addition it allocates an 270 offscreen bitmap. All drawing calls are directed there, and only when 271 the balancing call to restore() is made is that offscreen transfered to 272 the canvas (or the previous layer). 273 @param bounds (may be null) This rect, if non-null, is used as a hint to 274 limit the size of the offscreen, and thus drawing may be 275 clipped to it, though that clipping is not guaranteed to 276 happen. If exact clipping is desired, use clipRect(). 277 @param alpha This is applied to the offscreen when restore() is called. 278 @param flags LayerFlags 279 @return The value to pass to restoreToCount() to balance this save() 280 */ 281 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 282 SaveFlags flags = kARGB_ClipLayer_SaveFlag); 283 284 /** This call balances a previous call to save(), and is used to remove all 285 modifications to the matrix/clip/drawFilter state since the last save 286 call. 287 It is an error to call restore() more times than save() was called. 288 */ 289 virtual void restore(); 290 291 /** Returns the number of matrix/clip states on the SkCanvas' private stack. 292 This will equal # save() calls - # restore() calls. 293 */ 294 int getSaveCount() const; 295 296 /** Efficient way to pop any calls to save() that happened after the save 297 count reached saveCount. It is an error for saveCount to be less than 298 getSaveCount() 299 @param saveCount The number of save() levels to restore from 300 */ 301 void restoreToCount(int saveCount); 302 303 /** Returns true if drawing is currently going to a layer (from saveLayer) 304 * rather than to the root device. 305 */ 306 virtual bool isDrawingToLayer() const; 307 308 /** Preconcat the current matrix with the specified translation 309 @param dx The distance to translate in X 310 @param dy The distance to translate in Y 311 returns true if the operation succeeded (e.g. did not overflow) 312 */ 313 virtual bool translate(SkScalar dx, SkScalar dy); 314 315 /** Preconcat the current matrix with the specified scale. 316 @param sx The amount to scale in X 317 @param sy The amount to scale in Y 318 returns true if the operation succeeded (e.g. did not overflow) 319 */ 320 virtual bool scale(SkScalar sx, SkScalar sy); 321 322 /** Preconcat the current matrix with the specified rotation. 323 @param degrees The amount to rotate, in degrees 324 returns true if the operation succeeded (e.g. did not overflow) 325 */ 326 virtual bool rotate(SkScalar degrees); 327 328 /** Preconcat the current matrix with the specified skew. 329 @param sx The amount to skew in X 330 @param sy The amount to skew in Y 331 returns true if the operation succeeded (e.g. did not overflow) 332 */ 333 virtual bool skew(SkScalar sx, SkScalar sy); 334 335 /** Preconcat the current matrix with the specified matrix. 336 @param matrix The matrix to preconcatenate with the current matrix 337 @return true if the operation succeeded (e.g. did not overflow) 338 */ 339 virtual bool concat(const SkMatrix& matrix); 340 341 /** Replace the current matrix with a copy of the specified matrix. 342 @param matrix The matrix that will be copied into the current matrix. 343 */ 344 virtual void setMatrix(const SkMatrix& matrix); 345 346 /** Helper for setMatrix(identity). Sets the current matrix to identity. 347 */ 348 void resetMatrix(); 349 350 /** 351 * Modify the current clip with the specified rectangle. 352 * @param rect The rect to combine with the current clip 353 * @param op The region op to apply to the current clip 354 * @param doAntiAlias true if the clip should be antialiased 355 * @return true if the canvas' clip is non-empty 356 */ 357 virtual bool clipRect(const SkRect& rect, 358 SkRegion::Op op = SkRegion::kIntersect_Op, 359 bool doAntiAlias = false); 360 361 /** 362 * Modify the current clip with the specified SkRRect. 363 * @param rrect The rrect to combine with the current clip 364 * @param op The region op to apply to the current clip 365 * @param doAntiAlias true if the clip should be antialiased 366 * @return true if the canvas' clip is non-empty 367 */ 368 virtual bool clipRRect(const SkRRect& rrect, 369 SkRegion::Op op = SkRegion::kIntersect_Op, 370 bool doAntiAlias = false); 371 372 /** 373 * Modify the current clip with the specified path. 374 * @param path The path to combine with the current clip 375 * @param op The region op to apply to the current clip 376 * @param doAntiAlias true if the clip should be antialiased 377 * @return true if the canvas' new clip is non-empty 378 */ 379 virtual bool clipPath(const SkPath& path, 380 SkRegion::Op op = SkRegion::kIntersect_Op, 381 bool doAntiAlias = false); 382 383 /** EXPERIMENTAL -- only used for testing 384 Set to false to force clips to be hard, even if doAntiAlias=true is 385 passed to clipRect or clipPath. 386 */ setAllowSoftClip(bool allow)387 void setAllowSoftClip(bool allow) { 388 fAllowSoftClip = 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 */ setClipRegion(const SkRegion & deviceRgn)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 */ quickRejectY(SkScalar top,SkScalar bottom)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 */ drawIRect(const SkIRect & rect,const SkPaint & paint)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 drawBitmapRect(const SkBitmap & bitmap,const SkRect & dst,const SkPaint * paint)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 stretch at all. 709 * - The sides are stretch in only one axis. 710 * - The center is stretch 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 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 857 ////////////////////////////////////////////////////////////////////////// 858 859 /** Get the current bounder object. 860 The bounder's reference count is unchaged. 861 @return the canva's bounder (or NULL). 862 */ getBounder()863 SkBounder* getBounder() const { return fBounder; } 864 865 /** Set a new bounder (or NULL). 866 Pass NULL to clear any previous bounder. 867 As a convenience, the parameter passed is also returned. 868 If a previous bounder exists, its reference count is decremented. 869 If bounder is not NULL, its reference count is incremented. 870 @param bounder the new bounder (or NULL) to be installed in the canvas 871 @return the set bounder object 872 */ 873 virtual SkBounder* setBounder(SkBounder* bounder); 874 875 /** Get the current filter object. The filter's reference count is not 876 affected. The filter is saved/restored, just like the matrix and clip. 877 @return the canvas' filter (or NULL). 878 */ 879 SkDrawFilter* getDrawFilter() const; 880 881 /** Set the new filter (or NULL). Pass NULL to clear any existing filter. 882 As a convenience, the parameter is returned. If an existing filter 883 exists, its refcnt is decrement. If the new filter is not null, its 884 refcnt is incremented. The filter is saved/restored, just like the 885 matrix and clip. 886 @param filter the new filter (or NULL) 887 @return the new filter 888 */ 889 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); 890 891 ////////////////////////////////////////////////////////////////////////// 892 893 /** Return the current matrix on the canvas. 894 This does not account for the translate in any of the devices. 895 @return The current matrix on the canvas. 896 */ 897 const SkMatrix& getTotalMatrix() const; 898 899 enum ClipType { 900 kEmpty_ClipType = 0, 901 kRect_ClipType, 902 kComplex_ClipType 903 }; 904 905 /** Returns a description of the total clip; may be cheaper than 906 getting the clip and querying it directly. 907 */ 908 ClipType getClipType() const; 909 910 /** Return the current device clip (concatenation of all clip calls). 911 * This does not account for the translate in any of the devices. 912 * @return the current device clip (concatenation of all clip calls). 913 * 914 * DEPRECATED -- call getClipDeviceBounds() instead. 915 */ 916 const SkRegion& getTotalClip() const; 917 918 /** Return the clip stack. The clip stack stores all the individual 919 * clips organized by the save/restore frame in which they were 920 * added. 921 * @return the current clip stack ("list" of individual clip elements) 922 */ getClipStack()923 const SkClipStack* getClipStack() const { 924 return &fClipStack; 925 } 926 927 class ClipVisitor { 928 public: 929 virtual ~ClipVisitor(); 930 virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0; 931 virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0; 932 }; 933 934 /** 935 * Replays the clip operations, back to front, that have been applied to 936 * the canvas, calling the appropriate method on the visitor for each 937 * clip. All clips have already been transformed into device space. 938 */ 939 void replayClips(ClipVisitor*) const; 940 941 /////////////////////////////////////////////////////////////////////////// 942 943 /** After calling saveLayer(), there can be any number of devices that make 944 up the top-most drawing area. LayerIter can be used to iterate through 945 those devices. Note that the iterator is only valid until the next API 946 call made on the canvas. Ownership of all pointers in the iterator stays 947 with the canvas, so none of them should be modified or deleted. 948 */ 949 class SK_API LayerIter /*: SkNoncopyable*/ { 950 public: 951 /** Initialize iterator with canvas, and set values for 1st device */ 952 LayerIter(SkCanvas*, bool skipEmptyClips); 953 ~LayerIter(); 954 955 /** Return true if the iterator is done */ done()956 bool done() const { return fDone; } 957 /** Cycle to the next device */ 958 void next(); 959 960 // These reflect the current device in the iterator 961 962 SkDevice* device() const; 963 const SkMatrix& matrix() const; 964 const SkRegion& clip() const; 965 const SkPaint& paint() const; 966 int x() const; 967 int y() const; 968 969 private: 970 // used to embed the SkDrawIter object directly in our instance, w/o 971 // having to expose that class def to the public. There is an assert 972 // in our constructor to ensure that fStorage is large enough 973 // (though needs to be a compile-time-assert!). We use intptr_t to work 974 // safely with 32 and 64 bit machines (to ensure the storage is enough) 975 intptr_t fStorage[32]; 976 class SkDrawIter* fImpl; // this points at fStorage 977 SkPaint fDefaultPaint; 978 bool fDone; 979 }; 980 981 protected: 982 // Returns the canvas to be used by DrawIter. Default implementation 983 // returns this. Subclasses that encapsulate an indirect canvas may 984 // need to overload this method. The impl must keep track of this, as it 985 // is not released or deleted by the caller. 986 virtual SkCanvas* canvasForDrawIter(); 987 988 // all of the drawBitmap variants call this guy 989 void commonDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix&, 990 const SkPaint& paint); 991 992 // Clip rectangle bounds. Called internally by saveLayer. 993 // returns false if the entire rectangle is entirely clipped out 994 bool clipRectBounds(const SkRect* bounds, SaveFlags flags, 995 SkIRect* intersection); 996 997 // notify our surface (if we have one) that we are about to draw, so it 998 // can perform copy-on-write or invalidate any cached images 999 void predrawNotify(); 1000 1001 /** DEPRECATED -- use constructor(device) 1002 1003 Marked as 'protected' to avoid new clients using this before we can 1004 completely remove it. 1005 1006 Specify a device for this canvas to draw into. If it is not null, its 1007 reference count is incremented. If the canvas was already holding a 1008 device, its reference count is decremented. The new device is returned. 1009 */ 1010 virtual SkDevice* setDevice(SkDevice* device); 1011 1012 #ifdef SK_BUILD_FOR_ANDROID 1013 friend class WebCore::GaneshRenderer; 1014 friend class WebCore::RasterRenderer; 1015 #endif 1016 1017 private: 1018 class MCRec; 1019 1020 SkClipStack fClipStack; 1021 SkDeque fMCStack; 1022 // points to top of stack 1023 MCRec* fMCRec; 1024 // the first N recs that can fit here mean we won't call malloc 1025 uint32_t fMCRecStorage[32]; 1026 1027 SkBounder* fBounder; 1028 int fSaveLayerCount; // number of successful saveLayer calls 1029 1030 SkMetaData* fMetaData; 1031 1032 SkSurface_Base* fSurfaceBase; getSurfaceBase()1033 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; } setSurfaceBase(SkSurface_Base * sb)1034 void setSurfaceBase(SkSurface_Base* sb) { 1035 fSurfaceBase = sb; 1036 } 1037 friend class SkSurface_Base; 1038 1039 bool fDeviceCMDirty; // cleared by updateDeviceCMCache() 1040 void updateDeviceCMCache(); 1041 1042 friend class SkDrawIter; // needs setupDrawForLayerDevice() 1043 friend class AutoDrawLooper; 1044 1045 SkDevice* createLayerDevice(SkBitmap::Config, int width, int height, 1046 bool isOpaque); 1047 1048 SkDevice* init(SkDevice*); 1049 1050 // internal methods are not virtual, so they can safely be called by other 1051 // canvas apis, without confusing subclasses (like SkPictureRecording) 1052 void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m, 1053 const SkPaint* paint); 1054 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 1055 const SkRect& dst, const SkPaint* paint); 1056 void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 1057 const SkRect& dst, const SkPaint* paint); 1058 void internalDrawPaint(const SkPaint& paint); 1059 int internalSaveLayer(const SkRect* bounds, const SkPaint* paint, 1060 SaveFlags, bool justForImageFilter); 1061 void internalDrawDevice(SkDevice*, int x, int y, const SkPaint*); 1062 1063 // shared by save() and saveLayer() 1064 int internalSave(SaveFlags flags); 1065 void internalRestore(); 1066 static void DrawRect(const SkDraw& draw, const SkPaint& paint, 1067 const SkRect& r, SkScalar textSize); 1068 static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 1069 const char text[], size_t byteLength, 1070 SkScalar x, SkScalar y); 1071 1072 /* These maintain a cache of the clip bounds in local coordinates, 1073 (converted to 2s-compliment if floats are slow). 1074 */ 1075 mutable SkRectCompareType fLocalBoundsCompareType; 1076 mutable bool fLocalBoundsCompareTypeDirty; 1077 bool fAllowSoftClip; 1078 getLocalClipBoundsCompareType()1079 const SkRectCompareType& getLocalClipBoundsCompareType() const { 1080 if (fLocalBoundsCompareTypeDirty) { 1081 this->computeLocalClipBoundsCompareType(); 1082 fLocalBoundsCompareTypeDirty = false; 1083 } 1084 return fLocalBoundsCompareType; 1085 } 1086 void computeLocalClipBoundsCompareType() const; 1087 1088 class AutoValidateClip : ::SkNoncopyable { 1089 public: AutoValidateClip(SkCanvas * canvas)1090 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) { 1091 fCanvas->validateClip(); 1092 } ~AutoValidateClip()1093 ~AutoValidateClip() { fCanvas->validateClip(); } 1094 1095 private: 1096 const SkCanvas* fCanvas; 1097 }; 1098 1099 #ifdef SK_DEBUG 1100 void validateClip() const; 1101 #else validateClip()1102 void validateClip() const {} 1103 #endif 1104 1105 typedef SkRefCnt INHERITED; 1106 }; 1107 1108 /** Stack helper class to automatically call restoreToCount() on the canvas 1109 when this object goes out of scope. Use this to guarantee that the canvas 1110 is restored to a known state. 1111 */ 1112 class SkAutoCanvasRestore : SkNoncopyable { 1113 public: SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)1114 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) { 1115 SkASSERT(canvas); 1116 fSaveCount = canvas->getSaveCount(); 1117 if (doSave) { 1118 canvas->save(); 1119 } 1120 } ~SkAutoCanvasRestore()1121 ~SkAutoCanvasRestore() { 1122 if (fCanvas) { 1123 fCanvas->restoreToCount(fSaveCount); 1124 } 1125 } 1126 1127 /** 1128 * Perform the restore now, instead of waiting for the destructor. Will 1129 * only do this once. 1130 */ restore()1131 void restore() { 1132 if (fCanvas) { 1133 fCanvas->restoreToCount(fSaveCount); 1134 fCanvas = NULL; 1135 } 1136 } 1137 1138 private: 1139 SkCanvas* fCanvas; 1140 int fSaveCount; 1141 }; 1142 1143 #endif 1144