Package icyllis.modernui.graphics

# Class Canvas

java.lang.Object
icyllis.modernui.graphics.Canvas

public abstract class Canvas extends Object
A Canvas provides an interface for drawing 2D geometries, images, and how the drawing is clipped and transformed. 2D geometries may include points, lines, triangles, rectangles, rounded rectangles, circular arcs, quadratic curves, etc.

A Canvas and a Paint together provide the state to draw into Surface or Device. Each Canvas draw call transforms the geometry of the object by the pre-multiplication of all transform matrices in the stack. The transformed geometry is clipped by the intersection of all clip values in the stack. The Canvas draw calls use Paint to supply drawing state such as color, text size, stroke width, filter and so on.

A surface canvas will quickly compute, optimize and generate the data required by the underlying 3D graphics API on the application side (client rendering pipeline). The render tasks will be transmitted to GPU on render thread (deferred rendering), determined by the drawing device.

A recording canvas records draw calls to a surface canvas. Although deferred rendering has been done in surface canvas, sometimes we don't need to update animations or transformations on the client side, so we can save draw calls, and don't need to update the buffer in GPU. This is not recommended for frequently updated scenes.

The Canvas uses analytic geometry to draw geometry, instead of meshing or tessellation. This will produce very high quality rendering results (analytical solution rather than approximate solution), but requires GPU to solve cubic equations for quadratic curves.

The Canvas supports multiple color buffers in one off-screen rendering target, which can be used for many complex color blending and temporary operations. Note that depth buffer and depth test is not enabled, Z ordering or transparency sorting is required on the client pipeline before drawing onto the Canvas. All layers are considered translucent and drawn from far to near.

For tree structures, each child canvas may use its transition layers for rendering. These transition layers are designed for short-time alpha animation, and it avoids creating a large number framebuffers.

The root canvas and device is backed by the main render target (a custom framebuffer). Multisampling anti-aliasing (MSAA) should be always enabled.

The projection matrix is globally shared, and the one of surface canvas must be an orthographic projection matrix. Canvas's matrix stack is the local model view matrix on client side, it should be an affine transformation. The pipeline will calculate the world coordinates in advance.

This API is stable.

