{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %} {% include "_shared/_reference-head-tags.html" %}

Canvas

public interface Canvas


Summary

Public methods

abstract void
clipPath(@NonNull Path path, @NonNull ClipOp clipOp)

Reduces the clip region to the intersection of the current clip and the given Path.

default void
clipRect(@NonNull Rect rect, @NonNull ClipOp clipOp)

Reduces the clip region to the intersection of the current clip and the given rectangle.

abstract void
clipRect(
    float left,
    float top,
    float right,
    float bottom,
    @NonNull ClipOp clipOp
)

Reduces the clip region to the intersection of the current clip and the given bounds.

abstract void

Multiply the current transform by the specified 4⨉4 transformation matrix specified as a list of values in column-major order.

abstract void

Disables Z support, preventing any layers drawn after this point from being visually reordered or having shadows rendered.

default void
drawArc(
    @NonNull Rect rect,
    float startAngle,
    float sweepAngle,
    boolean useCenter,
    @NonNull Paint paint
)

Draw an arc scaled to fit inside the given rectangle.

abstract void
drawArc(
    float left,
    float top,
    float right,
    float bottom,
    float startAngle,
    float sweepAngle,
    boolean useCenter,
    @NonNull Paint paint
)

Draw an arc scaled to fit inside the given rectangle.

default void
drawArcRad(
    @NonNull Rect rect,
    float startAngleRad,
    float sweepAngleRad,
    boolean useCenter,
    @NonNull Paint paint
)

Draw an arc scaled to fit inside the given rectangle.

abstract void
drawCircle(@NonNull Offset center, float radius, @NonNull Paint paint)

Draws a circle centered at the point given by the first argument and that has the radius given by the second argument, with the Paint given in the third argument.

abstract void
drawImage(
    @NonNull ImageBitmap image,
    @NonNull Offset topLeftOffset,
    @NonNull Paint paint
)

Draws the given ImageBitmap into the canvas with its top-left corner at the given Offset.

abstract void
drawImageRect(
    @NonNull ImageBitmap image,
    @NonNull IntOffset srcOffset,
    @NonNull IntSize srcSize,
    @NonNull IntOffset dstOffset,
    @NonNull IntSize dstSize,
    @NonNull Paint paint
)

Draws the subset of the given image described by the src argument into the canvas in the axis-aligned rectangle given by the dst argument.

abstract void

Draws a line between the given points using the given paint.

default void
drawOval(@NonNull Rect rect, @NonNull Paint paint)

Draws an axis-aligned oval that fills the given axis-aligned rectangle with the given Paint.

abstract void
drawOval(
    float left,
    float top,
    float right,
    float bottom,
    @NonNull Paint paint
)

Draws an axis-aligned oval that fills the given bounds provided with the given Paint.

abstract void
drawPath(@NonNull Path path, @NonNull Paint paint)

Draws the given Path with the given Paint.

abstract void
drawPoints(
    @NonNull PointMode pointMode,
    @NonNull List<@NonNull Offset> points,
    @NonNull Paint paint
)

Draws a sequence of points according to the given PointMode.

abstract void
drawRawPoints(
    @NonNull PointMode pointMode,
    @NonNull float[] points,
    @NonNull Paint paint
)

Draws a sequence of points according to the given PointMode.

default void
drawRect(@NonNull Rect rect, @NonNull Paint paint)

Draws a rectangle with the given Paint.

abstract void
drawRect(
    float left,
    float top,
    float right,
    float bottom,
    @NonNull Paint paint
)

Draws a rectangle with the given Paint.

abstract void
drawRoundRect(
    float left,
    float top,
    float right,
    float bottom,
    float radiusX,
    float radiusY,
    @NonNull Paint paint
)

Draws a rounded rectangle with the given Paint.

abstract void
drawVertices(
    @NonNull Vertices vertices,
    @NonNull BlendMode blendMode,
    @NonNull Paint paint
)
abstract void

