aboutsummaryrefslogtreecommitdiffstats
path: root/include/core/SkCanvas.h
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:35 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:35 -0800
commit0910916c0f7b951ee55c4b7c6358295b9bca0565 (patch)
tree059e9645510636ae148ba4594b3d6009918655e2 /include/core/SkCanvas.h
parent6eb364108744656fcd23a96a478aa772cd4e85bc (diff)
downloadexternal_skia-0910916c0f7b951ee55c4b7c6358295b9bca0565.zip
external_skia-0910916c0f7b951ee55c4b7c6358295b9bca0565.tar.gz
external_skia-0910916c0f7b951ee55c4b7c6358295b9bca0565.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'include/core/SkCanvas.h')
-rw-r--r--include/core/SkCanvas.h794
1 files changed, 794 insertions, 0 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
new file mode 100644
index 0000000..a19a5ae
--- /dev/null
+++ b/include/core/SkCanvas.h
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkCanvas_DEFINED
+#define SkCanvas_DEFINED
+
+#include "SkTypes.h"
+#include "SkBitmap.h"
+#include "SkDeque.h"
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+#include "SkPorterDuff.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+#include "SkScalarCompare.h"
+
+class SkBounder;
+class SkDevice;
+class SkDraw;
+class SkDrawFilter;
+class SkPicture;
+
+/** \class SkCanvas
+
+ A Canvas encapsulates all of the state about drawing into a device (bitmap).
+ This includes a reference to the device itself, and a stack of matrix/clip
+ values. For any given draw call (e.g. drawRect), the geometry of the object
+ being drawn is transformed by the concatenation of all the matrices in the
+ stack. The transformed geometry is clipped by the intersection of all of
+ the clips in the stack.
+
+ While the Canvas holds the state of the drawing device, the state (style)
+ of the object being drawn is held by the Paint, which is provided as a
+ parameter to each of the draw() methods. The Paint holds attributes such as
+ color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
+ etc.
+*/
+class SkCanvas : public SkRefCnt {
+public:
+ /** Construct a canvas with the specified bitmap to draw into.
+ @param bitmap Specifies a bitmap for the canvas to draw into. Its
+ structure are copied to the canvas.
+ */
+ explicit SkCanvas(const SkBitmap& bitmap);
+ /** Construct a canvas with the specified device to draw into.
+ @param device Specifies a device for the canvas to draw into. The
+ device may be null.
+ */
+ explicit SkCanvas(SkDevice* device = NULL);
+ virtual ~SkCanvas();
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** If this subclass of SkCanvas supports GL viewports, return true and set
+ size (if not null) to the size of the viewport. If it is not supported,
+ ignore vp and return false.
+ */
+ virtual bool getViewport(SkIPoint* size) const;
+
+ /** If this subclass of SkCanvas supports GL viewports, return true and set
+ the viewport to the specified x and y dimensions. If it is not
+ supported, ignore x and y and return false.
+ */
+ virtual bool setViewport(int x, int y);
+
+ /** Return the canvas' device object, which may be null. The device holds
+ the bitmap of the pixels that the canvas draws into. The reference count
+ of the returned device is not changed by this call.
+ */
+ SkDevice* getDevice() const;
+
+ /** Specify a device for this canvas to draw into. If it is not null, its
+ reference count is incremented. If the canvas was already holding a
+ device, its reference count is decremented. The new device is returned.
+ */
+ SkDevice* setDevice(SkDevice* device);
+
+ /** Specify a bitmap for the canvas to draw into. This is a help method for
+ setDevice(), and it creates a device for the bitmap by calling
+ createDevice(). The structure of the bitmap is copied into the device.
+ */
+ virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ enum SaveFlags {
+ /** save the matrix state, restoring it on restore() */
+ kMatrix_SaveFlag = 0x01,
+ /** save the clip state, restoring it on restore() */
+ kClip_SaveFlag = 0x02,
+ /** the layer needs to support per-pixel alpha */
+ kHasAlphaLayer_SaveFlag = 0x04,
+ /** the layer needs to support 8-bits per color component */
+ kFullColorLayer_SaveFlag = 0x08,
+ /** the layer should clip against the bounds argument */
+ kClipToLayer_SaveFlag = 0x10,
+
+ // helper masks for common choices
+ kMatrixClip_SaveFlag = 0x03,
+ kARGB_NoClipLayer_SaveFlag = 0x0F,
+ kARGB_ClipLayer_SaveFlag = 0x1F
+ };
+
+ /** This call saves the current matrix and clip information, and pushes a
+ copy onto a private stack. Subsequent calls to translate, scale,
+ rotate, skew, concat or clipRect, clipPath all operate on this copy.
+ When the balancing call to restore() is made, this copy is deleted and
+ the previous matrix/clip state is restored.
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
+
+ /** This behaves the same as save(), but in addition it allocates an
+ offscreen bitmap. All drawing calls are directed there, and only when
+ the balancing call to restore() is made is that offscreen transfered to
+ the canvas (or the previous layer). Subsequent calls to translate,
+ scale, rotate, skew, concat or clipRect, clipPath all operate on this
+ copy. When the balancing call to restore() is made, this copy is deleted
+ and the previous matrix/clip state is restored.
+ @param bounds (may be null) the maximum size the offscreen bitmap needs
+ to be (in local coordinates)
+ @param paint (may be null) This is copied, and is applied to the
+ offscreen when restore() is called
+ @param flags LayerFlags
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag);
+
+ /** This behaves the same as save(), but in addition it allocates an
+ offscreen bitmap. All drawing calls are directed there, and only when
+ the balancing call to restore() is made is that offscreen transfered to
+ the canvas (or the previous layer). Subsequent calls to translate,
+ scale, rotate, skew, concat or clipRect, clipPath all operate on this
+ copy. When the balancing call to restore() is made, this copy is deleted
+ and the previous matrix/clip state is restored.
+ @param bounds (may be null) the maximum size the offscreen bitmap needs
+ to be (in local coordinates)
+ @param alpha This is applied to the offscreen when restore() is called.
+ @param flags LayerFlags
+ @return The value to pass to restoreToCount() to balance this save()
+ */
+ int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag);
+
+ /** This call balances a previous call to save(), and is used to remove all
+ modifications to the matrix/clip state since the last save call. It is
+ an error to call restore() more times than save() was called.
+ */
+ virtual void restore();
+
+ /** Returns the number of matrix/clip states on the SkCanvas' private stack.
+ This will equal # save() calls - # restore() calls.
+ */
+ int getSaveCount() const;
+
+ /** Efficient way to pop any calls to save() that happened after the save
+ count reached saveCount. It is an error for saveCount to be less than
+ getSaveCount()
+ @param saveCount The number of save() levels to restore from
+ */
+ void restoreToCount(int saveCount);
+
+ /** Preconcat the current matrix with the specified translation
+ @param dx The distance to translate in X
+ @param dy The distance to translate in Y
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool translate(SkScalar dx, SkScalar dy);
+
+ /** Preconcat the current matrix with the specified scale.
+ @param sx The amount to scale in X
+ @param sy The amount to scale in Y
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool scale(SkScalar sx, SkScalar sy);
+
+ /** Preconcat the current matrix with the specified rotation.
+ @param degrees The amount to rotate, in degrees
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool rotate(SkScalar degrees);
+
+ /** Preconcat the current matrix with the specified skew.
+ @param sx The amount to skew in X
+ @param sy The amount to skew in Y
+ returns true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool skew(SkScalar sx, SkScalar sy);
+
+ /** Preconcat the current matrix with the specified matrix.
+ @param matrix The matrix to preconcatenate with the current matrix
+ @return true if the operation succeeded (e.g. did not overflow)
+ */
+ virtual bool concat(const SkMatrix& matrix);
+
+ /** Replace the current matrix with a copy of the specified matrix.
+ @param matrix The matrix that will be copied into the current matrix.
+ */
+ virtual void setMatrix(const SkMatrix& matrix);
+
+ /** Helper for setMatrix(identity). Sets the current matrix to identity.
+ */
+ void resetMatrix();
+
+ /** Modify the current clip with the specified rectangle.
+ @param rect The rect to intersect with the current clip
+ @param op The region op to apply to the current clip
+ @return true if the canvas' clip is non-empty
+ */
+ virtual bool clipRect(const SkRect& rect,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ /** Modify the current clip with the specified path.
+ @param path The path to apply to the current clip
+ @param op The region op to apply to the current clip
+ @return true if the canvas' new clip is non-empty
+ */
+ virtual bool clipPath(const SkPath& path,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ /** Modify the current clip with the specified region. Note that unlike
+ clipRect() and clipPath() which transform their arguments by the current
+ matrix, clipRegion() assumes its argument is already in device
+ coordinates, and so no transformation is performed.
+ @param deviceRgn The region to apply to the current clip
+ @param op The region op to apply to the current clip
+ @return true if the canvas' new clip is non-empty
+ */
+ virtual bool clipRegion(const SkRegion& deviceRgn,
+ SkRegion::Op op = SkRegion::kIntersect_Op);
+
+ /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
+ specified region. This does not intersect or in any other way account
+ for the existing clip region.
+ @param deviceRgn The region to copy into the current clip.
+ @return true if the new clip region is non-empty
+ */
+ bool setClipRegion(const SkRegion& deviceRgn) {
+ return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
+ }
+
+ /** Enum describing how to treat edges when performing quick-reject tests
+ of a geometry against the current clip. Treating them as antialiased
+ (kAA_EdgeType) will take into account the extra pixels that may be drawn
+ if the edge does not lie exactly on a device pixel boundary (after being
+ transformed by the current matrix).
+ */
+ enum EdgeType {
+ /** Treat the edges as B&W (not antialiased) for the purposes of testing
+ against the current clip
+ */
+ kBW_EdgeType,
+ /** Treat the edges as antialiased for the purposes of testing
+ against the current clip
+ */
+ kAA_EdgeType
+ };
+
+ /** Return true if the specified rectangle, after being transformed by the
+ current matrix, would lie completely outside of the current clip. Call
+ this to check if an area you intend to draw into is clipped out (and
+ therefore you can skip making the draw calls).
+ @param rect the rect to compare with the current clip
+ @param et specifies how to treat the edges (see EdgeType)
+ @return true if the rect (transformed by the canvas' matrix) does not
+ intersect with the canvas' clip
+ */
+ bool quickReject(const SkRect& rect, EdgeType et) const;
+
+ /** Return true if the specified path, after being transformed by the
+ current matrix, would lie completely outside of the current clip. Call
+ this to check if an area you intend to draw into is clipped out (and
+ therefore you can skip making the draw calls). Note, for speed it may
+ return false even if the path itself might not intersect the clip
+ (i.e. the bounds of the path intersects, but the path does not).
+ @param path The path to compare with the current clip
+ @param et specifies how to treat the edges (see EdgeType)
+ @return true if the path (transformed by the canvas' matrix) does not
+ intersect with the canvas' clip
+ */
+ bool quickReject(const SkPath& path, EdgeType et) const;
+
+ /** Return true if the horizontal band specified by top and bottom is
+ completely clipped out. This is a conservative calculation, meaning
+ that it is possible that if the method returns false, the band may still
+ in fact be clipped out, but the converse is not true. If this method
+ returns true, then the band is guaranteed to be clipped out.
+ @param top The top of the horizontal band to compare with the clip
+ @param bottom The bottom of the horizontal and to compare with the clip
+ @return true if the horizontal band is completely clipped out (i.e. does
+ not intersect the current clip)
+ */
+ bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const;
+
+ /** Return the bounds of the current clip (in local coordinates) in the
+ bounds parameter, and return true if it is non-empty. This can be useful
+ in a way similar to quickReject, in that it tells you that drawing
+ outside of these bounds will be clipped out.
+ */
+ bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified ARGB color, using the specified PorterDuff mode.
+ @param a the alpha component (0..255) of the color to fill the canvas
+ @param r the red component (0..255) of the color to fill the canvas
+ @param g the green component (0..255) of the color to fill the canvas
+ @param b the blue component (0..255) of the color to fill the canvas
+ @param mode the mode to apply the color in (defaults to SrcOver)
+ */
+ void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
+ SkPorterDuff::Mode mode = SkPorterDuff::kSrcOver_Mode);
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified color and porter-duff xfermode.
+ @param color the color to draw with
+ @param mode the mode to apply the color in (defaults to SrcOver)
+ */
+ void drawColor(SkColor color,
+ SkPorterDuff::Mode mode = SkPorterDuff::kSrcOver_Mode);
+
+ /** Fill the entire canvas' bitmap (restricted to the current clip) with the
+ specified paint.
+ @param paint The paint used to fill the canvas
+ */
+ virtual void drawPaint(const SkPaint& paint);
+
+ enum PointMode {
+ /** drawPoints draws each point separately */
+ kPoints_PointMode,
+ /** drawPoints draws each pair of points as a line segment */
+ kLines_PointMode,
+ /** drawPoints draws the array of points as a polygon */
+ kPolygon_PointMode
+ };
+
+ /** Draw a series of points, interpreted based on the PointMode mode. For
+ all modes, the count parameter is interpreted as the total number of
+ points. For kLine mode, count/2 line segments are drawn.
+ For kPoint mode, each point is drawn centered at its coordinate, and its
+ size is specified by the paint's stroke-width. It draws as a square,
+ unless the paint's cap-type is round, in which the points are drawn as
+ circles.
+ For kLine mode, each pair of points is drawn as a line segment,
+ respecting the paint's settings for cap/join/width.
+ For kPolygon mode, the entire array is drawn as a series of connected
+ line segments.
+ Note that, while similar, kLine and kPolygon modes draw slightly
+ differently than the equivalent path built with a series of moveto,
+ lineto calls, in that the path will draw all of its contours at once,
+ with no interactions if contours intersect each other (think XOR
+ xfermode). drawPoints always draws each element one at a time.
+ @param mode PointMode specifying how to draw the array of points.
+ @param count The number of points in the array
+ @param pts Array of points to draw
+ @param paint The paint used to draw the points
+ */
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint);
+
+ /** Helper method for drawing a single point. See drawPoints() for a more
+ details.
+ */
+ void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
+
+ /** Draws a single pixel in the specified color.
+ @param x The X coordinate of which pixel to draw
+ @param y The Y coordiante of which pixel to draw
+ @param color The color to draw
+ */
+ void drawPoint(SkScalar x, SkScalar y, SkColor color);
+
+ /** Draw a line segment with the specified start and stop x,y coordinates,
+ using the specified paint. NOTE: since a line is always "framed", the
+ paint's Style is ignored.
+ @param x0 The x-coordinate of the start point of the line
+ @param y0 The y-coordinate of the start point of the line
+ @param x1 The x-coordinate of the end point of the line
+ @param y1 The y-coordinate of the end point of the line
+ @param paint The paint used to draw the line
+ */
+ void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
+ const SkPaint& paint);
+
+ /** Draw the specified rectangle using the specified paint. The rectangle
+ will be filled or stroked based on the Style in the paint.
+ @param rect The rect to be drawn
+ @param paint The paint used to draw the rect
+ */
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint);
+
+ /** Draw the specified rectangle using the specified paint. The rectangle
+ will be filled or framed based on the Style in the paint.
+ @param rect The rect to be drawn
+ @param paint The paint used to draw the rect
+ */
+ void drawIRect(const SkIRect& rect, const SkPaint& paint)
+ {
+ SkRect r;
+ r.set(rect); // promotes the ints to scalars
+ this->drawRect(r, paint);
+ }
+
+ /** Draw the specified rectangle using the specified paint. The rectangle
+ will be filled or framed based on the Style in the paint.
+ @param left The left side of the rectangle to be drawn
+ @param top The top side of the rectangle to be drawn
+ @param right The right side of the rectangle to be drawn
+ @param bottom The bottom side of the rectangle to be drawn
+ @param paint The paint used to draw the rect
+ */
+ void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
+ SkScalar bottom, const SkPaint& paint);
+
+ /** Draw the specified oval using the specified paint. The oval will be
+ filled or framed based on the Style in the paint.
+ @param oval The rectangle bounds of the oval to be drawn
+ @param paint The paint used to draw the oval
+ */
+ void drawOval(const SkRect& oval, const SkPaint&);
+
+ /** Draw the specified circle using the specified paint. If radius is <= 0,
+ then nothing will be drawn. The circle will be filled
+ or framed based on the Style in the paint.
+ @param cx The x-coordinate of the center of the cirle to be drawn
+ @param cy The y-coordinate of the center of the cirle to be drawn
+ @param radius The radius of the cirle to be drawn
+ @param paint The paint used to draw the circle
+ */
+ void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
+ const SkPaint& paint);
+
+ /** Draw the specified arc, which will be scaled to fit inside the
+ specified oval. If the sweep angle is >= 360, then the oval is drawn
+ completely. Note that this differs slightly from SkPath::arcTo, which
+ treats the sweep angle mod 360.
+ @param oval The bounds of oval used to define the shape of the arc
+ @param startAngle Starting angle (in degrees) where the arc begins
+ @param sweepAngle Sweep angle (in degrees) measured clockwise
+ @param useCenter true means include the center of the oval. For filling
+ this will draw a wedge. False means just use the arc.
+ @param paint The paint used to draw the arc
+ */
+ void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
+ bool useCenter, const SkPaint& paint);
+
+ /** Draw the specified round-rect using the specified paint. The round-rect
+ will be filled or framed based on the Style in the paint.
+ @param rect The rectangular bounds of the roundRect to be drawn
+ @param rx The x-radius of the oval used to round the corners
+ @param ry The y-radius of the oval used to round the corners
+ @param paint The paint used to draw the roundRect
+ */
+ void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
+ const SkPaint& paint);
+
+ /** Draw the specified path using the specified paint. The path will be
+ filled or framed based on the Style in the paint.
+ @param path The path to be drawn
+ @param paint The paint used to draw the path
+ */
+ virtual void drawPath(const SkPath& path, const SkPaint& paint);
+
+ /** Draw the specified bitmap, with its top/left corner at (x,y), using the
+ specified paint, transformed by the current matrix. Note: if the paint
+ contains a maskfilter that generates a mask which extends beyond the
+ bitmap's original width/height, then the bitmap will be drawn as if it
+ were in a Shader with CLAMP mode. Thus the color outside of the original
+ width/height will be the edge color replicated.
+ @param bitmap The bitmap to be drawn
+ @param left The position of the left side of the bitmap being drawn
+ @param top The position of the top side of the bitmap being drawn
+ @param paint The paint used to draw the bitmap, or NULL
+ */
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
+ const SkPaint* paint = NULL);
+
+ /** Draw the specified bitmap, with the specified matrix applied (before the
+ canvas' matrix is applied).
+ @param bitmap The bitmap to be drawn
+ @param src Optional: specify the subset of the bitmap to be drawn
+ @param dst The destination rectangle where the scaled/translated
+ image will be drawn
+ @param paint The paint used to draw the bitmap, or NULL
+ */
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint = NULL);
+
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
+ const SkPaint* paint = NULL);
+
+ /** Draw the specified bitmap, with its top/left corner at (x,y),
+ NOT transformed by the current matrix. Note: if the paint
+ contains a maskfilter that generates a mask which extends beyond the
+ bitmap's original width/height, then the bitmap will be drawn as if it
+ were in a Shader with CLAMP mode. Thus the color outside of the original
+ width/height will be the edge color replicated.
+ @param bitmap The bitmap to be drawn
+ @param left The position of the left side of the bitmap being drawn
+ @param top The position of the top side of the bitmap being drawn
+ @param paint The paint used to draw the bitmap, or NULL
+ */
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint = NULL);
+
+ /** Draw the text, with origin at (x,y), using the specified paint.
+ The origin is interpreted based on the Align setting in the paint.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param x The x-coordinate of the origin of the text being drawn
+ @param y The y-coordinate of the origin of the text being drawn
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ virtual void drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint);
+
+ /** Draw the text, with each character/glyph origin specified by the pos[]
+ array. The origin is interpreted by the Align setting in the paint.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param pos Array of positions, used to position each character
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint);
+
+ /** Draw the text, with each character/glyph origin specified by the x
+ coordinate taken from the xpos[] array, and the y from the constY param.
+ The origin is interpreted by the Align setting in the paint.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param xpos Array of x-positions, used to position each character
+ @param constY The shared Y coordinate for all of the positions
+ @param paint The paint used for the text (e.g. color, size, style)
+ */
+ virtual void drawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY,
+ const SkPaint& paint);
+
+ /** Draw the text, with origin at (x,y), using the specified paint, along
+ the specified path. The paint's Align setting determins where along the
+ path to start the text.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param path The path the text should follow for its baseline
+ @param hOffset The distance along the path to add to the text's
+ starting position
+ @param vOffset The distance above(-) or below(+) the path to
+ position the text
+ @param paint The paint used for the text
+ */
+ void drawTextOnPathHV(const void* text, size_t byteLength,
+ const SkPath& path, SkScalar hOffset,
+ SkScalar vOffset, const SkPaint& paint);
+
+ /** Draw the text, with origin at (x,y), using the specified paint, along
+ the specified path. The paint's Align setting determins where along the
+ path to start the text.
+ @param text The text to be drawn
+ @param byteLength The number of bytes to read from the text parameter
+ @param path The path the text should follow for its baseline
+ @param matrix (may be null) Applied to the text before it is
+ mapped onto the path
+ @param paint The paint used for the text
+ */
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint);
+
+ /** Draw the picture into this canvas. This method effective brackets the
+ playback of the picture's draw calls with save/restore, so the state
+ of this canvas will be unchanged after this call. This contrasts with
+ the more immediate method SkPicture::draw(), which does not bracket
+ the canvas with save/restore, thus the canvas may be left in a changed
+ state after the call.
+ @param picture The recorded drawing commands to playback into this
+ canvas.
+ */
+ virtual void drawPicture(SkPicture& picture);
+
+ enum VertexMode {
+ kTriangles_VertexMode,
+ kTriangleStrip_VertexMode,
+ kTriangleFan_VertexMode
+ };
+
+ /** Draw the array of vertices, interpreted as triangles (based on mode).
+ @param vmode How to interpret the array of vertices
+ @param vertexCount The number of points in the vertices array (and
+ corresponding texs and colors arrays if non-null)
+ @param vertices Array of vertices for the mesh
+ @param texs May be null. If not null, specifies the coordinate
+ in texture space for each vertex.
+ @param colors May be null. If not null, specifies a color for each
+ vertex, to be interpolated across the triangle.
+ @param xmode Used if both texs and colors are present. In this
+ case the colors are combined with the texture using mode,
+ before being drawn using the paint. If mode is null, then
+ the porter-duff MULTIPLY mode is used.
+ @param indices If not null, array of indices to reference into the
+ vertex (texs, colors) array.
+ @param indexCount number of entries in the indices array (if not null)
+ @param paint Specifies the shader/texture if present.
+ */
+ virtual void drawVertices(VertexMode vmode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint);
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Get the current bounder object.
+ The bounder's reference count is unchaged.
+ @return the canva's bounder (or NULL).
+ */
+ SkBounder* getBounder() const { return fBounder; }
+
+ /** Set a new bounder (or NULL).
+ Pass NULL to clear any previous bounder.
+ As a convenience, the parameter passed is also returned.
+ If a previous bounder exists, its reference count is decremented.
+ If bounder is not NULL, its reference count is incremented.
+ @param bounder the new bounder (or NULL) to be installed in the canvas
+ @return the set bounder object
+ */
+ virtual SkBounder* setBounder(SkBounder* bounder);
+
+ /** Get the current filter object. The filter's reference count is not
+ affected. The filter is part of the state this is affected by
+ save/restore.
+ @return the canvas' filter (or NULL).
+ */
+ SkDrawFilter* getDrawFilter() const;
+
+ /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
+ As a convenience, the parameter is returned. If an existing filter
+ exists, its refcnt is decrement. If the new filter is not null, its
+ refcnt is incremented. The filter is part of the state this is affected
+ by save/restore.
+ @param filter the new filter (or NULL)
+ @return the new filter
+ */
+ virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
+
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Return the current matrix on the canvas.
+ This does not account for the translate in any of the devices.
+ @return The current matrix on the canvas.
+ */
+ const SkMatrix& getTotalMatrix() const;
+
+ /** Return the current device clip (concatenation of all clip calls).
+ This does not account for the translate in any of the devices.
+ @return the current device clip (concatenation of all clip calls).
+ */
+ const SkRegion& getTotalClip() const;
+
+ /** May be overridden by subclasses. This returns a compatible device
+ for this canvas, with the specified config/width/height. If isOpaque
+ is true, then the underlying bitmap is optimized to assume that every
+ pixel will be drawn to, and thus it does not need to clear the alpha
+ channel ahead of time (assuming the specified config supports per-pixel
+ alpha.) If isOpaque is false, then the bitmap should clear its alpha
+ channel.
+ */
+ virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
+ bool isOpaque, bool isForLayer);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ /** After calling saveLayer(), there can be any number of devices that make
+ up the top-most drawing area. LayerIter can be used to iterate through
+ those devices. Note that the iterator is only valid until the next API
+ call made on the canvas. Ownership of all pointers in the iterator stays
+ with the canvas, so none of them should be modified or deleted.
+ */
+ class LayerIter /*: SkNoncopyable*/ {
+ public:
+ /** Initialize iterator with canvas, and set values for 1st device */
+ LayerIter(SkCanvas*, bool skipEmptyClips);
+ ~LayerIter();
+
+ /** Return true if the iterator is done */
+ bool done() const { return fDone; }
+ /** Cycle to the next device */
+ void next();
+
+ // These reflect the current device in the iterator
+
+ SkDevice* device() const;
+ const SkMatrix& matrix() const;
+ const SkRegion& clip() const;
+ const SkPaint& paint() const;
+ int x() const;
+ int y() const;
+
+ private:
+ // used to embed the SkDrawIter object directly in our instance, w/o
+ // having to expose that class def to the public. There is an assert
+ // in our constructor to ensure that fStorage is large enough
+ // (though needs to be a compile-time-assert!). We use intptr_t to work
+ // safely with 32 and 64 bit machines (to ensure the storage is enough)
+ intptr_t fStorage[12];
+ class SkDrawIter* fImpl; // this points at fStorage
+ SkPaint fDefaultPaint;
+ bool fDone;
+ };
+
+protected:
+ // all of the drawBitmap variants call this guy
+ virtual void commonDrawBitmap(const SkBitmap&, const SkMatrix& m,
+ const SkPaint& paint);
+
+private:
+ class MCRec;
+
+ SkDeque fMCStack;
+ // points to top of stack
+ MCRec* fMCRec;
+ // the first N recs that can fit here mean we won't call malloc
+ uint32_t fMCRecStorage[32];
+
+ SkBounder* fBounder;
+
+ void prepareForDeviceDraw(SkDevice*);
+
+ bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
+ void updateDeviceCMCache();
+
+ friend class SkDrawIter; // needs setupDrawForLayerDevice()
+
+ SkDevice* init(SkDevice*);
+ void internalDrawBitmap(const SkBitmap&, const SkMatrix& m,
+ const SkPaint* paint);
+ void drawDevice(SkDevice*, int x, int y, const SkPaint*);
+ // shared by save() and saveLayer()
+ int internalSave(SaveFlags flags);
+ void internalRestore();
+
+ /* These maintain a cache of the clip bounds in local coordinates,
+ (converted to 2s-compliment if floats are slow).
+ */
+ mutable SkRectCompareType fLocalBoundsCompareType;
+ mutable bool fLocalBoundsCompareTypeDirty;
+
+ const SkRectCompareType& getLocalClipBoundsCompareType() const {
+ if (fLocalBoundsCompareTypeDirty) {
+ this->computeLocalClipBoundsCompareType();
+ fLocalBoundsCompareTypeDirty = false;
+ }
+ return fLocalBoundsCompareType;
+ }
+ void computeLocalClipBoundsCompareType() const;
+};
+
+/** Stack helper class to automatically call restoreToCount() on the canvas
+ when this object goes out of scope. Use this to guarantee that the canvas
+ is restored to a known state.
+*/
+class SkAutoCanvasRestore : SkNoncopyable {
+public:
+ SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
+ SkASSERT(canvas);
+ fSaveCount = canvas->getSaveCount();
+ if (doSave) {
+ canvas->save();
+ }
+ }
+ ~SkAutoCanvasRestore() {
+ fCanvas->restoreToCount(fSaveCount);
+ }
+
+private:
+ SkCanvas* fCanvas;
+ int fSaveCount;
+};
+
+#endif
+