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