pub trait CydDisplay: DisplayBackend {
Show 15 methods
// Required methods
fn screen_size(&self) -> Size;
fn background_color(&self) -> Rgb888;
fn foreground_color(&self) -> Rgb888;
fn background_565(&self) -> Rgb565;
fn foreground_565(&self) -> Rgb565;
fn fill_rectangle(
&mut self,
rectangle: Rectangle,
color: Rgb565,
) -> Result<(), Self::Error>;
fn fill_contiguous<I>(
&mut self,
rectangle: Rectangle,
pixels: I,
) -> Result<(), Self::Error>
where I: IntoIterator<Item = Rgb565>;
// Provided methods
fn to_rgb565(&self, color: Rgb888) -> Rgb565 { ... }
fn frame_mut(&mut self, rectangle: Rectangle) -> Self::Frame<'_> { ... }
fn full_frame_mut(&mut self) -> Self::Frame<'_> { ... }
fn fill_contiguous_full<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where I: IntoIterator<Item = Rgb565> { ... }
fn draw_items<const DRAW_ITEM_CAPACITY: usize>(
&mut self,
bounds: Rectangle,
background_color: Rgb565,
items: impl IntoIterator<Item = DrawItem>,
) -> Result<(), Self::Error> { ... }
fn clear(&mut self) -> Result<(), Self::Error> { ... }
fn fill(&mut self, color: Rgb565) -> Result<(), Self::Error> { ... }
fn for_each_tile<'a, F>(
&'a mut self,
grid: TileGrid,
draw: F,
) -> impl Future<Output = Result<(), Self::Error>> + 'a
where Self: Sized,
F: for<'frame> FnMut(&mut Self::Frame<'frame>) + 'a { ... }
}Expand description
A CYD display.
The screen is a fixed 320×240 RGB565 panel.
| Need | API | Reusable pixel-buffer storage |
|---|---|---|
| Normal drawing with enough RAM | full_frame_mut | 153,600 bytes |
| Redraw one region | frame_mut | 2 × rectangle pixel count bytes |
| Normal drawing with little RAM | for_each_tile | 2 × largest tile pixel count bytes |
| Existing or generated row-major RGB565 pixels | fill_contiguous or fill_contiguous_full | No reusable frame buffer |
Small immediate DrawItem scene | draw_items | No pixel frame buffer |
The full-screen figure is 320 × 240 × 2 bytes for the fixed RGB565 panel.
draw_items does not need a pixel frame buffer, but it does need
allocation-free prepared-item capacity. Each nondegenerate DrawItem
consumes at most one prepared-item slot, so setting the capacity to the
number of supplied items is always safe. See CydDisplay::draw_items for
details.
Start with CydDisplay::full_frame_mut when a 153,600-byte frame buffer is
practical. The
drawing-strategy guide compares
full-screen and regional buffering, tiled replay, and contiguous-pixel
streaming.
Required Methods§
Sourcefn screen_size(&self) -> Size
fn screen_size(&self) -> Size
Screen size after applying the configured Orientation:
320×240 in landscape or 240×320 in portrait.
use device_envoy_core::cyd::CydDisplay;
let size = display.screen_size();
assert!(
(size.width == 320 && size.height == 240)
|| (size.width == 240 && size.height == 320)
);Sourcefn background_color(&self) -> Rgb888
fn background_color(&self) -> Rgb888
The device default background color.
use device_envoy_core::cyd::CydDisplay;
let background = display.background_color();
let foreground = display.foreground_color();
assert_eq!(display.background_565(), display.to_rgb565(background));
assert_eq!(display.foreground_565(), display.to_rgb565(foreground));Sourcefn foreground_color(&self) -> Rgb888
fn foreground_color(&self) -> Rgb888
The device default foreground/text color.
See the color getter example.
Sourcefn background_565(&self) -> Rgb565
fn background_565(&self) -> Rgb565
The device default background color in the native Rgb565 format.
See the color getter example.
Sourcefn foreground_565(&self) -> Rgb565
fn foreground_565(&self) -> Rgb565
The device default foreground/text color in the native Rgb565 format.
See the color getter example.
Sourcefn fill_rectangle(
&mut self,
rectangle: Rectangle,
color: Rgb565,
) -> Result<(), Self::Error>
fn fill_rectangle( &mut self, rectangle: Rectangle, color: Rgb565, ) -> Result<(), Self::Error>
Fill rectangle immediately with color in logical display coordinates.
Unlike filling a frame returned by CydDisplay::frame_mut, this is a
device-level operation rather than a frame-buffered draw. Implementations
clip to the logical display and treat an empty intersection as a no-op.
The following example covers the immediate and contiguous operations:
CydDisplay::fill_contiguous, CydDisplay::draw_items, CydDisplay::clear,
and CydDisplay::fill.
use device_envoy_core::cyd::{CydDisplay, display::DrawItem};
use embedded_graphics::{pixelcolor::{Rgb565, Rgb888}, prelude::{Point, RgbColor, Size}, primitives::Rectangle};
async fn draw<D: CydDisplay>(display: &mut D) -> Result<(), D::Error> {
let rectangle = Rectangle::new(Point::zero(), Size::new(2, 2));
display.fill_rectangle(rectangle, Rgb565::BLACK)?;
display.fill_contiguous(rectangle, [Rgb565::RED; 4])?;
// One DrawItem, so reserve one prepared-item slot.
display.draw_items::<1>(rectangle, Rgb565::BLACK, [
DrawItem::Circle {
center: (1.0, 1.0), pixel_radius: 1.0, color: Rgb888::WHITE,
},
])?;
display.clear()?;
display.fill(Rgb565::WHITE)
}Sourcefn fill_contiguous<I>(
&mut self,
rectangle: Rectangle,
pixels: I,
) -> Result<(), Self::Error>where
I: IntoIterator<Item = Rgb565>,
fn fill_contiguous<I>(
&mut self,
rectangle: Rectangle,
pixels: I,
) -> Result<(), Self::Error>where
I: IntoIterator<Item = Rgb565>,
Fill rectangle immediately from row-major native-color pixels.
Empty rectangles are a no-op. Otherwise supply exactly
rectangle_pixel_count(rectangle) pixels: a short iterator leaves the
remaining pixels untouched, while extra pixels are ignored. This method
does not infer missing pixels or repeat the final value.
§Example
Stream an image directly when its RGB565 pixels do not need further drawing or transformation:
use device_envoy_core::cyd::{
CydDisplay,
display::{Image565Fixed, tga},
};
use embedded_graphics::{
prelude::Point,
primitives::Rectangle,
};
const BITMAP: Image565Fixed<45, 73, { 45 * 73 }> =
tga!(concat!(env!("CARGO_MANIFEST_DIR"),
"/docs/assets/cyd_fill_contiguous.tga"))
.to_565();
fn stream_bitmap<D: CydDisplay>(display: &mut D) -> Result<(), D::Error> {
let bitmap = BITMAP.view();
let destination = Rectangle::new(Point::new(40, 30), bitmap.size());
display.fill_contiguous(destination, bitmap.rgb565_iter())
}The tga! macro embeds and decodes the file at compile time. The view
borrows that const image, supplies its dimensions, and yields pixels
in row-major order. The destination can be anywhere on the display, and
this path requires neither a frame buffer nor heap allocation.
For a whole-screen bitmap, see the
fill_contiguous_full example. See the
shared DNS tester’s bitmap-streaming code
for a complete working example.
Provided Methods§
Sourcefn to_rgb565(&self, color: Rgb888) -> Rgb565
fn to_rgb565(&self, color: Rgb888) -> Rgb565
Convert an Rgb888 color to the device’s native Rgb565 format.
See the color getter example.
Sourcefn frame_mut(&mut self, rectangle: Rectangle) -> Self::Frame<'_>
fn frame_mut(&mut self, rectangle: Rectangle) -> Self::Frame<'_>
Borrow a frame covering rectangle, cleared to the device background color.
See CydFrame for the
shared screen-coordinate and clipping model.
use device_envoy_core::cyd::{CydDisplay, display::CydFrame};
use embedded_graphics::{
pixelcolor::{Rgb565, RgbColor},
prelude::{Point, Size},
primitives::Rectangle,
};
async fn draw<D: CydDisplay>(display: &mut D) -> Result<(), D::Error> {
let mut frame = display.frame_mut(Rectangle::new(
Point::new(10, 10),
Size::new(100, 40),
));
frame.fill(Rgb565::BLUE).write_text("CYD").flush().await
}
Sourcefn full_frame_mut(&mut self) -> Self::Frame<'_>
fn full_frame_mut(&mut self) -> Self::Frame<'_>
Borrow a full-screen frame, cleared to the device background color.
See the Cyd device-loop example.
Sourcefn fill_contiguous_full<I>(&mut self, pixels: I) -> Result<(), Self::Error>where
I: IntoIterator<Item = Rgb565>,
fn fill_contiguous_full<I>(&mut self, pixels: I) -> Result<(), Self::Error>where
I: IntoIterator<Item = Rgb565>,
Fill the complete screen immediately from row-major native-color pixels.
This is the whole-screen counterpart to CydDisplay::fill_contiguous.
It expresses full-screen streaming intent without repeating the complete
screen rectangle. Streaming is an advanced raster path: the caller
generates every pixel in row-major order rather than drawing a scene.
§Example
use device_envoy_core::cyd::CydDisplay;
use embedded_graphics::{pixelcolor::Rgb565, prelude::RgbColor};
fn stream_background<D: CydDisplay>(display: &mut D) -> Result<(), D::Error> {
let screen_size = display.screen_size();
// A blue-green RGB565 gradient with a warmer lower-right corner.
let pixels = (0..screen_size.height).flat_map(|position_y| {
(0..screen_size.width).map(move |position_x| {
Rgb565::new(
(position_x * 31 / (screen_size.width - 1)) as u8,
(position_y * 63 / (screen_size.height - 1)) as u8,
((position_x + position_y) * 31
/ (screen_size.width + screen_size.height - 2)) as u8,
)
})
});
display.fill_contiguous_full(pixels)
}The iterator generates each pixel just before it is sent, without a
frame buffer or heap allocation. To position a stored bitmap, see the
fill_contiguous example. The
Linkage Blaze clock
demonstrates full-screen streaming in a complete application.
Sourcefn draw_items<const DRAW_ITEM_CAPACITY: usize>(
&mut self,
bounds: Rectangle,
background_color: Rgb565,
items: impl IntoIterator<Item = DrawItem>,
) -> Result<(), Self::Error>
fn draw_items<const DRAW_ITEM_CAPACITY: usize>( &mut self, bounds: Rectangle, background_color: Rgb565, items: impl IntoIterator<Item = DrawItem>, ) -> Result<(), Self::Error>
Draw items immediately inside bounds.
See the immediate-operations example for a
complete immediate-drawing flow.
DRAW_ITEM_CAPACITY is the allocation-free capacity for prepared draw
items. Each nondegenerate item consumes at most one slot, including an
item that lies outside bounds. Using the total number of supplied items
is always safe.
§Panics
Panics if preparing the items exhausts DRAW_ITEM_CAPACITY.
Sourcefn clear(&mut self) -> Result<(), Self::Error>
fn clear(&mut self) -> Result<(), Self::Error>
Clear the whole screen to the device default background color.
New frames already start cleared to this color. This is for immediately returning the logical display to the default background between frame workflows.
See the immediate-operations example.
Sourcefn fill(&mut self, color: Rgb565) -> Result<(), Self::Error>
fn fill(&mut self, color: Rgb565) -> Result<(), Self::Error>
Fill the whole screen with an explicit color.
See the immediate-operations example.
Sourcefn for_each_tile<'a, F>(
&'a mut self,
grid: TileGrid,
draw: F,
) -> impl Future<Output = Result<(), Self::Error>> + 'a
fn for_each_tile<'a, F>( &'a mut self, grid: TileGrid, draw: F, ) -> impl Future<Output = Result<(), Self::Error>> + 'a
Draw and flush each tile in grid.
draw receives one frame for each tile. See
CydFrame for how the same
screen-coordinate scene is clipped to each tile. Each frame is flushed
after draw returns and before the next tile is processed. Only one tile
is buffered at a time.
See the TileGrid example for grid
construction, buffer sizing, and a scene drawn across tile boundaries.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".