1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SkCanvas_DEFINED 18 #define SkCanvas_DEFINED 19 20 #include "SkTypes.h" 21 #include "SkBitmap.h" 22 #include "SkDeque.h" 23 #include "SkPaint.h" 24 #include "SkRefCnt.h" 25 #include "SkPath.h" 26 #include "SkRegion.h" 27 #include "SkScalarCompare.h" 28 #include "SkXfermode.h" 29 30 class SkBounder; 31 class SkDevice; 32 class SkDraw; 33 class SkDrawFilter; 34 class SkPicture; 35 class SkShape; 36 37 /** \class SkCanvas 38 39 A Canvas encapsulates all of the state about drawing into a device (bitmap). 40 This includes a reference to the device itself, and a stack of matrix/clip 41 values. For any given draw call (e.g. drawRect), the geometry of the object 42 being drawn is transformed by the concatenation of all the matrices in the 43 stack. The transformed geometry is clipped by the intersection of all of 44 the clips in the stack. 45 46 While the Canvas holds the state of the drawing device, the state (style) 47 of the object being drawn is held by the Paint, which is provided as a 48 parameter to each of the draw() methods. The Paint holds attributes such as 49 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns), 50 etc. 51 */ 52 class SkCanvas : public SkRefCnt { 53 public: 54 /** Construct a canvas with the specified bitmap to draw into. 55 @param bitmap Specifies a bitmap for the canvas to draw into. Its 56 structure are copied to the canvas. 57 */ 58 explicit SkCanvas(const SkBitmap& bitmap); 59 /** Construct a canvas with the specified device to draw into. 60 @param device Specifies a device for the canvas to draw into. The 61 device may be null. 62 */ 63 explicit SkCanvas(SkDevice* device = NULL); 64 virtual ~SkCanvas(); 65 66 /////////////////////////////////////////////////////////////////////////// 67 68 /** If this subclass of SkCanvas supports GL viewports, return true and set 69 size (if not null) to the size of the viewport. If it is not supported, 70 ignore vp and return false. 71 */ 72 virtual bool getViewport(SkIPoint* size) const; 73 74 /** If this subclass of SkCanvas supports GL viewports, return true and set 75 the viewport to the specified x and y dimensions. If it is not 76 supported, ignore x and y and return false. 77 */ 78 virtual bool setViewport(int x, int y); 79 80 /** Return the canvas' device object, which may be null. The device holds 81 the bitmap of the pixels that the canvas draws into. The reference count 82 of the returned device is not changed by this call. 83 */ 84 SkDevice* getDevice() const; 85 86 /** Specify a device for this canvas to draw into. If it is not null, its 87 reference count is incremented. If the canvas was already holding a 88 device, its reference count is decremented. The new device is returned. 89 */ 90 SkDevice* setDevice(SkDevice* device); 91 92 /** Specify a bitmap for the canvas to draw into. This is a help method for 93 setDevice(), and it creates a device for the bitmap by calling 94 createDevice(). The structure of the bitmap is copied into the device. 95 */ 96 virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap); 97 98 /////////////////////////////////////////////////////////////////////////// 99 100 enum SaveFlags { 101 /** save the matrix state, restoring it on restore() */ 102 kMatrix_SaveFlag = 0x01, 103 /** save the clip state, restoring it on restore() */ 104 kClip_SaveFlag = 0x02, 105 /** the layer needs to support per-pixel alpha */ 106 kHasAlphaLayer_SaveFlag = 0x04, 107 /** the layer needs to support 8-bits per color component */ 108 kFullColorLayer_SaveFlag = 0x08, 109 /** the layer should clip against the bounds argument */ 110 kClipToLayer_SaveFlag = 0x10, 111 112 // helper masks for common choices 113 kMatrixClip_SaveFlag = 0x03, 114 kARGB_NoClipLayer_SaveFlag = 0x0F, 115 kARGB_ClipLayer_SaveFlag = 0x1F 116 }; 117 118 /** This call saves the current matrix, clip, and drawFilter, and pushes a 119 copy onto a private stack. Subsequent calls to translate, scale, 120 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all 121 operate on this copy. 122 When the balancing call to restore() is made, the previous matrix, clip, 123 and drawFilter are restored. 124 @return The value to pass to restoreToCount() to balance this save() 125 */ 126 virtual int save(SaveFlags flags = kMatrixClip_SaveFlag); 127 128 /** This behaves the same as save(), but in addition it allocates an 129 offscreen bitmap. All drawing calls are directed there, and only when 130 the balancing call to restore() is made is that offscreen transfered to 131 the canvas (or the previous layer). 132 @param bounds (may be null) the maximum size the offscreen bitmap needs 133 to be (in local coordinates) 134 @param paint (may be null) This is copied, and is applied to the 135 offscreen when restore() is called 136 @param flags LayerFlags 137 @return The value to pass to restoreToCount() to balance this save() 138 */ 139 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, 140 SaveFlags flags = kARGB_ClipLayer_SaveFlag); 141 142 /** This behaves the same as save(), but in addition it allocates an 143 offscreen bitmap. All drawing calls are directed there, and only when 144 the balancing call to restore() is made is that offscreen transfered to 145 the canvas (or the previous layer). 146 @param bounds (may be null) the maximum size the offscreen bitmap needs 147 to be (in local coordinates) 148 @param alpha This is applied to the offscreen when restore() is called. 149 @param flags LayerFlags 150 @return The value to pass to restoreToCount() to balance this save() 151 */ 152 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 153 SaveFlags flags = kARGB_ClipLayer_SaveFlag); 154 155 /** This call balances a previous call to save(), and is used to remove all 156 modifications to the matrix/clip/drawFilter state since the last save 157 call. 158 It is an error to call restore() more times than save() was called. 159 */ 160 virtual void restore(); 161 162 /** Returns the number of matrix/clip states on the SkCanvas' private stack. 163 This will equal # save() calls - # restore() calls. 164 */ 165 int getSaveCount() const; 166 167 /** Efficient way to pop any calls to save() that happened after the save 168 count reached saveCount. It is an error for saveCount to be less than 169 getSaveCount() 170 @param saveCount The number of save() levels to restore from 171 */ 172 void restoreToCount(int saveCount); 173 174 /** Preconcat the current matrix with the specified translation 175 @param dx The distance to translate in X 176 @param dy The distance to translate in Y 177 returns true if the operation succeeded (e.g. did not overflow) 178 */ 179 virtual bool translate(SkScalar dx, SkScalar dy); 180 181 /** Preconcat the current matrix with the specified scale. 182 @param sx The amount to scale in X 183 @param sy The amount to scale in Y 184 returns true if the operation succeeded (e.g. did not overflow) 185 */ 186 virtual bool scale(SkScalar sx, SkScalar sy); 187 188 /** Preconcat the current matrix with the specified rotation. 189 @param degrees The amount to rotate, in degrees 190 returns true if the operation succeeded (e.g. did not overflow) 191 */ 192 virtual bool rotate(SkScalar degrees); 193 194 /** Preconcat the current matrix with the specified skew. 195 @param sx The amount to skew in X 196 @param sy The amount to skew in Y 197 returns true if the operation succeeded (e.g. did not overflow) 198 */ 199 virtual bool skew(SkScalar sx, SkScalar sy); 200 201 /** Preconcat the current matrix with the specified matrix. 202 @param matrix The matrix to preconcatenate with the current matrix 203 @return true if the operation succeeded (e.g. did not overflow) 204 */ 205 virtual bool concat(const SkMatrix& matrix); 206 207 /** Replace the current matrix with a copy of the specified matrix. 208 @param matrix The matrix that will be copied into the current matrix. 209 */ 210 virtual void setMatrix(const SkMatrix& matrix); 211 212 /** Helper for setMatrix(identity). Sets the current matrix to identity. 213 */ 214 void resetMatrix(); 215 216 /** Modify the current clip with the specified rectangle. 217 @param rect The rect to intersect with the current clip 218 @param op The region op to apply to the current clip 219 @return true if the canvas' clip is non-empty 220 */ 221 virtual bool clipRect(const SkRect& rect, 222 SkRegion::Op op = SkRegion::kIntersect_Op); 223 224 /** Modify the current clip with the specified path. 225 @param path The path to apply to the current clip 226 @param op The region op to apply to the current clip 227 @return true if the canvas' new clip is non-empty 228 */ 229 virtual bool clipPath(const SkPath& path, 230 SkRegion::Op op = SkRegion::kIntersect_Op); 231 232 /** Modify the current clip with the specified region. Note that unlike 233 clipRect() and clipPath() which transform their arguments by the current 234 matrix, clipRegion() assumes its argument is already in device 235 coordinates, and so no transformation is performed. 236 @param deviceRgn The region to apply to the current clip 237 @param op The region op to apply to the current clip 238 @return true if the canvas' new clip is non-empty 239 */ 240 virtual bool clipRegion(const SkRegion& deviceRgn, 241 SkRegion::Op op = SkRegion::kIntersect_Op); 242 243 /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the 244 specified region. This does not intersect or in any other way account 245 for the existing clip region. 246 @param deviceRgn The region to copy into the current clip. 247 @return true if the new clip region is non-empty 248 */ setClipRegion(const SkRegion & deviceRgn)249 bool setClipRegion(const SkRegion& deviceRgn) { 250 return this->clipRegion(deviceRgn, SkRegion::kReplace_Op); 251 } 252 253 /** Enum describing how to treat edges when performing quick-reject tests 254 of a geometry against the current clip. Treating them as antialiased 255 (kAA_EdgeType) will take into account the extra pixels that may be drawn 256 if the edge does not lie exactly on a device pixel boundary (after being 257 transformed by the current matrix). 258 */ 259 enum EdgeType { 260 /** Treat the edges as B&W (not antialiased) for the purposes of testing 261 against the current clip 262 */ 263 kBW_EdgeType, 264 /** Treat the edges as antialiased for the purposes of testing 265 against the current clip 266 */ 267 kAA_EdgeType 268 }; 269 270 /** Return true if the specified rectangle, after being transformed by the 271 current matrix, would lie completely outside of the current clip. Call 272 this to check if an area you intend to draw into is clipped out (and 273 therefore you can skip making the draw calls). 274 @param rect the rect to compare with the current clip 275 @param et specifies how to treat the edges (see EdgeType) 276 @return true if the rect (transformed by the canvas' matrix) does not 277 intersect with the canvas' clip 278 */ 279 bool quickReject(const SkRect& rect, EdgeType et) const; 280 281 /** Return true if the specified path, after being transformed by the 282 current matrix, would lie completely outside of the current clip. Call 283 this to check if an area you intend to draw into is clipped out (and 284 therefore you can skip making the draw calls). Note, for speed it may 285 return false even if the path itself might not intersect the clip 286 (i.e. the bounds of the path intersects, but the path does not). 287 @param path The path to compare with the current clip 288 @param et specifies how to treat the edges (see EdgeType) 289 @return true if the path (transformed by the canvas' matrix) does not 290 intersect with the canvas' clip 291 */ 292 bool quickReject(const SkPath& path, EdgeType et) const; 293 294 /** Return true if the horizontal band specified by top and bottom is 295 completely clipped out. This is a conservative calculation, meaning 296 that it is possible that if the method returns false, the band may still 297 in fact be clipped out, but the converse is not true. If this method 298 returns true, then the band is guaranteed to be clipped out. 299 @param top The top of the horizontal band to compare with the clip 300 @param bottom The bottom of the horizontal and to compare with the clip 301 @return true if the horizontal band is completely clipped out (i.e. does 302 not intersect the current clip) 303 */ 304 bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const; 305 306 /** Return the bounds of the current clip (in local coordinates) in the 307 bounds parameter, and return true if it is non-empty. This can be useful 308 in a way similar to quickReject, in that it tells you that drawing 309 outside of these bounds will be clipped out. 310 */ 311 bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const; 312 313 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 314 specified ARGB color, using the specified mode. 315 @param a the alpha component (0..255) of the color to fill the canvas 316 @param r the red component (0..255) of the color to fill the canvas 317 @param g the green component (0..255) of the color to fill the canvas 318 @param b the blue component (0..255) of the color to fill the canvas 319 @param mode the mode to apply the color in (defaults to SrcOver) 320 */ 321 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 322 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); 323 324 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 325 specified color and mode. 326 @param color the color to draw with 327 @param mode the mode to apply the color in (defaults to SrcOver) 328 */ 329 void drawColor(SkColor color, 330 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); 331 332 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 333 specified paint. 334 @param paint The paint used to fill the canvas 335 */ 336 virtual void drawPaint(const SkPaint& paint); 337 338 enum PointMode { 339 /** drawPoints draws each point separately */ 340 kPoints_PointMode, 341 /** drawPoints draws each pair of points as a line segment */ 342 kLines_PointMode, 343 /** drawPoints draws the array of points as a polygon */ 344 kPolygon_PointMode 345 }; 346 347 /** Draw a series of points, interpreted based on the PointMode mode. For 348 all modes, the count parameter is interpreted as the total number of 349 points. For kLine mode, count/2 line segments are drawn. 350 For kPoint mode, each point is drawn centered at its coordinate, and its 351 size is specified by the paint's stroke-width. It draws as a square, 352 unless the paint's cap-type is round, in which the points are drawn as 353 circles. 354 For kLine mode, each pair of points is drawn as a line segment, 355 respecting the paint's settings for cap/join/width. 356 For kPolygon mode, the entire array is drawn as a series of connected 357 line segments. 358 Note that, while similar, kLine and kPolygon modes draw slightly 359 differently than the equivalent path built with a series of moveto, 360 lineto calls, in that the path will draw all of its contours at once, 361 with no interactions if contours intersect each other (think XOR 362 xfermode). drawPoints always draws each element one at a time. 363 @param mode PointMode specifying how to draw the array of points. 364 @param count The number of points in the array 365 @param pts Array of points to draw 366 @param paint The paint used to draw the points 367 */ 368 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 369 const SkPaint& paint); 370 371 /** Helper method for drawing a single point. See drawPoints() for a more 372 details. 373 */ 374 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint); 375 376 /** Draws a single pixel in the specified color. 377 @param x The X coordinate of which pixel to draw 378 @param y The Y coordiante of which pixel to draw 379 @param color The color to draw 380 */ 381 void drawPoint(SkScalar x, SkScalar y, SkColor color); 382 383 /** Draw a line segment with the specified start and stop x,y coordinates, 384 using the specified paint. NOTE: since a line is always "framed", the 385 paint's Style is ignored. 386 @param x0 The x-coordinate of the start point of the line 387 @param y0 The y-coordinate of the start point of the line 388 @param x1 The x-coordinate of the end point of the line 389 @param y1 The y-coordinate of the end point of the line 390 @param paint The paint used to draw the line 391 */ 392 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 393 const SkPaint& paint); 394 395 /** Draw the specified rectangle using the specified paint. The rectangle 396 will be filled or stroked based on the Style in the paint. 397 @param rect The rect to be drawn 398 @param paint The paint used to draw the rect 399 */ 400 virtual void drawRect(const SkRect& rect, const SkPaint& paint); 401 402 /** Draw the specified rectangle using the specified paint. The rectangle 403 will be filled or framed based on the Style in the paint. 404 @param rect The rect to be drawn 405 @param paint The paint used to draw the rect 406 */ drawIRect(const SkIRect & rect,const SkPaint & paint)407 void drawIRect(const SkIRect& rect, const SkPaint& paint) 408 { 409 SkRect r; 410 r.set(rect); // promotes the ints to scalars 411 this->drawRect(r, paint); 412 } 413 414 /** Draw the specified rectangle using the specified paint. The rectangle 415 will be filled or framed based on the Style in the paint. 416 @param left The left side of the rectangle to be drawn 417 @param top The top side of the rectangle to be drawn 418 @param right The right side of the rectangle to be drawn 419 @param bottom The bottom side of the rectangle to be drawn 420 @param paint The paint used to draw the rect 421 */ 422 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right, 423 SkScalar bottom, const SkPaint& paint); 424 425 /** Draw the specified oval using the specified paint. The oval will be 426 filled or framed based on the Style in the paint. 427 @param oval The rectangle bounds of the oval to be drawn 428 @param paint The paint used to draw the oval 429 */ 430 void drawOval(const SkRect& oval, const SkPaint&); 431 432 /** Draw the specified circle using the specified paint. If radius is <= 0, 433 then nothing will be drawn. The circle will be filled 434 or framed based on the Style in the paint. 435 @param cx The x-coordinate of the center of the cirle to be drawn 436 @param cy The y-coordinate of the center of the cirle to be drawn 437 @param radius The radius of the cirle to be drawn 438 @param paint The paint used to draw the circle 439 */ 440 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 441 const SkPaint& paint); 442 443 /** Draw the specified arc, which will be scaled to fit inside the 444 specified oval. If the sweep angle is >= 360, then the oval is drawn 445 completely. Note that this differs slightly from SkPath::arcTo, which 446 treats the sweep angle mod 360. 447 @param oval The bounds of oval used to define the shape of the arc 448 @param startAngle Starting angle (in degrees) where the arc begins 449 @param sweepAngle Sweep angle (in degrees) measured clockwise 450 @param useCenter true means include the center of the oval. For filling 451 this will draw a wedge. False means just use the arc. 452 @param paint The paint used to draw the arc 453 */ 454 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 455 bool useCenter, const SkPaint& paint); 456 457 /** Draw the specified round-rect using the specified paint. The round-rect 458 will be filled or framed based on the Style in the paint. 459 @param rect The rectangular bounds of the roundRect to be drawn 460 @param rx The x-radius of the oval used to round the corners 461 @param ry The y-radius of the oval used to round the corners 462 @param paint The paint used to draw the roundRect 463 */ 464 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, 465 const SkPaint& paint); 466 467 /** Draw the specified path using the specified paint. The path will be 468 filled or framed based on the Style in the paint. 469 @param path The path to be drawn 470 @param paint The paint used to draw the path 471 */ 472 virtual void drawPath(const SkPath& path, const SkPaint& paint); 473 474 /** Draw the specified bitmap, with its top/left corner at (x,y), using the 475 specified paint, transformed by the current matrix. Note: if the paint 476 contains a maskfilter that generates a mask which extends beyond the 477 bitmap's original width/height, then the bitmap will be drawn as if it 478 were in a Shader with CLAMP mode. Thus the color outside of the original 479 width/height will be the edge color replicated. 480 @param bitmap The bitmap to be drawn 481 @param left The position of the left side of the bitmap being drawn 482 @param top The position of the top side of the bitmap being drawn 483 @param paint The paint used to draw the bitmap, or NULL 484 */ 485 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 486 const SkPaint* paint = NULL); 487 488 /** Draw the specified bitmap, with the specified matrix applied (before the 489 canvas' matrix is applied). 490 @param bitmap The bitmap to be drawn 491 @param src Optional: specify the subset of the bitmap to be drawn 492 @param dst The destination rectangle where the scaled/translated 493 image will be drawn 494 @param paint The paint used to draw the bitmap, or NULL 495 */ 496 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, 497 const SkRect& dst, const SkPaint* paint = NULL); 498 499 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, 500 const SkPaint* paint = NULL); 501 502 /** Draw the specified bitmap, with its top/left corner at (x,y), 503 NOT transformed by the current matrix. Note: if the paint 504 contains a maskfilter that generates a mask which extends beyond the 505 bitmap's original width/height, then the bitmap will be drawn as if it 506 were in a Shader with CLAMP mode. Thus the color outside of the original 507 width/height will be the edge color replicated. 508 @param bitmap The bitmap to be drawn 509 @param left The position of the left side of the bitmap being drawn 510 @param top The position of the top side of the bitmap being drawn 511 @param paint The paint used to draw the bitmap, or NULL 512 */ 513 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 514 const SkPaint* paint = NULL); 515 516 /** Draw the text, with origin at (x,y), using the specified paint. 517 The origin is interpreted based on the Align setting in the paint. 518 @param text The text to be drawn 519 @param byteLength The number of bytes to read from the text parameter 520 @param x The x-coordinate of the origin of the text being drawn 521 @param y The y-coordinate of the origin of the text being drawn 522 @param paint The paint used for the text (e.g. color, size, style) 523 */ 524 virtual void drawText(const void* text, size_t byteLength, SkScalar x, 525 SkScalar y, const SkPaint& paint); 526 527 /** Draw the text, with each character/glyph origin specified by the pos[] 528 array. The origin is interpreted by the Align setting in the paint. 529 @param text The text to be drawn 530 @param byteLength The number of bytes to read from the text parameter 531 @param pos Array of positions, used to position each character 532 @param paint The paint used for the text (e.g. color, size, style) 533 */ 534 virtual void drawPosText(const void* text, size_t byteLength, 535 const SkPoint pos[], const SkPaint& paint); 536 537 /** Draw the text, with each character/glyph origin specified by the x 538 coordinate taken from the xpos[] array, and the y from the constY param. 539 The origin is interpreted by the Align setting in the paint. 540 @param text The text to be drawn 541 @param byteLength The number of bytes to read from the text parameter 542 @param xpos Array of x-positions, used to position each character 543 @param constY The shared Y coordinate for all of the positions 544 @param paint The paint used for the text (e.g. color, size, style) 545 */ 546 virtual void drawPosTextH(const void* text, size_t byteLength, 547 const SkScalar xpos[], SkScalar constY, 548 const SkPaint& paint); 549 550 /** Draw the text, with origin at (x,y), using the specified paint, along 551 the specified path. The paint's Align setting determins where along the 552 path to start the text. 553 @param text The text to be drawn 554 @param byteLength The number of bytes to read from the text parameter 555 @param path The path the text should follow for its baseline 556 @param hOffset The distance along the path to add to the text's 557 starting position 558 @param vOffset The distance above(-) or below(+) the path to 559 position the text 560 @param paint The paint used for the text 561 */ 562 void drawTextOnPathHV(const void* text, size_t byteLength, 563 const SkPath& path, SkScalar hOffset, 564 SkScalar vOffset, const SkPaint& paint); 565 566 /** Draw the text, with origin at (x,y), using the specified paint, along 567 the specified path. The paint's Align setting determins where along the 568 path to start the text. 569 @param text The text to be drawn 570 @param byteLength The number of bytes to read from the text parameter 571 @param path The path the text should follow for its baseline 572 @param matrix (may be null) Applied to the text before it is 573 mapped onto the path 574 @param paint The paint used for the text 575 */ 576 virtual void drawTextOnPath(const void* text, size_t byteLength, 577 const SkPath& path, const SkMatrix* matrix, 578 const SkPaint& paint); 579 580 /** Draw the text on path, with each character/glyph origin specified by the pos[] 581 array. The origin is interpreted by the Align setting in the paint. 582 @param text The text to be drawn 583 @param byteLength The number of bytes to read from the text parameter 584 @param pos Array of positions, used to position each character 585 @param paint The paint used for the text (e.g. color, size, style) 586 @param path The path to draw on 587 @param matrix The canvas matrix 588 */ 589 void drawPosTextOnPath(const void* text, size_t byteLength, 590 const SkPoint pos[], const SkPaint& paint, 591 const SkPath& path, const SkMatrix* matrix); 592 593 /** Draw the picture into this canvas. This method effective brackets the 594 playback of the picture's draw calls with save/restore, so the state 595 of this canvas will be unchanged after this call. This contrasts with 596 the more immediate method SkPicture::draw(), which does not bracket 597 the canvas with save/restore, thus the canvas may be left in a changed 598 state after the call. 599 @param picture The recorded drawing commands to playback into this 600 canvas. 601 */ 602 virtual void drawPicture(SkPicture& picture); 603 604 /** Draws the specified shape 605 */ 606 virtual void drawShape(SkShape*); 607 608 enum VertexMode { 609 kTriangles_VertexMode, 610 kTriangleStrip_VertexMode, 611 kTriangleFan_VertexMode 612 }; 613 614 /** Draw the array of vertices, interpreted as triangles (based on mode). 615 @param vmode How to interpret the array of vertices 616 @param vertexCount The number of points in the vertices array (and 617 corresponding texs and colors arrays if non-null) 618 @param vertices Array of vertices for the mesh 619 @param texs May be null. If not null, specifies the coordinate 620 in texture space for each vertex. 621 @param colors May be null. If not null, specifies a color for each 622 vertex, to be interpolated across the triangle. 623 @param xmode Used if both texs and colors are present. In this 624 case the colors are combined with the texture using mode, 625 before being drawn using the paint. If mode is null, then 626 kMultiply_Mode is used. 627 @param indices If not null, array of indices to reference into the 628 vertex (texs, colors) array. 629 @param indexCount number of entries in the indices array (if not null) 630 @param paint Specifies the shader/texture if present. 631 */ 632 virtual void drawVertices(VertexMode vmode, int vertexCount, 633 const SkPoint vertices[], const SkPoint texs[], 634 const SkColor colors[], SkXfermode* xmode, 635 const uint16_t indices[], int indexCount, 636 const SkPaint& paint); 637 638 /** Send a blob of data to the canvas. 639 For canvases that draw, this call is effectively a no-op, as the data 640 is not parsed, but just ignored. However, this call exists for 641 subclasses like SkPicture's recording canvas, that can store the data 642 and then play it back later (via another call to drawData). 643 */ 644 virtual void drawData(const void* data, size_t length); 645 646 ////////////////////////////////////////////////////////////////////////// 647 648 /** Get the current bounder object. 649 The bounder's reference count is unchaged. 650 @return the canva's bounder (or NULL). 651 */ getBounder()652 SkBounder* getBounder() const { return fBounder; } 653 654 /** Set a new bounder (or NULL). 655 Pass NULL to clear any previous bounder. 656 As a convenience, the parameter passed is also returned. 657 If a previous bounder exists, its reference count is decremented. 658 If bounder is not NULL, its reference count is incremented. 659 @param bounder the new bounder (or NULL) to be installed in the canvas 660 @return the set bounder object 661 */ 662 virtual SkBounder* setBounder(SkBounder* bounder); 663 664 /** Get the current filter object. The filter's reference count is not 665 affected. The filter is saved/restored, just like the matrix and clip. 666 @return the canvas' filter (or NULL). 667 */ 668 SkDrawFilter* getDrawFilter() const; 669 670 /** Set the new filter (or NULL). Pass NULL to clear any existing filter. 671 As a convenience, the parameter is returned. If an existing filter 672 exists, its refcnt is decrement. If the new filter is not null, its 673 refcnt is incremented. The filter is saved/restored, just like the 674 matrix and clip. 675 @param filter the new filter (or NULL) 676 @return the new filter 677 */ 678 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); 679 680 ////////////////////////////////////////////////////////////////////////// 681 682 /** Return the current matrix on the canvas. 683 This does not account for the translate in any of the devices. 684 @return The current matrix on the canvas. 685 */ 686 const SkMatrix& getTotalMatrix() const; 687 688 /** Return the current device clip (concatenation of all clip calls). 689 This does not account for the translate in any of the devices. 690 @return the current device clip (concatenation of all clip calls). 691 */ 692 const SkRegion& getTotalClip() const; 693 694 /** May be overridden by subclasses. This returns a compatible device 695 for this canvas, with the specified config/width/height. If isOpaque 696 is true, then the underlying bitmap is optimized to assume that every 697 pixel will be drawn to, and thus it does not need to clear the alpha 698 channel ahead of time (assuming the specified config supports per-pixel 699 alpha.) If isOpaque is false, then the bitmap should clear its alpha 700 channel. 701 */ 702 virtual SkDevice* createDevice(SkBitmap::Config, int width, int height, 703 bool isOpaque, bool isForLayer); 704 705 /////////////////////////////////////////////////////////////////////////// 706 707 /** After calling saveLayer(), there can be any number of devices that make 708 up the top-most drawing area. LayerIter can be used to iterate through 709 those devices. Note that the iterator is only valid until the next API 710 call made on the canvas. Ownership of all pointers in the iterator stays 711 with the canvas, so none of them should be modified or deleted. 712 */ 713 class LayerIter /*: SkNoncopyable*/ { 714 public: 715 /** Initialize iterator with canvas, and set values for 1st device */ 716 LayerIter(SkCanvas*, bool skipEmptyClips); 717 ~LayerIter(); 718 719 /** Return true if the iterator is done */ done()720 bool done() const { return fDone; } 721 /** Cycle to the next device */ 722 void next(); 723 724 // These reflect the current device in the iterator 725 726 SkDevice* device() const; 727 const SkMatrix& matrix() const; 728 const SkRegion& clip() const; 729 const SkPaint& paint() const; 730 int x() const; 731 int y() const; 732 733 private: 734 // used to embed the SkDrawIter object directly in our instance, w/o 735 // having to expose that class def to the public. There is an assert 736 // in our constructor to ensure that fStorage is large enough 737 // (though needs to be a compile-time-assert!). We use intptr_t to work 738 // safely with 32 and 64 bit machines (to ensure the storage is enough) 739 intptr_t fStorage[12]; 740 class SkDrawIter* fImpl; // this points at fStorage 741 SkPaint fDefaultPaint; 742 bool fDone; 743 }; 744 745 protected: 746 // all of the drawBitmap variants call this guy 747 virtual void commonDrawBitmap(const SkBitmap&, const SkMatrix& m, 748 const SkPaint& paint); 749 750 private: 751 class MCRec; 752 753 SkDeque fMCStack; 754 // points to top of stack 755 MCRec* fMCRec; 756 // the first N recs that can fit here mean we won't call malloc 757 uint32_t fMCRecStorage[32]; 758 759 SkBounder* fBounder; 760 SkDevice* fLastDeviceToGainFocus; 761 762 void prepareForDeviceDraw(SkDevice*); 763 764 bool fDeviceCMDirty; // cleared by updateDeviceCMCache() 765 void updateDeviceCMCache(); 766 767 friend class SkDrawIter; // needs setupDrawForLayerDevice() 768 769 SkDevice* init(SkDevice*); 770 void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, 771 const SkPaint* paint); 772 void drawDevice(SkDevice*, int x, int y, const SkPaint*); 773 // shared by save() and saveLayer() 774 int internalSave(SaveFlags flags); 775 void internalRestore(); 776 777 /* These maintain a cache of the clip bounds in local coordinates, 778 (converted to 2s-compliment if floats are slow). 779 */ 780 mutable SkRectCompareType fLocalBoundsCompareType; 781 mutable bool fLocalBoundsCompareTypeDirty; 782 783 mutable SkRectCompareType fLocalBoundsCompareTypeBW; 784 mutable bool fLocalBoundsCompareTypeDirtyBW; 785 786 /* Get the local clip bounds with an anti-aliased edge. 787 */ getLocalClipBoundsCompareType()788 const SkRectCompareType& getLocalClipBoundsCompareType() const { 789 return getLocalClipBoundsCompareType(kAA_EdgeType); 790 } 791 getLocalClipBoundsCompareType(EdgeType et)792 const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const { 793 if (et == kAA_EdgeType) { 794 if (fLocalBoundsCompareTypeDirty) { 795 this->computeLocalClipBoundsCompareType(et); 796 fLocalBoundsCompareTypeDirty = false; 797 } 798 return fLocalBoundsCompareType; 799 } else { 800 if (fLocalBoundsCompareTypeDirtyBW) { 801 this->computeLocalClipBoundsCompareType(et); 802 fLocalBoundsCompareTypeDirtyBW = false; 803 } 804 return fLocalBoundsCompareTypeBW; 805 } 806 } 807 void computeLocalClipBoundsCompareType(EdgeType et) const; 808 }; 809 810 /** Stack helper class to automatically call restoreToCount() on the canvas 811 when this object goes out of scope. Use this to guarantee that the canvas 812 is restored to a known state. 813 */ 814 class SkAutoCanvasRestore : SkNoncopyable { 815 public: SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)816 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) { 817 SkASSERT(canvas); 818 fSaveCount = canvas->getSaveCount(); 819 if (doSave) { 820 canvas->save(); 821 } 822 } ~SkAutoCanvasRestore()823 ~SkAutoCanvasRestore() { 824 fCanvas->restoreToCount(fSaveCount); 825 } 826 827 private: 828 SkCanvas* fCanvas; 829 int fSaveCount; 830 }; 831 832 #endif 833 834