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-graphicscrate. - Frames are rendered by a panel type generated with
led2d!. SeeLed2dGeneratedfor the full API of the generated panel type. - For animation, call
animatewith 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:
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>
impl<const W: usize, const H: usize> Frame2d<W, H>
Sourcepub const SIZE: Size
pub const SIZE: Size
Frame dimensions as a Size.
For embedded-graphics drawing operation.
Sourcepub const TOP_LEFT: Point
pub const TOP_LEFT: Point
Top-left corner coordinate as a Point.
For embedded-graphics drawing operation.
Sourcepub const TOP_RIGHT: Point
pub const TOP_RIGHT: Point
Top-right corner coordinate as a Point.
For embedded-graphics drawing operation.
Sourcepub const BOTTOM_LEFT: Point
pub const BOTTOM_LEFT: Point
Bottom-left corner coordinate as a Point.
For embedded-graphics drawing operation.
Sourcepub const BOTTOM_RIGHT: Point
pub const BOTTOM_RIGHT: Point
Bottom-right corner coordinate as a Point.
For embedded-graphics drawing operation.
Trait Implementations§
Source§impl<const W: usize, const H: usize> DrawTarget for Frame2d<W, H>
impl<const W: usize, const H: usize> DrawTarget for Frame2d<W, H>
Source§type Error = Infallible
type Error = Infallible
Source§fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
Source§fn fill_contiguous<I>(
&mut self,
area: &Rectangle,
colors: I,
) -> Result<(), Self::Error>where
I: IntoIterator<Item = Self::Color>,
fn fill_contiguous<I>(
&mut self,
area: &Rectangle,
colors: I,
) -> Result<(), Self::Error>where
I: IntoIterator<Item = Self::Color>,
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Dimensions for Twhere
T: OriginDimensions,
impl<T> Dimensions for Twhere
T: OriginDimensions,
Source§fn bounding_box(&self) -> Rectangle
fn bounding_box(&self) -> Rectangle
Source§impl<T> DrawTargetExt for Twhere
T: DrawTarget,
impl<T> DrawTargetExt for Twhere
T: DrawTarget,
Source§fn translated(&mut self, offset: Point) -> Translated<'_, T>
fn translated(&mut self, offset: Point) -> Translated<'_, T>
Source§fn cropped(&mut self, area: &Rectangle) -> Cropped<'_, T>
fn cropped(&mut self, area: &Rectangle) -> Cropped<'_, T>
Source§fn clipped(&mut self, area: &Rectangle) -> Clipped<'_, T>
fn clipped(&mut self, area: &Rectangle) -> Clipped<'_, T>
Source§fn color_converted<C>(&mut self) -> ColorConverted<'_, T, C>
fn color_converted<C>(&mut self) -> ColorConverted<'_, T, C>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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