diff --git a/rust/src/cells.rs b/rust/src/cells.rs index ea027950b..c376b9a4d 100644 --- a/rust/src/cells.rs +++ b/rust/src/cells.rs @@ -57,7 +57,7 @@ use crate as ffi; use ffi::types::{ - AlphaBits, Channel, ChannelPair, Color, GraphemeCluster, PaletteIndex, StyleMask, + AlphaBits, Channel, ChannelPair, Color, EGC, PaletteIndex, StyleMask, }; use ffi::{cell, ncplane}; @@ -67,7 +67,7 @@ use ffi::{cell, ncplane}; pub fn cell_prime( plane: &mut ffi::ncplane, cell: &mut ffi::cell, - gcluster: GraphemeCluster, + gcluster: EGC, style: u16, channels: ChannelPair, ) -> IntResult { @@ -98,7 +98,7 @@ pub fn cells_load_box( lr: &mut cell, hl: &mut cell, vl: &mut cell, - gcluster: GraphemeCluster, + gcluster: EGC, ) -> IntResult { let mut ulen; @@ -266,7 +266,7 @@ pub fn cellcmp(plane1: &ncplane, cell1: &cell, plane2: &ncplane, cell2: &cell) - return true; } unsafe { - libc::strcmp( + ffi::strcmp( ffi::cell_extended_gcluster(plane1, cell1), ffi::cell_extended_gcluster(plane2, cell2), ) != 0 @@ -281,7 +281,7 @@ pub fn cell_load_simple(plane: &mut ncplane, cell: &mut cell, ch: char) -> i32 { ffi::cell_release(plane, cell); } cell.channels &= !(ffi::CELL_WIDEASIAN_MASK as u64 | ffi::CELL_NOBACKGROUND_MASK); - cell.gcluster = ch as GraphemeCluster; + cell.gcluster = ch as EGC; 1 } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index c9bbef67d..db074ae21 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -11,6 +11,9 @@ mod bindings { } pub use bindings::*; +#[macro_use] +mod macros; + mod cells; mod channel; mod key; diff --git a/rust/src/macros.rs b/rust/src/macros.rs new file mode 100644 index 000000000..489ef26ff --- /dev/null +++ b/rust/src/macros.rs @@ -0,0 +1,31 @@ + +// #define CELL_INITIALIZER(c, s, chan) { .gcluster = (c), .gcluster_backstop = 0, .reserved = 0, .stylemask = (s), .channels = (chan), } +#[macro_export] +macro_rules! cell_initializer { + ( $c:expr, $s:expr, $chan:expr ) => { + cell { + gcluster: $c as EGC, + gcluster_backstop: 0 as EGCBackstop, + reserved: 0, + stylemask: $s, + channels: $chan, + } + }; +} + +//#define CELL_SIMPLE_INITIALIZER(c) { .gcluster = (c), .gcluster_backstop = 0, .reserved = 0, .stylemask = 0, .channels = 0, } +#[macro_export] +macro_rules! cell_simple_initializer { + ( $c:expr ) => { + cell_initializer![$c, 0, 0] + }; +} + + +// #define CELL_TRIVIAL_INITIALIZER { } +#[macro_export] +macro_rules! cell_trivial_initializer { + ( ) => { + cell_simple_initializer![0] + }; +} diff --git a/rust/src/types.rs b/rust/src/types.rs index 320101526..32d991941 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -138,7 +138,7 @@ pub type Pixel = u32; // // type in C: cell (struct) -/// GCluster +/// EGC (Extended Grapheme Cluster) /// /// These 32 bits, together with the associated plane's associated egcpool, /// completely define this cell's EGC. Unless the EGC requires more than four @@ -153,25 +153,32 @@ pub type Pixel = u32; /// byte of this struct (the GClusterBackStop field, see below) is /// guaranteed to be zero, as are any unused bytes in gcluster. /// -/// A spilled EGC is indicated by the value 0x01XXXXXX. This cannot alias a +/// A spilled EGC is indicated by the value 0x01iiiiii. This cannot alias a /// true supra-ASCII EGC, because UTF-8 only encodes bytes <= 0x80 when they -/// are single-byte ASCII-derived values. The XXXXXX is interpreted as a 24-bit +/// are single-byte ASCII-derived values. The iiiiii is interpreted as a 24-bit /// index into the egcpool (which may thus be up to 16MB): /// -/// 00000001 IIIIIIII IIIIIIII IIIIIIII +/// 00000001 iiiiiiii iiiiiiii iiiiiiii /// sign 24bit index to egpool /// /// The cost of this scheme is that the character 0x01 (SOH) cannot be encoded /// in a cell, and therefore it must not be allowed through the API. /// +/// ----- +/// NOTE that even if the EGC is <= 4 bytes and inlined, is still interpreted a +/// a NUL-terminated char * (technically, &cell->gcluster is treated as a char*). +/// If it is more than 4 bytes, cell->gcluster has a first byte of 0x01, +/// and the remaining 24 bits are an index into the plane's egcpool, +/// which is carved into NUL-terminated chunks of arbitrary length. +/// /// type in C: gcluster (uint32_t) /// -pub type GraphemeCluster = u32; +pub type EGC = u32; -/// GraphemeClusterBackStop +/// EGC BackStop /// /// type in C: cell.gcluster_backstop -pub type GraphemeClusterBackStop = u8; +pub type EGCBackstop = u8; /// StyleMask ///