Enables Z support which defaults to disabled.

abstract void

Pops the current save stack, if there is anything to pop.

abstract void
rotate(float degrees)

Add a rotation (in degrees clockwise) to the current transform

abstract void

Saves a copy of the current transform and clip on the save stack.

abstract void
saveLayer(@NonNull Rect bounds, @NonNull Paint paint)

Saves a copy of the current transform and clip on the save stack, and then creates a new group which subsequent calls will become a part of.

abstract void
scale(float sx, float sy)

Add an axis-aligned scale to the current transform, scaling by the first argument in the horizontal direction and the second in the vertical direction.

abstract void
skew(float sx, float sy)

Add an axis-aligned skew to the current transform, with the first argument being the horizontal skew in degrees clockwise around the origin, and the second argument being the vertical skew in degrees clockwise around the origin.

default void
skewRad(float sxRad, float syRad)

Add an axis-aligned skew to the current transform, with the first argument being the horizontal skew in radians clockwise around the origin, and the second argument being the vertical skew in radians clockwise around the origin.

abstract void
translate(float dx, float dy)

Add a translation to the current transform, shifting the coordinate space horizontally by the first argument and vertically by the second argument.

Extension functions

default final @NonNull NativeCanvas

Return an instance of the native primitive that implements the Canvas interface

default final void
CanvasKt.rotate(
    @NonNull Canvas receiver,
    float degrees,
    float pivotX,
    float pivotY
)

Add a rotation (in degrees clockwise) to the current transform at the given pivot point.

default final void
CanvasKt.rotateRad(
    @NonNull Canvas receiver,
    float radians,
    float pivotX,
    float pivotY
)

Add a rotation (in radians clockwise) to the current transform at the given pivot point.

default final void
CanvasKt.scale(
    @NonNull Canvas receiver,
    float sx,
    float sy,
    float pivotX,
    float pivotY
)

Add an axis-aligned scale to the current transform, scaling by the first argument in the horizontal direction and the second in the vertical direction at the given pivot coordinate.

default final void
CanvasKt.withSave(
    @NonNull Canvas receiver,
    @NonNull Function0<Unit> block
)

Saves a copy of the current transform and clip on the save stack and executes the provided lambda with the current transform applied.

default final void
CanvasKt.withSaveLayer(
    @NonNull Canvas receiver,
    @NonNull Rect bounds,
    @NonNull Paint paint,
    @NonNull Function0<Unit> block
)

Saves a copy of the current transform and clip on the save stack, and then creates a new group which subsequent calls will become a part of.

default final void
OutlineKt.drawOutline(
    @NonNull Canvas receiver,
    @NonNull Outline outline,
    @NonNull Paint paint
)

Draws the Outline on a Canvas.

Public methods

clipPath

abstract void clipPath(@NonNull Path path, @NonNull ClipOp clipOp)

Reduces the clip region to the intersection of the current clip and the given Path.

clipRect

default void clipRect(@NonNull Rect rect, @NonNull ClipOp clipOp)

Reduces the clip region to the intersection of the current clip and the given rectangle.

Use ClipOp.Difference to subtract the provided rectangle from the current clip.

clipRect

abstract void clipRect(
    float left,
    float top,
    float right,
    float bottom,
    @NonNull ClipOp clipOp
)

Reduces the clip region to the intersection of the current clip and the given bounds.

Use ClipOp.Difference to subtract the provided rectangle from the current clip.

Parameters
float left

Left bound of the clip region

float top

Top bound of the clip region

float right

Right bound of the clip region

float bottom

Bottom bound of the clip region

@NonNull ClipOp clipOp

Clipping operation to conduct on the given bounds, defaults to ClipOp.Intersect

concat

abstract void concat(@NonNull Matrix matrix)

Multiply the current transform by the specified 4⨉4 transformation matrix specified as a list of values in column-major order.