Since:
  1.6

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `Canvas.VertexMode`
  Supported primitive topologies, corresponding to OpenGL and Vulkan defined values.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final org.apache.logging.log4j.Marker`
  `MARKER`

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `Canvas()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `final void`
  `clear(float r, float g, float b, float a)`
  Fills the current clip with the specified color, using SRC blend mode.
  `final void`
  `clear(int color)`
  Fills the current clip with the specified color, using SRC blend mode.
  `abstract boolean`
  `clipOutRect(float left, float top, float right, float bottom)`
  Set the clip to the difference of the current clip and the specified rectangle, which is expressed in local coordinates.
  `final boolean`
  `clipOutRect(Rect rect)`
  Set the clip to the difference of the current clip and the specified rectangle, which is expressed in local coordinates.
  `final boolean`
  `clipOutRect(RectF rect)`
  Set the clip to the difference of the current clip and the specified rectangle, which is expressed in local coordinates.
  `abstract boolean`
  `clipRect(float left, float top, float right, float bottom)`
  Intersect the current clip with the specified rectangle and updates the stencil buffer if changed, which is expressed in local coordinates.
  `final boolean`
  `clipRect(Rect rect)`
  Intersect the current clip with the specified rectangle and updates the stencil buffer if changed, which is expressed in local coordinates.
  `final boolean`
  `clipRect(RectF rect)`
  Intersect the current clip with the specified rectangle and updates the stencil buffer if changed, which is expressed in local coordinates.
  `abstract void`
  `concat(Matrix4 matrix)`
  Pre-multiply the current matrix by the specified matrix.
  `abstract void`
  `concat(Matrix matrix)`
  Pre-multiply the current matrix by the specified matrix.
  `abstract void`
  `drawArc(float cx, float cy, float radius, float startAngle, float sweepAngle, Paint paint)`
  Draw a circular arc at (cx, cy) with radius using the current matrix, clip and specified paint.
  `abstract void`
  `drawArc(float cx, float cy, float radius, float startAngle, float sweepAngle, Paint.Cap cap, float thickness, Paint paint)`
  Draw a circular arc at (cx, cy) with radius using the current matrix, clip and specified paint.
  `final void`
  `drawArc(PointF center, float radius, float startAngle, float sweepAngle, Paint paint)`
  Variant version of `drawArc(float, float, float, float, float, Paint)`.
  `abstract void`
  `drawBezier(float x0, float y0, float x1, float y1, float x2, float y2, Paint paint)`
  Deprecated.
  use drawPath() instead
  `final void`
  `drawBezier(PointF p0, PointF p1, PointF p2, Paint paint)`
  Deprecated.
  use drawPath() instead
  `abstract void`
  `drawChord(float cx, float cy, float radius, float startAngle, float sweepAngle, Paint paint)`
  Draw a circular segment (i.e., a cut disk) at (cx, cy) with radius using the current matrix, clip and specified paint.
  `final void`
  `drawChord(PointF center, float radius, float startAngle, float sweepAngle, Paint paint)`
  Variant version of `drawChord(float, float, float, float, float, Paint)`.
  `abstract void`
  `drawCircle(float cx, float cy, float radius, Paint paint)`
  Draw the specified circle at (cx, cy) with radius using the specified paint.
  `final void`
  `drawCircle(PointF center, float radius, Paint paint)`
  Variant of `drawCircle(float, float, float, Paint)`.
  `final void`
  `drawColor(float r, float g, float b, float a)`
  Fill the current clip with the specified color, using SRC_OVER blend mode.
  `abstract void`
  `drawColor(float r, float g, float b, float a, BlendMode mode)`
  Fill the current clip with the specified color, the blend mode determines how color is combined with destination.
  `final void`
  `drawColor(int color)`
  Fill the current clip with the specified color, using SRC_OVER blend mode.
  `abstract void`
  `drawColor(int color, BlendMode mode)`
  Fill the current clip with the specified color, the blend mode determines how color is combined with destination.
  `final void`
  `drawCustomDrawable(CustomDrawable drawable)`
  Deprecated.
  `void`
  `drawCustomDrawable(CustomDrawable drawable, Matrix4 matrix)`
  Deprecated.
  `abstract void`
  `drawGlyphs(int[] glyphs, int glyphOffset, float[] positions, int positionOffset, int glyphCount, Font font, float x, float y, Paint paint)`
  Draw array of glyphs with specified font in order visually left-to-right.
  `abstract void`
  `drawImage(Image image, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, Paint paint)`
  Draw the specified image, scaling/translating automatically to fill the destination rectangle.
  `abstract void`
  `drawImage(Image image, float left, float top, Paint paint)`
  Draw the specified image with its top/left corner at (x,y), using the specified paint, transformed by the current matrix.
  `final void`
  `drawImage(Image image, Rect src, RectF dst, Paint paint)`
  Draw the specified image, scaling/translating automatically to fill the destination rectangle.
  `final void`
  `drawImage(Image image, Rect src, Rect dst, Paint paint)`
  Draw the specified image, scaling/translating automatically to fill the destination rectangle.
  `final void`
  `drawLine(float x0, float y0, float x1, float y1, float thickness, Paint paint)`
  Equivalent to `drawLine(float, float, float, float, Paint.Cap, float, Paint)`.
  `abstract void`
  `drawLine(float x0, float y0, float x1, float y1, Paint paint)`
  Draws line segment from (x0, y0) to (x1, y1) using the current matrix, clip and specified paint.
  `abstract void`
  `drawLine(float x0, float y0, float x1, float y1, Paint.Cap cap, float thickness, Paint paint)`
  Draw a line segment from (x0, y0) to (x1, y1) using the specified paint.
  `final void`
  `drawLine(PointF p0, PointF p1, float thickness, Paint paint)`
  Equivalent to `drawLine(float, float, float, float, Paint.Cap, float, Paint)`.
  `final void`
  `drawLine(PointF p0, PointF p1, Paint paint)`
  Draws line segment from (x0, y0) to (x1, y1) using the current matrix, clip and specified paint.
  `final void`
  `drawLineListMesh(FloatBuffer pos, IntBuffer color, Paint paint)`
  Special case of `drawMesh(VertexMode, FloatBuffer, FloatBuffer, IntBuffer, ShortBuffer, BlendMode, Paint)`.
  `abstract void`
  `drawLines(float[] pts, int offset, int count, boolean connected, Paint paint)`
  Draw a series of lines.
  `abstract void`
  `drawMesh(Canvas.VertexMode mode, FloatBuffer positions, FloatBuffer texCoords, IntBuffer colors, ShortBuffer indices, BlendMode blendMode, Paint paint)`
  Draw an instance of a custom mesh with the given vertex data, the vertices are interpreted as the given primitive topology.
  `abstract void`
  `drawPaint(Paint paint)`
  Fills the current clip with the specified paint.
  `abstract void`
  `drawPie(float cx, float cy, float radius, float startAngle, float sweepAngle, Paint paint)`
  Draw a circular sector (i.e., a pie) at (cx, cy) with radius using the current matrix, clip and specified paint.
  `final void`
  `drawPie(PointF center, float radius, float startAngle, float sweepAngle, Paint paint)`
  Variant version of `drawPie(float, float, float, float, float, Paint)`.
  `abstract void`
  `drawPoint(float x, float y, Paint paint)`
  Draws a point centered at (x, y) using the specified paint.
  `final void`
  `drawPoint(PointF p, Paint paint)`
  Draws a point centered at (x, y) using the specified paint.
  `final void`
  `drawPointListMesh(FloatBuffer pos, IntBuffer color, Paint paint)`
  Special case of `drawMesh(VertexMode, FloatBuffer, FloatBuffer, IntBuffer, ShortBuffer, BlendMode, Paint)`.
  `abstract void`
  `drawPoints(float[] pts, int offset, int count, Paint paint)`
  Draw a series of points.
  `final void`
  `drawPoints(float[] pts, Paint paint)`
  Draw a series of points.
  `abstract void`
  `drawRect(float left, float top, float right, float bottom, Paint paint)`
  Draw the specified Rect using the specified paint.
  `final void`
  `drawRect(RectF r, Paint paint)`
  Draw the specified Rect using the specified paint.
  `final void`
  `drawRect(Rect r, Paint paint)`
  Draw the specified Rect using the specified paint.
  `abstract void`
  `drawRectGradient(float left, float top, float right, float bottom, int colorUL, int colorUR, int colorLR, int colorLL, Paint paint)`
  Similar to `drawRect(float, float, float, float, Paint)`, but paint's color and shader are ignored in this case.
  `abstract void`
  `drawRoundImage(Image image, float left, float top, float radius, Paint paint)`
  Deprecated.
  use ImageShader instead
  `void`
  `drawRoundLines(float[] pts, int offset, int count, boolean strip, Paint paint)`
  Deprecated.
  use `drawLines(float[], int, int, boolean, Paint)` instead
  `abstract void`
  `drawRoundRect(float left, float top, float right, float bottom, float radius, int sides, Paint paint)`
  Draw a rectangle with rounded corners within a rectangular bounds.
  `abstract void`
  `drawRoundRect(float left, float top, float right, float bottom, float radius, Paint paint)`
  Draw a rectangle with rounded corners within a rectangular bounds.
  `final void`
  `drawRoundRect(RectF rect, float radius, int sides, Paint paint)`
  Draw a rectangle with rounded corners within a rectangular bounds.
  `final void`
  `drawRoundRect(RectF rect, float radius, Paint paint)`
  Draw a rectangle with rounded corners within a rectangular bounds.
  `abstract void`
  `drawRoundRectGradient(float left, float top, float right, float bottom, int colorUL, int colorUR, int colorLR, int colorLL, float radius, Paint paint)`
  Similar to `drawRoundRect(float, float, float, float, float, Paint)`, but paint's color and shader are ignored in this case.
  `final void`
  `drawShapedText(ShapedText text, float x, float y, Paint paint)`
  Draw a single style run of positioned glyphs in order visually left-to-right, where a single style run may contain multiple BiDi runs and font runs.
  `final void`
  `drawSimpleText(char[] text, Font font, float x, float y, Paint paint)`
  `final void`
  `drawSimpleText(String text, Font font, float x, float y, Paint paint)`
  `abstract void`
  `drawTextBlob(TextBlob blob, float x, float y, Paint paint)`
  `final void`
  `drawTriangleListMesh(FloatBuffer pos, IntBuffer color, Paint paint)`
  Special case of `drawMesh(VertexMode, FloatBuffer, FloatBuffer, IntBuffer, ShortBuffer, BlendMode, Paint)`.
  `abstract void`
  `drawVertices(Canvas.VertexMode mode, int vertexCount, float[] positions, int positionOffset, float[] texCoords, int texCoordOffset, int[] colors, int colorOffset, short[] indices, int indexOffset, int indexCount, BlendMode blendMode, Paint paint)`
  Draw an instance of a custom mesh with the given vertex data, the vertices are interpreted as the given primitive topology.
  `abstract boolean`
  `getLocalClipBounds(RectF bounds)`
  Return the bounds of the current clip (in local coordinates) in the bounds parameter, and return true if it is non-empty.
  `abstract int`
  `getSaveCount()`
  Returns the depth of saved matrix/clip states on the Canvas' private stack.
  `abstract boolean`
  `isClipEmpty()`
  Returns true if clip is empty; that is, nothing will draw.
  `abstract boolean`
  `isClipRect()`
  Returns true if clip is a Rect and not empty.
  `abstract boolean`
  `quickReject(float left, float top, float right, float bottom)`
  Return true if the specified rectangle, after being transformed by the current matrix, would lie completely outside the current clip.
  `final boolean`
  `quickReject(RectF rect)`
  Return true if the specified rectangle, after being transformed by the current matrix, would lie completely outside the current clip.
  `abstract void`
  `restore()`
  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.
  `abstract void`
  `restoreToCount(int saveCount)`
  Efficient way to pop any calls to save() that happened after the save count reached saveCount.
  `abstract void`
  `rotate(float degrees)`
  Rotates the current matrix by degrees clockwise about the Z axis.
  `abstract void`
  `rotate(float degrees, float px, float py)`
  Rotates the current matrix by degrees clockwise about the Z axis at (px, py).
  `abstract int`
  `save()`
  Saves the current matrix and clip onto a private stack.
  `abstract int`
  `saveLayer(float left, float top, float right, float bottom, int alpha)`
  Deprecated.
  this method does nothing, you should manually create a layer, or possibly manage a pool of layers, or use
  invalid reference

      icyllis.modernui.view.View#LAYER_TYPE_HARDWARE

  .
  `final int`
  `saveLayer(RectF bounds, int alpha)`
  Deprecated.
  this method does nothing, you should manually create a layer, or possibly manage a pool of layers, or use
  invalid reference

      icyllis.modernui.view.View#LAYER_TYPE_HARDWARE

  .
  `abstract void`
  `scale(float sx, float sy)`
  Scales the current matrix by sx on the x-axis and sy on the y-axis.
  `abstract void`
  `scale(float sx, float sy, float sz)`
  Scales the current matrix by sx on the x-axis, sy on the y-axis, and sz on the z-axis.
  `abstract void`
  `scale(float sx, float sy, float px, float py)`
  Scales the current matrix by sx on the x-axis and sy on the y-axis at (px, py).
  `abstract void`
  `shear(float sx, float sy)`
  Shears the current matrix by sx on the x-axis and sy on the y-axis.
  `abstract void`
  `shear(float sx, float sy, float px, float py)`
  Pre-multiply the current matrix by the specified shearing.
  `final void`
  `skew(float sx, float sy)`
  Pre-multiply the current matrix by the specified skew.
  `final void`
  `skew(float sx, float sy, float px, float py)`
  Pre-multiply the current matrix by the specified skew.
  `abstract void`
  `translate(float dx, float dy)`
  Translates the current matrix by dx along the x-axis and dy along the y-axis.
  `abstract void`
  `translate(float dx, float dy, float dz)`
  Translates the current matrix by dx along the x-axis, dy along the y-axis, and dz along the z-axis.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### MARKER

    public static final org.apache.logging.log4j.Marker MARKER

