embedded-graphics/tinybmp

`uefi-rs` integration?

Closed this issue · 1 comments

  • Version of tinybmp in use (if applicable): 0.4.0

Description of the problem/feature request/other

Hi there, I am using tinybmp to render a bootsplash in a bootloader in a UEFI environment, I wonder if you are interested in a PR to add support for blt-ting on a EFI Graphics Output Protocol, the uefi-rs provides a "nice" high level API: https://docs.rs/uefi/latest/uefi/proto/console/gop/struct.GraphicsOutput.html which could be used to integrate a proper DrawTarget I imagine.

(also, the doc link to DrawTarget seems to be dead.)

Test case (if applicable)

fn graphics_splash(boot_services: &BootServices, contents: &[u8]) -> uefi::Result {
    let mut gop = boot_services.open_protocol_exclusive::<GraphicsOutput>(
        boot_services.get_handle_for_protocol::<GraphicsOutput>()?
    )?;
    let current_mode = gop.current_mode_info();

    let splash_bmp = tinybmp::RawBmp::from_slice(contents)
        .map_err(|_err| uefi::Status::LOAD_ERROR)?;

    let splash_header = splash_bmp.header();

    ensure_supported_bmp(&splash_bmp)?;

    // Center it if possible.
    let cur_resolution = current_mode.resolution();
    let splash_size: (usize, usize) = (splash_header.image_size.width.try_into().unwrap(), splash_header.image_size.height.try_into().unwrap());
    // FIXME: properly error handle usize < u32... :)
    let x_pos = (cur_resolution.0 - core::cmp::min(splash_size.0, cur_resolution.0)) / 2;
    let y_pos = (cur_resolution.1 - core::cmp::min(splash_size.1, cur_resolution.1)) / 2;

    let background = BltOp::VideoFill {
            color: BltPixel::new(0x0, 0x0, 0x0),
            dest: (0, 0),
            dims: current_mode.resolution()
    };

    // Blit the background
    gop.blt(background)?;

    // Read the current contents to do alpha blending
    let mut current_contents = vec![BltPixel::new(0, 0, 0); splash_size.0 * splash_size.1].into_boxed_slice();

    gop.blt(BltOp::VideoToBltBuffer {
        buffer: &mut (*current_contents),
        src: (x_pos, y_pos),
        dest: BltRegion::Full,
        dims: splash_size
    });

    // Blit the BMP

    Ok(())
}

Here's some code to give you an idea, ideally, I'd like to replace the dance of doing alpha blending myself and blt'ing the final BMP if possible by just replacing it by some Draw or something, what do you think?

Closed as this is clearly a uefi-rs thing to implement DrawTarget.