disableZ

abstract void disableZ()

Disables Z support, preventing any layers drawn after this point from being visually reordered or having shadows rendered. This is not impacted by any save or restore calls as it is not considered part of the matrix or clip.

See also
enableZ

drawArc

default void drawArc(
    @NonNull Rect rect,
    float startAngle,
    float sweepAngle,
    boolean useCenter,
    @NonNull Paint paint
)

Draw an arc scaled to fit inside the given rectangle. It starts from startAngle degrees around the oval up to startAngle + sweepAngle degrees around the oval, with zero degrees being the point on the right hand side of the oval that crosses the horizontal line that intersects the center of the rectangle and with positive angles going clockwise around the oval. If useCenter is true, the arc is closed back to the center, forming a circle sector. Otherwise, the arc is not closed, forming a circle segment.

This method is optimized for drawing arcs and should be faster than Path.arcTo.

drawArc

abstract void drawArc(
    float left,
    float top,
    float right,
    float bottom,
    float startAngle,
    float sweepAngle,
    boolean useCenter,
    @NonNull Paint paint
)

Draw an arc scaled to fit inside the given rectangle. It starts from startAngle degrees around the oval up to startAngle + sweepAngle degrees around the oval, with zero degrees being the point on the right hand side of the oval that crosses the horizontal line that intersects the center of the rectangle and with positive angles going clockwise around the oval. If useCenter is true, the arc is closed back to the center, forming a circle sector. Otherwise, the arc is not closed, forming a circle segment.

This method is optimized for drawing arcs and should be faster than Path.arcTo.

Parameters
float left

Left bound of the arc

float top

Top bound of the arc

float right

Right bound of the arc

float bottom

Bottom bound of the arc

float startAngle

Starting angle of the arc relative to 3 o'clock

float sweepAngle

Sweep angle in degrees clockwise

boolean useCenter

Flag indicating whether or not to include the center of the oval in the

@NonNull Paint paint

Paint used to draw the arc. arc, and close it if it is being stroked. This will draw a wedge.

drawArcRad

default void drawArcRad(
    @NonNull Rect rect,
    float startAngleRad,
    float sweepAngleRad,
    boolean useCenter,
    @NonNull Paint paint
)

Draw an arc scaled to fit inside the given rectangle. It starts from startAngle radians around the oval up to startAngle + sweepAngle radians around the oval, with zero radians being the point on the right hand side of the oval that crosses the horizontal line that intersects the center of the rectangle and with positive angles going clockwise around the oval. If useCenter is true, the arc is closed back to the center, forming a circle sector. Otherwise, the arc is not closed, forming a circle segment.

This method is optimized for drawing arcs and should be faster than Path.arcTo.

drawCircle

abstract void drawCircle(@NonNull Offset center, float radius, @NonNull Paint paint)

Draws a circle centered at the point given by the first argument and that has the radius given by the second argument, with the Paint given in the third argument. Whether the circle is filled or stroked (or both) is controlled by Paint.style.

drawImage

abstract void drawImage(
    @NonNull ImageBitmap image,
    @NonNull Offset topLeftOffset,
    @NonNull Paint paint
)

Draws the given ImageBitmap into the canvas with its top-left corner at the given Offset. The image is composited into the canvas using the given Paint.

drawImageRect

abstract void drawImageRect(
    @NonNull ImageBitmap image,
    @NonNull IntOffset srcOffset,
    @NonNull IntSize srcSize,
    @NonNull IntOffset dstOffset,
    @NonNull IntSize dstSize,
    @NonNull Paint paint
)

Draws the subset of the given image described by the src argument into the canvas in the axis-aligned rectangle given by the dst argument.

This might sample from outside the src rect by up to half the width of an applied filter.

Parameters
@NonNull ImageBitmap image

ImageBitmap to draw

@NonNull IntOffset srcOffset

: Optional offset representing the top left offset of the source image to draw, this defaults to the origin of image

