Skip to main content

Frame2d

Struct Frame2d 

Source
pub struct Frame2d<const W: usize, const H: usize>(pub [[RGB8; W]; H]);
Expand description

2D pixel array used for general graphics on LED panels (includes examples).

This page provides the primary documentation for drawing onto LED panels.

Read the examples below first. After that, keep these details in mind:

  • Use a frame to prepare an image before sending it to the panel.
  • Coordinates are (x, y) with (0, 0) at the top-left. The x-axis increases to the right, and the y-axis increases downward.
  • Set pixels using tuple indexing: frame[(x, y)] = colors::RED;.
  • For shapes, lines, and text rendering, use the embedded-graphics crate.
  • Frames are rendered by a panel type generated with led2d!. See Led2dGenerated for the full API of the generated panel type.
  • For animation, call animate with a sequence of (Frame2d, Duration) pairs. See the led2d module for an example.

§Indexing and storage

Frame2d supports both:

  • (x, y) tuple indexing: frame[(x, y)]
  • Row-major array indexing: frame[y][x]

Tuple indexing matches display coordinates. Array indexing matches the underlying storage.

§Rendering pipeline (what happens when you display a frame)

Frame2d is only pixel storage. When you render a frame through a generated panel type, the device abstraction:

  • Maps (x, y) pixels to the physical LED wiring order
  • Applies gamma correction
  • Scales brightness to respect the configured electrical current budget

These steps are implemented using two compile-time–generated lookup tables. Writing a frame performs only indexed memory reads and writes.

§Example: Draw pixels both directly and with embedded-graphics:

LED panel preview

use device_envoy::{led2d::Frame2d, led_strip::ToRgb888};
use embedded_graphics::{
    prelude::*,
    primitives::{Circle, PrimitiveStyle, Rectangle},
};
use smart_leds::colors;

type Frame = Frame2d<12, 8>;

/// Calculate the top-left corner position to center a shape within a bounding box.
const fn centered_top_left(width: usize, height: usize, size: usize) -> Point {
    assert!(size <= width);
    assert!(size <= height);
    Point::new(((width - size) / 2) as i32, ((height - size) / 2) as i32)
}

// Create a frame to draw on. This is just an in-memory 2D pixel buffer.
let mut frame = Frame::new();

// Use the embedded-graphics crate to draw a red rectangle border around the edge of the frame.
// We use `to_rgb888()` to convert from smart-leds RGB8 to embedded-graphics Rgb888.
Rectangle::new(Frame::TOP_LEFT, Frame::SIZE)
    .into_styled(PrimitiveStyle::with_stroke(colors::RED.to_rgb888(), 1))
    .draw(&mut frame)
    .expect("rectangle draw must succeed");

// Direct pixel access: set the upper-left LED pixel (x = 0, y = 0).
// Frame2d stores LED colors directly, so we write an LED color here.
frame[(0, 0)] = colors::CYAN;

// Use the embedded-graphics crate to draw a green circle centered in the frame.
const DIAMETER: u32 = 6;
const CIRCLE_TOP_LEFT: Point = centered_top_left(Frame::WIDTH, Frame::HEIGHT, DIAMETER as usize);
Circle::new(CIRCLE_TOP_LEFT, DIAMETER)
    .into_styled(PrimitiveStyle::with_stroke(colors::LIME.to_rgb888(), 1))
    .draw(&mut frame)
    .expect("circle draw must succeed");

Tuple Fields§

§0: [[RGB8; W]; H]

Implementations§

Source§

impl<const W: usize, const H: usize> Frame2d<W, H>

Source

pub const WIDTH: usize = W

The width of the frame.

Source

pub const HEIGHT: usize = H

The height of the frame.

Source

pub const LEN: usize

Total pixels in this frame (width × height).

Source

pub const SIZE: Size

Frame dimensions as a Size.

For embedded-graphics drawing operation.

Source

pub const TOP_LEFT: Point

Top-left corner coordinate as a Point.

For embedded-graphics drawing operation.

Source

pub const TOP_RIGHT: Point

Top-right corner coordinate as a Point.

For embedded-graphics drawing operation.

Source

pub const BOTTOM_LEFT: Point

Bottom-left corner coordinate as a Point.

For embedded-graphics drawing operation.

Source

pub const BOTTOM_RIGHT: Point

Bottom-right corner coordinate as a Point.

For embedded-graphics drawing operation.

Source

pub const fn new() -> Self

Create a new blank (all black) frame.

Source

pub const fn filled(color: RGB8) -> Self

Create a frame filled with a single color.

Trait Implementations§

