Skip to main content

CydDisplay

Trait CydDisplay 

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

NeedAPIReusable pixel-buffer storage
Normal drawing with enough RAMfull_frame_mut153,600 bytes
Redraw one regionframe_mut2 × rectangle pixel count bytes
Normal drawing with little RAMfor_each_tile2 × largest tile pixel count bytes
Existing or generated row-major RGB565 pixelsfill_contiguous or fill_contiguous_fullNo reusable frame buffer
Small immediate DrawItem scenedraw_itemsNo 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§

Source

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)
);
Source

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));
Source

fn foreground_color(&self) -> Rgb888

The device default foreground/text color.

See the color getter example.

Source

fn background_565(&self) -> Rgb565

The device default background color in the native Rgb565 format.

See the color getter example.

Source

fn foreground_565(&self) -> Rgb565

The device default foreground/text color in the native Rgb565 format.

See the color getter example.

Source

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)
}
Source

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.

A bitmap streamed into a region of an in-memory CYD display.

Provided Methods§

Source

fn to_rgb565(&self, color: Rgb888) -> Rgb565

Convert an Rgb888 color to the device’s native Rgb565 format.

See the color getter example.

Source

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
}

CYD frame preview

Source

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.

Source

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.

A numerically generated gradient streamed into an in-memory CYD display.

Source

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.

Source

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.

Source

fn fill(&mut self, color: Rgb565) -> Result<(), Self::Error>

Fill the whole screen with an explicit color.

See the immediate-operations example.

Source

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,

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".

Implementors§