@NonNull IntSize srcSize

: Optional dimensions of the source image to draw relative to srcOffset, this defaults the width and height of image

@NonNull IntOffset dstOffset

: Offset representing the top left offset of the destination image to draw

@NonNull IntSize dstSize

: Dimensions of the destination to draw

@NonNull Paint paint

Paint used to composite the ImageBitmap pixels into the canvas

drawLine

abstract void drawLine(@NonNull Offset p1, @NonNull Offset p2, @NonNull Paint paint)

Draws a line between the given points using the given paint. The line is stroked, the value of the Paint.style is ignored for this call.

The p1 and p2 arguments are interpreted as offsets from the origin.

drawOval

default void drawOval(@NonNull Rect rect, @NonNull Paint paint)

Draws an axis-aligned oval that fills the given axis-aligned rectangle with the given Paint. Whether the oval is filled or stroked (or both) is controlled by Paint.style.

drawOval

abstract void drawOval(
    float left,
    float top,
    float right,
    float bottom,
    @NonNull Paint paint
)

Draws an axis-aligned oval that fills the given bounds provided with the given Paint. Whether the rectangle is filled or stroked (or both) is controlled by Paint.style.

Parameters
float left

The left bound of the rectangle

float top

The top bound of the rectangle

float right

The right bound of the rectangle

float bottom

The bottom bound of the rectangle

@NonNull Paint paint

Paint used to color the rectangle with a fill or stroke

drawPath

abstract void drawPath(@NonNull Path path, @NonNull Paint paint)

Draws the given Path with the given Paint. Whether this shape is filled or stroked (or both) is controlled by Paint.style. If the path is filled, then subpaths within it are implicitly closed (see Path.close).

drawPoints

abstract void drawPoints(
    @NonNull PointMode pointMode,
    @NonNull List<@NonNull Offset> points,
    @NonNull Paint paint
)

Draws a sequence of points according to the given PointMode.

The points argument is interpreted as offsets from the origin.

See also:

drawRawPoints

abstract void drawRawPoints(
    @NonNull PointMode pointMode,
    @NonNull float[] points,
    @NonNull Paint paint
)

Draws a sequence of points according to the given PointMode.

The points argument is interpreted as a list of pairs of floating point numbers, where each pair represents an x and y offset from the origin.

See also:

drawRect

default void drawRect(@NonNull Rect rect, @NonNull Paint paint)

Draws a rectangle with the given Paint. Whether the rectangle is filled or stroked (or both) is controlled by Paint.style.

drawRect

abstract void drawRect(
    float left,
    float top,
    float right,
    float bottom,
    @NonNull Paint paint
)

Draws a rectangle with the given Paint. Whether the rectangle is filled or stroked (or both) is controlled by Paint.style.

Parameters
float left

The left bound of the rectangle

float top

The top bound of the rectangle

float right

The right bound of the rectangle

float bottom

The bottom bound of the rectangle

@NonNull Paint paint

Paint used to color the rectangle with a fill or stroke

drawRoundRect

abstract void drawRoundRect(
    float left,
    float top,
    float right,
    float bottom,
    float radiusX,
    float radiusY,
    @NonNull Paint paint
)

Draws a rounded rectangle with the given Paint. Whether the rectangle is filled or stroked (or both) is controlled by Paint.style.

drawVertices

abstract void drawVertices(
    @NonNull Vertices vertices,
    @NonNull BlendMode blendMode,
    @NonNull Paint paint
)

enableZ

abstract void enableZ()

Enables Z support which defaults to disabled. This allows layers drawn with different elevations to be rearranged based on their elevation. It also enables rendering of shadows.

See also
disableZ

restore

abstract void restore()

Pops the current save stack, if there is anything to pop. Otherwise, does nothing.

Use save and saveLayer to push state onto the stack.

If the state was pushed with with saveLayer, then this call will also cause the new layer to be composited into the previous layer.

