Skip to main content

Canvas

Struct Canvas 

Source
pub struct Canvas<'a> { /* private fields */ }
Expand description

A clipped, writable pixel target.

Every operation is clipped to Canvas::clip, which starts as the whole frame and only ever shrinks. Clipping is rectangular: that covers scrolling regions, damage-restricted repaint and nested panels, which is all a UI actually needs. Arbitrary clip shapes are not planned.

Coordinates are physical pixels relative to the frame origin, never relative to the clip.

Implementations§

Source§

impl<'a> Canvas<'a>

Source

pub fn new(frame: &'a mut Frame<'_>) -> Self

Borrows a frame for drawing, clipped to the whole frame.

Source

pub fn from_pixels( pixels: &'a mut [u32], size: Size, stride: u32, format: PixelFormat, ) -> Option<Self>

Wraps a raw pixel slice. Returns None if it is too small for the geometry.

Prefer Canvas::new; this exists for offscreen buffers and benchmarks that have no Frame to hand.

Source

pub const fn size(&self) -> Size

Full extent of the underlying frame.

Source

pub const fn format(&self) -> PixelFormat

Word layout of the target.

Source

pub const fn clip(&self) -> Rect

The region operations are currently restricted to.

Source

pub fn clip_to(&mut self, rect: Rect)

Narrows the clip in place. Never widens it.

Source

pub fn with_clip(&mut self, rect: Rect) -> Canvas<'_>

A canvas over the same pixels with a tighter clip.

The borrow ends when the returned canvas is dropped, so this is how a parent hands a child a region to draw in without either being able to escape it.

Source

pub const fn is_clipped_out(&self) -> bool

Returns true if the clip admits no pixels, so drawing can be skipped.

Source

pub fn visible(&self, rect: Rect) -> Option<Rect>

The clipped, visible part of rect.

Source

pub fn clear(&mut self, color: Color)

Fills the entire clip with an opaque colour.

This is the full-frame clear when the clip is untouched, and the damage-restricted clear when it is not.

Source

pub fn copy_from(&mut self, src: &PixelView<'_>, regions: &[Rect])

Copies matching regions out of another buffer.

Source and destination coordinates are the same, so this is the damage-driven “publish what changed” blit a double-buffered backend needs — not a general blitter. Regions are clipped to both buffers.

Source§

impl Canvas<'_>

Source

pub fn blit_mask(&mut self, at: Point, mask: &Mask<'_>, color: impl Into<Paint>)

Composites mask in color, with its top-left corner at at.

Coverage multiplies the paint’s own alpha, so a half-transparent colour through a half-covered pixel lands at a quarter, which is what it should be.

Source§

impl Canvas<'_>

Source

pub fn draw_glyph( &mut self, glyph: &Glyph, at: Point, scale: i32, color: impl Into<Paint>, )

Draws one glyph with its cell’s top-left corner at at.

Source

pub fn draw_text( &mut self, font: &BitmapFont, at: Point, scale: i32, text: &str, color: impl Into<Paint>, ) -> Size

Draws text with the first cell’s top-left corner at at, honouring \n.

Returns the extent actually laid out, whether or not it was clipped.

Source§

impl Canvas<'_>

Source

pub fn fill_circle( &mut self, centre: Point, radius: i32, color: impl Into<Paint>, )

Fills a circle of radius around centre, anti-aliased.

Exactly Canvas::fill_rounded_rect on the bounding square — this name exists so the intent is readable and the radius impossible to get wrong. The painted diameter is 2 * radius pixels.

Source

pub fn stroke_circle( &mut self, centre: Point, radius: i32, thickness: i32, color: impl Into<Paint>, )

Draws a ring of thickness pixels just inside the circle of radius around centre, anti-aliased.

Source

pub fn stroke_arc( &mut self, centre: Point, radius: i32, thickness: i32, start: i32, sweep: i32, color: impl Into<Paint>, )

Draws part of a ring: from start, sweeping sweep, both in units of TURN. Angle 0 is twelve o’clock and positive sweeps go clockwise; a negative sweep goes the other way. The ends are cut flat along the radius — butt caps.

A sweep of at least a full TURN is exactly Canvas::stroke_circle, which is what lets a progress ring pass done * TURN / total without special-casing 100%. A thickness of at least radius fills to the centre, which makes a pie slice.

The cost is proportional to the pixels the arc actually covers, not to its bounding square — a thin spinner touches a thin ring of pixels. What to damage for an animated arc is the caller’s business, but the same property means a conservative bounding rectangle only costs rasterising the ring inside it, not the square.

Source§

impl Canvas<'_>

Source

pub fn blit(&mut self, src: &PixelView<'_>, at: Point)

Draws src with its top-left corner at at, one source pixel per destination pixel, composited with source-over alpha.

Source pixels are premultiplied 0xAARRGGBB — see the module docs. Clipped to the canvas clip like every other operation; any part of the image outside it is simply not drawn.

Source

pub fn blit_scaled(&mut self, src: &PixelView<'_>, dest: Rect)

Draws all of src into dest, nearest-neighbour resampled, composited with source-over alpha.

Source pixels are premultiplied 0xAARRGGBB — see the module docs. When dest is exactly the source size this is Canvas::blit. Sampling is at pixel centres, so an integer upscale turns each source pixel into an even block, and a downscale picks representative pixels rather than always the top-left ones.

Source

pub fn blit_rounded( &mut self, src: &PixelView<'_>, dest: Rect, shape: Rect, radius: i32, )

Draws all of src into dest, masked to shape with rounded corners of radius, anti-aliased.

shape is the rectangle whose corners are rounded and outside which nothing is drawn; sampling is still mapped from the whole of dest. They are separate arguments because they genuinely differ in the Cover case — an image scaled past its box so the box is filled edge to edge — where dest overflows and shape is the box. When the picture and the mask are the same rectangle, pass it twice. radius is clamped to half of shape’s shorter side, so a full radius on a square shape is a circle — the avatar crop. Zero draws exactly Canvas::blit_scaled restricted to shape.

The mask must not come from the clip: the clip is damage, and a damage-restricted repaint of half an image has to round the image’s corners, never the damage rectangle’s.

Source§

impl Canvas<'_>

Source

pub fn draw_line(&mut self, a: Point, b: Point, color: impl Into<Paint>)

Draws a one-pixel line between two pixel centres, anti-aliased.

Axis-aligned lines take an exact integer path and get no anti-aliasing, because a horizontal rule that has been softened to 97% grey looks like a rendering bug, not like quality. Everything else is a Wu-style two-pixel blend along the minor axis.

Thickness is not a parameter. Borders come from Canvas::stroke_rect and Canvas::stroke_rounded_rect; thick arbitrary-angle lines are not something a UI toolkit needs before it can draw a chart, and that is not this milestone.

Source§

impl Canvas<'_>

Source

pub fn fill_rect(&mut self, rect: Rect, color: impl Into<Paint>)

Fills rect, compositing with the destination if the paint has alpha.

Source

pub fn fill_rects(&mut self, rects: &[Rect], color: impl Into<Paint>)

Fills every rectangle. Overlapping rectangles composite twice.

Source

pub fn stroke_rect( &mut self, rect: Rect, thickness: i32, color: impl Into<Paint>, )

Draws a border of thickness pixels inside rect.

The four bands are cut so they do not overlap. Drawing them as four full-length rectangles would composite the corners twice, which is invisible at full alpha and obvious at anything less.

Source§

impl Canvas<'_>

Source

pub fn fill_rounded_rect( &mut self, rect: Rect, radius: i32, color: impl Into<Paint>, )

Fills a rectangle with rounded corners, anti-aliased.

radius is clamped to half the shorter side; a radius of zero is exactly Canvas::fill_rect.

Source

pub fn stroke_rounded_rect( &mut self, rect: Rect, radius: i32, thickness: i32, color: impl Into<Paint>, )

Draws a rounded border of thickness pixels inside rect, anti-aliased.

The inner radius follows the outer one so the band keeps a constant width around the corner.

Trait Implementations§

Source§

impl<'a> Debug for Canvas<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> !UnwindSafe for Canvas<'a>

§

impl<'a> Freeze for Canvas<'a>

§

impl<'a> RefUnwindSafe for Canvas<'a>

§

impl<'a> Send for Canvas<'a>

§

impl<'a> Sync for Canvas<'a>

§

impl<'a> Unpin for Canvas<'a>

§

impl<'a> UnsafeUnpin for Canvas<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.