SkCanvas.h revision d302f1401b3c9aea094804bad4e76de98782cfe8
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 31class SkBounder; 32class SkDevice; 33class SkDeviceFactory; 34class SkDraw; 35class SkDrawFilter; 36class SkPicture; 37class 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*/ 54class SkCanvas : public SkRefCnt { 55public: 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 /** If the Device supports GL viewports, return true and set size (if not 79 null) to the size of the viewport. If it is not supported, ignore size 80 and return false. 81 */ 82 virtual bool getViewport(SkIPoint* size) const; 83 84 /** If the Device supports GL viewports, return true and set the viewport 85 to the specified x and y dimensions. If it is not supported, ignore x 86 and y and return false. 87 */ 88 virtual bool setViewport(int x, int y); 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 /** Specify a device for this canvas to draw into. If it is not null, its 97 reference count is incremented. If the canvas was already holding a 98 device, its reference count is decremented. The new device is returned. 99 */ 100 SkDevice* setDevice(SkDevice* device); 101 102 /** May be overridden by subclasses. This returns a compatible device 103 for this canvas, with the specified config/width/height. If the device 104 is raster, the pixels will be allocated automatically. 105 */ 106 virtual SkDevice* createDevice(SkBitmap::Config, int width, int height, 107 bool isOpaque, bool forLayer = false); 108 109 /** 110 * Create a new raster device and make it current. This also returns 111 * the new device. 112 */ 113 SkDevice* setBitmapDevice(const SkBitmap& bitmap, bool forLayer = false); 114 115 /** 116 * Return the current device factory, or NULL. 117 */ 118 SkDeviceFactory* getDeviceFactory() const { return fDeviceFactory; } 119 120 /** 121 * Replace any existing factory with the specified factory. 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 */ 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 /** Fill the entire canvas' bitmap (restricted to the current clip) with the 382 specified paint. 383 @param paint The paint used to fill the canvas 384 */ 385 virtual void drawPaint(const SkPaint& paint); 386 387 enum PointMode { 388 /** drawPoints draws each point separately */ 389 kPoints_PointMode, 390 /** drawPoints draws each pair of points as a line segment */ 391 kLines_PointMode, 392 /** drawPoints draws the array of points as a polygon */ 393 kPolygon_PointMode 394 }; 395 396 /** Draw a series of points, interpreted based on the PointMode mode. For 397 all modes, the count parameter is interpreted as the total number of 398 points. For kLine mode, count/2 line segments are drawn. 399 For kPoint mode, each point is drawn centered at its coordinate, and its 400 size is specified by the paint's stroke-width. It draws as a square, 401 unless the paint's cap-type is round, in which the points are drawn as 402 circles. 403 For kLine mode, each pair of points is drawn as a line segment, 404 respecting the paint's settings for cap/join/width. 405 For kPolygon mode, the entire array is drawn as a series of connected 406 line segments. 407 Note that, while similar, kLine and kPolygon modes draw slightly 408 differently than the equivalent path built with a series of moveto, 409 lineto calls, in that the path will draw all of its contours at once, 410 with no interactions if contours intersect each other (think XOR 411 xfermode). drawPoints always draws each element one at a time. 412 @param mode PointMode specifying how to draw the array of points. 413 @param count The number of points in the array 414 @param pts Array of points to draw 415 @param paint The paint used to draw the points 416 */ 417 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 418 const SkPaint& paint); 419 420 /** Helper method for drawing a single point. See drawPoints() for a more 421 details. 422 */ 423 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint); 424 425 /** Draws a single pixel in the specified color. 426 @param x The X coordinate of which pixel to draw 427 @param y The Y coordiante of which pixel to draw 428 @param color The color to draw 429 */ 430 void drawPoint(SkScalar x, SkScalar y, SkColor color); 431 432 /** Draw a line segment with the specified start and stop x,y coordinates, 433 using the specified paint. NOTE: since a line is always "framed", the 434 paint's Style is ignored. 435 @param x0 The x-coordinate of the start point of the line 436 @param y0 The y-coordinate of the start point of the line 437 @param x1 The x-coordinate of the end point of the line 438 @param y1 The y-coordinate of the end point of the line 439 @param paint The paint used to draw the line 440 */ 441 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 442 const SkPaint& paint); 443 444 /** Draw the specified rectangle using the specified paint. The rectangle 445 will be filled or stroked based on the Style in the paint. 446 @param rect The rect to be drawn 447 @param paint The paint used to draw the rect 448 */ 449 virtual void drawRect(const SkRect& rect, const SkPaint& paint); 450 451 /** Draw the specified rectangle using the specified paint. The rectangle 452 will be filled or framed based on the Style in the paint. 453 @param rect The rect to be drawn 454 @param paint The paint used to draw the rect 455 */ 456 void drawIRect(const SkIRect& rect, const SkPaint& paint) 457 { 458 SkRect r; 459 r.set(rect); // promotes the ints to scalars 460 this->drawRect(r, paint); 461 } 462 463 /** Draw the specified rectangle using the specified paint. The rectangle 464 will be filled or framed based on the Style in the paint. 465 @param left The left side of the rectangle to be drawn 466 @param top The top side of the rectangle to be drawn 467 @param right The right side of the rectangle to be drawn 468 @param bottom The bottom side of the rectangle to be drawn 469 @param paint The paint used to draw the rect 470 */ 471 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right, 472 SkScalar bottom, const SkPaint& paint); 473 474 /** Draw the specified oval using the specified paint. The oval will be 475 filled or framed based on the Style in the paint. 476 @param oval The rectangle bounds of the oval to be drawn 477 @param paint The paint used to draw the oval 478 */ 479 void drawOval(const SkRect& oval, const SkPaint&); 480 481 /** Draw the specified circle using the specified paint. If radius is <= 0, 482 then nothing will be drawn. The circle will be filled 483 or framed based on the Style in the paint. 484 @param cx The x-coordinate of the center of the cirle to be drawn 485 @param cy The y-coordinate of the center of the cirle to be drawn 486 @param radius The radius of the cirle to be drawn 487 @param paint The paint used to draw the circle 488 */ 489 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 490 const SkPaint& paint); 491 492 /** Draw the specified arc, which will be scaled to fit inside the 493 specified oval. If the sweep angle is >= 360, then the oval is drawn 494 completely. Note that this differs slightly from SkPath::arcTo, which 495 treats the sweep angle mod 360. 496 @param oval The bounds of oval used to define the shape of the arc 497 @param startAngle Starting angle (in degrees) where the arc begins 498 @param sweepAngle Sweep angle (in degrees) measured clockwise 499 @param useCenter true means include the center of the oval. For filling 500 this will draw a wedge. False means just use the arc. 501 @param paint The paint used to draw the arc 502 */ 503 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 504 bool useCenter, const SkPaint& paint); 505 506 /** Draw the specified round-rect using the specified paint. The round-rect 507 will be filled or framed based on the Style in the paint. 508 @param rect The rectangular bounds of the roundRect to be drawn 509 @param rx The x-radius of the oval used to round the corners 510 @param ry The y-radius of the oval used to round the corners 511 @param paint The paint used to draw the roundRect 512 */ 513 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, 514 const SkPaint& paint); 515 516 /** Draw the specified path using the specified paint. The path will be 517 filled or framed based on the Style in the paint. 518 @param path The path to be drawn 519 @param paint The paint used to draw the path 520 */ 521 virtual void drawPath(const SkPath& path, const SkPaint& paint); 522 523 /** Draw the specified bitmap, with its top/left corner at (x,y), using the 524 specified paint, transformed by the current matrix. Note: if the paint 525 contains a maskfilter that generates a mask which extends beyond the 526 bitmap's original width/height, then the bitmap will be drawn as if it 527 were in a Shader with CLAMP mode. Thus the color outside of the original 528 width/height will be the edge color replicated. 529 @param bitmap The bitmap to be drawn 530 @param left The position of the left side of the bitmap being drawn 531 @param top The position of the top side of the bitmap being drawn 532 @param paint The paint used to draw the bitmap, or NULL 533 */ 534 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 535 const SkPaint* paint = NULL); 536 537 /** Draw the specified bitmap, with the specified matrix applied (before the 538 canvas' matrix is applied). 539 @param bitmap The bitmap to be drawn 540 @param src Optional: specify the subset of the bitmap to be drawn 541 @param dst The destination rectangle where the scaled/translated 542 image will be drawn 543 @param paint The paint used to draw the bitmap, or NULL 544 */ 545 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, 546 const SkRect& dst, const SkPaint* paint = NULL); 547 548 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, 549 const SkPaint* paint = NULL); 550 551 /** Draw the specified bitmap, with its top/left corner at (x,y), 552 NOT transformed by the current matrix. Note: if the paint 553 contains a maskfilter that generates a mask which extends beyond the 554 bitmap's original width/height, then the bitmap will be drawn as if it 555 were in a Shader with CLAMP mode. Thus the color outside of the original 556 width/height will be the edge color replicated. 557 @param bitmap The bitmap to be drawn 558 @param left The position of the left side of the bitmap being drawn 559 @param top The position of the top side of the bitmap being drawn 560 @param paint The paint used to draw the bitmap, or NULL 561 */ 562 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 563 const SkPaint* paint = NULL); 564 565 /** Draw the text, with origin at (x,y), using the specified paint. 566 The origin is interpreted based on the Align setting in the paint. 567 @param text The text to be drawn 568 @param byteLength The number of bytes to read from the text parameter 569 @param x The x-coordinate of the origin of the text being drawn 570 @param y The y-coordinate of the origin of the text being drawn 571 @param paint The paint used for the text (e.g. color, size, style) 572 */ 573 virtual void drawText(const void* text, size_t byteLength, SkScalar x, 574 SkScalar y, const SkPaint& paint); 575 576 /** Draw the text, with each character/glyph origin specified by the pos[] 577 array. The origin is interpreted by the Align setting in the paint. 578 @param text The text to be drawn 579 @param byteLength The number of bytes to read from the text parameter 580 @param pos Array of positions, used to position each character 581 @param paint The paint used for the text (e.g. color, size, style) 582 */ 583 virtual void drawPosText(const void* text, size_t byteLength, 584 const SkPoint pos[], const SkPaint& paint); 585 586 /** Draw the text, with each character/glyph origin specified by the x 587 coordinate taken from the xpos[] array, and the y from the constY param. 588 The origin is interpreted by the Align setting in the paint. 589 @param text The text to be drawn 590 @param byteLength The number of bytes to read from the text parameter 591 @param xpos Array of x-positions, used to position each character 592 @param constY The shared Y coordinate for all of the positions 593 @param paint The paint used for the text (e.g. color, size, style) 594 */ 595 virtual void drawPosTextH(const void* text, size_t byteLength, 596 const SkScalar xpos[], SkScalar constY, 597 const SkPaint& paint); 598 599 /** Draw the text, with origin at (x,y), using the specified paint, along 600 the specified path. The paint's Align setting determins where along the 601 path to start the text. 602 @param text The text to be drawn 603 @param byteLength The number of bytes to read from the text parameter 604 @param path The path the text should follow for its baseline 605 @param hOffset The distance along the path to add to the text's 606 starting position 607 @param vOffset The distance above(-) or below(+) the path to 608 position the text 609 @param paint The paint used for the text 610 */ 611 void drawTextOnPathHV(const void* text, size_t byteLength, 612 const SkPath& path, SkScalar hOffset, 613 SkScalar vOffset, const SkPaint& paint); 614 615 /** Draw the text, with origin at (x,y), using the specified paint, along 616 the specified path. The paint's Align setting determins where along the 617 path to start the text. 618 @param text The text to be drawn 619 @param byteLength The number of bytes to read from the text parameter 620 @param path The path the text should follow for its baseline 621 @param matrix (may be null) Applied to the text before it is 622 mapped onto the path 623 @param paint The paint used for the text 624 */ 625 virtual void drawTextOnPath(const void* text, size_t byteLength, 626 const SkPath& path, const SkMatrix* matrix, 627 const SkPaint& paint); 628 629 /** Draw the picture into this canvas. This method effective brackets the 630 playback of the picture's draw calls with save/restore, so the state 631 of this canvas will be unchanged after this call. This contrasts with 632 the more immediate method SkPicture::draw(), which does not bracket 633 the canvas with save/restore, thus the canvas may be left in a changed 634 state after the call. 635 @param picture The recorded drawing commands to playback into this 636 canvas. 637 */ 638 virtual void drawPicture(SkPicture& picture); 639 640 /** Draws the specified shape 641 */ 642 virtual void drawShape(SkShape*); 643 644 enum VertexMode { 645 kTriangles_VertexMode, 646 kTriangleStrip_VertexMode, 647 kTriangleFan_VertexMode 648 }; 649 650 /** Draw the array of vertices, interpreted as triangles (based on mode). 651 @param vmode How to interpret the array of vertices 652 @param vertexCount The number of points in the vertices array (and 653 corresponding texs and colors arrays if non-null) 654 @param vertices Array of vertices for the mesh 655 @param texs May be null. If not null, specifies the coordinate 656 in texture space for each vertex. 657 @param colors May be null. If not null, specifies a color for each 658 vertex, to be interpolated across the triangle. 659 @param xmode Used if both texs and colors are present. In this 660 case the colors are combined with the texture using mode, 661 before being drawn using the paint. If mode is null, then 662 kMultiply_Mode is used. 663 @param indices If not null, array of indices to reference into the 664 vertex (texs, colors) array. 665 @param indexCount number of entries in the indices array (if not null) 666 @param paint Specifies the shader/texture if present. 667 */ 668 virtual void drawVertices(VertexMode vmode, int vertexCount, 669 const SkPoint vertices[], const SkPoint texs[], 670 const SkColor colors[], SkXfermode* xmode, 671 const uint16_t indices[], int indexCount, 672 const SkPaint& paint); 673 674 /** Send a blob of data to the canvas. 675 For canvases that draw, this call is effectively a no-op, as the data 676 is not parsed, but just ignored. However, this call exists for 677 subclasses like SkPicture's recording canvas, that can store the data 678 and then play it back later (via another call to drawData). 679 */ 680 virtual void drawData(const void* data, size_t length); 681 682 ////////////////////////////////////////////////////////////////////////// 683 684 /** Get the current bounder object. 685 The bounder's reference count is unchaged. 686 @return the canva's bounder (or NULL). 687 */ 688 SkBounder* getBounder() const { return fBounder; } 689 690 /** Set a new bounder (or NULL). 691 Pass NULL to clear any previous bounder. 692 As a convenience, the parameter passed is also returned. 693 If a previous bounder exists, its reference count is decremented. 694 If bounder is not NULL, its reference count is incremented. 695 @param bounder the new bounder (or NULL) to be installed in the canvas 696 @return the set bounder object 697 */ 698 virtual SkBounder* setBounder(SkBounder* bounder); 699 700 /** Get the current filter object. The filter's reference count is not 701 affected. The filter is saved/restored, just like the matrix and clip. 702 @return the canvas' filter (or NULL). 703 */ 704 SkDrawFilter* getDrawFilter() const; 705 706 /** Set the new filter (or NULL). Pass NULL to clear any existing filter. 707 As a convenience, the parameter is returned. If an existing filter 708 exists, its refcnt is decrement. If the new filter is not null, its 709 refcnt is incremented. The filter is saved/restored, just like the 710 matrix and clip. 711 @param filter the new filter (or NULL) 712 @return the new filter 713 */ 714 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter); 715 716 ////////////////////////////////////////////////////////////////////////// 717 718 /** Return the current matrix on the canvas. 719 This does not account for the translate in any of the devices. 720 @return The current matrix on the canvas. 721 */ 722 const SkMatrix& getTotalMatrix() const; 723 724 /** Return the current device clip (concatenation of all clip calls). 725 This does not account for the translate in any of the devices. 726 @return the current device clip (concatenation of all clip calls). 727 */ 728 const SkRegion& getTotalClip() const; 729 730 /** 731 * Return the current clipstack. This mirrors the result in getTotalClip() 732 * but is represented as a stack of geometric clips + region-ops. 733 */ 734 const SkClipStack& getTotalClipStack() const; 735 736 void setExternalMatrix(const SkMatrix* = NULL); 737 738 /////////////////////////////////////////////////////////////////////////// 739 740 /** After calling saveLayer(), there can be any number of devices that make 741 up the top-most drawing area. LayerIter can be used to iterate through 742 those devices. Note that the iterator is only valid until the next API 743 call made on the canvas. Ownership of all pointers in the iterator stays 744 with the canvas, so none of them should be modified or deleted. 745 */ 746 class LayerIter /*: SkNoncopyable*/ { 747 public: 748 /** Initialize iterator with canvas, and set values for 1st device */ 749 LayerIter(SkCanvas*, bool skipEmptyClips); 750 ~LayerIter(); 751 752 /** Return true if the iterator is done */ 753 bool done() const { return fDone; } 754 /** Cycle to the next device */ 755 void next(); 756 757 // These reflect the current device in the iterator 758 759 SkDevice* device() const; 760 const SkMatrix& matrix() const; 761 const SkRegion& clip() const; 762 const SkPaint& paint() const; 763 int x() const; 764 int y() const; 765 766 private: 767 // used to embed the SkDrawIter object directly in our instance, w/o 768 // having to expose that class def to the public. There is an assert 769 // in our constructor to ensure that fStorage is large enough 770 // (though needs to be a compile-time-assert!). We use intptr_t to work 771 // safely with 32 and 64 bit machines (to ensure the storage is enough) 772 intptr_t fStorage[32]; 773 class SkDrawIter* fImpl; // this points at fStorage 774 SkPaint fDefaultPaint; 775 bool fDone; 776 }; 777 778protected: 779 // all of the drawBitmap variants call this guy 780 virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*, 781 const SkMatrix&, const SkPaint& paint); 782 783private: 784 class MCRec; 785 786 SkClipStack fClipStack; 787 SkDeque fMCStack; 788 // points to top of stack 789 MCRec* fMCRec; 790 // the first N recs that can fit here mean we won't call malloc 791 uint32_t fMCRecStorage[32]; 792 793 SkBounder* fBounder; 794 SkDevice* fLastDeviceToGainFocus; 795 SkDeviceFactory* fDeviceFactory; 796 797 void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&, 798 const SkClipStack& clipStack); 799 800 bool fDeviceCMDirty; // cleared by updateDeviceCMCache() 801 void updateDeviceCMCache(); 802 803 friend class SkDrawIter; // needs setupDrawForLayerDevice() 804 805 SkDevice* init(SkDevice*); 806 void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m, 807 const SkPaint* paint); 808 void drawDevice(SkDevice*, int x, int y, const SkPaint*); 809 // shared by save() and saveLayer() 810 int internalSave(SaveFlags flags); 811 void internalRestore(); 812 813 /* These maintain a cache of the clip bounds in local coordinates, 814 (converted to 2s-compliment if floats are slow). 815 */ 816 mutable SkRectCompareType fLocalBoundsCompareType; 817 mutable bool fLocalBoundsCompareTypeDirty; 818 819 mutable SkRectCompareType fLocalBoundsCompareTypeBW; 820 mutable bool fLocalBoundsCompareTypeDirtyBW; 821 822 /* Get the local clip bounds with an anti-aliased edge. 823 */ 824 const SkRectCompareType& getLocalClipBoundsCompareType() const { 825 return getLocalClipBoundsCompareType(kAA_EdgeType); 826 } 827 828 const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const { 829 if (et == kAA_EdgeType) { 830 if (fLocalBoundsCompareTypeDirty) { 831 this->computeLocalClipBoundsCompareType(et); 832 fLocalBoundsCompareTypeDirty = false; 833 } 834 return fLocalBoundsCompareType; 835 } else { 836 if (fLocalBoundsCompareTypeDirtyBW) { 837 this->computeLocalClipBoundsCompareType(et); 838 fLocalBoundsCompareTypeDirtyBW = false; 839 } 840 return fLocalBoundsCompareTypeBW; 841 } 842 } 843 void computeLocalClipBoundsCompareType(EdgeType et) const; 844 845 SkMatrix fExternalMatrix, fExternalInverse; 846 bool fUseExternalMatrix; 847 848 class AutoValidateClip : ::SkNoncopyable { 849 public: 850 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) { 851 fCanvas->validateClip(); 852 } 853 ~AutoValidateClip() { fCanvas->validateClip(); } 854 855 private: 856 const SkCanvas* fCanvas; 857 }; 858 859#ifdef SK_DEBUG 860 void validateClip() const; 861#else 862 void validateClip() const {} 863#endif 864}; 865 866/** Stack helper class to automatically call restoreToCount() on the canvas 867 when this object goes out of scope. Use this to guarantee that the canvas 868 is restored to a known state. 869*/ 870class SkAutoCanvasRestore : SkNoncopyable { 871public: 872 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) { 873 SkASSERT(canvas); 874 fSaveCount = canvas->getSaveCount(); 875 if (doSave) { 876 canvas->save(); 877 } 878 } 879 ~SkAutoCanvasRestore() { 880 fCanvas->restoreToCount(fSaveCount); 881 } 882 883private: 884 SkCanvas* fCanvas; 885 int fSaveCount; 886}; 887 888#endif 889 890