Source§

impl<const W: usize, const H: usize> Clone for Frame2d<W, H>

Source§

fn clone(&self) -> Frame2d<W, H>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<const W: usize, const H: usize> Debug for Frame2d<W, H>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<const W: usize, const H: usize> Default for Frame2d<W, H>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<const W: usize, const H: usize> Deref for Frame2d<W, H>

Source§

type Target = [[Rgb<u8>; W]; H]

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<const W: usize, const H: usize> DerefMut for Frame2d<W, H>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<const W: usize, const H: usize> DrawTarget for Frame2d<W, H>

Source§

type Color = Rgb888

The pixel color type the targetted display supports.
Source§

type Error = Infallible

Error type to return when a drawing operation fails. Read more
Source§

fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where I: IntoIterator<Item = Pixel<Self::Color>>,

Draw individual pixels to the display without a defined order. Read more
Source§

fn fill_contiguous<I>( &mut self, area: &Rectangle, colors: I, ) -> Result<(), Self::Error>
where I: IntoIterator<Item = Self::Color>,

Fill a given area with an iterator providing a contiguous stream of pixel colors. Read more
Source§

fn fill_solid( &mut self, area: &Rectangle, color: Self::Color, ) -> Result<(), Self::Error>

Fill a given area with a solid color. Read more
Source§

fn clear(&mut self, color: Self::Color) -> Result<(), Self::Error>

Fill the entire display with a solid color. Read more
Source§

impl<const W: usize, const H: usize> From<[[Rgb<u8>; W]; H]> for Frame2d<W, H>

Source§

fn from(array: [[RGB8; W]; H]) -> Self

Converts to this type from the input type.
Source§

impl<const W: usize, const H: usize> From<Frame2d<W, H>> for [[RGB8; W]; H]

Source§

fn from(frame: Frame2d<W, H>) -> Self

Converts to this type from the input type.
Source§

impl<const W: usize, const H: usize> Index<(usize, usize)> for Frame2d<W, H>

Source§

type Output = Rgb<u8>

The returned type after indexing.
Source§

fn index(&self, (x_index, y_index): (usize, usize)) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<const W: usize, const H: usize> IndexMut<(usize, usize)> for Frame2d<W, H>

Source§

fn index_mut(&mut self, (x_index, y_index): (usize, usize)) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl<const W: usize, const H: usize> OriginDimensions for Frame2d<W, H>

Source§

fn size(&self) -> Size

Returns the size of the bounding box.
Source§

impl<const W: usize, const H: usize> Copy for Frame2d<W, H>

Auto Trait Implementations§

§

impl<const W: usize, const H: usize> Freeze for Frame2d<W, H>

§

impl<const W: usize, const H: usize> RefUnwindSafe for Frame2d<W, H>

§

impl<const W: usize, const H: usize> Send for Frame2d<W, H>

§

impl<const W: usize, const H: usize> Sync for Frame2d<W, H>

§

impl<const W: usize, const H: usize> Unpin for Frame2d<W, H>

§

impl<const W: usize, const H: usize> UnwindSafe for Frame2d<W, H>

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> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
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<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Dimensions for T

Source§

fn bounding_box(&self) -> Rectangle

Returns the bounding box.
Source§

impl<T> DrawTargetExt for T
where T: DrawTarget,

Source§

fn translated(&mut self, offset: Point) -> Translated<'_, T>

Creates a translated draw target based on this draw target. Read more
Source§

fn cropped(&mut self, area: &Rectangle) -> Cropped<'_, T>

Creates a cropped draw target based on this draw target. Read more
Source§

fn clipped(&mut self, area: &Rectangle) -> Clipped<'_, T>

Creates a clipped draw target based on this draw target. Read more
Source§

fn color_converted<C>(&mut self) -> ColorConverted<'_, T, C>
where C: PixelColor + Into<<T as DrawTarget>::Color>,

Creates a color conversion draw target. 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<Src, Dst> LosslessTryInto<Dst> for Src
where Dst: LosslessTryFrom<Src>,

Source§

fn lossless_try_into(self) -> Option<Dst>

Performs the conversion.
Source§

impl<Src, Dst> LossyInto<Dst> for Src
where Dst: LossyFrom<Src>,

Source§

fn lossy_into(self) -> Dst

Performs the conversion.
Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> StrictAs for T

Source§

fn strict_as<Dst>(self) -> Dst
where T: StrictCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> StrictCastFrom<Src> for Dst
where Src: StrictCast<Dst>,

Source§

fn strict_cast_from(src: Src) -> Dst

Casts the value.
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.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.