rename PixelGrid to Bitmap

This commit is contained in:
Vinzenz Schroeter 2024-10-14 22:42:45 +02:00
parent f64ce6e57e
commit bd0ecd77d2
23 changed files with 1037 additions and 1042 deletions

View file

@ -15,7 +15,7 @@ fn main() {
let connection = Connection::open(cli.destination) let connection = Connection::open(cli.destination)
.expect("could not connect to display"); .expect("could not connect to display");
let mut pixels = PixelGrid::max_sized(); let mut pixels = Bitmap::max_sized();
pixels.fill(true); pixels.fill(true);
let command = Command::BitmapLinearWin( let command = Command::BitmapLinearWin(

View file

@ -34,7 +34,7 @@ fn main() {
} }
} }
fn iteration(field: PixelGrid) -> PixelGrid { fn iteration(field: Bitmap) -> Bitmap {
let mut next = field.clone(); let mut next = field.clone();
for x in 0..field.width() { for x in 0..field.width() {
for y in 0..field.height() { for y in 0..field.height() {
@ -51,7 +51,7 @@ fn iteration(field: PixelGrid) -> PixelGrid {
next next
} }
fn count_neighbors(field: &PixelGrid, x: i32, y: i32) -> i32 { fn count_neighbors(field: &Bitmap, x: i32, y: i32) -> i32 {
let mut count = 0; let mut count = 0;
for nx in x - 1..=x + 1 { for nx in x - 1..=x + 1 {
for ny in y - 1..=y + 1 { for ny in y - 1..=y + 1 {
@ -78,8 +78,8 @@ fn count_neighbors(field: &PixelGrid, x: i32, y: i32) -> i32 {
count count
} }
fn make_random_field(probability: f64) -> PixelGrid { fn make_random_field(probability: f64) -> Bitmap {
let mut field = PixelGrid::max_sized(); let mut field = Bitmap::max_sized();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let d = distributions::Bernoulli::new(probability).unwrap(); let d = distributions::Bernoulli::new(probability).unwrap();
for x in 0..field.width() { for x in 0..field.width() {

View file

@ -16,7 +16,7 @@ fn main() {
let connection = Connection::open(Cli::parse().destination) let connection = Connection::open(Cli::parse().destination)
.expect("could not connect to display"); .expect("could not connect to display");
let mut pixels = PixelGrid::max_sized(); let mut pixels = Bitmap::max_sized();
for x_offset in 0..usize::MAX { for x_offset in 0..usize::MAX {
pixels.fill(false); pixels.fill(false);

View file

@ -28,7 +28,7 @@ fn main() {
// put all pixels in on state // put all pixels in on state
if cli.enable_all { if cli.enable_all {
let mut filled_grid = PixelGrid::max_sized(); let mut filled_grid = Bitmap::max_sized();
filled_grid.fill(true); filled_grid.fill(true);
let command = BitmapLinearWin( let command = BitmapLinearWin(

View file

@ -1,7 +1,7 @@
//! Example for how to use the WebSocket connection //! Example for how to use the WebSocket connection
use servicepoint::{ use servicepoint::{
Command, CompressionCode, Connection, Grid, Origin, PixelGrid, Command, CompressionCode, Connection, Grid, Origin, Bitmap,
}; };
fn main() { fn main() {
@ -13,7 +13,7 @@ fn main() {
// use send_mut instead of send // use send_mut instead of send
connection.send_mut(Command::Clear).unwrap(); connection.send_mut(Command::Clear).unwrap();
let mut pixels = PixelGrid::max_sized(); let mut pixels = Bitmap::max_sized();
pixels.fill(true); pixels.fill(true);
// use send_mut instead of send // use send_mut instead of send

View file

@ -25,7 +25,7 @@ fn main() {
let connection = Connection::open(cli.destination) let connection = Connection::open(cli.destination)
.expect("could not connect to display"); .expect("could not connect to display");
let mut enabled_pixels = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); let mut enabled_pixels = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT);
enabled_pixels.fill(true); enabled_pixels.fill(true);
for x_offset in 0..PIXEL_WIDTH { for x_offset in 0..PIXEL_WIDTH {

View file

@ -6,21 +6,21 @@ use crate::{BitVec, DataRef, Grid, SpBitVec, PIXEL_HEIGHT, PIXEL_WIDTH};
/// A grid of pixels stored in packed bytes. /// A grid of pixels stored in packed bytes.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct PixelGrid { pub struct Bitmap {
width: usize, width: usize,
height: usize, height: usize,
bit_vec: SpBitVec, bit_vec: SpBitVec,
} }
impl PixelGrid { impl Bitmap {
/// Creates a new [PixelGrid] with the specified dimensions. /// Creates a new [Bitmap] with the specified dimensions.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `width`: size in pixels in x-direction /// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction /// - `height`: size in pixels in y-direction
/// ///
/// returns: [PixelGrid] initialized to all pixels off /// returns: [Bitmap] initialized to all pixels off
/// ///
/// # Panics /// # Panics
/// ///
@ -40,14 +40,14 @@ impl PixelGrid {
Self::new(PIXEL_WIDTH, PIXEL_HEIGHT) Self::new(PIXEL_WIDTH, PIXEL_HEIGHT)
} }
/// Loads a [PixelGrid] with the specified dimensions from the provided data. /// Loads a [Bitmap] with the specified dimensions from the provided data.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `width`: size in pixels in x-direction /// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction /// - `height`: size in pixels in y-direction
/// ///
/// returns: [PixelGrid] that contains a copy of the provided data /// returns: [Bitmap] that contains a copy of the provided data
/// ///
/// # Panics /// # Panics
/// ///
@ -64,12 +64,12 @@ impl PixelGrid {
} }
} }
/// Iterate over all cells in [PixelGrid]. /// Iterate over all cells in [Bitmap].
/// ///
/// Order is equivalent to the following loop: /// Order is equivalent to the following loop:
/// ``` /// ```
/// # use servicepoint::{PixelGrid, Grid}; /// # use servicepoint::{Bitmap, Grid};
/// # let grid = PixelGrid::new(8,2); /// # let grid = Bitmap::new(8,2);
/// for y in 0..grid.height() { /// for y in 0..grid.height() {
/// for x in 0..grid.width() { /// for x in 0..grid.width() {
/// grid.get(x, y); /// grid.get(x, y);
@ -80,12 +80,12 @@ impl PixelGrid {
self.bit_vec.iter().by_refs() self.bit_vec.iter().by_refs()
} }
/// Iterate over all cells in [PixelGrid] mutably. /// Iterate over all cells in [Bitmap] mutably.
/// ///
/// Order is equivalent to the following loop: /// Order is equivalent to the following loop:
/// ``` /// ```
/// # use servicepoint::{PixelGrid, Grid}; /// # use servicepoint::{Bitmap, Grid};
/// # let mut grid = PixelGrid::new(8,2); /// # let mut grid = Bitmap::new(8,2);
/// # let value = false; /// # let value = false;
/// for y in 0..grid.height() { /// for y in 0..grid.height() {
/// for x in 0..grid.width() { /// for x in 0..grid.width() {
@ -96,8 +96,8 @@ impl PixelGrid {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use servicepoint::{PixelGrid, Grid}; /// # use servicepoint::{Bitmap, Grid};
/// # let mut grid = PixelGrid::new(8,2); /// # let mut grid = Bitmap::new(8,2);
/// # let value = false; /// # let value = false;
/// for (index, mut pixel) in grid.iter_mut().enumerate() { /// for (index, mut pixel) in grid.iter_mut().enumerate() {
/// pixel.set(index % 2 == 0) /// pixel.set(index % 2 == 0)
@ -107,17 +107,17 @@ impl PixelGrid {
self.bit_vec.iter_mut() self.bit_vec.iter_mut()
} }
/// Iterate over all rows in [PixelGrid] top to bottom. /// Iterate over all rows in [Bitmap] top to bottom.
pub fn iter_rows(&self) -> IterRows { pub fn iter_rows(&self) -> IterRows {
IterRows { IterRows {
pixel_grid: self, bitmap: self,
row: 0, row: 0,
} }
} }
} }
impl Grid<bool> for PixelGrid { impl Grid<bool> for Bitmap {
/// Sets the value of the specified position in the [PixelGrid]. /// Sets the value of the specified position in the [Bitmap].
/// ///
/// # Arguments /// # Arguments
/// ///
@ -139,7 +139,7 @@ impl Grid<bool> for PixelGrid {
self.bit_vec[x + y * self.width] self.bit_vec[x + y * self.width]
} }
/// Sets the state of all pixels in the [PixelGrid]. /// Sets the state of all pixels in the [Bitmap].
/// ///
/// # Arguments /// # Arguments
/// ///
@ -158,7 +158,7 @@ impl Grid<bool> for PixelGrid {
} }
} }
impl DataRef<u8> for PixelGrid { impl DataRef<u8> for Bitmap {
fn data_ref_mut(&mut self) -> &mut [u8] { fn data_ref_mut(&mut self) -> &mut [u8] {
self.bit_vec.as_raw_mut_slice() self.bit_vec.as_raw_mut_slice()
} }
@ -168,15 +168,15 @@ impl DataRef<u8> for PixelGrid {
} }
} }
impl From<PixelGrid> for Vec<u8> { impl From<Bitmap> for Vec<u8> {
/// Turns a [PixelGrid] into the underlying [`Vec<u8>`]. /// Turns a [Bitmap] into the underlying [`Vec<u8>`].
fn from(value: PixelGrid) -> Self { fn from(value: Bitmap) -> Self {
value.bit_vec.into() value.bit_vec.into()
} }
} }
pub struct IterRows<'t> { pub struct IterRows<'t> {
pixel_grid: &'t PixelGrid, bitmap: &'t Bitmap,
row: usize, row: usize,
} }
@ -184,24 +184,24 @@ impl<'t> Iterator for IterRows<'t> {
type Item = &'t BitSlice<u8, Msb0>; type Item = &'t BitSlice<u8, Msb0>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.row >= self.pixel_grid.height { if self.row >= self.bitmap.height {
return None; return None;
} }
let start = self.row * self.pixel_grid.width; let start = self.row * self.bitmap.width;
let end = start + self.pixel_grid.width; let end = start + self.bitmap.width;
self.row += 1; self.row += 1;
Some(&self.pixel_grid.bit_vec[start..end]) Some(&self.bitmap.bit_vec[start..end])
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{DataRef, Grid, PixelGrid}; use crate::{DataRef, Grid, Bitmap};
#[test] #[test]
fn fill() { fn fill() {
let mut grid = PixelGrid::new(8, 2); let mut grid = Bitmap::new(8, 2);
assert_eq!(grid.data_ref(), [0x00, 0x00]); assert_eq!(grid.data_ref(), [0x00, 0x00]);
grid.fill(true); grid.fill(true);
@ -213,7 +213,7 @@ mod tests {
#[test] #[test]
fn get_set() { fn get_set() {
let mut grid = PixelGrid::new(8, 2); let mut grid = Bitmap::new(8, 2);
assert!(!grid.get(0, 0)); assert!(!grid.get(0, 0));
assert!(!grid.get(1, 1)); assert!(!grid.get(1, 1));
@ -228,7 +228,7 @@ mod tests {
#[test] #[test]
fn load() { fn load() {
let mut grid = PixelGrid::new(8, 3); let mut grid = Bitmap::new(8, 3);
for x in 0..grid.width { for x in 0..grid.width {
for y in 0..grid.height { for y in 0..grid.height {
grid.set(x, y, (x + y) % 2 == 0); grid.set(x, y, (x + y) % 2 == 0);
@ -239,33 +239,33 @@ mod tests {
let data: Vec<u8> = grid.into(); let data: Vec<u8> = grid.into();
let grid = PixelGrid::load(8, 3, &data); let grid = Bitmap::load(8, 3, &data);
assert_eq!(grid.data_ref(), [0xAA, 0x55, 0xAA]); assert_eq!(grid.data_ref(), [0xAA, 0x55, 0xAA]);
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn out_of_bounds_x() { fn out_of_bounds_x() {
let vec = PixelGrid::new(8, 2); let vec = Bitmap::new(8, 2);
vec.get(8, 1); vec.get(8, 1);
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn out_of_bounds_y() { fn out_of_bounds_y() {
let mut vec = PixelGrid::new(8, 2); let mut vec = Bitmap::new(8, 2);
vec.set(1, 2, false); vec.set(1, 2, false);
} }
#[test] #[test]
fn iter() { fn iter() {
let grid = PixelGrid::new(8, 2); let grid = Bitmap::new(8, 2);
assert_eq!(16, grid.iter().count()) assert_eq!(16, grid.iter().count())
} }
#[test] #[test]
fn iter_rows() { fn iter_rows() {
let grid = PixelGrid::load(8, 2, &[0x04, 0x40]); let grid = Bitmap::load(8, 2, &[0x04, 0x40]);
let mut iter = grid.iter_rows(); let mut iter = grid.iter_rows();
assert_eq!(iter.next().unwrap().count_ones(), 1); assert_eq!(iter.next().unwrap().count_ones(), 1);
@ -275,7 +275,7 @@ mod tests {
#[test] #[test]
fn iter_mut() { fn iter_mut() {
let mut grid = PixelGrid::new(8, 2); let mut grid = Bitmap::new(8, 2);
for (index, mut pixel) in grid.iter_mut().enumerate() { for (index, mut pixel) in grid.iter_mut().enumerate() {
pixel.set(index % 2 == 0); pixel.set(index % 2 == 0);
} }
@ -284,7 +284,7 @@ mod tests {
#[test] #[test]
fn data_ref_mut() { fn data_ref_mut() {
let mut grid = PixelGrid::new(8, 2); let mut grid = Bitmap::new(8, 2);
let data = grid.data_ref_mut(); let data = grid.data_ref_mut();
data[1] = 0x0F; data[1] = 0x0F;
assert!(grid.get(7, 1)); assert!(grid.get(7, 1));

View file

@ -4,7 +4,7 @@ use crate::{
command_code::CommandCode, command_code::CommandCode,
compression::into_decompressed, compression::into_decompressed,
packet::{Header, Packet}, packet::{Header, Packet},
Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, PixelGrid, Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, Bitmap,
Pixels, PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE, Pixels, PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE,
}; };
@ -105,10 +105,10 @@ pub enum Command {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use servicepoint::{Command, CompressionCode, Grid, PixelGrid}; /// # use servicepoint::{Command, CompressionCode, Grid, Bitmap};
/// # let connection = servicepoint::Connection::Fake; /// # let connection = servicepoint::Connection::Fake;
/// # /// #
/// let mut pixels = PixelGrid::max_sized(); /// let mut pixels = Bitmap::max_sized();
/// // draw something to the pixels here /// // draw something to the pixels here
/// # pixels.set(2, 5, true); /// # pixels.set(2, 5, true);
/// ///
@ -121,7 +121,7 @@ pub enum Command {
/// ///
/// connection.send(command).expect("send failed"); /// connection.send(command).expect("send failed");
/// ``` /// ```
BitmapLinearWin(Origin<Pixels>, PixelGrid, CompressionCode), BitmapLinearWin(Origin<Pixels>, Bitmap, CompressionCode),
/// Set the brightness of all tiles to the same value. /// Set the brightness of all tiles to the same value.
/// ///
@ -337,7 +337,7 @@ impl Command {
Ok(Command::BitmapLinearWin( Ok(Command::BitmapLinearWin(
Origin::new(tiles_x as usize * TILE_SIZE, pixels_y as usize), Origin::new(tiles_x as usize * TILE_SIZE, pixels_y as usize),
PixelGrid::load( Bitmap::load(
tile_w as usize * TILE_SIZE, tile_w as usize * TILE_SIZE,
pixel_h as usize, pixel_h as usize,
&payload, &payload,
@ -371,7 +371,7 @@ impl Command {
} }
} }
/// Helper method for Packets into `BitMapLinear*`-Commands /// Helper method for Packets into `BitmapLinear*`-Commands
fn packet_into_linear_bitmap( fn packet_into_linear_bitmap(
packet: Packet, packet: Packet,
) -> Result<(SpBitVec, CompressionCode), TryFromPacketError> { ) -> Result<(SpBitVec, CompressionCode), TryFromPacketError> {
@ -496,7 +496,7 @@ mod tests {
origin::Pixels, origin::Pixels,
packet::{Header, Packet}, packet::{Header, Packet},
Brightness, BrightnessGrid, Command, CompressionCode, Origin, Brightness, BrightnessGrid, Command, CompressionCode, Origin,
PixelGrid, PrimitiveGrid, Bitmap, PrimitiveGrid,
}; };
fn round_trip(original: Command) { fn round_trip(original: Command) {
@ -589,7 +589,7 @@ mod tests {
)); ));
round_trip(Command::BitmapLinearWin( round_trip(Command::BitmapLinearWin(
Origin::new(0, 0), Origin::new(0, 0),
PixelGrid::max_sized(), Bitmap::max_sized(),
compression, compression,
)); ));
} }
@ -714,7 +714,7 @@ mod tests {
for compression in all_compressions().to_owned() { for compression in all_compressions().to_owned() {
let p: Packet = Command::BitmapLinearWin( let p: Packet = Command::BitmapLinearWin(
Origin::new(16, 8), Origin::new(16, 8),
PixelGrid::new(8, 8), Bitmap::new(8, 8),
compression, compression,
) )
.into(); .into();

View file

@ -3,13 +3,13 @@
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use servicepoint::{Command, CompressionCode, Origin, PixelGrid}; /// # use servicepoint::{Command, CompressionCode, Origin, Bitmap};
/// // create command without payload compression /// // create command without payload compression
/// # let pixels = PixelGrid::max_sized(); /// # let pixels = Bitmap::max_sized();
/// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Uncompressed); /// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Uncompressed);
/// ///
/// // create command with payload compressed with lzma and appropriate header flags /// // create command with payload compressed with lzma and appropriate header flags
/// # let pixels = PixelGrid::max_sized(); /// # let pixels = Bitmap::max_sized();
/// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Lzma); /// _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Lzma);
/// ``` /// ```
#[repr(u16)] #[repr(u16)]

View file

@ -7,7 +7,7 @@
//! # Examples //! # Examples
//! //!
//! ```rust //! ```rust
//! use servicepoint::{Command, CompressionCode, Grid, PixelGrid}; //! use servicepoint::{Command, CompressionCode, Grid, Bitmap};
//! //!
//! let connection = servicepoint::Connection::open("127.0.0.1:2342") //! let connection = servicepoint::Connection::open("127.0.0.1:2342")
//! .expect("connection failed"); //! .expect("connection failed");
@ -18,10 +18,10 @@
//! ``` //! ```
//! //!
//! ```rust //! ```rust
//! # use servicepoint::{Command, CompressionCode, Grid, PixelGrid}; //! # use servicepoint::{Command, CompressionCode, Grid, Bitmap};
//! # let connection = servicepoint::Connection::open("127.0.0.1:2342").expect("connection failed"); //! # let connection = servicepoint::Connection::open("127.0.0.1:2342").expect("connection failed");
//! // turn on all pixels in a grid //! // turn on all pixels in a grid
//! let mut pixels = PixelGrid::max_sized(); //! let mut pixels = Bitmap::max_sized();
//! pixels.fill(true); //! pixels.fill(true);
//! //!
//! // create command to send pixels //! // create command to send pixels
@ -48,7 +48,7 @@ pub use crate::cp437::{CharGrid, Cp437Grid};
pub use crate::data_ref::DataRef; pub use crate::data_ref::DataRef;
pub use crate::grid::Grid; pub use crate::grid::Grid;
pub use crate::origin::{Origin, Pixels, Tiles}; pub use crate::origin::{Origin, Pixels, Tiles};
pub use crate::pixel_grid::PixelGrid; pub use crate::bitmap::Bitmap;
pub use crate::primitive_grid::PrimitiveGrid; pub use crate::primitive_grid::PrimitiveGrid;
type SpBitVec = BitVec<u8, Msb0>; type SpBitVec = BitVec<u8, Msb0>;
@ -64,7 +64,7 @@ mod data_ref;
mod grid; mod grid;
mod origin; mod origin;
pub mod packet; pub mod packet;
mod pixel_grid; mod bitmap;
mod primitive_grid; mod primitive_grid;
/// size of a single tile in one dimension /// size of a single tile in one dimension
@ -95,8 +95,8 @@ pub const TILE_HEIGHT: usize = 20;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; /// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, Bitmap};
/// let grid = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); /// let grid = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT);
/// ``` /// ```
pub const PIXEL_WIDTH: usize = TILE_WIDTH * TILE_SIZE; pub const PIXEL_WIDTH: usize = TILE_WIDTH * TILE_SIZE;
@ -105,8 +105,8 @@ pub const PIXEL_WIDTH: usize = TILE_WIDTH * TILE_SIZE;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; /// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, Bitmap};
/// let grid = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); /// let grid = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT);
/// ``` /// ```
pub const PIXEL_HEIGHT: usize = TILE_HEIGHT * TILE_SIZE; pub const PIXEL_HEIGHT: usize = TILE_HEIGHT * TILE_SIZE;
@ -119,10 +119,10 @@ pub const PIXEL_COUNT: usize = PIXEL_WIDTH * PIXEL_HEIGHT;
/// ///
/// ```rust /// ```rust
/// # use std::time::Instant; /// # use std::time::Instant;
/// # use servicepoint::{Command, CompressionCode, FRAME_PACING, Origin, PixelGrid}; /// # use servicepoint::{Command, CompressionCode, FRAME_PACING, Origin, Bitmap};
/// # let connection = servicepoint::Connection::open("172.23.42.29:2342") /// # let connection = servicepoint::Connection::open("172.23.42.29:2342")
/// # .expect("connection failed"); /// # .expect("connection failed");
/// # let pixels = PixelGrid::max_sized(); /// # let pixels = Bitmap::max_sized();
/// loop { /// loop {
/// let start = Instant::now(); /// let start = Instant::now();
/// ///

View file

@ -28,7 +28,7 @@ use std::mem::size_of;
use crate::compression::into_compressed; use crate::compression::into_compressed;
use crate::{ use crate::{
command_code::CommandCode, Command, CompressionCode, Grid, Offset, Origin, command_code::CommandCode, Command, CompressionCode, Grid, Offset, Origin,
PixelGrid, Pixels, Tiles, TILE_SIZE, Bitmap, Pixels, Tiles, TILE_SIZE,
}; };
/// A raw header. /// A raw header.
@ -214,7 +214,7 @@ impl From<Command> for Packet {
} }
impl Packet { impl Packet {
/// Helper method for `BitMapLinear*`-Commands into [Packet] /// Helper method for `BitmapLinear*`-Commands into [Packet]
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
fn bitmap_linear_into_packet( fn bitmap_linear_into_packet(
command: CommandCode, command: CommandCode,
@ -239,7 +239,7 @@ impl Packet {
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
fn bitmap_win_into_packet( fn bitmap_win_into_packet(
origin: Origin<Pixels>, origin: Origin<Pixels>,
pixels: PixelGrid, pixels: Bitmap,
compression: CompressionCode, compression: CompressionCode,
) -> Packet { ) -> Packet {
debug_assert_eq!(origin.x % 8, 0); debug_assert_eq!(origin.x % 8, 0);

View file

@ -21,8 +21,8 @@ int main(void) {
if (connection == NULL) if (connection == NULL)
return 1; return 1;
SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT);
sp_pixel_grid_fill(pixels, true); sp_bitmap_fill(pixels, true);
SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
while (sp_connection_send_command(connection, sp_command_clone(command))); while (sp_connection_send_command(connection, sp_command_clone(command)));

View file

@ -83,6 +83,20 @@ typedef uint16_t SPCompressionCode;
*/ */
typedef struct SPBitVec SPBitVec; typedef struct SPBitVec SPBitVec;
/**
* A grid of pixels.
*
* # Examples
*
* ```C
* Cp437Grid grid = sp_bitmap_new(8, 3);
* sp_bitmap_fill(grid, true);
* sp_bitmap_set(grid, 0, 0, false);
* sp_bitmap_free(grid);
* ```
*/
typedef struct SPBitmap SPBitmap;
/** /**
* A grid containing brightness values. * A grid containing brightness values.
* *
@ -152,20 +166,6 @@ typedef struct SPCp437Grid SPCp437Grid;
*/ */
typedef struct SPPacket SPPacket; typedef struct SPPacket SPPacket;
/**
* A grid of pixels.
*
* # Examples
*
* ```C
* Cp437Grid grid = sp_pixel_grid_new(8, 3);
* sp_pixel_grid_fill(grid, true);
* sp_pixel_grid_set(grid, 0, 0, false);
* sp_pixel_grid_free(grid);
* ```
*/
typedef struct SPPixelGrid SPPixelGrid;
/** /**
* Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code.
* *
@ -403,6 +403,219 @@ void sp_bit_vec_set(struct SPBitVec *bit_vec, size_t index, bool value);
*/ */
struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *bit_vec); struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *bit_vec);
/**
* Clones a [SPBitmap].
*
* Will never return NULL.
*
* # Panics
*
* - when `bitmap` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
* - `bitmap` is not written to concurrently
* - the returned instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_bitmap_free`.
*/
struct SPBitmap *sp_bitmap_clone(const struct SPBitmap *bitmap);
/**
* Sets the state of all pixels in the [SPBitmap].
*
* # Arguments
*
* - `bitmap`: instance to write to
* - `value`: the value to set all pixels to
*
* # Panics
*
* - when `bitmap` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
* - `bitmap` is not written to or read from concurrently
*/
void sp_bitmap_fill(struct SPBitmap *bitmap, bool value);
/**
* Deallocates a [SPBitmap].
*
* # Panics
*
* - when `bitmap` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
* - `bitmap` is not used concurrently or after bitmap call
* - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
*/
void sp_bitmap_free(struct SPBitmap *bitmap);
/**
* Gets the current value at the specified position in the [SPBitmap].
*
* # Arguments
*
* - `bitmap`: instance to read from
* - `x` and `y`: position of the cell to read
*
* # Panics
*
* - when `bitmap` is NULL
* - when accessing `x` or `y` out of bounds
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
* - `bitmap` is not written to concurrently
*/
bool sp_bitmap_get(const struct SPBitmap *bitmap, size_t x, size_t y);
/**
* Gets the height in pixels of the [SPBitmap] instance.
*
* # Arguments
*
* - `bitmap`: instance to read from
*
* # Panics
*
* - when `bitmap` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
*/
size_t sp_bitmap_height(const struct SPBitmap *bitmap);
/**
* Loads a [SPBitmap] with the specified dimensions from the provided data.
*
* # Arguments
*
* - `width`: size in pixels in x-direction
* - `height`: size in pixels in y-direction
*
* returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL.
*
* # Panics
*
* - when `data` is NULL
* - when the dimensions and data size do not match exactly.
* - when the width is not dividable by 8
*
* # Safety
*
* The caller has to make sure that:
*
* - `data` points to a valid memory location of at least `data_length` bytes in size.
* - the returned instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_bitmap_free`.
*/
struct SPBitmap *sp_bitmap_load(size_t width,
size_t height,
const uint8_t *data,
size_t data_length);
/**
* Creates a new [SPBitmap] with the specified dimensions.
*
* # Arguments
*
* - `width`: size in pixels in x-direction
* - `height`: size in pixels in y-direction
*
* returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
*
* # Panics
*
* - when the width is not dividable by 8
*
* # Safety
*
* The caller has to make sure that:
*
* - the returned instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_bitmap_free`.
*/
struct SPBitmap *sp_bitmap_new(size_t width,
size_t height);
/**
* Sets the value of the specified position in the [SPBitmap].
*
* # Arguments
*
* - `bitmap`: instance to write to
* - `x` and `y`: position of the cell
* - `value`: the value to write to the cell
*
* returns: old value of the cell
*
* # Panics
*
* - when `bitmap` is NULL
* - when accessing `x` or `y` out of bounds
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
* - `bitmap` is not written to or read from concurrently
*/
void sp_bitmap_set(struct SPBitmap *bitmap, size_t x, size_t y, bool value);
/**
* Gets an unsafe reference to the data of the [SPBitmap] instance.
*
* # Panics
*
* - when `bitmap` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
* - the returned memory range is never accessed after the passed [SPBitmap] has been freed
* - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
*/
struct SPByteSlice sp_bitmap_unsafe_data_ref(struct SPBitmap *bitmap);
/**
* Gets the width in pixels of the [SPBitmap] instance.
*
* # Arguments
*
* - `bitmap`: instance to read from
*
* # Panics
*
* - when `bitmap` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `bitmap` points to a valid [SPBitmap]
*/
size_t sp_bitmap_width(const struct SPBitmap *bitmap);
/** /**
* Clones a [SPBrightnessGrid]. * Clones a [SPBrightnessGrid].
* *
@ -726,28 +939,28 @@ struct SPCommand *sp_command_bitmap_linear_or(size_t offset,
/** /**
* Sets a window of pixels to the specified values. * Sets a window of pixels to the specified values.
* *
* The passed [SPPixelGrid] gets consumed. * The passed [SPBitmap] gets consumed.
* *
* Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. * Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL.
* *
* # Panics * # Panics
* *
* - when `pixel_grid` is null * - when `bitmap` is null
* - when `compression_code` is not a valid value * - when `compression_code` is not a valid value
* *
* # Safety * # Safety
* *
* The caller has to make sure that: * The caller has to make sure that:
* *
* - `pixel_grid` points to a valid instance of [SPPixelGrid] * - `bitmap` points to a valid instance of [SPBitmap]
* - `pixel_grid` is not used concurrently or after this call * - `bitmap` is not used concurrently or after this call
* - `compression` matches one of the allowed enum values * - `compression` matches one of the allowed enum values
* - the returned [SPCommand] instance is freed in some way, either by using a consuming function or * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_command_free`. * by explicitly calling `sp_command_free`.
*/ */
struct SPCommand *sp_command_bitmap_linear_win(size_t x, struct SPCommand *sp_command_bitmap_linear_win(size_t x,
size_t y, size_t y,
struct SPPixelGrid *pixel_grid, struct SPBitmap *bitmap,
SPCompressionCode compression_code); SPCompressionCode compression_code);
/** /**
@ -1330,224 +1543,6 @@ struct SPPacket *sp_packet_from_command(struct SPCommand *command);
struct SPPacket *sp_packet_try_load(const uint8_t *data, struct SPPacket *sp_packet_try_load(const uint8_t *data,
size_t length); size_t length);
/**
* Clones a [SPPixelGrid].
*
* Will never return NULL.
*
* # Panics
*
* - when `pixel_grid` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
* - `pixel_grid` is not written to concurrently
* - the returned instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_pixel_grid_free`.
*/
struct SPPixelGrid *sp_pixel_grid_clone(const struct SPPixelGrid *pixel_grid);
/**
* Sets the state of all pixels in the [SPPixelGrid].
*
* # Arguments
*
* - `pixel_grid`: instance to write to
* - `value`: the value to set all pixels to
*
* # Panics
*
* - when `pixel_grid` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
* - `pixel_grid` is not written to or read from concurrently
*/
void sp_pixel_grid_fill(struct SPPixelGrid *pixel_grid, bool value);
/**
* Deallocates a [SPPixelGrid].
*
* # Panics
*
* - when `pixel_grid` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
* - `pixel_grid` is not used concurrently or after pixel_grid call
* - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
*/
void sp_pixel_grid_free(struct SPPixelGrid *pixel_grid);
/**
* Gets the current value at the specified position in the [SPPixelGrid].
*
* # Arguments
*
* - `pixel_grid`: instance to read from
* - `x` and `y`: position of the cell to read
*
* # Panics
*
* - when `pixel_grid` is NULL
* - when accessing `x` or `y` out of bounds
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
* - `pixel_grid` is not written to concurrently
*/
bool sp_pixel_grid_get(const struct SPPixelGrid *pixel_grid,
size_t x,
size_t y);
/**
* Gets the height in pixels of the [SPPixelGrid] instance.
*
* # Arguments
*
* - `pixel_grid`: instance to read from
*
* # Panics
*
* - when `pixel_grid` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
*/
size_t sp_pixel_grid_height(const struct SPPixelGrid *pixel_grid);
/**
* Loads a [SPPixelGrid] with the specified dimensions from the provided data.
*
* # Arguments
*
* - `width`: size in pixels in x-direction
* - `height`: size in pixels in y-direction
*
* returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL.
*
* # Panics
*
* - when `data` is NULL
* - when the dimensions and data size do not match exactly.
* - when the width is not dividable by 8
*
* # Safety
*
* The caller has to make sure that:
*
* - `data` points to a valid memory location of at least `data_length` bytes in size.
* - the returned instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_pixel_grid_free`.
*/
struct SPPixelGrid *sp_pixel_grid_load(size_t width,
size_t height,
const uint8_t *data,
size_t data_length);
/**
* Creates a new [SPPixelGrid] with the specified dimensions.
*
* # Arguments
*
* - `width`: size in pixels in x-direction
* - `height`: size in pixels in y-direction
*
* returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL.
*
* # Panics
*
* - when the width is not dividable by 8
*
* # Safety
*
* The caller has to make sure that:
*
* - the returned instance is freed in some way, either by using a consuming function or
* by explicitly calling `sp_pixel_grid_free`.
*/
struct SPPixelGrid *sp_pixel_grid_new(size_t width,
size_t height);
/**
* Sets the value of the specified position in the [SPPixelGrid].
*
* # Arguments
*
* - `pixel_grid`: instance to write to
* - `x` and `y`: position of the cell
* - `value`: the value to write to the cell
*
* returns: old value of the cell
*
* # Panics
*
* - when `pixel_grid` is NULL
* - when accessing `x` or `y` out of bounds
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
* - `pixel_grid` is not written to or read from concurrently
*/
void sp_pixel_grid_set(struct SPPixelGrid *pixel_grid,
size_t x,
size_t y,
bool value);
/**
* Gets an unsafe reference to the data of the [SPPixelGrid] instance.
*
* # Panics
*
* - when `pixel_grid` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
* - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed
* - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly
*/
struct SPByteSlice sp_pixel_grid_unsafe_data_ref(struct SPPixelGrid *pixel_grid);
/**
* Gets the width in pixels of the [SPPixelGrid] instance.
*
* # Arguments
*
* - `pixel_grid`: instance to read from
*
* # Panics
*
* - when `pixel_grid` is NULL
*
* # Safety
*
* The caller has to make sure that:
*
* - `pixel_grid` points to a valid [SPPixelGrid]
*/
size_t sp_pixel_grid_width(const struct SPPixelGrid *pixel_grid);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif // __cplusplus #endif // __cplusplus

View file

@ -6,8 +6,8 @@ int main(void) {
if (connection == NULL) if (connection == NULL)
return 1; return 1;
SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT);
sp_pixel_grid_fill(pixels, true); sp_bitmap_fill(pixels, true);
SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, SP_COMPRESSION_CODE_UNCOMPRESSED); SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, SP_COMPRESSION_CODE_UNCOMPRESSED);
while (sp_connection_send_command(connection, sp_command_clone(command))); while (sp_connection_send_command(connection, sp_command_clone(command)));

View file

@ -0,0 +1,290 @@
//! C functions for interacting with [SPBitmap]s
//!
//! prefix `sp_bitmap_`
use servicepoint::{DataRef, Grid};
use crate::byte_slice::SPByteSlice;
/// A grid of pixels.
///
/// # Examples
///
/// ```C
/// Cp437Grid grid = sp_bitmap_new(8, 3);
/// sp_bitmap_fill(grid, true);
/// sp_bitmap_set(grid, 0, 0, false);
/// sp_bitmap_free(grid);
/// ```
pub struct SPBitmap(pub(crate) servicepoint::Bitmap);
/// Creates a new [SPBitmap] with the specified dimensions.
///
/// # Arguments
///
/// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction
///
/// returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
///
/// # Panics
///
/// - when the width is not dividable by 8
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_bitmap_free`.
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_new(
width: usize,
height: usize,
) -> *mut SPBitmap {
let result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::new(
width, height,
))));
assert!(!result.is_null());
result
}
/// Loads a [SPBitmap] with the specified dimensions from the provided data.
///
/// # Arguments
///
/// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction
///
/// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL.
///
/// # Panics
///
/// - when `data` is NULL
/// - when the dimensions and data size do not match exactly.
/// - when the width is not dividable by 8
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `data` points to a valid memory location of at least `data_length` bytes in size.
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_bitmap_free`.
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_load(
width: usize,
height: usize,
data: *const u8,
data_length: usize,
) -> *mut SPBitmap {
assert!(!data.is_null());
let data = std::slice::from_raw_parts(data, data_length);
let result = Box::into_raw(Box::new(SPBitmap(servicepoint::Bitmap::load(
width, height, data,
))));
assert!(!result.is_null());
result
}
/// Clones a [SPBitmap].
///
/// Will never return NULL.
///
/// # Panics
///
/// - when `bitmap` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
/// - `bitmap` is not written to concurrently
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_bitmap_free`.
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_clone(
bitmap: *const SPBitmap,
) -> *mut SPBitmap {
assert!(!bitmap.is_null());
let result = Box::into_raw(Box::new(SPBitmap((*bitmap).0.clone())));
assert!(!result.is_null());
result
}
/// Deallocates a [SPBitmap].
///
/// # Panics
///
/// - when `bitmap` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
/// - `bitmap` is not used concurrently or after bitmap call
/// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_free(bitmap: *mut SPBitmap) {
assert!(!bitmap.is_null());
_ = Box::from_raw(bitmap);
}
/// Gets the current value at the specified position in the [SPBitmap].
///
/// # Arguments
///
/// - `bitmap`: instance to read from
/// - `x` and `y`: position of the cell to read
///
/// # Panics
///
/// - when `bitmap` is NULL
/// - when accessing `x` or `y` out of bounds
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
/// - `bitmap` is not written to concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_get(
bitmap: *const SPBitmap,
x: usize,
y: usize,
) -> bool {
assert!(!bitmap.is_null());
(*bitmap).0.get(x, y)
}
/// Sets the value of the specified position in the [SPBitmap].
///
/// # Arguments
///
/// - `bitmap`: instance to write to
/// - `x` and `y`: position of the cell
/// - `value`: the value to write to the cell
///
/// returns: old value of the cell
///
/// # Panics
///
/// - when `bitmap` is NULL
/// - when accessing `x` or `y` out of bounds
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
/// - `bitmap` is not written to or read from concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_set(
bitmap: *mut SPBitmap,
x: usize,
y: usize,
value: bool,
) {
assert!(!bitmap.is_null());
(*bitmap).0.set(x, y, value);
}
/// Sets the state of all pixels in the [SPBitmap].
///
/// # Arguments
///
/// - `bitmap`: instance to write to
/// - `value`: the value to set all pixels to
///
/// # Panics
///
/// - when `bitmap` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
/// - `bitmap` is not written to or read from concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_fill(
bitmap: *mut SPBitmap,
value: bool,
) {
assert!(!bitmap.is_null());
(*bitmap).0.fill(value);
}
/// Gets the width in pixels of the [SPBitmap] instance.
///
/// # Arguments
///
/// - `bitmap`: instance to read from
///
/// # Panics
///
/// - when `bitmap` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_width(
bitmap: *const SPBitmap,
) -> usize {
assert!(!bitmap.is_null());
(*bitmap).0.width()
}
/// Gets the height in pixels of the [SPBitmap] instance.
///
/// # Arguments
///
/// - `bitmap`: instance to read from
///
/// # Panics
///
/// - when `bitmap` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_height(
bitmap: *const SPBitmap,
) -> usize {
assert!(!bitmap.is_null());
(*bitmap).0.height()
}
/// Gets an unsafe reference to the data of the [SPBitmap] instance.
///
/// # Panics
///
/// - when `bitmap` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid [SPBitmap]
/// - the returned memory range is never accessed after the passed [SPBitmap] has been freed
/// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
#[no_mangle]
pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref(
bitmap: *mut SPBitmap,
) -> SPByteSlice {
assert!(!bitmap.is_null());
let data = (*bitmap).0.data_ref_mut();
SPByteSlice {
start: data.as_mut_ptr_range().start,
length: data.len(),
}
}

View file

@ -8,7 +8,7 @@ use servicepoint::{Brightness, Origin};
use crate::{ use crate::{
SPBitVec, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, SPPacket, SPBitVec, SPBrightnessGrid, SPCompressionCode, SPCp437Grid, SPPacket,
SPPixelGrid, SPBitmap,
}; };
/// A low-level display command. /// A low-level display command.
@ -413,21 +413,21 @@ pub unsafe extern "C" fn sp_command_cp437_data(
/// Sets a window of pixels to the specified values. /// Sets a window of pixels to the specified values.
/// ///
/// The passed [SPPixelGrid] gets consumed. /// The passed [SPBitmap] gets consumed.
/// ///
/// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL. /// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL.
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is null /// - when `bitmap` is null
/// - when `compression_code` is not a valid value /// - when `compression_code` is not a valid value
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid instance of [SPPixelGrid] /// - `bitmap` points to a valid instance of [SPBitmap]
/// - `pixel_grid` is not used concurrently or after this call /// - `bitmap` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values /// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or /// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
@ -435,11 +435,11 @@ pub unsafe extern "C" fn sp_command_cp437_data(
pub unsafe extern "C" fn sp_command_bitmap_linear_win( pub unsafe extern "C" fn sp_command_bitmap_linear_win(
x: usize, x: usize,
y: usize, y: usize,
pixel_grid: *mut SPPixelGrid, bitmap: *mut SPBitmap,
compression_code: SPCompressionCode, compression_code: SPCompressionCode,
) -> *mut SPCommand { ) -> *mut SPCommand {
assert!(!pixel_grid.is_null()); assert!(!bitmap.is_null());
let byte_grid = (*Box::from_raw(pixel_grid)).0; let byte_grid = (*Box::from_raw(bitmap)).0;
let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( let result = Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin(
Origin::new(x, y), Origin::new(x, y),
byte_grid, byte_grid,

View file

@ -13,8 +13,8 @@
//! if (connection == NULL) //! if (connection == NULL)
//! return 1; //! return 1;
//! //!
//! SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); //! SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT);
//! sp_pixel_grid_fill(pixels, true); //! sp_bitmap_fill(pixels, true);
//! //!
//! SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); //! SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
//! while (sp_connection_send_command(connection, sp_command_clone(command))); //! while (sp_connection_send_command(connection, sp_command_clone(command)));
@ -33,7 +33,7 @@ pub use crate::connection::*;
pub use crate::constants::*; pub use crate::constants::*;
pub use crate::cp437_grid::*; pub use crate::cp437_grid::*;
pub use crate::packet::*; pub use crate::packet::*;
pub use crate::pixel_grid::*; pub use crate::bitmap::*;
mod bit_vec; mod bit_vec;
mod brightness_grid; mod brightness_grid;
@ -43,4 +43,4 @@ mod connection;
mod constants; mod constants;
mod cp437_grid; mod cp437_grid;
mod packet; mod packet;
mod pixel_grid; mod bitmap;

View file

@ -1,290 +0,0 @@
//! C functions for interacting with [SPPixelGrid]s
//!
//! prefix `sp_pixel_grid_`
use servicepoint::{DataRef, Grid};
use crate::byte_slice::SPByteSlice;
/// A grid of pixels.
///
/// # Examples
///
/// ```C
/// Cp437Grid grid = sp_pixel_grid_new(8, 3);
/// sp_pixel_grid_fill(grid, true);
/// sp_pixel_grid_set(grid, 0, 0, false);
/// sp_pixel_grid_free(grid);
/// ```
pub struct SPPixelGrid(pub(crate) servicepoint::PixelGrid);
/// Creates a new [SPPixelGrid] with the specified dimensions.
///
/// # Arguments
///
/// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction
///
/// returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL.
///
/// # Panics
///
/// - when the width is not dividable by 8
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_pixel_grid_free`.
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_new(
width: usize,
height: usize,
) -> *mut SPPixelGrid {
let result = Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::new(
width, height,
))));
assert!(!result.is_null());
result
}
/// Loads a [SPPixelGrid] with the specified dimensions from the provided data.
///
/// # Arguments
///
/// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction
///
/// returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL.
///
/// # Panics
///
/// - when `data` is NULL
/// - when the dimensions and data size do not match exactly.
/// - when the width is not dividable by 8
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `data` points to a valid memory location of at least `data_length` bytes in size.
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_pixel_grid_free`.
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_load(
width: usize,
height: usize,
data: *const u8,
data_length: usize,
) -> *mut SPPixelGrid {
assert!(!data.is_null());
let data = std::slice::from_raw_parts(data, data_length);
let result = Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::load(
width, height, data,
))));
assert!(!result.is_null());
result
}
/// Clones a [SPPixelGrid].
///
/// Will never return NULL.
///
/// # Panics
///
/// - when `pixel_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
/// - `pixel_grid` is not written to concurrently
/// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_pixel_grid_free`.
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_clone(
pixel_grid: *const SPPixelGrid,
) -> *mut SPPixelGrid {
assert!(!pixel_grid.is_null());
let result = Box::into_raw(Box::new(SPPixelGrid((*pixel_grid).0.clone())));
assert!(!result.is_null());
result
}
/// Deallocates a [SPPixelGrid].
///
/// # Panics
///
/// - when `pixel_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
/// - `pixel_grid` is not used concurrently or after pixel_grid call
/// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_free(pixel_grid: *mut SPPixelGrid) {
assert!(!pixel_grid.is_null());
_ = Box::from_raw(pixel_grid);
}
/// Gets the current value at the specified position in the [SPPixelGrid].
///
/// # Arguments
///
/// - `pixel_grid`: instance to read from
/// - `x` and `y`: position of the cell to read
///
/// # Panics
///
/// - when `pixel_grid` is NULL
/// - when accessing `x` or `y` out of bounds
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
/// - `pixel_grid` is not written to concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_get(
pixel_grid: *const SPPixelGrid,
x: usize,
y: usize,
) -> bool {
assert!(!pixel_grid.is_null());
(*pixel_grid).0.get(x, y)
}
/// Sets the value of the specified position in the [SPPixelGrid].
///
/// # Arguments
///
/// - `pixel_grid`: instance to write to
/// - `x` and `y`: position of the cell
/// - `value`: the value to write to the cell
///
/// returns: old value of the cell
///
/// # Panics
///
/// - when `pixel_grid` is NULL
/// - when accessing `x` or `y` out of bounds
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
/// - `pixel_grid` is not written to or read from concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_set(
pixel_grid: *mut SPPixelGrid,
x: usize,
y: usize,
value: bool,
) {
assert!(!pixel_grid.is_null());
(*pixel_grid).0.set(x, y, value);
}
/// Sets the state of all pixels in the [SPPixelGrid].
///
/// # Arguments
///
/// - `pixel_grid`: instance to write to
/// - `value`: the value to set all pixels to
///
/// # Panics
///
/// - when `pixel_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
/// - `pixel_grid` is not written to or read from concurrently
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_fill(
pixel_grid: *mut SPPixelGrid,
value: bool,
) {
assert!(!pixel_grid.is_null());
(*pixel_grid).0.fill(value);
}
/// Gets the width in pixels of the [SPPixelGrid] instance.
///
/// # Arguments
///
/// - `pixel_grid`: instance to read from
///
/// # Panics
///
/// - when `pixel_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_width(
pixel_grid: *const SPPixelGrid,
) -> usize {
assert!(!pixel_grid.is_null());
(*pixel_grid).0.width()
}
/// Gets the height in pixels of the [SPPixelGrid] instance.
///
/// # Arguments
///
/// - `pixel_grid`: instance to read from
///
/// # Panics
///
/// - when `pixel_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_height(
pixel_grid: *const SPPixelGrid,
) -> usize {
assert!(!pixel_grid.is_null());
(*pixel_grid).0.height()
}
/// Gets an unsafe reference to the data of the [SPPixelGrid] instance.
///
/// # Panics
///
/// - when `pixel_grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid [SPPixelGrid]
/// - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed
/// - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly
#[no_mangle]
pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref(
pixel_grid: *mut SPPixelGrid,
) -> SPByteSlice {
assert!(!pixel_grid.is_null());
let data = (*pixel_grid).0.data_ref_mut();
SPByteSlice {
start: data.as_mut_ptr_range().start,
length: data.len(),
}
}

View file

@ -11,7 +11,7 @@ using ServicePoint;
// using statement calls Dispose() on scope exit, which frees unmanaged instances // using statement calls Dispose() on scope exit, which frees unmanaged instances
using var connection = Connection.Open("127.0.0.1:2342"); using var connection = Connection.Open("127.0.0.1:2342");
using var pixels = PixelGrid.New(Constants.PixelWidth, Constants.PixelHeight); using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight);
while (true) while (true)
{ {

View file

@ -464,341 +464,6 @@ namespace ServicePoint.BindGen
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid);
/// <summary>
/// Tries to turn a [SPPacket] into a [SPCommand].
///
/// The packet is deallocated in the process.
///
/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
///
/// # Panics
///
/// - when `packet` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - [SPPacket] points to a valid instance of [SPPacket]
/// - [SPPacket] is not used concurrently or after this call
/// - the result is checked for NULL
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_try_from_packet(Packet* packet);
/// <summary>
/// Clones a [SPCommand] instance.
///
/// returns: new [SPCommand] instance. Will never return NULL.
///
/// # Panics
///
/// - when `command` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `command` points to a valid instance of [SPCommand]
/// - `command` is not written to concurrently
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_clone(Command* command);
/// <summary>
/// Set all pixels to the off state.
///
/// Does not affect brightness.
///
/// Returns: a new [Command::Clear] instance. Will never return NULL.
///
/// # Examples
///
/// ```C
/// sp_connection_send_command(connection, sp_command_clear());
/// ```
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_clear();
/// <summary>
/// Kills the udp daemon on the display, which usually results in a restart.
///
/// Please do not send this in your normal program flow.
///
/// Returns: a new [Command::HardReset] instance. Will never return NULL.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_hard_reset();
/// <summary>
/// A yet-to-be-tested command.
///
/// Returns: a new `Command::FadeOut` instance. Will never return NULL.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_fade_out();
/// <summary>
/// Set the brightness of all tiles to the same value.
///
/// Returns: a new [Command::Brightness] instance. Will never return NULL.
///
/// # Panics
///
/// - When the provided brightness value is out of range (0-11).
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_brightness(byte brightness);
/// <summary>
/// Set the brightness of individual tiles in a rectangular area of the display.
///
/// The passed [SPBrightnessGrid] gets consumed.
///
/// Returns: a new [Command::CharBrightness] instance. Will never return NULL.
///
/// # Panics
///
/// - when `grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `grid` points to a valid instance of [SPBrightnessGrid]
/// - `grid` is not used concurrently or after this call
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid);
/// <summary>
/// Set pixel data starting at the pixel offset on screen.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinear] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Set pixel data according to an and-mask starting at the offset.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Set pixel data according to an or-mask starting at the offset.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Set pixel data according to a xor-mask starting at the offset.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Show text on the screen.
///
/// The passed [SPCp437Grid] gets consumed.
///
/// Returns: a new [Command::Cp437Data] instance. Will never return NULL.
///
/// # Panics
///
/// - when `grid` is null
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `grid` points to a valid instance of [SPCp437Grid]
/// - `grid` is not used concurrently or after this call
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_cp437_data(nuint x, nuint y, Cp437Grid* grid);
/// <summary>
/// Sets a window of pixels to the specified values.
///
/// The passed [SPPixelGrid] gets consumed.
///
/// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL.
///
/// # Panics
///
/// - when `pixel_grid` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `pixel_grid` points to a valid instance of [SPPixelGrid]
/// - `pixel_grid` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, PixelGrid* pixel_grid, CompressionCode compression_code);
/// <summary>
/// Deallocates a [SPCommand].
///
/// # Examples
///
/// ```C
/// SPCommand c = sp_command_clear();
/// sp_command_free(c);
/// ```
///
/// # Panics
///
/// - when `command` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `command` points to a valid [SPCommand]
/// - `command` is not used concurrently or after this call
/// - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void sp_command_free(Command* command);
/// <summary> /// <summary>
/// Creates a new instance of [SPConnection]. /// Creates a new instance of [SPConnection].
/// ///
@ -1172,14 +837,349 @@ namespace ServicePoint.BindGen
public static extern void sp_packet_free(Packet* packet); public static extern void sp_packet_free(Packet* packet);
/// <summary> /// <summary>
/// Creates a new [SPPixelGrid] with the specified dimensions. /// Tries to turn a [SPPacket] into a [SPCommand].
///
/// The packet is deallocated in the process.
///
/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
///
/// # Panics
///
/// - when `packet` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - [SPPacket] points to a valid instance of [SPPacket]
/// - [SPPacket] is not used concurrently or after this call
/// - the result is checked for NULL
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_try_from_packet(Packet* packet);
/// <summary>
/// Clones a [SPCommand] instance.
///
/// returns: new [SPCommand] instance. Will never return NULL.
///
/// # Panics
///
/// - when `command` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `command` points to a valid instance of [SPCommand]
/// - `command` is not written to concurrently
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_clone(Command* command);
/// <summary>
/// Set all pixels to the off state.
///
/// Does not affect brightness.
///
/// Returns: a new [Command::Clear] instance. Will never return NULL.
///
/// # Examples
///
/// ```C
/// sp_connection_send_command(connection, sp_command_clear());
/// ```
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_clear();
/// <summary>
/// Kills the udp daemon on the display, which usually results in a restart.
///
/// Please do not send this in your normal program flow.
///
/// Returns: a new [Command::HardReset] instance. Will never return NULL.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_hard_reset();
/// <summary>
/// A yet-to-be-tested command.
///
/// Returns: a new `Command::FadeOut` instance. Will never return NULL.
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_fade_out();
/// <summary>
/// Set the brightness of all tiles to the same value.
///
/// Returns: a new [Command::Brightness] instance. Will never return NULL.
///
/// # Panics
///
/// - When the provided brightness value is out of range (0-11).
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_brightness(byte brightness);
/// <summary>
/// Set the brightness of individual tiles in a rectangular area of the display.
///
/// The passed [SPBrightnessGrid] gets consumed.
///
/// Returns: a new [Command::CharBrightness] instance. Will never return NULL.
///
/// # Panics
///
/// - when `grid` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `grid` points to a valid instance of [SPBrightnessGrid]
/// - `grid` is not used concurrently or after this call
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid);
/// <summary>
/// Set pixel data starting at the pixel offset on screen.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinear] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Set pixel data according to an and-mask starting at the offset.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinearAnd] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Set pixel data according to an or-mask starting at the offset.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinearOr] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Set pixel data according to a xor-mask starting at the offset.
///
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
/// once the starting row is full, overwriting will continue on column 0.
///
/// The contained [SPBitVec] is always uncompressed.
///
/// The passed [SPBitVec] gets consumed.
///
/// Returns: a new [Command::BitmapLinearXor] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bit_vec` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bit_vec` points to a valid instance of [SPBitVec]
/// - `bit_vec` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression);
/// <summary>
/// Show text on the screen.
///
/// The passed [SPCp437Grid] gets consumed.
///
/// Returns: a new [Command::Cp437Data] instance. Will never return NULL.
///
/// # Panics
///
/// - when `grid` is null
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `grid` points to a valid instance of [SPCp437Grid]
/// - `grid` is not used concurrently or after this call
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_cp437_data(nuint x, nuint y, Cp437Grid* grid);
/// <summary>
/// Sets a window of pixels to the specified values.
///
/// The passed [SPBitmap] gets consumed.
///
/// Returns: a new [Command::BitmapLinearWin] instance. Will never return NULL.
///
/// # Panics
///
/// - when `bitmap` is null
/// - when `compression_code` is not a valid value
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `bitmap` points to a valid instance of [SPBitmap]
/// - `bitmap` is not used concurrently or after this call
/// - `compression` matches one of the allowed enum values
/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_command_free`.
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, Bitmap* bitmap, CompressionCode compression_code);
/// <summary>
/// Deallocates a [SPCommand].
///
/// # Examples
///
/// ```C
/// SPCommand c = sp_command_clear();
/// sp_command_free(c);
/// ```
///
/// # Panics
///
/// - when `command` is NULL
///
/// # Safety
///
/// The caller has to make sure that:
///
/// - `command` points to a valid [SPCommand]
/// - `command` is not used concurrently or after this call
/// - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
/// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void sp_command_free(Command* command);
/// <summary>
/// Creates a new [SPBitmap] with the specified dimensions.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `width`: size in pixels in x-direction /// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction /// - `height`: size in pixels in y-direction
/// ///
/// returns: [SPPixelGrid] initialized to all pixels off. Will never return NULL. /// returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
/// ///
/// # Panics /// # Panics
/// ///
@ -1190,20 +1190,20 @@ namespace ServicePoint.BindGen
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - the returned instance is freed in some way, either by using a consuming function or /// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_pixel_grid_free`. /// by explicitly calling `sp_bitmap_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern PixelGrid* sp_pixel_grid_new(nuint width, nuint height); public static extern Bitmap* sp_bitmap_new(nuint width, nuint height);
/// <summary> /// <summary>
/// Loads a [SPPixelGrid] with the specified dimensions from the provided data. /// Loads a [SPBitmap] with the specified dimensions from the provided data.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `width`: size in pixels in x-direction /// - `width`: size in pixels in x-direction
/// - `height`: size in pixels in y-direction /// - `height`: size in pixels in y-direction
/// ///
/// returns: [SPPixelGrid] that contains a copy of the provided data. Will never return NULL. /// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL.
/// ///
/// # Panics /// # Panics
/// ///
@ -1217,80 +1217,80 @@ namespace ServicePoint.BindGen
/// ///
/// - `data` points to a valid memory location of at least `data_length` bytes in size. /// - `data` points to a valid memory location of at least `data_length` bytes in size.
/// - the returned instance is freed in some way, either by using a consuming function or /// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_pixel_grid_free`. /// by explicitly calling `sp_bitmap_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern PixelGrid* sp_pixel_grid_load(nuint width, nuint height, byte* data, nuint data_length); public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length);
/// <summary> /// <summary>
/// Clones a [SPPixelGrid]. /// Clones a [SPBitmap].
/// ///
/// Will never return NULL. /// Will never return NULL.
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// - `pixel_grid` is not written to concurrently /// - `bitmap` is not written to concurrently
/// - the returned instance is freed in some way, either by using a consuming function or /// - the returned instance is freed in some way, either by using a consuming function or
/// by explicitly calling `sp_pixel_grid_free`. /// by explicitly calling `sp_bitmap_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern PixelGrid* sp_pixel_grid_clone(PixelGrid* pixel_grid); public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap);
/// <summary> /// <summary>
/// Deallocates a [SPPixelGrid]. /// Deallocates a [SPBitmap].
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// - `pixel_grid` is not used concurrently or after pixel_grid call /// - `bitmap` is not used concurrently or after bitmap call
/// - `pixel_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void sp_pixel_grid_free(PixelGrid* pixel_grid); public static extern void sp_bitmap_free(Bitmap* bitmap);
/// <summary> /// <summary>
/// Gets the current value at the specified position in the [SPPixelGrid]. /// Gets the current value at the specified position in the [SPBitmap].
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `pixel_grid`: instance to read from /// - `bitmap`: instance to read from
/// - `x` and `y`: position of the cell to read /// - `x` and `y`: position of the cell to read
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// - when accessing `x` or `y` out of bounds /// - when accessing `x` or `y` out of bounds
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// - `pixel_grid` is not written to concurrently /// - `bitmap` is not written to concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
public static extern bool sp_pixel_grid_get(PixelGrid* pixel_grid, nuint x, nuint y); public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y);
/// <summary> /// <summary>
/// Sets the value of the specified position in the [SPPixelGrid]. /// Sets the value of the specified position in the [SPBitmap].
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `pixel_grid`: instance to write to /// - `bitmap`: instance to write to
/// - `x` and `y`: position of the cell /// - `x` and `y`: position of the cell
/// - `value`: the value to write to the cell /// - `value`: the value to write to the cell
/// ///
@ -1298,98 +1298,98 @@ namespace ServicePoint.BindGen
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// - when accessing `x` or `y` out of bounds /// - when accessing `x` or `y` out of bounds
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// - `pixel_grid` is not written to or read from concurrently /// - `bitmap` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void sp_pixel_grid_set(PixelGrid* pixel_grid, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value);
/// <summary> /// <summary>
/// Sets the state of all pixels in the [SPPixelGrid]. /// Sets the state of all pixels in the [SPBitmap].
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `pixel_grid`: instance to write to /// - `bitmap`: instance to write to
/// - `value`: the value to set all pixels to /// - `value`: the value to set all pixels to
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// - `pixel_grid` is not written to or read from concurrently /// - `bitmap` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void sp_pixel_grid_fill(PixelGrid* pixel_grid, [MarshalAs(UnmanagedType.U1)] bool value); public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value);
/// <summary> /// <summary>
/// Gets the width in pixels of the [SPPixelGrid] instance. /// Gets the width in pixels of the [SPBitmap] instance.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `pixel_grid`: instance to read from /// - `bitmap`: instance to read from
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern nuint sp_pixel_grid_width(PixelGrid* pixel_grid); public static extern nuint sp_bitmap_width(Bitmap* bitmap);
/// <summary> /// <summary>
/// Gets the height in pixels of the [SPPixelGrid] instance. /// Gets the height in pixels of the [SPBitmap] instance.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `pixel_grid`: instance to read from /// - `bitmap`: instance to read from
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern nuint sp_pixel_grid_height(PixelGrid* pixel_grid); public static extern nuint sp_bitmap_height(Bitmap* bitmap);
/// <summary> /// <summary>
/// Gets an unsafe reference to the data of the [SPPixelGrid] instance. /// Gets an unsafe reference to the data of the [SPBitmap] instance.
/// ///
/// # Panics /// # Panics
/// ///
/// - when `pixel_grid` is NULL /// - when `bitmap` is NULL
/// ///
/// # Safety /// # Safety
/// ///
/// The caller has to make sure that: /// The caller has to make sure that:
/// ///
/// - `pixel_grid` points to a valid [SPPixelGrid] /// - `bitmap` points to a valid [SPBitmap]
/// - the returned memory range is never accessed after the passed [SPPixelGrid] has been freed /// - the returned memory range is never accessed after the passed [SPBitmap] has been freed
/// - the returned memory range is never accessed concurrently, either via the [SPPixelGrid] or directly /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern ByteSlice sp_pixel_grid_unsafe_data_ref(PixelGrid* pixel_grid); public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap);
} }
@ -1411,11 +1411,6 @@ namespace ServicePoint.BindGen
public nuint length; public nuint length;
} }
[StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Command
{
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Connection public unsafe partial struct Connection
{ {
@ -1432,7 +1427,12 @@ namespace ServicePoint.BindGen
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct PixelGrid public unsafe partial struct Command
{
}
[StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Bitmap
{ {
} }

View file

@ -2,33 +2,33 @@ using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> public sealed class Bitmap : SpNativeInstance<BindGen.Bitmap>
{ {
public static PixelGrid New(int width, int height) public static Bitmap New(int width, int height)
{ {
unsafe unsafe
{ {
return new PixelGrid(NativeMethods.sp_pixel_grid_new((nuint)width, (nuint)height)); return new Bitmap(NativeMethods.sp_bitmap_new((nuint)width, (nuint)height));
} }
} }
public static PixelGrid Load(int width, int height, Span<byte> bytes) public static Bitmap Load(int width, int height, Span<byte> bytes)
{ {
unsafe unsafe
{ {
fixed (byte* bytesPtr = bytes) fixed (byte* bytesPtr = bytes)
{ {
return new PixelGrid(NativeMethods.sp_pixel_grid_load((nuint)width, (nuint)height, bytesPtr, return new Bitmap(NativeMethods.sp_bitmap_load((nuint)width, (nuint)height, bytesPtr,
(nuint)bytes.Length)); (nuint)bytes.Length));
} }
} }
} }
public PixelGrid Clone() public Bitmap Clone()
{ {
unsafe unsafe
{ {
return new PixelGrid(NativeMethods.sp_pixel_grid_clone(Instance)); return new Bitmap(NativeMethods.sp_bitmap_clone(Instance));
} }
} }
@ -38,14 +38,14 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid>
{ {
unsafe unsafe
{ {
return NativeMethods.sp_pixel_grid_get(Instance, (nuint)x, (nuint)y); return NativeMethods.sp_bitmap_get(Instance, (nuint)x, (nuint)y);
} }
} }
set set
{ {
unsafe unsafe
{ {
NativeMethods.sp_pixel_grid_set(Instance, (nuint)x, (nuint)y, value); NativeMethods.sp_bitmap_set(Instance, (nuint)x, (nuint)y, value);
} }
} }
} }
@ -54,7 +54,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid>
{ {
unsafe unsafe
{ {
NativeMethods.sp_pixel_grid_fill(Instance, value); NativeMethods.sp_bitmap_fill(Instance, value);
} }
} }
@ -64,7 +64,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid>
{ {
unsafe unsafe
{ {
return (int)NativeMethods.sp_pixel_grid_width(Instance); return (int)NativeMethods.sp_bitmap_width(Instance);
} }
} }
} }
@ -75,7 +75,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid>
{ {
unsafe unsafe
{ {
return (int)NativeMethods.sp_pixel_grid_height(Instance); return (int)NativeMethods.sp_bitmap_height(Instance);
} }
} }
} }
@ -86,15 +86,15 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid>
{ {
unsafe unsafe
{ {
var slice = NativeMethods.sp_pixel_grid_unsafe_data_ref(Instance); var slice = NativeMethods.sp_bitmap_unsafe_data_ref(Instance);
return new Span<byte>(slice.start, (int)slice.length); return new Span<byte>(slice.start, (int)slice.length);
} }
} }
} }
private unsafe PixelGrid(BindGen.PixelGrid* instance) : base(instance) private unsafe Bitmap(BindGen.Bitmap* instance) : base(instance)
{ {
} }
private protected override unsafe void Free() => NativeMethods.sp_pixel_grid_free(Instance); private protected override unsafe void Free() => NativeMethods.sp_bitmap_free(Instance);
} }

View file

@ -105,11 +105,11 @@ public sealed class Command : SpNativeInstance<BindGen.Command>
} }
} }
public static Command BitmapLinearWin(int x, int y, PixelGrid pixelGrid, CompressionCode compression) public static Command BitmapLinearWin(int x, int y, Bitmap bitmap, CompressionCode compression)
{ {
unsafe unsafe
{ {
return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, pixelGrid.Into(), compression)); return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, bitmap.Into(), compression));
} }
} }

View file

@ -6,7 +6,7 @@ using var connection = Connection.Open("127.0.0.1:2342");
connection.Send(Command.Clear().IntoPacket()); connection.Send(Command.Clear().IntoPacket());
connection.Send(Command.Brightness(128).IntoPacket()); connection.Send(Command.Brightness(128).IntoPacket());
using var pixels = PixelGrid.New(Constants.PixelWidth, Constants.PixelHeight); using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight);
for (var offset = 0; offset < int.MaxValue; offset++) for (var offset = 0; offset < int.MaxValue; offset++)
{ {