- ## Constructor Details

  - ### Canvas

    protected Canvas()

- ## Method Details

  - ### save

    public abstract int save()
    Saves the current matrix and clip onto a private stack.

    Subsequent calls to translate, scale, rotate, shear, concat or clipRect, clipPath will all operate as usual, but when the balancing call to restore() is made, those calls will be forgotten, and the settings that existed before the save() will be reinstated.

    Saved Canvas state is put on a stack; multiple calls to save() should be balance by an equal number of calls to restore(). Call restoreToCount() with the return value of this method to restore this and subsequent saves.

    Returns:
      depth of saved stack to pass to restoreToCount() to balance this call

  - ### saveLayer

    @Deprecated public final int saveLayer(@Nullable RectF bounds, int alpha)
    Deprecated.
    this method does nothing, you should manually create a layer, or possibly manage a pool of layers, or use
    invalid reference

        icyllis.modernui.view.View#LAYER_TYPE_HARDWARE

    .
    This behaves the same as `save()`, but in addition it allocates and redirects drawing to an offscreen rendering target.

    Note: this method is very expensive, incurring more than double rendering cost for contained content. Avoid using this method when possible.

    All drawing calls are directed to a newly allocated offscreen rendering target. Only when the balancing call to restore() is made, is that offscreen buffer drawn back to the current target of the Canvas (which can potentially be a previous layer if these calls are nested).

    Parameters:
      `bounds` - May be null. The maximum size the offscreen render target needs to be (in local coordinates)
      `alpha` - The alpha to apply to the offscreen when it is drawn during restore()
    Returns:
      value to pass to restoreToCount() to balance this call

  - ### saveLayer

    @Deprecated public abstract int saveLayer(float left, float top, float right, float bottom, int alpha)
    Deprecated.
    this method does nothing, you should manually create a layer, or possibly manage a pool of layers, or use
    invalid reference

        icyllis.modernui.view.View#LAYER_TYPE_HARDWARE

    .
    Convenience for `saveLayer(RectF, int)` that takes the four float coordinates of the bounds' rectangle.
    See Also:
      - `saveLayer(RectF, int)`

  - ### restore

    public abstract void restore()
    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. The state is removed from the stack. It is an error to call restore() more or less times than save() was called in the final state.

  - ### getSaveCount

    public abstract int getSaveCount()
    Returns the depth of saved matrix/clip states on the Canvas' private stack. This will equal save() calls minus restore() calls, and the number of save() calls less the number of restore() calls plus one. The save count of a new canvas is one.
    Returns:
      depth of save state stack

  - ### restoreToCount

    public abstract void restoreToCount(int saveCount)
    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 1.

    Example:

         int count = canvas.save();
         ... // more calls potentially to save()
         canvas.restoreToCount(count);
         // now the canvas is back in the same state it
         // was before the initial call to save().

    Parameters:
      `saveCount` - the depth of state stack to restore
    Throws:
      `IllegalStateException` - stack underflow (i.e. saveCount is less than 1)

  - ### translate

    public abstract void translate(float dx, float dy)
    Translates the current matrix by dx along the x-axis and dy along the y-axis. Mathematically, pre-multiply the current matrix with a translation matrix.

    This has the effect of moving the drawing by (dx, dy) before transforming the result with the current matrix.

    Parameters:
      `dx` - the distance to translate on x-axis
      `dy` - the distance to translate on y-axis

  - ### translate

    public abstract void translate(float dx, float dy, float dz)
    Translates the current matrix by dx along the x-axis, dy along the y-axis, and dz along the z-axis. Mathematically, pre-multiply the current matrix with a translation matrix.

    This has the effect of moving the drawing by (dx, dy, dz) before transforming the result with the current matrix.

    Parameters:
      `dx` - the distance to translate on x-axis
      `dy` - the distance to translate on y-axis
      `dz` - the distance to translate on z-axis

  - ### scale

    public abstract void scale(float sx, float sy)
    Scales the current matrix by sx on the x-axis and sy on the y-axis. Mathematically, pre-multiply the current matrix with a scaling matrix.

    This has the effect of scaling the drawing by (sx, sy) before transforming the result with the current matrix.

    Parameters:
      `sx` - the amount to scale on x-axis
      `sy` - the amount to scale on y-axis

  - ### scale

    public abstract void scale(float sx, float sy, float sz)
    Scales the current matrix by sx on the x-axis, sy on the y-axis, and sz on the z-axis. Mathematically, pre-multiply the current matrix with a scaling matrix.

    This has the effect of scaling the drawing by (sx, sy, sz) before transforming the result with the current matrix.

    Parameters:
      `sx` - the amount to scale on x-axis
      `sy` - the amount to scale on y-axis
      `sz` - the amount to scale on z-axis

  - ### scale

    public abstract void scale(float sx, float sy, float px, float py)
    Scales the current matrix by sx on the x-axis and sy on the y-axis at (px, py). Mathematically, pre-multiply the current matrix with a translation matrix; pre-multiply the current matrix with a scaling matrix; then pre-multiply the current matrix with a negative translation matrix;

    This has the effect of scaling the drawing by (sx, sy) before transforming the result with the current matrix.

    Parameters:
      `sx` - the amount to scale on x-axis
      `sy` - the amount to scale on y-axis
      `px` - the x-coord for the pivot point (unchanged by the scale)
      `py` - the y-coord for the pivot point (unchanged by the scale)

  - ### rotate

    public abstract void rotate(float degrees)
    Rotates the current matrix by degrees clockwise about the Z axis. Mathematically, pre-multiply the current matrix with a rotation matrix;

    This has the effect of rotating the drawing by degrees before transforming the result with the current matrix.

    Parameters:
      `degrees` - the amount to rotate, in degrees

  - ### rotate

    public abstract void rotate(float degrees, float px, float py)
    Rotates the current matrix by degrees clockwise about the Z axis at (px, py). Mathematically, pre-multiply the current matrix with a translation matrix; pre-multiply the current matrix with a rotation matrix; then pre-multiply the current matrix with a negative translation matrix;

    This has the effect of rotating the drawing by degrees before transforming the result with the current matrix.

    Parameters:
      `degrees` - the amount to rotate, in degrees
      `px` - the x-coord for the pivot point (unchanged by the rotation)
      `py` - the y-coord for the pivot point (unchanged by the rotation)

  - ### skew

    public final void skew(float sx, float sy)
    Pre-multiply the current matrix by the specified skew. This method is equivalent to calling `shear(float, float)`.
    Parameters:
      `sx` - The amount to skew in X
      `sy` - The amount to skew in Y

  - ### skew

    public final void skew(float sx, float sy, float px, float py)
    Pre-multiply the current matrix by the specified skew. This method is equivalent to calling `shear(float, float)`.
    Parameters:
      `sx` - The amount to skew in X
      `sy` - The amount to skew in Y
      `px` - The x-coord for the pivot point (unchanged by the skew)
      `py` - The y-coord for the pivot point (unchanged by the skew)

  - ### shear

    public abstract void shear(float sx, float sy)
    Shears the current matrix by sx on the x-axis and sy on the y-axis. A positive value of sx shears the drawing right as y-axis values increase; a positive value of sy shears the drawing down as x-axis values increase.

    Mathematically, pre-multiply the current matrix with a shearing matrix.

    This has the effect of shearing the drawing by (sx, sy) before transforming the result with the current matrix.

    Parameters:
      `sx` - the amount to shear on x-axis
      `sy` - the amount to shear on y-axis

  - ### shear

    public abstract void shear(float sx, float sy, float px, float py)
    Pre-multiply the current matrix by the specified shearing.
    Parameters:
      `sx` - the x-component of the shearing, y is unchanged
      `sy` - the y-component of the shearing, x is unchanged
      `px` - the x-component of the pivot (unchanged by the shear)
      `py` - the y-component of the pivot (unchanged by the shear)

  - ### concat

    public abstract void concat(@NonNull Matrix matrix)
    Pre-multiply the current matrix by the specified matrix.

    This has the effect of transforming the drawn geometry by matrix, before transforming the result with the current matrix.

    Parameters:
      `matrix` - the matrix to premultiply with the current matrix

  - ### concat

    @Experimental public abstract void concat(@NonNull Matrix4 matrix)
    Pre-multiply the current matrix by the specified matrix.

    This has the effect of transforming the drawn geometry by matrix, before transforming the result with the current matrix.

    Parameters:
      `matrix` - the matrix to premultiply with the current matrix

  - ### clipRect

    public final boolean clipRect(@NonNull Rect rect)
    Intersect the current clip with the specified rectangle and updates the stencil buffer if changed, which is expressed in local coordinates. The clip bounds cannot be expanded unless restore() is called.
    Parameters:
      `rect` - The rectangle to intersect with the current clip.
    Returns:
      true if the resulting clip is non-empty, otherwise further drawing will be always quick rejected until restore() is called

  - ### clipRect

    public final boolean clipRect(@NonNull RectF rect)
    Intersect the current clip with the specified rectangle and updates the stencil buffer if changed, which is expressed in local coordinates. The clip bounds cannot be expanded unless restore() is called.
    Parameters:
      `rect` - The rectangle to intersect with the current clip.
    Returns:
      true if the resulting clip is non-empty, otherwise further drawing will be always quick rejected until restore() is called

  - ### clipRect

    public abstract boolean clipRect(float left, float top, float right, float bottom)
    Intersect the current clip with the specified rectangle and updates the stencil buffer if changed, which is expressed in local coordinates. The clip bounds cannot be expanded unless restore() is called.
    Parameters:
      `left` - The left side of the rectangle to intersect with the current clip
      `top` - The top of the rectangle to intersect with the current clip
      `right` - The right side of the rectangle to intersect with the current clip
      `bottom` - The bottom of the rectangle to intersect with the current clip
    Returns:
      true if the resulting clip is non-empty, otherwise further drawing will be always quick rejected until restore() is called

  - ### clipOutRect

    public final boolean clipOutRect(@NonNull Rect rect)
    Set the clip to the difference of the current clip and the specified rectangle, which is expressed in local coordinates.
    Parameters:
      `rect` - The rectangle to perform a difference op with the current clip.
    Returns:
      true if the resulting clip is non-empty

  - ### clipOutRect

    public final boolean clipOutRect(@NonNull RectF rect)
    Set the clip to the difference of the current clip and the specified rectangle, which is expressed in local coordinates.
    Parameters:
      `rect` - The rectangle to perform a difference op with the current clip.
    Returns:
      true if the resulting clip is non-empty

  - ### clipOutRect

    public abstract boolean clipOutRect(float left, float top, float right, float bottom)
    Set the clip to the difference of the current clip and the specified rectangle, which is expressed in local coordinates.
    Parameters:
      `left` - The left side of the rectangle used in the difference operation
      `top` - The top of the rectangle used in the difference operation
      `right` - The right side of the rectangle used in the difference operation
      `bottom` - The bottom of the rectangle used in the difference operation
    Returns:
      true if the resulting clip is non-empty

  - ### quickReject

    public final boolean quickReject(@NonNull RectF rect)
    Return true if the specified rectangle, after being transformed by the current matrix, would lie completely outside 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). May return false even though rect is outside of clip (conservative).

    Note that each draw all will check this internally. This is used to skip subsequent draw calls.

    Parameters:
      `rect` - the rect to compare with the current clip
    Returns:
      true if the given rect (transformed by the canvas' matrix) intersecting with the maximum rect representing the canvas' clip is empty

  - ### quickReject

    public abstract boolean quickReject(float left, float top, float right, float bottom)
    Return true if the specified rectangle, after being transformed by the current matrix, would lie completely outside 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). May return false even though rect is outside of clip (conservative).

    Note that each draw all will check this internally. This is used to skip subsequent draw calls.

    Parameters:
      `left` - the left side of the rectangle to compare with the current clip
      `top` - the top of the rectangle to compare with the current clip
      `right` - the right side of the rectangle to compare with the current clip
      `bottom` - the bottom of the rectangle to compare with the current clip
    Returns:
      true if the given rect (transformed by the canvas' matrix) intersecting with the maximum rect representing the canvas' clip is empty

  - ### getLocalClipBounds

    public abstract boolean getLocalClipBounds(@NonNull RectF bounds)
    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.
    Parameters:
      `bounds` - Return the clip bounds here.
    Returns:
      true if the current clip is non-empty.

  - ### clear

    public final void clear(@ColorInt int color)
    Fills the current clip with the specified color, using SRC blend mode. This has the effect of replacing all pixels contained by clip with color.
    Parameters:
      `color` - the un-premultiplied (straight) color to draw onto the canvas

  - ### clear

    public final void clear(float r, float g, float b, float a)
    Fills the current clip with the specified color, using SRC blend mode. This has the effect of replacing all pixels contained by clip with color.
    Parameters:
      `r` - the red component of the straight color to draw onto the canvas
      `g` - the red component of the straight color to draw onto the canvas
      `b` - the red component of the straight color to draw onto the canvas
      `a` - the red component of the straight color to draw onto the canvas

  - ### drawColor

    public final void drawColor(@ColorInt int color)
    Fill the current clip with the specified color, using SRC_OVER blend mode.
    Parameters:
      `color` - the straight color to draw onto the canvas

  - ### drawColor

    public final void drawColor(float r, float g, float b, float a)
    Fill the current clip with the specified color, using SRC_OVER blend mode.
    Parameters:
      `r` - the red component of the straight color to draw onto the canvas
      `g` - the red component of the straight color to draw onto the canvas
      `b` - the red component of the straight color to draw onto the canvas
      `a` - the red component of the straight color to draw onto the canvas

  - ### drawColor

    public abstract void drawColor(@ColorInt int color, @NonNull BlendMode mode)
    Fill the current clip with the specified color, the blend mode determines how color is combined with destination.
    Parameters:
      `color` - the straight color to draw onto the canvas
      `mode` - the blend mode used to combine source color and destination

  - ### drawColor

    public abstract void drawColor(float r, float g, float b, float a, @NonNull BlendMode mode)
    Fill the current clip with the specified color, the blend mode determines how color is combined with destination.
    Parameters:
      `r` - the red component of the straight color to draw onto the canvas
      `g` - the red component of the straight color to draw onto the canvas
      `b` - the red component of the straight color to draw onto the canvas
      `a` - the red component of the straight color to draw onto the canvas
      `mode` - the blend mode used to combine source color and destination

  - ### drawPaint

    public abstract void drawPaint(@NonNull Paint paint)
    Fills the current clip with the specified paint. Paint components, Shader, ColorFilter, ImageFilter, and BlendMode affect drawing.

    This is equivalent (but faster) to drawing an infinitely large rectangle with the specified paint.

    Parameters:
      `paint` - the paint used to draw onto the canvas

  - ### drawPoint

    public abstract void drawPoint(float x, float y, @NonNull Paint paint)
    Draws a point centered at (x, y) using the specified paint.

    The shape of point drawn depends on paint's cap. If paint is set to `Paint.CAP_ROUND`, draw a circle of diameter paint stroke width (as transformed by the canvas' matrix), with special treatment for a stroke width of 0, which always draws exactly 1 pixel (or at most 4 if anti-aliasing is enabled). Otherwise, draw a square of width and height paint stroke width. Paint's style is ignored, as if were set to `Paint.STROKE`.

    Parameters:
      `x` - the center x of circle or square
      `y` - the center y of circle or square
      `paint` - the paint used to draw the point

  - ### drawPoint

    public final void drawPoint(@NonNull PointF p, @NonNull Paint paint)
    Draws a point centered at (x, y) using the specified paint.

    The shape of point drawn depends on paint's cap. If paint is set to `Paint.CAP_ROUND`, draw a circle of diameter paint stroke width (as transformed by the canvas' matrix), with special treatment for a stroke width of 0, which always draws exactly 1 pixel (or at most 4 if anti-aliasing is enabled). Otherwise, draw a square of width and height paint stroke width. Paint's style is ignored, as if were set to `Paint.FILL`.

    Parameters:
      `p` - the center point of circle or square
      `paint` - the paint used to draw the point

  - ### drawPoints

    public abstract void drawPoints(@Size(multiple=2L) @NonNull float[] pts, int offset, int count, @NonNull Paint paint)
    Draw a series of points. Each point is centered at the coordinate specified by pts[], and its diameter is specified by the paint's stroke width (as transformed by the canvas' CTM), with special treatment for a stroke width of 0, which always draws exactly 1 pixel (or at most 4 if anti-aliasing is enabled). The shape of the point is controlled by the paint's Cap type. The shape is a square, unless the cap type is Round, in which case the shape is a circle. If count is odd, the last value is ignored.
    Parameters:
      `pts` - the array of points to draw [x0 y0 x1 y1 x2 y2 ...]
      `offset` - the number of values to skip before starting to draw.
      `count` - the number of values to process, after skipping offset of them. Since one point uses two values, the number of "points" that are drawn is really (count >> 1).
      `paint` - the paint used to draw the points

  - ### drawPoints

    public final void drawPoints(@Size(multiple=2L) @NonNull float[] pts, @NonNull Paint paint)
    Draw a series of points. Each point is centered at the coordinate specified by pts[], and its diameter is specified by the paint's stroke width (as transformed by the canvas' CTM), with special treatment for a stroke width of 0, which always draws exactly 1 pixel (or at most 4 if anti-aliasing is enabled). The shape of the point is controlled by the paint's Cap type. The shape is a square, unless the cap type is Round, in which case the shape is a circle. If count is odd, the last value is ignored.
    Parameters:
      `pts` - the array of points to draw [x0 y0 x1 y1 x2 y2 ...]
      `paint` - the paint used to draw the points

  - ### drawLine

    public abstract void drawLine(float x0, float y0, float x1, float y1, @NonNull Paint paint)
    Draws line segment from (x0, y0) to (x1, y1) using the current matrix, clip and specified paint. In paint: stroke width describes the line thickness; Cap draws the end rounded or square; Style is ignored, as if were set to `Paint.STROKE`.
    Parameters:
      `x0` - start of line segment on x-axis
      `y0` - start of line segment on y-axis
      `x1` - end of line segment on x-axis
      `y1` - end of line segment on y-axis
      `paint` - the paint used to draw the line

  - ### drawLine

    public final void drawLine(@NonNull PointF p0, @NonNull PointF p1, @NonNull Paint paint)
    Draws line segment from (x0, y0) to (x1, y1) using the current matrix, clip and specified paint. In paint: stroke width describes the line thickness; Cap draws the end rounded or square; Style is ignored, as if were set to `Paint.STROKE`.
    Parameters:
      `p0` - start of line segment
      `p1` - end of line segment
      `paint` - the paint used to draw the line

  - ### drawLine

    public abstract void drawLine(float x0, float y0, float x1, float y1, @NonNull Paint.Cap cap, float thickness, @NonNull Paint paint)
    Draw a line segment from (x0, y0) to (x1, y1) using the specified paint.

    Line covers an area, and is not a stroke path in the concept of Modern UI. Therefore, a line may be either "filled" (path) or "stroked" (annular, hollow), depending on paint's style. Additionally, paint's cap draws the end rounded or square, if filled; the other properties of paint work as intended.

    If thickness = 0 (also known as hairline), then this uses the mesh version. See `drawLineListMesh(FloatBuffer, IntBuffer, Paint)` for the mesh version.

    Parameters:
      `x0` - the start of the line segment on x-axis
      `y0` - the start of the line segment on y-axis
      `x1` - the end of the line segment on x-axis
      `y1` - the end of the line segment on y-axis
      `cap` - the line end used to determine the shape of the line
      `thickness` - the thickness of the line segment
      `paint` - the paint used to draw the line segment

  - ### drawLine

    public final void drawLine(float x0, float y0, float x1, float y1, float thickness, @NonNull Paint paint)
    Equivalent to `drawLine(float, float, float, float, Paint.Cap, float, Paint)`. with a round cap.
    Parameters:
      `x0` - the start of the line segment on x-axis
      `y0` - the start of the line segment on y-axis
      `x1` - the end of the line segment on x-axis
      `y1` - the end of the line segment on y-axis
      `thickness` - the thickness of the line segment
      `paint` - the paint used to draw the line segment

  - ### drawLine

    public final void drawLine(@NonNull PointF p0, @NonNull PointF p1, float thickness, @NonNull Paint paint)
    Equivalent to `drawLine(float, float, float, float, Paint.Cap, float, Paint)`. with a round cap.
    Parameters:
      `p0` - start of line segment
      `p1` - end of line segment
      `thickness` - the thickness of the line segment
      `paint` - the paint used to draw the line

  - ### drawLines

    public abstract void drawLines(@Size(multiple=2L) @NonNull float[] pts, int offset, int count, boolean connected, @NonNull Paint paint)
    Draw a series of lines.

    If connected is false, each line is taken from 4 consecutive values in the pts array. Thus, to draw 1 line, the array must contain at least 4 values. This is logically the same as drawing the array as follows: drawLine(pts[0], pts[1], pts[2], pts[3]) followed by drawLine(pts[4], pts[5], pts[6], pts[7]) and so on.

    If connected is true, the first line is taken from 4 consecutive values in the pts array, and each remaining line is taken from last 2 values and next 2 values in the array. Thus, to draw 1 line, the array must contain at least 4 values. This is logically the same as drawing the array as follows: drawLine(pts[0], pts[1], pts[2], pts[3]) followed by drawLine(pts[2], pts[3], pts[4], pts[5]) and so on.

    Parameters:
      `pts` - The array of points of the lines to draw [x0 y0 x1 y1 x2 y2 ...]
      `offset` - Number of values in the array to skip before drawing.
      `count` - The number of values in the array to process, after skipping "offset" of them. Since each line uses 4 values, the number of "lines" that are drawn is really (count >> 2) if connected, or ((count - 2) >> 1) if separate.
      `connected` - Whether line points are connected
      `paint` - The paint used to draw the lines

  - ### drawRoundLines

    @Deprecated public void drawRoundLines(float[] pts, int offset, int count, boolean strip, Paint paint)
    Deprecated.
    use `drawLines(float[], int, int, boolean, Paint)` instead
    Draw a series of round lines.

    When discontinuous, each line is taken from 4 consecutive values in the pts array. Thus, to draw 1 line, the array must contain at least 4 values. This is logically the same as drawing the array as follows: drawLine(pts[0], pts[1], pts[2], pts[3]) followed by drawLine(pts[4], pts[5], pts[6], pts[7]) and so on.

    When continuous, the first line is taken from 4 consecutive values in the pts array, and each remaining line is taken from last 2 values and next 2 values in the array. Thus, to draw 1 line, the array must contain at least 4 values. This is logically the same as drawing the array as follows: drawLine(pts[0], pts[1], pts[2], pts[3]) followed by drawLine(pts[2], pts[3], pts[4], pts[5]) and so on.

    Parameters:
      `pts` - The array of points of the lines to draw [x0 y0 x1 y1 x2 y2 ...]
      `offset` - Number of values in the array to skip before drawing.
      `count` - The number of values in the array to process, after skipping "offset" of them. Since each line uses 4 values, the number of "lines" that are drawn is really (count >> 2) if continuous, or ((count - 2) >> 1) if discontinuous.
      `strip` - Whether line points are continuous
      `paint` - The paint used to draw the lines

  - ### drawRect

    public final void drawRect(@NonNull RectF r, @NonNull Paint paint)
    Draw the specified Rect using the specified paint. In paint: Paint's style determines if rectangle is stroked or filled; if stroked, Paint's stroke width describes the line thickness, and Paint's join draws the corners rounded or square.
    Parameters:
      `r` - the rectangle to be drawn.
      `paint` - the paint used to draw the rectangle

  - ### drawRect

    public final void drawRect(@NonNull Rect r, @NonNull Paint paint)
    Draw the specified Rect using the specified paint. In paint: Paint's style determines if rectangle is stroked or filled; if stroked, Paint's stroke width describes the line thickness, and Paint's join draws the corners rounded or square.
    Parameters:
      `r` - the rectangle to be drawn.
      `paint` - the paint used to draw the rectangle

  - ### drawRect

    public abstract void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)
    Draw the specified Rect using the specified paint. In paint: Paint's style determines if rectangle is stroked or filled; if stroked, Paint's stroke width describes the line thickness, and Paint's join draws the corners rounded or square.
    Parameters:
      `left` - the left side of the rectangle to be drawn
      `top` - the top side of the rectangle to be drawn
      `right` - the right side of the rectangle to be drawn
      `bottom` - the bottom side of the rectangle to be drawn
      `paint` - the paint used to draw the rect

  - ### drawRectGradient

    @Experimental public abstract void drawRectGradient(float left, float top, float right, float bottom, int colorUL, int colorUR, int colorLR, int colorLL, Paint paint)
    Similar to `drawRect(float, float, float, float, Paint)`, but paint's color and shader are ignored in this case. Instead, draw a bilinear gradient with the four given colors, in 0xAARRGGBB format, in the sRGB color space.
    Parameters:
      `left` - the left side of the rectangle to be drawn
      `top` - the top side of the rectangle to be drawn
      `right` - the right side of the rectangle to be drawn
      `bottom` - the bottom side of the rectangle to be drawn
      `colorUL` - the color of the upper left corner
      `colorUR` - the color of the upper right corner
      `colorLR` - the color of the lower right corner
      `colorLL` - the color of the lower left corner
      `paint` - the paint used to draw the rect

  - ### drawRoundRect

    public final void drawRoundRect(@NonNull RectF rect, float radius, @NonNull Paint paint)
    Draw a rectangle with rounded corners within a rectangular bounds. The round rectangle will be filled or framed based on the Style in the paint.
    Parameters:
      `rect` - The rectangular bounds of the round rect to be drawn
      `radius` - the radius used to round the corners
      `paint` - the paint used to draw the round rectangle

  - ### drawRoundRect

    public abstract void drawRoundRect(float left, float top, float right, float bottom, float radius, @NonNull Paint paint)
    Draw a rectangle with rounded corners within a rectangular bounds. The round rectangle will be filled or framed based on the Style in the paint.
    Parameters:
      `left` - the left of the rectangular bounds
      `top` - the top of the rectangular bounds
      `right` - the right of the rectangular bounds
      `bottom` - the bottom of the rectangular bounds
      `radius` - the radius used to round the corners
      `paint` - the paint used to draw the round rectangle

  - ### drawRoundRect

    public final void drawRoundRect(@NonNull RectF rect, float radius, int sides, @NonNull Paint paint)
    Draw a rectangle with rounded corners within a rectangular bounds. The round rectangle will be filled or framed based on the Style in the paint.
    Parameters:
      `rect` - The rectangular bounds of the round rect to be drawn
      `radius` - the radius used to round the corners
      `sides` - the side to round, accepted values are 0 (all sides), or one of `Gravity.TOP`, `Gravity.BOTTOM`, `Gravity.LEFT`, `Gravity.RIGHT`, or any combination of two adjacent sides
      `paint` - the paint used to draw the round rectangle

  - ### drawRoundRect

    public abstract void drawRoundRect(float left, float top, float right, float bottom, float radius, int sides, @NonNull Paint paint)
    Draw a rectangle with rounded corners within a rectangular bounds. The round rectangle will be filled or framed based on the Style in the paint.
    Parameters:
      `left` - the left of the rectangular bounds
      `top` - the top of the rectangular bounds
      `right` - the right of the rectangular bounds
      `bottom` - the bottom of the rectangular bounds
      `radius` - the radius used to round the corners
      `sides` - the side to round, accepted values are 0 (all sides), or one of `Gravity.TOP`, `Gravity.BOTTOM`, `Gravity.LEFT`, `Gravity.RIGHT`, or any combination of two adjacent sides
      `paint` - the paint used to draw the round rectangle

  - ### drawRoundRectGradient

    @Experimental public abstract void drawRoundRectGradient(float left, float top, float right, float bottom, int colorUL, int colorUR, int colorLR, int colorLL, float radius, Paint paint)
    Similar to `drawRoundRect(float, float, float, float, float, Paint)`, but paint's color and shader are ignored in this case. Instead, draw a bilinear gradient with the four given colors, in 0xAARRGGBB format, in the sRGB color space.
    Parameters:
      `left` - the left of the rectangular bounds
      `top` - the top of the rectangular bounds
      `right` - the right of the rectangular bounds
      `bottom` - the bottom of the rectangular bounds
      `colorUL` - the color of the upper left corner
      `colorUR` - the color of the upper right corner
      `colorLR` - the color of the lower right corner
      `colorLL` - the color of the lower left corner
      `radius` - the radius used to round the corners
      `paint` - the paint used to draw the round rectangle

  - ### drawCircle

    public abstract void drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
    Draw the specified circle at (cx, cy) with radius using the specified paint. If radius is zero or less, nothing is drawn. In paint: Paint's style determines if circle is stroked or filled; if stroked, paint's stroke width describes the line thickness.
    Parameters:
      `cx` - the x-coordinate of the center of the circle to be drawn
      `cy` - the y-coordinate of the center of the circle to be drawn
      `radius` - the radius of the circle to be drawn
      `paint` - the paint used to draw the circle

  - ### drawCircle

    public final void drawCircle(@NonNull PointF center, float radius, @NonNull Paint paint)
    Variant of `drawCircle(float, float, float, Paint)`.
    Parameters:
      `center` - the center point of the circle to be drawn
      `radius` - the radius of the circle to be drawn
      `paint` - the paint used to draw the circle

  - ### drawArc

    public abstract void drawArc(float cx, float cy, float radius, float startAngle, float sweepAngle, @NonNull Paint paint)
    Draw a circular arc at (cx, cy) with radius using the current matrix, clip and specified paint.

    If the start angle is negative or >= 360, the start angle is treated as start angle modulo 360. If the sweep angle is >= 360, then the circle is drawn completely. If the sweep angle is negative, the sweep angle is treated as sweep angle modulo 360.

    The arc is drawn clockwise. An angle of 0 degrees correspond to the geometric angle of 0 degrees (3 o'clock on a watch). If radius is non-positive or sweep angle is zero, nothing is drawn.

    Parameters:
      `cx` - the x-coordinate of the center of the arc to be drawn
      `cy` - the y-coordinate of the center of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `paint` - the paint used to draw the arc

  - ### drawArc

    public final void drawArc(@NonNull PointF center, float radius, float startAngle, float sweepAngle, @NonNull Paint paint)
    Variant version of `drawArc(float, float, float, float, float, Paint)`.
    Parameters:
      `center` - the center point of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `paint` - the paint used to draw the arc

  - ### drawArc

    public abstract void drawArc(float cx, float cy, float radius, float startAngle, float sweepAngle, @NonNull Paint.Cap cap, float thickness, @NonNull Paint paint)
    Draw a circular arc at (cx, cy) with radius using the current matrix, clip and specified paint. Note that arc shape is a stroked arc rather than an arc path, you can fill or stroke the stroked arc.

    If the start angle is negative or >= 360, the start angle is treated as start angle modulo 360. If the sweep angle is >= 360, then the circle is drawn completely. If the sweep angle is negative, the sweep angle is treated as sweep angle modulo 360.

    The arc is drawn clockwise. An angle of 0 degrees correspond to the geometric angle of 0 degrees (3 o'clock on a watch). If radius is non-positive or sweep angle is zero, nothing is drawn.

    The cap describes the end of the arc shape, the width describes the arc shape thickness. In paint: Style determines if arc shape is stroked or filled; If stroked (i.e. double stroke), stroke width describes the shape outline thickness, Cap describes line ends, Join draws the corners rounded or square, and Align determines the position or direction to stroke.

    Parameters:
      `cx` - the x-coordinate of the center of the arc to be drawn
      `cy` - the y-coordinate of the center of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `cap` - the line end used to determine the shape of the arc
      `thickness` - the thickness of arc segment
      `paint` - the paint used to draw the arc

  - ### drawPie

    public abstract void drawPie(float cx, float cy, float radius, float startAngle, float sweepAngle, @NonNull Paint paint)
    Draw a circular sector (i.e., a pie) at (cx, cy) with radius using the current matrix, clip and specified paint.

    Similar to `drawArc(float, float, float, float, float, Paint)`, but when the shape is not a full circle, the geometry is closed by the arc and two line segments from the end of the arc to the center of the circle.

    Parameters:
      `cx` - the x-coordinate of the center of the arc to be drawn
      `cy` - the y-coordinate of the center of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `paint` - the paint used to draw the arc

  - ### drawPie

    public final void drawPie(@NonNull PointF center, float radius, float startAngle, float sweepAngle, @NonNull Paint paint)
    Variant version of `drawPie(float, float, float, float, float, Paint)`.
    Parameters:
      `center` - the center point of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `paint` - the paint used to draw the arc

  - ### drawChord

    public abstract void drawChord(float cx, float cy, float radius, float startAngle, float sweepAngle, @NonNull Paint paint)
    Draw a circular segment (i.e., a cut disk) at (cx, cy) with radius using the current matrix, clip and specified paint.

    Similar to `drawArc(float, float, float, float, float, Paint)`, but when the shape is not a full circle, the geometry is closed by the arc and a line segment from the start of the arc segment to the end of the arc segment.

    Parameters:
      `cx` - the x-coordinate of the center of the arc to be drawn
      `cy` - the y-coordinate of the center of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `paint` - the paint used to draw the arc

  - ### drawChord

    public final void drawChord(@NonNull PointF center, float radius, float startAngle, float sweepAngle, @NonNull Paint paint)
    Variant version of `drawChord(float, float, float, float, float, Paint)`.
    Parameters:
      `center` - the center point of the arc to be drawn
      `radius` - the radius of the circular arc to be drawn
      `startAngle` - starting angle (in degrees) where the arc begins
      `sweepAngle` - sweep angle or angular extent (in degrees); positive is clockwise
      `paint` - the paint used to draw the arc

  - ### drawBezier

    @Deprecated public abstract void drawBezier(float x0, float y0, float x1, float y1, float x2, float y2, Paint paint)
    Deprecated.
    use drawPath() instead
    Draw a quadratic Bézier curve using the specified paint. The three points represent the starting point, the first control point and the end control point respectively.

    The style is ignored in the paint, Bézier curves are always stroked. The stroke width in the paint represents the width of the curve.

    Note that the distance from a point to the quadratic curve requires the GPU to solve cubic equations. Therefore, this method has higher overhead to the GPU.

    Parameters:
      `x0` - the x-coordinate of the starting point of the Bézier curve
      `y0` - the y-coordinate of the starting point of the Bézier curve
      `x1` - the x-coordinate of the first control point of the Bézier curve
      `y1` - the y-coordinate of the first control point of the Bézier curve
      `x2` - the x-coordinate of the end control point of the Bézier curve
      `y2` - the y-coordinate of the end control point of the Bézier curve
      `paint` - the paint used to draw the Bézier curve

  - ### drawBezier

    @Deprecated public final void drawBezier(PointF p0, PointF p1, PointF p2, Paint paint)
    Deprecated.
    use drawPath() instead
    Draw a quadratic Bézier curve using the specified paint. The three points represent the starting point, the first control point and the end control point respectively.

    The style is ignored in the paint, Bézier curves are always stroked. The stroke width in the paint represents the width of the curve.

    Note that the distance from a point to the quadratic curve requires the GPU to solve cubic equations. Therefore, this method has higher overhead to the GPU.

    Parameters:
      `p0` - the starting point of the Bézier curve
      `p1` - the first control point of the Bézier curve
      `p2` - the end control point of the Bézier curve
      `paint` - the paint used to draw the Bézier curve

  - ### drawImage

    public abstract void drawImage(Image image, float left, float top, @Nullable Paint paint)
    Draw the specified image with its top/left corner at (x,y), using the specified paint, transformed by the current matrix. The Style and smooth radius is ignored in the paint, images are always filled.
    Parameters:
      `image` - the image to be drawn
      `left` - the position of the left side of the image being drawn
      `top` - the position of the top side of the image being drawn
      `paint` - the paint used to draw the image, null meaning a default paint

  - ### drawImage

    public final void drawImage(Image image, @Nullable Rect src, @NonNull Rect dst, @Nullable Paint paint)
    Draw the specified image, scaling/translating automatically to fill the destination rectangle. If the source rectangle is not null, it specifies the subset of the image to draw. The Style and smooth radius is ignored in the paint, images are always filled.
    Parameters:
      `image` - the image to be drawn
      `src` - the subset of the image to be drawn, null meaning full image
      `dst` - the rectangle that the image will be scaled/translated to fit into
      `paint` - the paint used to draw the image, null meaning a default paint

  - ### drawImage

    public final void drawImage(Image image, @Nullable Rect src, @NonNull RectF dst, @Nullable Paint paint)
    Draw the specified image, scaling/translating automatically to fill the destination rectangle. If the source rectangle is not null, it specifies the subset of the image to draw. The Style and smooth radius is ignored in the paint, images are always filled.
    Parameters:
      `image` - the image to be drawn
      `src` - the subset of the image to be drawn, null meaning full image
      `dst` - the rectangle that the image will be scaled/translated to fit into
      `paint` - the paint used to draw the image, null meaning a default paint

  - ### drawImage

    public abstract void drawImage(Image image, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, @Nullable Paint paint)
    Draw the specified image, scaling/translating automatically to fill the destination rectangle. If the source rectangle is not null, it specifies the subset of the image to draw. The Style and smooth radius is ignored in the paint, images are always filled.
    Parameters:
      `image` - the image to be drawn
      `paint` - the paint used to draw the image, null meaning a default paint

  - ### drawRoundImage

    @Deprecated public abstract void drawRoundImage(Image image, float left, float top, float radius, @Nullable Paint paint)
    Deprecated.
    use ImageShader instead
    Draw the specified image with rounded corners, whose top/left corner at (x,y) using the specified paint, transformed by the current matrix. The Style is ignored in the paint, images are always filled.
    Parameters:
      `image` - the image to be drawn
      `left` - the position of the left side of the image being drawn
      `top` - the position of the top side of the image being drawn
      `radius` - the radius used to round the corners
      `paint` - the paint used to draw the round image

  - ### drawGlyphs

    public abstract void drawGlyphs(@NonNull int[] glyphs, int glyphOffset, @NonNull float[] positions, int positionOffset, int glyphCount, @NonNull Font font, float x, float y, @NonNull Paint paint)
    Draw array of glyphs with specified font in order visually left-to-right. The Paint must be the same as the one passed to any of `TextShaper` methods. All the given arrays MUST BE IMMUTABLE!
    Parameters:
      `glyphs` - Array of glyph IDs. The length of array must be greater than or equal to `glyphStart + glyphCount`.
      `glyphOffset` - Number of elements to skip before drawing in `glyphIds` array.
      `positions` - A flattened X and Y position array. The first glyph X position must be stored at `positionOffset`. The first glyph Y position must be stored at `positionOffset + 1`, then the second glyph X position must be stored at `positionOffset + 2`. The length of array must be greater than or equal to `positionOffset + glyphCount * 2`.
      `positionOffset` - Number of elements to skip before drawing in `positions`. The first glyph X position must be stored at `positionOffset`. The first glyph Y position must be stored at `positionOffset + 1`, then the second glyph X position must be stored at `positionOffset + 2`.
      `glyphCount` - Number of glyphs to be drawn.
      `font` - FontFace used for drawing.
      `x` - Additional amount of x offset of the glyph X positions.
      `y` - Additional amount of y offset of the glyph Y positions.
      `paint` - Paint used for drawing.
    See Also:
      - `TextShaper`
      - `drawShapedText(icyllis.modernui.graphics.text.ShapedText, float, float, icyllis.modernui.graphics.Paint)`

  - ### drawTextBlob

    @Experimental public abstract void drawTextBlob(TextBlob blob, float x, float y, @NonNull Paint paint)

  - ### drawShapedText

    public final void drawShapedText(@NonNull ShapedText text, float x, float y, @NonNull Paint paint)
    Draw a single style run of positioned glyphs in order visually left-to-right, where a single style run may contain multiple BiDi runs and font runs. The Paint must be the same as the one passed to any of `TextShaper` methods.
    Parameters:
      `text` - A sequence of positioned glyphs.
      `x` - Additional amount of x offset of the glyph X positions, i.e. left position
      `y` - Additional amount of y offset of the glyph Y positions, i.e. baseline position
      `paint` - Paint used for drawing.
    See Also:
      - `TextShaper`

  - ### drawSimpleText

    public final void drawSimpleText(@NonNull char[] text, @NonNull Font font, float x, float y, @NonNull Paint paint)

  - ### drawSimpleText

    public final void drawSimpleText(@NonNull String text, @NonNull Font font, float x, float y, @NonNull Paint paint)

  - ### drawVertices

    public abstract void drawVertices(@NonNull Canvas.VertexMode mode, int vertexCount, @Size(multiple=2L) @NonNull float[] positions, int positionOffset, @Size(multiple=2L) @Nullable float[] texCoords, int texCoordOffset, @Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount, @Nullable BlendMode blendMode, @NonNull Paint paint)
    Draw an instance of a custom mesh with the given vertex data, the vertices are interpreted as the given primitive topology.

    The positions is required, and specifies the x,y pairs for each vertex in local coordinates, numbered 0, 1, 2, ..., N-1, where N is the number of vertices and N = vertexCount / 2.

    If there is colors, but there is no texCoords, then each colors (AARRGGBB) blends with paint colors using the given blendMode, and is interpolated across its corresponding topology in a gradient. The default is `BlendMode.DST` in this case.

    If there is texCoords, then it is used to specify the coordinate in UV coordinates to use at each vertex (the paint must have a shader in this case). If there is also colors, then they behave as before, but blend with paint shader. The default is `BlendMode.MODULATE` in this case.

    If there is indices array, then it is used to specify the index of each topology, rather than just walking through the arrays in order.

    For `Canvas.VertexMode.TRIANGLES` and `Canvas.VertexMode.TRIANGLE_STRIP`, counterclockwise triangles face forward.

    MaskFilter and antialiasing are ignored, antialiasing state only depends on MSAA state of the current render target.

    Parameters:
      `mode` - How to interpret the array of vertices
      `vertexCount` - The number of values in the vertices array (and corresponding texCoords and colors arrays if non-null). Each logical vertex is two values (x, y), vertexCount must be a multiple of 2.
      `positions` - Array of vertices for the mesh
      `positionOffset` - Number of values in the positions to skip before drawing.
      `texCoords` - May be null. If not null, specifies the coordinates to sample into the current shader (e.g. bitmap tile or gradient)
      `texCoordOffset` - Number of values in texCoords to skip before drawing.
      `colors` - May be null. If not null, specifies a color for each vertex, to be interpolated across the triangle.
      `colorOffset` - Number of values in colors to skip before drawing.
      `indices` - If not null, array of indices to reference into the vertex (texCoords, colors) array.
      `indexCount` - Number of entries in the indices array (if not null).
      `blendMode` - Blends vertices' colors with shader if present or paint colors if not, ignored if there is no colors array, or null to use the default
      `paint` - Specifies the shader to use if the texCoords array is non-null. Antialiasing is not supported.

  - ### drawMesh

    public abstract void drawMesh(@NonNull Canvas.VertexMode mode, @NonNull FloatBuffer positions, @Nullable FloatBuffer texCoords, @Nullable IntBuffer colors, @Nullable ShortBuffer indices, @Nullable BlendMode blendMode, @NonNull Paint paint)
    Draw an instance of a custom mesh with the given vertex data, the vertices are interpreted as the given primitive topology.

    The positions is required, and specifies the x,y pairs for each vertex in local coordinates, numbered 0, 1, 2, ..., N-1, where N is the number of vertices and N = positions.remaining() / 2.

    If there is colors, but there is no texCoords, then each colors (AARRGGBB) blends with paint colors using the given blendMode, and is interpolated across its corresponding topology in a gradient. The default is `BlendMode.DST` in this case.

    If there is texCoords, then it is used to specify the coordinate in UV coordinates to use at each vertex (the paint must have a shader in this case). If there is also colors, then they behave as before, but blend with paint shader. The default is `BlendMode.MODULATE` in this case.

    If there is indices array, then it is used to specify the index of each topology, rather than just walking through the arrays in order.

    For `Canvas.VertexMode.TRIANGLES` and `Canvas.VertexMode.TRIANGLE_STRIP`, counterclockwise triangles face forward.

    MaskFilter and antialiasing are ignored, antialiasing state only depends on MSAA state of the current render target.

    Parameters:
      `mode` - how to interpret the array of vertices
      `positions` - array of positions for the mesh, remaining should be multiple of 2
      `texCoords` - if not null, specifies the coordinates to sample into the current shader (e.g. bitmap tile or gradient), remaining >= 2*N
      `colors` - if not null, specifies a colors for each vertex, to be interpolated across the topology, remaining >= N
      `indices` - if not null, array of indices to reference into the vertex array
      `blendMode` - blends vertices' colors with shader if present or paint colors if not, ignored if there is no colors array, or null to use the default
      `paint` - specifies the texture to use if there is texCoords array and constant colors (a shader uniform) if there is no colors array
    Throws:
      `BufferUnderflowException` - insufficient vertex data

  - ### drawPointListMesh

    public final void drawPointListMesh(@NonNull FloatBuffer pos, @Nullable IntBuffer color, @NonNull Paint paint)
    Special case of `drawMesh(VertexMode, FloatBuffer, FloatBuffer, IntBuffer, ShortBuffer, BlendMode, Paint)`.

    Each point is always 1-pixel in screen-space (device space), no matter what transformation is applied. It has zero area.

    Parameters:
      `pos` - array of positions for the mesh, remaining should be multiple of 2
      `color` - if not null, specifies a color for each vertex, to be interpolated across the topology, remaining >= N
      `paint` - specifies a constant color (a shader uniform) if there is no color array

  - ### drawLineListMesh

    public final void drawLineListMesh(@NonNull FloatBuffer pos, @Nullable IntBuffer color, @NonNull Paint paint)
    Special case of `drawMesh(VertexMode, FloatBuffer, FloatBuffer, IntBuffer, ShortBuffer, BlendMode, Paint)`.

    Each line is always 1-pixel wide in screen-space (device space), no matter what transformation is applied. This is known as hairline and it has zero area.

    Parameters:
      `pos` - array of positions for the mesh, remaining should be multiple of 2
      `color` - if not null, specifies a color for each vertex, to be interpolated across the topology, remaining >= N
      `paint` - specifies a constant color (a shader uniform) if there is no color array

  - ### drawTriangleListMesh

    public final void drawTriangleListMesh(@NonNull FloatBuffer pos, @Nullable IntBuffer color, @NonNull Paint paint)
    Special case of `drawMesh(VertexMode, FloatBuffer, FloatBuffer, IntBuffer, ShortBuffer, BlendMode, Paint)`.
    Parameters:
      `pos` - array of positions for the mesh, remaining should be multiple of 2
      `color` - if not null, specifies a color for each vertex, to be interpolated across the topology, remaining >= N
      `paint` - specifies a constant color (a shader uniform) if there is no color array

  - ### drawCustomDrawable

    @Deprecated public void drawCustomDrawable(@NonNull CustomDrawable drawable, @Nullable Matrix4 matrix)
    Deprecated.

  - ### drawCustomDrawable

    @Deprecated public final void drawCustomDrawable(@NonNull CustomDrawable drawable)
    Deprecated.

  - ### isClipEmpty

    public abstract boolean isClipEmpty()
    Returns true if clip is empty; that is, nothing will draw.

    May do work when called; it should not be called more often than needed. However, once called, subsequent calls perform no work until clip changes.

    Returns:
      true if clip is empty

  - ### isClipRect

    public abstract boolean isClipRect()
    Returns true if clip is a Rect and not empty. Returns false if the clip is empty, or if it is complex.
    Returns:
      true if clip is a Rect and not empty