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 fn pen(&mut self) -> Pen<'_>

A Pen drawing through this canvas.

The bridge from a concrete rasteriser to the painter-agnostic API widgets and the text engine take.

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 scroll_rows(&mut self, rect: Rect, dy: i32) -> bool

Moves the pixels inside rect up by dy rows, or down by -dy rows when dy is negative, within the clip, leaving the rows that came into view as they were. Painter::scroll_rows for a buffer of words, which is the one kind of target that can: a copy_within per row, top to bottom when the content moves up and bottom to top when it moves down, so the destination always trails the source. Answers false only when there is nothing to copy — no rows inside the clip, or a move further than the rectangle is tall.

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_icon(&mut self, icon: &Icon, rect: Rect, fore: Color, back: Color)

Draws an icon into rect, scaled from its grid.

fore is the content colour and back is whatever the icon is sitting on — a shape marked Ink::Back is drawn in it, which is how an outline or a cut-out is made.

The icon is scaled to rect and not kept square: give it a square rectangle if you want it square. Anything beyond MAX_SHAPES is ignored rather than drawn wrong.

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_star( &mut self, centre: Point, outer_radius: i32, inner_radius: i32, points: u32, rotation: i32, color: impl Into<Paint>, )

Fills a star, anti-aliased.

points is the number of spikes — five for the familiar one. Vertices alternate between outer_radius at the tips and inner_radius at the valleys, so the ratio between them is how pointed the star looks: about 0.38 of the outer radius is the classic pentagram, and an inner radius approaching the outer one is a polygon with 2 × points sides.

rotation is in the same binary turns as the arcs — see TURN — and zero puts a tip at twelve o’clock.

Vertices are computed to sub-pixel precision even though the centre is whole pixels, which is what keeps a small star from looking chewed.

§A five-pointed star is not exactly five-fold symmetric

TURN is a power of two, so it divides exactly by two, four and eight and not by five. A five-pointed star’s vertex angles are therefore each rounded to the nearest unit — at most half a unit in 65536, which is under a hundredth of a pixel at any radius a screen can show, and invisible. But it does mean a star rotated by TURN / 5 is not the bit-identical picture, only the same one. Anything that needs exactness should compare against a tolerance rather than against pixels.

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
Source§

impl Painter for Canvas<'_>

Source§

fn size(&self) -> Size

Full extent of the target.
Source§

fn format(&self) -> PixelFormat

Word layout of the target.
Source§

fn clip(&self) -> Rect

The region operations are currently restricted to.
Source§

fn push_clip(&mut self, rect: Rect) -> ClipToken

Narrows the clip to its intersection with rect, returning the old one. Read more
Source§

fn pop_clip(&mut self, token: ClipToken)

Restores the clip a push_clip replaced.
Source§

fn clear(&mut self, color: Color)

Fills the entire clip with an opaque colour.
Source§

fn fill_rect(&mut self, rect: Rect, paint: Paint)

Fills a rectangle.
Source§

fn fill_rounded_rect(&mut self, rect: Rect, radius: i32, paint: Paint)

Fills a rectangle with rounded corners.
Source§

fn stroke_rounded_rect( &mut self, rect: Rect, radius: i32, thickness: i32, paint: Paint, )

Strokes a rounded rectangle inside its bounds.
Source§

fn fill_circle(&mut self, centre: Point, radius: i32, paint: Paint)

Fills a circle.
Source§

fn stroke_circle( &mut self, centre: Point, radius: i32, thickness: i32, paint: Paint, )

Strokes a circle inside its bounds.
Source§

fn stroke_arc( &mut self, centre: Point, radius: i32, thickness: i32, start: i32, sweep: i32, paint: Paint, )

Strokes part of a circle, from start through sweep binary turns.
Source§

fn draw_line(&mut self, a: Point, b: Point, paint: Paint)

Draws a one-pixel line.
Source§

fn fill_polygon_fx(&mut self, points: &[(i32, i32)], paint: Paint)

Fills a polygon whose vertices are in the rasteriser’s 8.8 fixed point. Read more
Source§

fn blit_mask(&mut self, at: Point, mask: &Mask<'_>, paint: Paint)

Composites an 8-bit coverage mask. How glyphs arrive.
Source§

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

Copies a premultiplied source over the target at at.
Source§

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

Copies a premultiplied source, scaled to dest.
Source§

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

Copies a premultiplied source, scaled to dest and masked to a rounded shape.
Source§

fn scroll_rows(&mut self, rect: Rect, dy: i32) -> bool

Moves the pixels inside rect up by dy rows, or down by -dy rows when dy is negative, within the clip. The dy rows that come into view at the trailing edge are left as they were, for the caller to paint. Answers false when this target cannot move its own pixels, in which case nothing has changed and the caller repaints the lot. Read more
Source§

fn blit_glyph( &mut self, at: Point, page: &AtlasPage<'_>, rect: Rect, paint: Paint, )

Composites the glyph at rect of an atlas page. Read more
Source§

fn blit_image(&mut self, src: &ImageRef<'_>, dest: Rect)

Draws an image, scaled to dest. Read more
Source§

fn blit_image_rounded( &mut self, src: &ImageRef<'_>, dest: Rect, shape: Rect, radius: i32, )

Draws an image, scaled to dest and masked to a rounded shape. Read more
Source§

fn is_clipped_out(&self) -> bool

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

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

The clipped, visible part of rect.
Source§

fn fill_rects(&mut self, rects: &[Rect], paint: Paint)

Fills several rectangles in one colour.
Source§

fn stroke_rect(&mut self, rect: Rect, thickness: i32, paint: Paint)

Strokes a rectangle inside its bounds.
Source§

fn fill_star( &mut self, centre: Point, outer_radius: i32, inner_radius: i32, points: u32, rotation: i32, paint: Paint, )

Fills a star with points points. Read more
Source§

fn draw_icon(&mut self, icon: &Icon, rect: Rect, fore: Color, back: Color)

Draws an icon scaled to rect, in two inks.

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<P> PainterExt for P
where P: Painter + ?Sized,

Source§

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

A view of the same target with a tighter clip, restored on drop. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.