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