rotate

abstract void rotate(float degrees)

Add a rotation (in degrees clockwise) to the current transform

Parameters
float degrees

to rotate clockwise

save

abstract void save()

Saves a copy of the current transform and clip on the save stack.

Call restore to pop the save stack.

See also:

saveLayer

abstract void saveLayer(@NonNull Rect bounds, @NonNull Paint paint)

Saves a copy of the current transform and clip on the save stack, and then creates a new group which subsequent calls will become a part of. When the save stack is later popped, the group will be flattened into a layer and have the given paint's Paint.colorFilter and Paint.blendMode applied.

This lets you create composite effects, for example making a group of drawing commands semi-transparent. Without using saveLayer, each part of the group would be painted individually, so where they overlap would be darker than where they do not. By using saveLayer to group them together, they can be drawn with an opaque color at first, and then the entire group can be made transparent using the saveLayer's paint.

Call restore to pop the save stack and apply the paint to the group.

Using saveLayer with clips

When a rectangular clip operation (from clipRect) is not axis-aligned with the raster buffer, or when the clip operation is not rectalinear (e.g. because it is a rounded rectangle clip created by clipPath, the edge of the clip needs to be anti-aliased.

If two draw calls overlap at the edge of such a clipped region, without using saveLayer, the first drawing will be anti-aliased with the background first, and then the second will be anti-aliased with the result of blending the first drawing and the background. On the other hand, if saveLayer is used immediately after establishing the clip, the second drawing will cover the first in the layer, and thus the second alone will be anti-aliased with the background when the layer is clipped and composited (when restore is called).

(Incidentally, rather than using clipPath with a rounded rectangle defined in a path to draw rounded rectangles like this, prefer the drawRoundRect method.

Performance considerations

Generally speaking, saveLayer is relatively expensive.

There are a several different hardware architectures for GPUs (graphics processing units, the hardware that handles graphics), but most of them involve batching commands and reordering them for performance. When layers are used, they cause the rendering pipeline to have to switch render target (from one layer to another). Render target switches can flush the GPU's command buffer, which typically means that optimizations that one could get with larger batching are lost. Render target switches also generate a lot of memory churn because the GPU needs to copy out the current frame buffer contents from the part of memory that's optimized for writing, and then needs to copy it back in once the previous render target (layer) is restored.

See also:

scale

abstract void scale(float sx, float sy)

Add an axis-aligned scale to the current transform, scaling by the first argument in the horizontal direction and the second in the vertical direction.

If sy is unspecified, sx will be used for the scale in both directions.

Parameters
float sx

The amount to scale in X

float sy

The amount to scale in Y

skew

abstract void skew(float sx, float sy)

Add an axis-aligned skew to the current transform, with the first argument being the horizontal skew in degrees clockwise around the origin, and the second argument being the vertical skew in degrees clockwise around the origin.

skewRad

default void skewRad(float sxRad, float syRad)

Add an axis-aligned skew to the current transform, with the first argument being the horizontal skew in radians clockwise around the origin, and the second argument being the vertical skew in radians clockwise around the origin.

translate

abstract void translate(float dx, float dy)

Add a translation to the current transform, shifting the coordinate space horizontally by the first argument and vertically by the second argument.

Extension functions

CanvasKt.getNativeCanvas

default final @NonNull NativeCanvas CanvasKt.getNativeCanvas(@NonNull Canvas receiver)

Return an instance of the native primitive that implements the Canvas interface

CanvasKt.rotate

default final void CanvasKt.rotate(
    @NonNull Canvas receiver,
    float degrees,
    float pivotX,
    float pivotY
)

Add a rotation (in degrees clockwise) to the current transform at the given pivot point. The pivot coordinate remains unchanged by the rotation transformation

Parameters
float degrees

to rotate clockwise

float pivotX

The x-coord for the pivot point

float pivotY

The y-coord for the pivot point

CanvasKt.rotateRad

default final void CanvasKt.rotateRad(
    @NonNull Canvas receiver,
    float radians,
    float pivotX,
    float pivotY
)

Add a rotation (in radians clockwise) to the current transform at the given pivot point. The pivot coordinate remains unchanged by the rotation transformation

Parameters
float pivotX

The x-coord for the pivot point

float pivotY

The y-coord for the pivot point

CanvasKt.scale

default final void CanvasKt.scale(
    @NonNull Canvas receiver,
    float sx,
    float sy,
    float pivotX,
    float pivotY
)

Add an axis-aligned scale to the current transform, scaling by the first argument in the horizontal direction and the second in the vertical direction at the given pivot coordinate. The pivot coordinate remains unchanged by the scale transformation.

If sy is unspecified, sx will be used for the scale in both directions.

Parameters
float sx

The amount to scale in X

float sy

The amount to scale in Y

float pivotX

The x-coord for the pivot point

float pivotY

The y-coord for the pivot point

CanvasKt.withSave

default final void CanvasKt.withSave(
    @NonNull Canvas receiver,
    @NonNull Function0<Unit> block
)

Saves a copy of the current transform and clip on the save stack and executes the provided lambda with the current transform applied. Once the lambda has been executed, the transformation is popped from the stack, undoing the transformation.

See also:

Canvas.saveLayer, which does the same thing but additionally also groups the commands

CanvasKt.withSaveLayer

default final void CanvasKt.withSaveLayer(
    @NonNull Canvas receiver,
    @NonNull Rect bounds,
    @NonNull Paint paint,
    @NonNull Function0<Unit> block
)

Saves a copy of the current transform and clip on the save stack, and then creates a new group which subsequent calls will become a part of. When the lambda is executed and the save stack is popped, the group will be flattened into a layer and have the given paint's Paint.colorFilter and Paint.blendMode applied.

This lets you create composite effects, for example making a group of drawing commands semi-transparent. Without using Canvas.saveLayer, each part of the group would be painted individually, so where they overlap would be darker than where they do not. By using Canvas.saveLayer to group them together, they can be drawn with an opaque color at first, and then the entire group can be made transparent using the Canvas.saveLayer's paint.

Using saveLayer with clips

When a rectangular clip operation (from Canvas.clipRect) is not axis-aligned with the raster buffer, or when the clip operation is not rectalinear (e.g. because it is a rounded rectangle clip created by Canvas.clipPath), the edge of the clip needs to be anti-aliased.

If two draw calls overlap at the edge of such a clipped region, without using Canvas.saveLayer, the first drawing will be anti-aliased with the background first, and then the second will be anti-aliased with the result of blending the first drawing and the background. On the other hand, if Canvas.saveLayer is used immediately after establishing the clip, the second drawing will cover the first in the layer, and thus the second alone will be anti-aliased with the background when the layer is clipped and composited (when lambda is finished executing).

Performance considerations

Generally speaking, Canvas.saveLayer is relatively expensive.

There are a several different hardware architectures for GPUs (graphics processing units, the hardware that handles graphics), but most of them involve batching commands and reordering them for performance. When layers are used, they cause the rendering pipeline to have to switch render target (from one layer to another). Render target switches can flush the GPU's command buffer, which typically means that optimizations that one could get with larger batching are lost. Render target switches also generate a lot of memory churn because the GPU needs to copy out the current frame buffer contents from the part of memory that's optimized for writing, and then needs to copy it back in once the previous render target (layer) is restored.

See also:

OutlineKt.drawOutline

default final void OutlineKt.drawOutline(
    @NonNull Canvas receiver,
    @NonNull Outline outline,
    @NonNull Paint paint
)

Draws the Outline on a Canvas.

Parameters
@NonNull Outline outline

the outline to draw.

@NonNull Paint paint

the paint used for the drawing.