Canvas
Mojo struct 🡭
Canvas
@memory_only
struct CanvasA width x height RGBA raster buffer, row-major, 4 bytes per pixel.
Alpha is stored per-pixel and straight, not premultiplied (see
BYTES_PER_PIXEL), so a canvas can carry a transparent background and
write_png can emit real transparency.
draw_text is the DrawTarget method; canvas.text.render.draw_text
is the free function it wraps, which additionally offers the kerning
and ligature switches and the whole-pixel and cache-less overloads.
Fields
- width (
Int) - height (
Int) - pixels (
List[UInt8]) - clip_masks (
List[List[UInt8]])
Implemented traits
AnyType, Copyable, Deinitable, DrawTarget, Movable
Methods
__init__
fn def __init__(out self, width: Int, height: Int, fill: Color = Color(UInt8(255), UInt8(255), UInt8(255), UInt8(255)))Allocate a width x height canvas, every pixel set to fill.
A zero width or height gives an empty canvas and is allowed; a
negative one raises, since the allocation below sizes itself
from width * height * 4 and a negative length is not a
buffer this type can represent.
Args:
- width (
Int): Canvas width in pixels. - height (
Int): Canvas height in pixels. - fill (
Color): Initial color for every pixel. - self (
Self)
Returns:
Self
Raises:
Error: width or height is negative.
fn def __init__(out self, width: Int, height: Int, var pixels: List[UInt8])Wrap an already-built RGBA pixel buffer, skipping the solid-fill loop the (width, height, fill) constructor pays for. For a caller about to write every pixel itself, such as downsample() in canvas/resize.mojo.
Raises unless pixels is exactly width * height * 4 bytes (RGBA,
row-major, the layout get_pixel/set_pixel assume); a wrong-sized
buffer would corrupt every later index.
Args:
- width (
Int): Canvas width in pixels. - height (
Int): Canvas height in pixels. - pixels (
List[UInt8]): Row-major RGBA bytes, exactly width * height * 4 long. - self (
Self)
Returns:
Self
Raises:
Error: pixels’ length isn’t width * height * 4.
save
fn def save(mut self)Push the current transform, blend mode and clip state, for restore to put back. The pair works as Cairo’s cairo_save/cairo_restore and the HTML5 canvas’s save/restore do: whatever translate, rotate, scale, transform, set_transform, set_blend_mode, set_color_space, push_clip or push_clip_path does between the two is undone by restore, so a caller can set up a local frame for one part of a drawing and leave the canvas as it found it.
Args:
- self (
Self)
restore
fn def restore(mut self)Pop the state save pushed: the transform and blend mode go back to what they were, and every clip pushed since – rectangle or path – is popped. A no-op with nothing saved, matching pop_clip.
Args:
- self (
Self)
translate
fn def translate(mut self, tx: Float64, ty: Float64)Shift the origin subsequent drawing is measured from by (tx, ty), in the current user space: after scale(2.0, 2.0), translate(10.0, 0.0) moves it 20 pixels.
Args:
- self (
Self) - tx (
Float64): Horizontal shift. - ty (
Float64): Vertical shift.
rotate
fn def rotate(mut self, angle: Float64)Turn subsequent drawing by angle radians about the current origin. Positive turns +x toward +y, clockwise on screen.
Args:
- self (
Self) - angle (
Float64): Radians.
scale
fn def scale(mut self, sx: Float64, sy: Float64)Scale subsequent drawing about the current origin, each axis by its own factor. A negative factor mirrors that axis – scale(1.0, -1.0) after a translate to the bottom of a plot area gives a y-up coordinate system.
Args:
- self (
Self) - sx (
Float64): Horizontal factor. - sy (
Float64): Vertical factor.
transform
fn def transform(mut self, matrix: Matrix2D)Compose matrix into the current transform, applied to coordinates before everything already in place – the same order translate/rotate/scale compose in, so a Matrix2D(Transform2D(...)) slots in like any of them.
Args:
- self (
Self) - matrix (
Matrix2D): The map to apply first.
set_transform
fn def set_transform(mut self, matrix: Matrix2D)Replace the current transform outright.
Args:
- self (
Self) - matrix (
Matrix2D): The new map from user space to device pixels.
reset_transform
fn def reset_transform(mut self)Back to the identity: coordinates are device pixels again. Clips are left alone; restore undoes both.
Args:
- self (
Self)
current_transform
fn def current_transform(self) -> Matrix2DThe map every drawing call currently applies.
Args:
- self (
Self)
Returns:
Matrix2D: The current transform; the identity if none is set.
has_transform
fn def has_transform(self) -> BoolWhether the current transform is anything but the identity. Each drawing primitive checks this once and, when it is false, runs exactly as it did before transforms existed.
Args:
- self (
Self)
Returns:
Bool: True if drawing is being mapped.
set_blend_mode
fn def set_blend_mode(mut self, mode: BlendMode)Set how every later drawing call combines with the pixels already there – the equivalent of Cairo’s cairo_set_operator and the HTML5 canvas’s globalCompositeOperation.
save/restore carry the mode with the rest of the canvas
state. See canvas/blend.mojo for each mode’s formula and for
the three limits on where a mode applies.
Args:
- self (
Self) - mode (
BlendMode): The blend mode later calls use.
blend_mode
fn def blend_mode(self) -> BlendModeThe blend mode later drawing calls will use.
Args:
- self (
Self)
Returns:
BlendMode: The current mode, BlendMode.SOURCE_OVER until
set_blend_mode says otherwise.
set_max_workers
fn def set_max_workers(mut self, workers: Int)Cap how many worker threads a banded pass on this canvas may use. 0, the default, leaves it to the runtime.
An application rendering several canvases at once otherwise has each one fan out to every thread, which oversubscribes the machine rather than sharing it. This is a per-render ceiling, not a budget across renders: two canvases each capped at 8 may use 16 threads between them.
Passing a number above what the runtime offers is the same as passing 0. The cap changes how work is divided, never what is drawn: every banded pass writes disjoint rows, so a render is identical at any worker count.
save/restore do not carry it, unlike the transform, the
blend mode and the color space. It is a resource policy for the
whole render rather than drawing state a local frame should be
able to undo.
Args:
- self (
Self) - workers (
Int): Maximum worker threads, 0 for the runtime’s count.
max_workers
fn def max_workers(self) -> IntThe worker cap set_max_workers set.
Args:
- self (
Self)
Returns:
Int: The cap, or 0 when there is none and the runtime’s count
applies.
set_color_space
fn def set_color_space(mut self, space: ColorSpace)Set the space later source-over blends mix in: SRGB, the default, blends the stored channel bytes directly; LINEAR converts them to linear light, blends, and converts back (see ColorSpace). Every anti-aliased edge, translucent fill and composite drawn from here on takes it, since they all reach the pixels through the same source-over. The Porter-Duff operators and the blend modes (set_blend_mode) stay in sRGB either way.
save/restore carry the space, as they do the blend mode.
Args:
- self (
Self) - space (
ColorSpace): The color space later blends use.
color_space
fn def color_space(self) -> ColorSpaceThe space source-over blends mix in now.
Args:
- self (
Self)
Returns:
ColorSpace: The current space, ColorSpace.SRGB until
set_color_space says otherwise.
begin_batch
fn def begin_batch(mut self)Start deferring anti-aliased shapes so that end_batch can draw them all in one parallel pass, in the order they were called: what a chart’s gridlines, ticks and markers want, where each shape is far too small to split across cores on its own and drawing them one call at a time runs on one core.
Deferred: fill_path_aa, stroke_path_aa, fill_polygon_aa,
draw_line_aa, draw_polyline_aa, draw_polygon_aa,
fill_circle_aa, fill_ellipse_aa, fill_arc_aa,
fill_ring_sector_aa, draw_circle_aa, draw_ellipse_aa,
draw_arc_aa, and the solid fill_rect. Each is recorded at
the call, under the transform, clip, blend mode and color
space in force then – a stroke as its points and style, a
path as the path, so that end_batch can build their outlines
and edge tables in parallel before it rasterizes – and
rendered by the same row-restricted code its batched relatives
use, so the pixels are exactly the ones drawing it at once
would have written.
Everything else – text, gradient and pattern fills, the
hard-edged primitives, draw_canvas, draw_image, blur,
fill, and the
fill_circles_aa-style batches – first draws what is
pending and then draws itself, so it stays in order. So does a
change of clip, blend mode or color space, and restore. Two
things are not ordered against a pending batch: set_pixel
and write_pixel, whose per-pixel cost a check would double,
and reads – get_pixel, write_png, draw_canvas with this
canvas as the source – which see the canvas without the
pending shapes until end_batch.
Calls nest; only the outermost end_batch draws.
Args:
- self (
Self)
end_batch
fn def end_batch(mut self)Draw everything recorded since the matching begin_batch. A no-op with no batch open, like pop_clip with nothing to pop.
Args:
- self (
Self)
begin_supersampled
fn def begin_supersampled(mut self, factor: Int, background: Color = Color(UInt8(255), UInt8(255), UInt8(255), UInt8(255)))Draw the next region at factor times this canvas’s resolution without holding the enlarged buffer: drawing between here and end_supersampled is recorded, and end_supersampled replays it one output band at a time into a scratch that holds only that band, downsamples each band and writes it here.
Not everything can be recorded. Anti-aliased fills, strokes, paths, disks, ellipses, rects, bulk marker calls, glyphs and rect clips all have a recorded form. A primitive with none – a hard-edged shape, an image or canvas composite, a blur, a mask-backed clip – makes the region give up the banded replay where it appears: the enlarged buffer is allocated, the rest of the region draws into it, and the downsample happens at the end. The pixels are the same either way. What is lost is the memory the banded replay saves, and the speed with it, so a region built from recordable drawing is the one that pays.
Callers draw in this canvas’s own coordinates. The half-pixel
that box-downsampling costs is applied here, so a rectangle
drawn at the same coordinates lands where it would have
without the region – the recipe on downsample, which every
consumer would otherwise reimplement.
A factor of 1 or less opens nothing and draws directly.
Each band starts from background, as the recipe’s own
scratch does; what this canvas already shows underneath is not
carried into the region. Seeding from it was measured both as
a copy per pixel and as a nearest-neighbour upscale, and both
cost more than the region saves, so a caller who needs to draw
over existing content wants the two-step recipe instead.
Args:
- self (
Self) - factor (
Int): Resolution multiplier, 1 for none. - background (
Color): What each band starts from.
Raises:
Error: A region is already open.
end_supersampled
fn def end_supersampled(mut self)Draw what begin_supersampled recorded, band by band, and put the downsampled result on this canvas. A no-op when no region is open.
Args:
- self (
Self)
Raises:
Error: The band scratch cannot be allocated.
row_bounds
fn def row_bounds(self) -> Tuple[Int, Int]The rows this buffer holds, in the coordinates geometry is drawn in: (0, height) for an ordinary canvas, and the band’s own slice of the enlarged space inside a supersampled replay (#391). A rasterizer clamping to “the canvas” wants these rather than 0 and height.
Args:
- self (
Self)
Returns:
Tuple[Int, Int]: The first row and one past the last.
in_bounds
fn def in_bounds(self, x: Int, y: Int) -> BoolWhether (x, y) is a real pixel on this canvas.
Args:
- self (
Self) - x (
Int): Column to check. - y (
Int): Row to check.
Returns:
Bool: True if the column is on the canvas and the row is one this
buffer holds – normally 0 <= y < height, and the band’s own
rows when _row_origin is set.
push_clip
fn def push_clip(mut self, x: Int, y: Int, width: Int, height: Int)Restrict subsequent drawing to this sub-rectangle. Every primitive picks it up, since they all write through set_pixel.
Intersects with the current effective clip and pushes the result, so nested clips compose: a child can restrict further but never escape its parent’s region, even if its own rectangle extends past it. Pair with pop_clip(). A clip rectangle extending past the canvas bounds is fine; in_bounds still rejects anything outside the canvas.
Under a canvas transform the rectangle is in user space. An
axis-aligned transform maps it to another rectangle; a rotated
or skewed one turns it into a clip path, with its bounding
rectangle on this stack so pop_clip removes both together.
Args:
- self (
Self) - x (
Int): Clip rectangle’s left edge. - y (
Int): Clip rectangle’s top edge. - width (
Int): Clip rectangle’s width. - height (
Int): Clip rectangle’s height.
pop_clip
fn def pop_clip(mut self)Remove the most recently pushed clip, reverting to the parent clip if one exists or to the whole canvas if not.
A no-op on an empty stack rather than an error, matching in_bounds’ handling of out-of-range requests: a stack alone cannot distinguish an unbalanced pop from “nothing to undo”.
Args:
- self (
Self)
push_clip_path
fn def push_clip_path(mut self, path: Path, fill_rule: FillRule = FillRule.EVEN_ODD, supersample: Int = Int(4), curve_steps: Int = Int(0))Restrict subsequent drawing to path’s interior.
The clip is anti-aliased, not a hard in/out test: the path’s coverage becomes a 0-255 mask, and a pixel the path half covers lets half the drawing through.
A new mask is multiplied into the current one, so a nested clip
can only restrict further, never escape its parent. Rectangle
clips still apply independently on top. Pair with
pop_clip_path. Under a canvas transform path is in user
space and is mapped before it is rasterized.
Args:
- self (
Self) - path (
Path): Shape to clip to. Its interior is what stays visible. - fill_rule (
FillRule): EVEN_ODD (default) or NONZERO – see FillRule. Governs the interior of a self-intersecting or multi-sub-path clip shape exactly as it does a fill. - supersample (
Int): Sub-pixel grid side length used to compute the mask’s edge coverage. - curve_steps (
Int): Straight-line segments per quad/cubic Bezier. 0 (the default) picks a count from the curvature.
push_clip_coverage
fn def push_clip_coverage(mut self, var mask: List[UInt8])Restrict subsequent drawing to a coverage already computed: one 0-255 byte per canvas pixel, row-major, in device space. What push_clip_path pushes once it has rasterized its path, and what canvas.mask.push_clip_mask pushes for a Mask. Nests and pops exactly as a clip path does.
Args:
- self (
Self) - mask (
List[UInt8]):width * heightcoverage bytes, taken by value.
has_clip_mask
fn def has_clip_mask(self) -> BoolWhether a clip path is currently active.
The check a caller writing through write_pixel needs: that
method skips every per-pixel test, and a clip path’s coverage is
per-pixel by nature, so a bulk writer routes through set_pixel
while one is pushed. See write_pixel and _fill_region.
Args:
- self (
Self)
Returns:
Bool: True if at least one clip path is pushed.
pop_clip_path
fn def pop_clip_path(mut self)Remove the most recently pushed clip path, reverting to the parent clip path if one exists or to no path clip if not.
A no-op on an empty stack, matching pop_clip.
Args:
- self (
Self)
clip_coverage
fn def clip_coverage(self, x: Int, y: Int) -> UInt8How much of (x, y) the active clip paths let through: 255 if no clip path is active or the pixel is fully inside one, 0 if fully outside, in between on an anti-aliased boundary.
Rectangle clips are not included; in_clip covers those, and
set_pixel applies both.
Args:
- self (
Self) - x (
Int): Column to query. - y (
Int): Row to query.
Returns:
UInt8: Coverage 0-255.
in_clip
fn def in_clip(self, x: Int, y: Int) -> BoolWhether (x, y) is inside the active clip region.
Args:
- self (
Self) - x (
Int): Column to check. - y (
Int): Row to check.
Returns:
Bool: True if no clip is active, or (x, y) is inside the
innermost pushed clip rectangle.
set_pixel
fn def set_pixel(mut self, x: Int, y: Int, color: Color)Write color at (x, y), a no-op if it’s off-canvas or outside the active clip.
Inside a begin_batch or begin_supersampled region this is
an immediate primitive like a hard-edged shape: it draws what
is pending first, so it lands in order, and inside a region
that gives up the banded replay (_flush_batch). It cannot
simply write: while a region records, in_bounds accepts the
enlarged space on purpose, so a coordinate past this canvas’s
own rows is accepted and, written directly, is a store past
the end of pixels. The one-point case of an anti-aliased
polyline reached exactly that from inside a supersampled
region (dataviz_mojo#732); a recordable primitive with a
one-pixel case records it through _record_pixel instead.
Args:
- self (
Self) - x (
Int): Column to write. - y (
Int): Row to write. - color (
Color): Color to write, combined with the existing pixel under the current blend mode.
write_pixel
fn def write_pixel(mut self, x: Int, y: Int, color: Color)Write color at (x, y) without set_pixel’s in_bounds/ in_clip checks. The caller must already know (x, y) is inside both the canvas and the active clip, typically from a range effective_fill_rect (below) intersected against both.
It also skips the clip path mask, which effective_fill_rect
cannot fold in: a rectangle clip is a range, but a path clip is a
per-pixel coverage value. A bulk writer must therefore check
has_clip_mask() and fall back to set_pixel when one is
active, as _fill_region and the gradient rect fills in
canvas.shapes.rects do.
Writes go through pixels.unsafe_ptr(), unchecked. The index is
computed from width and the caller’s validated (x, y), so it
cannot leave the buffer. The blend path reads the background
bytes from the same pointer rather than through get_pixel.
Args:
- self (
Self) - x (
Int): Column to write. Must already be known in-bounds. - y (
Int): Row to write. Must already be known in-bounds. - color (
Color): Color to write, combined with the existing pixel under the current blend mode.
composite_alpha_row
fn def composite_alpha_row(mut self, x: Int, y: Int, alphas: List[UInt8], base: Int, count: Int, color: Color)write_pixel of color at alpha alphas[base + i] for each of count pixels from (x, y) rightward, as one loop over the row: what compositing a cached glyph mask does per pixel, without a method call, an index computation and a clip test for each. The caller has already intersected the row with the canvas and the rectangle clip, and there is no clip path active. Each pixel’s result is exactly write_pixel’s: the same shortcuts, the same Color.blend_over_opaque and blend_over.
Args:
- self (
Self) - x (
Int): Column of the first pixel. - y (
Int): Row. - alphas (
List[UInt8]): Per-pixel alpha, 0-255, read frombase. - base (
Int): Index inalphasof the first pixel’s alpha. - count (
Int): Pixels to write. - color (
Color): Color to write; its own alpha is replaced per pixel.
effective_fill_rect
fn def effective_fill_rect(self, x: Int, y: Int, width: Int, height: Int) -> Tuple[Int, Int, Int, Int]The (x, y, width, height) a rectangular fill covering [x, x+width) x [y, y+height) may actually touch, intersected against the canvas bounds and the active clip – the same intersection set_pixel enforces per pixel, computed once for a caller about to loop over the whole region. Pair with write_pixel.
A returned width/height of 0 means nothing in the requested
rectangle is drawable; range(0) is a no-op, so callers need no
separate check.
Args:
- self (
Self) - x (
Int): Requested rectangle’s left edge. - y (
Int): Requested rectangle’s top edge. - width (
Int): Requested rectangle’s width. - height (
Int): Requested rectangle’s height.
Returns:
Tuple[Int, Int, Int, Int]: (x, y, width, height) of the sub-rectangle actually
touchable, clamped to the canvas and the active clip.
get_pixel
fn def get_pixel(self, x: Int, y: Int) -> ColorRead the color at (x, y).
Args:
- self (
Self) - x (
Int): Column to read. - y (
Int): Row to read.
Returns:
Color: The pixel’s color, or opaque black if (x, y) is off-canvas.
read_pixel
fn def read_pixel(self, x: Int, y: Int) -> ColorRead (x, y) without get_pixel’s in_bounds check, the counterpart to write_pixel and subject to the same contract: the caller must already know the coordinate is on the canvas, typically because the loop bounds came from width/height.
get_pixel stays the checked entry point, and returns opaque
black off-canvas rather than reading out of range. Whole-image
passes – downsampling, encoding a file – derive every
coordinate from the canvas’s dimensions, so the check
re-establishes what the loop already guarantees.
Args:
- self (
Self) - x (
Int): Column to read. Must already be known in-bounds. - y (
Int): Row to read. Must already be known in-bounds.
Returns:
Color: The pixel’s color.
draw_text
fn def draw_text(mut self, x: Float64, y: Float64, text: String, color: Color, size: Float64, family: String = "Sans", slant: FontSlant = FontSlant.NORMAL, weight: FontWeight = FontWeight.NORMAL, rotation: Float64 = 0, align: TextAlign = TextAlign.LEFT, *, mut cache: FontCache)canvas.text.render.draw_text as a method: the DrawTarget form, so a caller generic over the trait can label what it draws. Same pixels as the free function with the same arguments; the free function keeps the kerning and ligature switches and the whole-pixel and cache-less overloads.
Args:
- self (
Self) - x (
Float64): Anchor x, sub-pixel. - y (
Float64): Anchor y, the first line’s baseline. - text (
String): Text to draw, “\n”-separated lines. - color (
Color): Fill color. - size (
Float64): Font size in pixels. - family (
String): Font family name or generic alias. - slant (
FontSlant): Upright, italic or oblique. - weight (
FontWeight): Normal or bold. - rotation (
Float64): Radians about the anchor. - align (
TextAlign): Horizontal alignment of each line. - cache (
FontCache): Shared font and glyph cache.
Raises:
Error: No font could be resolved for family.
draw_text_runs
fn def draw_text_runs(mut self, x: Float64, y: Float64, runs: List[TextRun], color: Color, family: String = "Sans", weight: FontWeight = FontWeight.NORMAL, rotation: Float64 = 0, align: TextAlign = TextAlign.LEFT, *, mut cache: FontCache)The DrawTarget form: draw_text once per run, each at the anchor canvas.text.render.text_run_anchors computes for it, so a run lands where the same text drawn alone at that anchor lands, byte for byte.
Args:
- self (
Self) - x (
Float64): Anchor x, sub-pixel. - y (
Float64): Anchor y, the label’s baseline. - runs (
List[TextRun]): The label’s runs, in reading order. - color (
Color): Fill color. - family (
String): Font family name or generic alias. - weight (
FontWeight): Normal or bold. - rotation (
Float64): Radians about the anchor. - align (
TextAlign): Horizontal alignment of the whole label. - cache (
FontCache): Shared font and glyph cache.
Raises:
Error: No font could be resolved for family.
draw_image
fn def draw_image(mut self, image: Self, x: Float64, y: Float64, width: Float64 = 0, height: Float64 = 0)Draw image as a block of cells with its top-left at (x, y), scaled to width x height (its own pixel size when 0), under the current transform: DrawTarget’s image primitive, the method form of draw_image in canvas/compose.mojo, which says how the cells land.
Args:
- self (
Self) - image (
Self): The cells to draw. Unchanged. - x (
Float64): Left edge, in user coordinates. - y (
Float64): Top edge. - width (
Float64): Drawn width, or 0 forimage.width. - height (
Float64): Drawn height, or 0 forimage.height.
Raises:
Error: The canvas transform is singular.
fill
fn def fill(mut self, color: Color)Fill the whole canvas (or the active clip region, if any) with color.
Args:
- self (
Self) - color (
Color): Color to fill with, blended over existing pixels if translucent.
begin_annotated_group
fn def begin_annotated_group(mut self, title: String)DrawTarget’s group label, which a raster canvas has nowhere to put: a no-op, so code written against the trait runs unchanged on any backend. SvgCanvas emits <g><title> here and PdfCanvas a marked-content sequence.
Args:
- self (
Self) - title (
String): Ignored.
end_annotated_group
fn def end_annotated_group(mut self)Closes what begin_annotated_group did not open: a no-op, for the same reason.
Args:
- self (
Self)
fill_rect
fn def fill_rect(mut self, x: Int, y: Int, width: Int, height: Int, color: Color)Same as canvas.shapes.rects.fill_rect, callable as a method.
Args:
- self (
Self) - x (
Int): Rectangle’s left edge. - y (
Int): Rectangle’s top edge. - width (
Int): Rectangle’s width. - height (
Int): Rectangle’s height. - color (
Color): Fill color.
fn def fill_rect(mut self, x: Float64, y: Float64, width: Float64, height: Float64, color: Color)Args:
- self (
Self) - x (
Float64) - y (
Float64) - width (
Float64) - height (
Float64) - color (
Color)
fill_rect_gradient
fn def fill_rect_gradient(mut self, x: Int, y: Int, width: Int, height: Int, gradient: LinearGradient)Same as canvas.shapes.rects.fill_rect_gradient, callable as a method.
Args:
- self (
Self) - x (
Int): Rectangle’s left edge. - y (
Int): Rectangle’s top edge. - width (
Int): Rectangle’s width. - height (
Int): Rectangle’s height. - gradient (
LinearGradient): Fill source, projected across the rectangle.
fn def fill_rect_gradient(mut self, x: Float64, y: Float64, width: Float64, height: Float64, gradient: LinearGradient)Args:
- self (
Self) - x (
Float64) - y (
Float64) - width (
Float64) - height (
Float64) - gradient (
LinearGradient)
draw_line_aa
fn def draw_line_aa(mut self, x0: Int, y0: Int, x1: Int, y1: Int, color: Color, width: Float64 = 1, dashes: List[Float64] = List(), dash_offset: Float64 = 0, cap: LineCap = LineCap.ROUND, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Same as canvas.shapes.lines.draw_line_aa, callable as a method.
Args:
- self (
Self) - x0 (
Int): Start point’s x. - y0 (
Int): Start point’s y. - x1 (
Int): End point’s x. - y1 (
Int): End point’s y. - color (
Color): Stroke color. - width (
Float64): Stroke width in pixels. - dashes (
List[Float64]): On/off segment lengths in user-space pixels, cycled along the line. Empty (default) draws a solid line. - dash_offset (
Float64): Distance into the dash pattern the line starts at. - cap (
LineCap): How the two ends are finished – see LineCap. - join (
LineJoin): Unused for a single segment, which has no corners. - miter_limit (
Float64): Unused for a single segment.
fn def draw_line_aa(mut self, x0: Float64, y0: Float64, x1: Float64, y1: Float64, color: Color, width: Float64 = 1, dashes: List[Float64] = List(), dash_offset: Float64 = 0, cap: LineCap = LineCap.ROUND, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Same as canvas.shapes.lines.draw_line_aa, callable as a method.
Args:
- self (
Self) - x0 (
Float64): Start point’s x. - y0 (
Float64): Start point’s y. - x1 (
Float64): End point’s x. - y1 (
Float64): End point’s y. - color (
Color): Stroke color. - width (
Float64): Stroke width in pixels. - dashes (
List[Float64]): On/off segment lengths in user-space pixels, cycled along the line. Empty (default) draws a solid line. - dash_offset (
Float64): Distance into the dash pattern the line starts at. - cap (
LineCap): How the two ends are finished – see LineCap. - join (
LineJoin): Unused for a single segment, which has no corners. - miter_limit (
Float64): Unused for a single segment.
fill_circle_aa
fn def fill_circle_aa(mut self, cx: Int, cy: Int, radius: Int, color: Color)Same as canvas.shapes.circles.fill_circle_aa, callable as a method.
Args:
- self (
Self) - cx (
Int): Center x. - cy (
Int): Center y. - radius (
Int): Circle radius in pixels. - color (
Color): Fill color.
fn def fill_circle_aa(mut self, cx: Float64, cy: Float64, radius: Float64, color: Color)Args:
- self (
Self) - cx (
Float64) - cy (
Float64) - radius (
Float64) - color (
Color)
fill_circles_aa
fn def fill_circles_aa(mut self, centers: List[FPoint], radius: Float64, color: Color)DrawTarget’s batched disks: the canvas is split across cores rather than the markers. See canvas.shapes.circles.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - radius (
Float64): Radius shared by every marker, in pixels. - color (
Color): Fill color shared by every marker.
Raises:
fn def fill_circles_aa(mut self, centers: List[FPoint], radius: Float64, colors: List[Color])fill_circles_aa with a color per marker.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - radius (
Float64): Radius shared by every marker, in pixels. - colors (
List[Color]): One color per centre, same length ascenters.
Raises:
Error: If colors is not the same length as centers.
fill_mesh
fn def fill_mesh(mut self, points: List[FPoint], faces: List[Int], colors: List[Color])DrawTarget’s mesh: adjacent triangles drawn as one anti-aliased shape, seam-free along shared edges. See canvas.shapes.mesh.
Args:
- self (
Self) - points (
List[FPoint]): The vertices, in the canvas’s coordinates. - faces (
List[Int]): Index triples intopoints, in draw order. - colors (
List[Color]): One color per triangle.
Raises:
Error: faces is not whole triples, an index is out of
range, or colors is not one per triangle.
fill_mesh_shaded
fn def fill_mesh_shaded(mut self, points: List[FPoint], faces: List[Int], vertex_colors: List[Color])DrawTarget’s smooth-shaded mesh: fill_mesh with a color per vertex interpolated across each face, in this canvas’s color space. See canvas.shapes.mesh.
Args:
- self (
Self) - points (
List[FPoint]): The vertices, in the canvas’s coordinates. - faces (
List[Int]): Index triples intopoints, in draw order. - vertex_colors (
List[Color]): One color per vertex.
Raises:
Error: faces is not whole triples, an index is out of
range, or vertex_colors is not one per vertex.
fill_ellipses_aa
fn def fill_ellipses_aa(mut self, centers: List[FPoint], rx: Float64, ry: Float64, color: Color)DrawTarget’s batched ellipses: the canvas is split across cores rather than the markers. See canvas.shapes.ellipses.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - rx (
Float64): Horizontal radius shared by every marker, in pixels. - ry (
Float64): Vertical radius shared by every marker, in pixels. - color (
Color): Fill color shared by every marker.
Raises:
fn def fill_ellipses_aa(mut self, centers: List[FPoint], rx: Float64, ry: Float64, colors: List[Color])fill_ellipses_aa with a color per marker.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each marker, in draw order. - rx (
Float64): Horizontal radius shared by every marker, in pixels. - ry (
Float64): Vertical radius shared by every marker, in pixels. - colors (
List[Color]): One color per centre, same length ascenters.
Raises:
draw_circle_aa
fn def draw_circle_aa(mut self, cx: Float64, cy: Float64, radius: Float64, color: Color, width: Float64 = 1)Same as canvas.shapes.circles.draw_circle_aa, callable as a method.
Args:
- self (
Self) - cx (
Float64): Center x, sub-pixel. - cy (
Float64): Center y, sub-pixel. - radius (
Float64): Circle radius in pixels, to the middle of the stroke. - color (
Color): Outline color. - width (
Float64): Stroke width in pixels.
fill_ellipse_aa
fn def fill_ellipse_aa(mut self, cx: Int, cy: Int, rx: Int, ry: Int, color: Color)Same as canvas.shapes.ellipses.fill_ellipse_aa, callable as a method.
Args:
- self (
Self) - cx (
Int): Center x. - cy (
Int): Center y. - rx (
Int): Horizontal radius in pixels. - ry (
Int): Vertical radius in pixels. - color (
Color): Fill color.
fn def fill_ellipse_aa(mut self, cx: Float64, cy: Float64, rx: Float64, ry: Float64, color: Color)Args:
- self (
Self) - cx (
Float64) - cy (
Float64) - rx (
Float64) - ry (
Float64) - color (
Color)
draw_ellipse_aa
fn def draw_ellipse_aa(mut self, cx: Int, cy: Int, rx: Int, ry: Int, color: Color)Same as canvas.shapes.ellipses.draw_ellipse_aa, callable as a method.
Args:
- self (
Self) - cx (
Int): Center x. - cy (
Int): Center y. - rx (
Int): Horizontal radius in pixels. - ry (
Int): Vertical radius in pixels. - color (
Color): Outline color.
fn def draw_ellipse_aa(mut self, cx: Float64, cy: Float64, rx: Float64, ry: Float64, color: Color, width: Float64 = 1)Same as canvas.shapes.ellipses.draw_ellipse_aa, callable as a method.
Args:
- self (
Self) - cx (
Float64): Center x, sub-pixel. - cy (
Float64): Center y, sub-pixel. - rx (
Float64): Horizontal radius in pixels, to the middle of the stroke. - ry (
Float64): Vertical radius in pixels, to the middle of the stroke. - color (
Color): Outline color. - width (
Float64): Stroke width in pixels.
fill_arc_aa
fn def fill_arc_aa(mut self, cx: Float64, cy: Float64, radius: Float64, start_angle: Float64, end_angle: Float64, color: Color)Same as canvas.shapes.arcs.fill_arc_aa, callable as a method.
Args:
- self (
Self) - cx (
Float64): Center x. - cy (
Float64): Center y. - radius (
Float64): Wedge radius in pixels. - start_angle (
Float64): Sweep start, radians, 0 pointing along +x. - end_angle (
Float64): Sweep end, radians. - color (
Color): Fill color.
fill_arcs_aa
fn def fill_arcs_aa(mut self, centers: List[FPoint], radius: Float64, start_angle: Float64, end_angle: Float64, color: Color)DrawTarget’s batched wedges: the canvas is split across cores rather than the wedges. See canvas.shapes.arcs.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each wedge, in draw order. - radius (
Float64): Radius shared by every wedge, in pixels. - start_angle (
Float64): Start of the sweep, radians, shared. - end_angle (
Float64): End of the sweep, radians, shared. - color (
Color): Fill color shared by every wedge.
Raises:
fn def fill_arcs_aa(mut self, centers: List[FPoint], radius: Float64, start_angle: Float64, end_angle: Float64, colors: List[Color])fill_arcs_aa with a color per wedge.
Args:
- self (
Self) - centers (
List[FPoint]): Sub-pixel centre of each wedge, in draw order. - radius (
Float64): Radius shared by every wedge, in pixels. - start_angle (
Float64): Start of the sweep, radians, shared. - end_angle (
Float64): End of the sweep, radians, shared. - colors (
List[Color]): One color per centre, same length ascenters.
Raises:
fill_ring_sector_aa
fn def fill_ring_sector_aa(mut self, cx: Float64, cy: Float64, inner_radius: Float64, outer_radius: Float64, start_angle: Float64, end_angle: Float64, color: Color)Same as canvas.shapes.arcs.fill_ring_sector_aa, callable as a method.
Args:
- self (
Self) - cx (
Float64): Center x. - cy (
Float64): Center y. - inner_radius (
Float64): Ring’s inner edge, in pixels. - outer_radius (
Float64): Ring’s outer edge, in pixels. - start_angle (
Float64): Sweep start, radians, 0 pointing along +x. - end_angle (
Float64): Sweep end, radians. - color (
Color): Fill color.
stroke_path_aa
fn def stroke_path_aa(mut self, path: Path, color: Color, width: Float64 = 1, dashes: List[Float64] = List(), dash_offset: Float64 = 0, cap: LineCap = LineCap.ROUND, join: LineJoin = LineJoin.ROUND, miter_limit: Float64 = 4)Same as canvas.path.stroke_path_aa, callable as a method.
Args:
- self (
Self) - path (
Path): Path to stroke. - color (
Color): Stroke color. - width (
Float64): Stroke width in pixels. - dashes (
List[Float64]): On/off segment lengths in user-space pixels, cycled along the stroke. Empty (default) draws a solid line. - dash_offset (
Float64): Distance into the dash pattern the stroke starts at. - cap (
LineCap): How an open sub-path’s two ends are finished – see LineCap. - join (
LineJoin): How corners are turned – see LineJoin. - miter_limit (
Float64): Ratio past which a MITER join falls back to BEVEL, as a multiple of half the stroke width.
fill_path_aa
fn def fill_path_aa(mut self, path: Path, color: Color, fill_rule: FillRule = FillRule.EVEN_ODD)Same as canvas.path.fill_path_aa, callable as a method.
Args:
- self (
Self) - path (
Path): Path to fill. - color (
Color): Fill color. - fill_rule (
FillRule): EVEN_ODD (default) or NONZERO – see FillRule.