mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
rust: big refactor
- move tests to their own submodules - move functions reimplementations to reimplemented submodule. - remove types submodules and move them to their parent. - add more NcPlane & Notcurses methods - rename NcChar back to NcEgc, and NcCharBackstop tp NcEgcBackstop - add ncpile_top & ncpile_bottom functions. - fix Notcurses stdplane(_mut) methods - make cell_load_char not return anything since it was always 1.
This commit is contained in:
parent
e5306f6197
commit
01e4f7de5a
@ -304,9 +304,11 @@ pub use bindgen::{
|
||||
#[doc(inline)]
|
||||
pub use bindgen::{
|
||||
// functions
|
||||
ncpile_bottom,
|
||||
ncpile_create,
|
||||
ncpile_rasterize,
|
||||
ncpile_render,
|
||||
ncpile_top,
|
||||
};
|
||||
|
||||
// ncplane ---------------------------------------------------------------------
|
||||
|
87
rust/src/cells/methods.rs
Normal file
87
rust/src/cells/methods.rs
Normal file
@ -0,0 +1,87 @@
|
||||
//! `NcCell` methods and associated functions.
|
||||
|
||||
pub use crate::{
|
||||
cell_load, cstring, NcCell, NcChannelPair, NcEgcBackstop, NcPlane, NcStyleMask, NCRESULT_ERR,
|
||||
};
|
||||
|
||||
use crate::{cell_extract, NcEgc};
|
||||
|
||||
/// # `NcCell` Constructors
|
||||
impl NcCell {
|
||||
/// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair].
|
||||
#[inline]
|
||||
pub const fn with_all(ch: char, stylemask: NcStyleMask, channels: NcChannelPair) -> Self {
|
||||
NcCell {
|
||||
gcluster: ch as u32,
|
||||
gcluster_backstop: 0 as NcEgcBackstop,
|
||||
reserved: 0,
|
||||
stylemask,
|
||||
channels,
|
||||
}
|
||||
}
|
||||
|
||||
/// New NcCell, expects a 7-bit [char].
|
||||
#[inline]
|
||||
pub const fn with_7bitchar(ch: char) -> Self {
|
||||
Self::with_all(ch, 0 as NcStyleMask, 0 as NcChannelPair)
|
||||
}
|
||||
|
||||
/// New NcCell, expects an [NcPlane] and a utf-8 [char].
|
||||
#[inline]
|
||||
pub fn with_char(plane: &mut NcPlane, ch: char) -> Self {
|
||||
let mut cell = Self::new();
|
||||
let result = unsafe { cell_load(plane, &mut cell, cstring![ch.to_string()]) };
|
||||
debug_assert_ne![NCRESULT_ERR, result];
|
||||
cell
|
||||
}
|
||||
|
||||
/// New NcCell, expects an [NcPlane] and a &[str].
|
||||
#[inline]
|
||||
pub fn with_str(plane: &mut NcPlane, string: &str) -> Self {
|
||||
let mut cell = Self::new();
|
||||
let result = unsafe { cell_load(plane, &mut cell, cstring![string]) };
|
||||
debug_assert_ne![NCRESULT_ERR, result];
|
||||
cell
|
||||
}
|
||||
|
||||
/// New NcCell, blank.
|
||||
#[inline]
|
||||
pub const fn new() -> Self {
|
||||
Self::with_7bitchar(0 as char)
|
||||
}
|
||||
}
|
||||
|
||||
/// # `NcCell` Methods
|
||||
impl NcCell {
|
||||
/// Saves the [NcStyleMask] and the [NcChannelPair], and returns the [NcEgc]
|
||||
/// (the three elements of an NcCell).
|
||||
pub fn extract(
|
||||
&mut self,
|
||||
plane: &mut NcPlane,
|
||||
styles: &mut NcStyleMask,
|
||||
channels: &mut NcChannelPair,
|
||||
) -> NcEgc {
|
||||
cell_extract(plane, self, styles, channels)
|
||||
}
|
||||
|
||||
/// Saves the [NcChannelPair] of the NcCell.
|
||||
// not in the C API
|
||||
pub fn channels(&mut self, plane: &mut NcPlane, channels: &mut NcChannelPair) {
|
||||
let mut _styles = 0;
|
||||
let _char = cell_extract(plane, self, &mut _styles, channels);
|
||||
}
|
||||
|
||||
/// Saves the [NcStyleMask] of the NcCell.
|
||||
// not in the C API
|
||||
pub fn styles(&mut self, plane: &mut NcPlane, styles: &mut NcStyleMask) {
|
||||
let mut _channels = 0;
|
||||
let _char = cell_extract(plane, self, styles, &mut _channels);
|
||||
}
|
||||
|
||||
/// Returns the [NcEgc] of the NcCell.
|
||||
// not in the C API
|
||||
pub fn egc(&mut self, plane: &mut NcPlane) -> NcEgc {
|
||||
let (mut _styles, mut _channels) = (0, 0);
|
||||
cell_extract(plane, self, &mut _styles, &mut _channels)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
//! [NcCell] `cell*_*` static functions reimplementations
|
||||
//! `NcCell`
|
||||
|
||||
// functions already exported by bindgen : 6
|
||||
// -----------------------------------------
|
||||
@ -9,498 +9,384 @@
|
||||
// cells_double_box
|
||||
// cells_rounded_box
|
||||
//
|
||||
// static inline functions total: 42
|
||||
// ------------------------------------------ (implement / remaining)
|
||||
// functions manually reimplemented: 42
|
||||
// ------------------------------------------
|
||||
// (X) wont: 2
|
||||
// (+) done: 40 / 0
|
||||
// (W) wrap: 1 / 39
|
||||
// (#) test: 26 / 14
|
||||
// ------------------------------------------
|
||||
//# cell_bchannel
|
||||
//# cell_bg_alpha
|
||||
//# cell_bg_default_p
|
||||
//# cell_bg_palindex
|
||||
//# cell_bg_palindex_p
|
||||
//# cell_bg_rgb
|
||||
//# cell_bg_rgb8
|
||||
//+ cellcmp
|
||||
//+ cell_double_wide_p
|
||||
//+ cell_extract
|
||||
//# cell_fchannel
|
||||
//# cell_fg_alpha
|
||||
//# cell_fg_default_p
|
||||
//# cell_fg_palindex
|
||||
//# cell_fg_palindex_p
|
||||
//# cell_fg_rgb
|
||||
//# cell_fg_rgb8
|
||||
//+ cell_init
|
||||
//+ cell_load_char
|
||||
//+ cell_prime
|
||||
//# cell_set_bchannel
|
||||
//# cell_set_bg_alpha
|
||||
//# cell_set_bg_default
|
||||
//# cell_set_bg_palindex
|
||||
//# cell_set_bg_rgb
|
||||
//# cell_set_bg_rgb8
|
||||
//X cell_set_bg_rgb8_clipped // unneeded
|
||||
//# cell_set_fchannel
|
||||
//# cell_set_fg_alpha
|
||||
//# cell_set_fg_default
|
||||
//# cell_set_fg_palindex
|
||||
//# cell_set_fg_rgb
|
||||
//# cell_set_fg_rgb8
|
||||
//X cell_set_fg_rgb8_clipped // unneeded
|
||||
//+ cells_load_box
|
||||
//+ cell_strdup
|
||||
//+ cell_styles
|
||||
//+ cell_styles_off
|
||||
//+ cell_styles_on
|
||||
//+ cell_styles_set
|
||||
//+ cell_wide_left_p
|
||||
//+ cell_wide_right_p
|
||||
// # cell_bchannel
|
||||
// # cell_bg_alpha
|
||||
// # cell_bg_default_p
|
||||
// # cell_bg_palindex
|
||||
// # cell_bg_palindex_p
|
||||
// # cell_bg_rgb
|
||||
// # cell_bg_rgb8
|
||||
// + cellcmp
|
||||
// + cell_double_wide_p
|
||||
//W+ cell_extract
|
||||
// # cell_fchannel
|
||||
// # cell_fg_alpha
|
||||
// # cell_fg_default_p
|
||||
// # cell_fg_palindex
|
||||
// # cell_fg_palindex_p
|
||||
// # cell_fg_rgb
|
||||
// # cell_fg_rgb8
|
||||
// + cell_init
|
||||
// + cell_load_char
|
||||
// + cell_prime
|
||||
// # cell_set_bchannel
|
||||
// # cell_set_bg_alpha
|
||||
// # cell_set_bg_default
|
||||
// # cell_set_bg_palindex
|
||||
// # cell_set_bg_rgb
|
||||
// # cell_set_bg_rgb8
|
||||
// X cell_set_bg_rgb8_clipped // unneeded
|
||||
// # cell_set_fchannel
|
||||
// # cell_set_fg_alpha
|
||||
// # cell_set_fg_default
|
||||
// # cell_set_fg_palindex
|
||||
// # cell_set_fg_rgb
|
||||
// # cell_set_fg_rgb8
|
||||
// X cell_set_fg_rgb8_clipped // unneeded
|
||||
// + cells_load_box
|
||||
// + cell_strdup
|
||||
// + cell_styles
|
||||
// + cell_styles_off
|
||||
// + cell_styles_on
|
||||
// + cell_styles_set
|
||||
// + cell_wide_left_p
|
||||
// + cell_wide_right_p
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod test;
|
||||
|
||||
mod types;
|
||||
pub use types::{
|
||||
NcCell, NcChar, NcCharBackstop, NcStyleMask, NCCELL_ALPHA_BLEND, NCCELL_ALPHA_HIGHCONTRAST,
|
||||
NCCELL_ALPHA_OPAQUE, NCCELL_ALPHA_TRANSPARENT, NCCELL_BGDEFAULT_MASK, NCCELL_BG_ALPHA_MASK,
|
||||
NCCELL_BG_PALETTE, NCCELL_BG_RGB_MASK, NCCELL_FGDEFAULT_MASK, NCCELL_FG_ALPHA_MASK,
|
||||
NCCELL_FG_PALETTE, NCCELL_FG_RGB_MASK, NCCELL_NOBACKGROUND_MASK, NCCELL_WIDEASIAN_MASK,
|
||||
NCSTYLE_BLINK, NCSTYLE_BOLD, NCSTYLE_DIM, NCSTYLE_INVIS, NCSTYLE_ITALIC, NCSTYLE_MASK,
|
||||
NCSTYLE_NONE, NCSTYLE_PROTECT, NCSTYLE_REVERSE, NCSTYLE_STANDOUT, NCSTYLE_STRUCK,
|
||||
NCSTYLE_UNDERLINE,
|
||||
};
|
||||
mod methods;
|
||||
mod reimplemented;
|
||||
pub use reimplemented::*;
|
||||
|
||||
mod wrapped;
|
||||
pub use wrapped::*;
|
||||
|
||||
use libc::strcmp;
|
||||
|
||||
use crate::{
|
||||
cell_extended_gcluster, cell_load, cell_release, channels_bchannel, channels_bg_alpha,
|
||||
channels_bg_default_p, channels_bg_palindex_p, channels_bg_rgb, channels_bg_rgb8,
|
||||
channels_fchannel, channels_fg_alpha, channels_fg_default_p, channels_fg_palindex_p,
|
||||
channels_fg_rgb, channels_fg_rgb8, channels_set_bchannel, channels_set_bg_alpha,
|
||||
channels_set_bg_default, channels_set_bg_rgb, channels_set_bg_rgb8, channels_set_fchannel,
|
||||
channels_set_fg_alpha, channels_set_fg_default, channels_set_fg_rgb, channels_set_fg_rgb8,
|
||||
NcAlphaBits, NcChannel, NcChannelPair, NcColor, NcPaletteIndex, NcPlane, NcResult, NcRgb,
|
||||
NCRESULT_ERR, NCRESULT_OK,
|
||||
};
|
||||
|
||||
/// Same as [cell_load], plus blasts the styling with 'style' and 'channels'.
|
||||
// NcCell
|
||||
/// A coordinate on an [`NcPlane`] storing 128 bits of data
|
||||
///
|
||||
/// - Breaks the UTF-8 string in 'gcluster' down, setting up the cell 'cell'.
|
||||
/// - Returns the number of bytes copied out of 'gcluster', or -1 on failure.
|
||||
/// - The styling of the cell is left untouched, but any resources are released.
|
||||
/// - Blasts the styling with 'style' and 'channels'.
|
||||
/// An `NcCell` corresponds to a single character cell on some [`NcPlane`],
|
||||
/// which can be occupied by a single [`NcEgc`] grapheme cluster (some root
|
||||
/// spacing glyph, along with possible combining characters, which might span
|
||||
/// multiple columns).
|
||||
///
|
||||
#[allow(unused_unsafe)]
|
||||
pub unsafe fn cell_prime(
|
||||
plane: &mut NcPlane,
|
||||
cell: &mut NcCell,
|
||||
gcluster: NcChar,
|
||||
style: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
) -> NcResult {
|
||||
cell.stylemask = style;
|
||||
cell.channels = channels;
|
||||
unsafe { cell_load(plane, cell, gcluster as u32 as *const i8) }
|
||||
}
|
||||
|
||||
/// Loads up six cells with the [NcChar]s necessary to draw a box.
|
||||
/// At any `NcCell`, we can have a theoretically arbitrarily long UTF-8 string,
|
||||
/// a foreground color, a background color, and an [`NcStyleMask`] attribute set.
|
||||
///
|
||||
/// Returns [NCRESULT_OK] on success, [NCRESULT_ERR] on error.
|
||||
/// Valid grapheme cluster contents include:
|
||||
///
|
||||
/// On error, any [NcCell]s this function might have loaded before the error
|
||||
/// are [cell_release]d. There must be at least six [NcChar]s in gcluster.
|
||||
/// - A NUL terminator,
|
||||
/// - A single [control character](https://en.wikipedia.org/wiki/Control_character),
|
||||
/// followed by a NUL terminator,
|
||||
/// - At most one [spacing
|
||||
/// character](https://en.wikipedia.org/wiki/Graphic_character#Spacing_character),
|
||||
/// followed by zero or more nonspacing characters, followed by a NUL terminator.
|
||||
///
|
||||
#[allow(unused_unsafe)]
|
||||
pub unsafe fn cells_load_box(
|
||||
plane: &mut NcPlane,
|
||||
style: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ul: &mut NcCell,
|
||||
ur: &mut NcCell,
|
||||
ll: &mut NcCell,
|
||||
lr: &mut NcCell,
|
||||
hl: &mut NcCell,
|
||||
vl: &mut NcCell,
|
||||
gcluster: NcChar,
|
||||
) -> NcResult {
|
||||
// mutable copy for pointer arithmetics:
|
||||
let mut gclu = gcluster as u32 as *const i8;
|
||||
let mut ulen: NcResult;
|
||||
|
||||
ulen = unsafe { cell_prime(plane, ul, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, ur, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, ll, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, lr, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, hl, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
let _gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, vl, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
return NCRESULT_OK;
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, hl);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, lr);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, ll);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, ur);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, ul);
|
||||
}
|
||||
}
|
||||
NCRESULT_ERR
|
||||
}
|
||||
|
||||
/// Initializes (zeroes out) an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_init(cell: &mut NcCell) {
|
||||
*cell = unsafe { core::mem::zeroed() }
|
||||
}
|
||||
|
||||
/// Sets *just* the specified [NcStyleMask] bits for an [NcCell],
|
||||
/// whether they're actively supported or not.
|
||||
#[inline]
|
||||
pub fn cell_styles_set(cell: &mut NcCell, stylebits: NcStyleMask) {
|
||||
cell.stylemask = stylebits & NCSTYLE_MASK as u16;
|
||||
}
|
||||
|
||||
/// Extracts the [NcStyleMask] bits from an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_styles(cell: &NcCell) -> NcStyleMask {
|
||||
cell.stylemask
|
||||
}
|
||||
|
||||
/// Adds the specified [NcStyleMask] bits to an [NcCell]'s existing spec.,
|
||||
/// whether they're actively supported or not.
|
||||
#[inline]
|
||||
pub fn cell_styles_on(cell: &mut NcCell, stylebits: NcStyleMask) {
|
||||
cell.stylemask |= stylebits & NCSTYLE_MASK as u16;
|
||||
}
|
||||
|
||||
/// Removes the specified [NcStyleMask] bits from an [NcCell]'s existing spec.
|
||||
#[inline]
|
||||
pub fn cell_styles_off(cell: &mut NcCell, stylebits: NcStyleMask) {
|
||||
cell.stylemask &= !(stylebits & NCSTYLE_MASK as u16);
|
||||
}
|
||||
|
||||
/// Indicates to use the "default color" for the **foreground** [NcChannel]
|
||||
/// of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_fg_default(cell: &mut NcCell) {
|
||||
channels_set_fg_default(&mut cell.channels);
|
||||
}
|
||||
|
||||
/// Indicates to use the "default color" for the **background** [NcChannel]
|
||||
/// of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_bg_default(cell: &mut NcCell) {
|
||||
channels_set_bg_default(&mut cell.channels);
|
||||
}
|
||||
|
||||
/// Sets the foreground [NcAlphaBits] of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_fg_alpha(cell: &mut NcCell, alpha: NcAlphaBits) {
|
||||
channels_set_fg_alpha(&mut cell.channels, alpha);
|
||||
}
|
||||
|
||||
/// Sets the background [NcAlphaBits] of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_bg_alpha(cell: &mut NcCell, alpha: NcAlphaBits) {
|
||||
channels_set_bg_alpha(&mut cell.channels, alpha);
|
||||
}
|
||||
|
||||
/// Does the [NcCell] contain an East Asian Wide codepoint?
|
||||
// NOTE: remove casting when fixed:
|
||||
// https://github.com/rust-lang/rust-bindgen/issues/1875
|
||||
#[inline]
|
||||
pub fn cell_double_wide_p(cell: &NcCell) -> bool {
|
||||
(cell.channels & NCCELL_WIDEASIAN_MASK as NcChannelPair) != 0
|
||||
}
|
||||
|
||||
/// Is this the right half of a wide character?
|
||||
#[inline]
|
||||
pub fn cell_wide_right_p(cell: &NcCell) -> bool {
|
||||
cell_double_wide_p(cell) && cell.gcluster == 0
|
||||
}
|
||||
|
||||
/// Is this the left half of a wide character?
|
||||
#[inline]
|
||||
pub fn cell_wide_left_p(cell: &NcCell) -> bool {
|
||||
cell_double_wide_p(cell) && cell.gcluster != 0
|
||||
}
|
||||
|
||||
/// Copies the UTF8-encoded [NcChar] out of the cell, whether simple
|
||||
/// or complex.
|
||||
/// ## Diagram
|
||||
///
|
||||
/// The result is not tied to the [NcPlane], and persists
|
||||
/// across erases and destruction.
|
||||
#[inline]
|
||||
pub fn cell_strdup(plane: &NcPlane, cell: &NcCell) -> NcChar {
|
||||
core::char::from_u32(unsafe { libc::strdup(cell_extended_gcluster(plane, cell)) } as i32 as u32)
|
||||
.expect("wrong char")
|
||||
|
||||
// unsafer option B (maybe faster, TODO: bench)
|
||||
// unsafe {
|
||||
// core::char::from_u32_unchecked(libc::strdup(cell_extended_gcluster(plane, cell)) as i32 as u32)
|
||||
// }
|
||||
}
|
||||
|
||||
/// Saves the [NcStyleMask] and [NcChannelPair] and returns the [NcChar]
|
||||
/// (the three elements of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_extract(
|
||||
plane: &NcPlane,
|
||||
cell: &NcCell,
|
||||
stylemask: &mut NcStyleMask,
|
||||
channels: &mut NcChannelPair,
|
||||
) -> NcChar {
|
||||
if *stylemask != 0 {
|
||||
*stylemask = cell.stylemask;
|
||||
}
|
||||
if *channels != 0 {
|
||||
*channels = cell.channels;
|
||||
}
|
||||
cell_strdup(plane, cell)
|
||||
}
|
||||
|
||||
/// Returns true if the two cells are distinct [NcChar]s, attributes, or channels
|
||||
/// ```txt
|
||||
/// NcCell: 128 bits structure comprised of the following 5 elements:
|
||||
///
|
||||
/// The actual egcpool index needn't be the same--indeed, the planes needn't even
|
||||
/// be the same. Only the expanded NcChar must be equal. The NcChar must be bit-equal;
|
||||
// NOTE: FIXME: it would probably be better to test whether they're Unicode-equal
|
||||
#[inline]
|
||||
pub fn cellcmp(plane1: &NcPlane, cell1: &NcCell, plane2: &NcPlane, cell2: &NcCell) -> bool {
|
||||
if cell1.stylemask != cell2.stylemask {
|
||||
return true;
|
||||
}
|
||||
if cell1.channels != cell2.channels {
|
||||
return true;
|
||||
}
|
||||
unsafe {
|
||||
strcmp(
|
||||
cell_extended_gcluster(plane1, cell1),
|
||||
cell_extended_gcluster(plane2, cell2),
|
||||
) != 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a 7-bit char into the [NcCell].
|
||||
// NOTE: remove casting for NCCELL_WIDEASIAN_MASK when fixed: https://github.com/rust-lang/rust-bindgen/issues/1875
|
||||
#[inline]
|
||||
pub fn cell_load_char(plane: &mut NcPlane, cell: &mut NcCell, ch: NcChar) -> i32 {
|
||||
unsafe {
|
||||
cell_release(plane, cell);
|
||||
}
|
||||
cell.channels &= !(NCCELL_WIDEASIAN_MASK as NcChannelPair | NCCELL_NOBACKGROUND_MASK);
|
||||
cell.gcluster = ch as u32;
|
||||
1
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit background [NcChannel] from an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_bchannel(cell: &NcCell) -> NcChannel {
|
||||
channels_bchannel(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit foreground [NcChannel] from an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_fchannel(cell: &NcCell) -> NcChannel {
|
||||
channels_fchannel(cell.channels)
|
||||
}
|
||||
|
||||
/// Sets the 32-bit background [NcChannel] of an [NcCell] and returns its new
|
||||
/// [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn cell_set_bchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair {
|
||||
channels_set_bchannel(&mut cell.channels, channel)
|
||||
}
|
||||
|
||||
/// Sets the 32-bit foreground [NcChannel] of an [NcCell] and returns its new
|
||||
/// [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn cell_set_fchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair {
|
||||
channels_set_fchannel(&mut cell.channels, channel)
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcCell]
|
||||
/// (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_fg_rgb(cell: &NcCell) -> NcRgb {
|
||||
channels_fg_rgb(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcCell]
|
||||
/// (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_bg_rgb(cell: &NcCell) -> NcRgb {
|
||||
channels_bg_rgb(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcAlphaBits] from an [NcCell] (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_fg_alpha(cell: &NcCell) -> NcAlphaBits {
|
||||
channels_fg_alpha(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcAlphaBits] from an [NcCell] (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_bg_alpha(cell: &NcCell) -> NcAlphaBits {
|
||||
channels_bg_alpha(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcCell] and saves it
|
||||
/// split into three [NcColor] 8-bit components. Also returns the corresponding
|
||||
/// [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn cell_fg_rgb8(
|
||||
cell: &NcCell,
|
||||
red: &mut NcColor,
|
||||
green: &mut NcColor,
|
||||
blue: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channels_fg_rgb8(cell.channels, red, green, blue)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcCell] and saves it
|
||||
/// split into three [NcColor] 8-bit components. Also returns the corresponding
|
||||
/// [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn cell_bg_rgb8(
|
||||
cell: &NcCell,
|
||||
red: &mut NcColor,
|
||||
green: &mut NcColor,
|
||||
blue: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channels_bg_rgb8(cell.channels, red, green, blue)
|
||||
}
|
||||
|
||||
/// Sets the RGB [NcColor] components for the foreground [NcChannel] of an
|
||||
/// [NcCell], and marks it as not using the default color.
|
||||
#[inline]
|
||||
pub fn cell_set_fg_rgb8(cell: &mut NcCell, red: NcColor, green: NcColor, blue: NcColor) {
|
||||
channels_set_fg_rgb8(&mut cell.channels, red, green, blue);
|
||||
}
|
||||
|
||||
/// Sets the 24-bit [NcRgb] value for the foreground [NcChannel] of an
|
||||
/// [NcCell], and marks it as not using the default color.
|
||||
#[inline]
|
||||
pub fn cell_set_fg_rgb(cell: &mut NcCell, rgb: NcRgb) {
|
||||
channels_set_fg_rgb(&mut cell.channels, rgb);
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s foreground [NcPaletteIndex].
|
||||
/// GCLUSTER GCLUSTER GCLUSTER GCLUSTER 1. NcEgc
|
||||
/// 00000000 ~~~~~~~~ 11111111 11111111 2. NcEgcBackstop + 3. reserved + 4. NcStyleMask
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB 5. NcChannelPair
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB |
|
||||
///
|
||||
/// Also sets [NCCELL_FG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_FGDEFAULT_MASK].
|
||||
/// 1. (32b) Extended Grapheme Cluster, presented either as:
|
||||
///
|
||||
// NOTE: unlike the original C function, this one can't fail
|
||||
#[inline]
|
||||
pub fn cell_set_fg_palindex(cell: &mut NcCell, index: NcPaletteIndex) {
|
||||
cell.channels |= NCCELL_FGDEFAULT_MASK;
|
||||
cell.channels |= NCCELL_FG_PALETTE;
|
||||
cell_set_fg_alpha(cell, NCCELL_ALPHA_OPAQUE);
|
||||
cell.channels &= 0xff000000ffffffff as NcChannelPair;
|
||||
cell.channels |= (index as NcChannelPair) << 32;
|
||||
}
|
||||
|
||||
/// Returns the [NcPaletteIndex] of the foreground [NcChannel] of the
|
||||
/// [NcCell]
|
||||
#[inline]
|
||||
pub fn cell_fg_palindex(cell: &NcCell) -> NcPaletteIndex {
|
||||
((cell.channels & 0xff00000000 as NcChannelPair) >> 32) as NcPaletteIndex
|
||||
}
|
||||
|
||||
/// Sets the [NcColor] 8-bit RGB components of the background [NcChannel]
|
||||
/// of the [NcCell], and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn cell_set_bg_rgb8(cell: &mut NcCell, red: NcColor, green: NcColor, blue: NcColor) {
|
||||
channels_set_bg_rgb8(&mut cell.channels, red, green, blue);
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit value for the background [NcChannel] of this
|
||||
/// [NcCell], and marks it as not using the default color.
|
||||
#[inline]
|
||||
pub fn cell_set_bg_rgb(cell: &mut NcCell, rgb: NcRgb) {
|
||||
channels_set_bg_rgb(&mut cell.channels, rgb);
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s background [NcPaletteIndex].
|
||||
/// 1.1. An NcEgc of up to 4 bytes:
|
||||
/// UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU
|
||||
///
|
||||
/// Also sets [NCCELL_BG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_BGDEFAULT_MASK].
|
||||
/// 1.2. A `0x01` in the first byte, plus 3 bytes with a 24b address to an egcpool:
|
||||
/// 00000001 IIIIIIII IIIIIIII IIIIIIII
|
||||
///
|
||||
// NOTE: unlike the original C function, this one can't fail
|
||||
#[inline]
|
||||
pub fn cell_set_bg_palindex(cell: &mut NcCell, index: NcPaletteIndex) {
|
||||
cell.channels |= NCCELL_BGDEFAULT_MASK as NcChannelPair;
|
||||
cell.channels |= NCCELL_BG_PALETTE as NcChannelPair;
|
||||
cell_set_bg_alpha(cell, NCCELL_ALPHA_OPAQUE);
|
||||
cell.channels &= 0xffffffffff000000;
|
||||
cell.channels |= index as NcChannelPair;
|
||||
}
|
||||
|
||||
/// Returns the [NcPaletteIndex] of the background [NcChannel] of the [NcCell]
|
||||
#[inline]
|
||||
pub fn cell_bg_palindex(cell: &NcCell) -> NcPaletteIndex {
|
||||
(cell.channels & 0xff) as NcPaletteIndex
|
||||
}
|
||||
|
||||
/// Is the foreground [NcChannel] of this [NcCell] using the
|
||||
/// "default foreground color"?
|
||||
#[inline]
|
||||
pub fn cell_fg_default_p(cell: &NcCell) -> bool {
|
||||
channels_fg_default_p(cell.channels)
|
||||
}
|
||||
|
||||
/// Is the foreground [NcChannel] of this [NcCell] using an
|
||||
/// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn cell_fg_palindex_p(cell: &NcCell) -> bool {
|
||||
channels_fg_palindex_p(cell.channels)
|
||||
}
|
||||
|
||||
/// Is the background [NcChannel] of this [NcCell] using the
|
||||
/// "default background color"?
|
||||
/// 2. (8b) Backstop (zero)
|
||||
/// 00000000
|
||||
///
|
||||
/// The "default background color" must generally be used to take advantage of
|
||||
/// terminal-effected transparency.
|
||||
#[inline]
|
||||
pub fn cell_bg_default_p(cell: &NcCell) -> bool {
|
||||
channels_bg_default_p(cell.channels)
|
||||
}
|
||||
/// 3. (8b) reserved (ought to be zero)
|
||||
/// ~~~~~~~~
|
||||
///
|
||||
/// 4. (16b) NcStyleMask
|
||||
/// 11111111 11111111
|
||||
///
|
||||
/// 5. (64b) NcChannelPair
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB|~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: cell (struct)`
|
||||
///
|
||||
/// ## Size
|
||||
///
|
||||
/// Multi-column characters can only have a single style/color throughout.
|
||||
/// [`wcwidth()`](https://www.man7.org/linux/man-pages/man3/wcwidth.3.html)
|
||||
/// is not reliable. It's just quoting whether or not the [`NcEgc`]
|
||||
/// contains a "Wide Asian" double-width character.
|
||||
/// This is set for some things, like most emoji, and not set for
|
||||
/// other things, like cuneiform.
|
||||
///
|
||||
/// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
|
||||
/// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB.
|
||||
/// Dynamic requirements (the egcpool) can add up to 16MB to an ncplane, but
|
||||
/// such large pools are unlikely in common use.
|
||||
///
|
||||
/// ## Alpha Compositing
|
||||
///
|
||||
/// We implement some small alpha compositing. Foreground and background both
|
||||
/// have two bits of inverted alpha. The actual grapheme written to a cell is
|
||||
/// the topmost non-zero grapheme.
|
||||
///
|
||||
/// - If its alpha is 00 ([`NCCELL_ALPHA_OPAQUE`]) its foreground color is used unchanged.
|
||||
///
|
||||
/// - If its alpha is 10 ([`NCCELL_ALPHA_TRANSPARENT`]) its foreground color is derived
|
||||
/// entirely from cells underneath it.
|
||||
///
|
||||
/// - If its alpha is 01 ([`NCCELL_ALPHA_BLEND`]) the result will be a composite.
|
||||
///
|
||||
/// Likewise for the background. If the bottom of a coordinate's zbuffer is
|
||||
/// reached with a cumulative alpha of zero, the default is used. In this way,
|
||||
/// a terminal configured with transparent background can be supported through
|
||||
/// multiple occluding ncplanes.
|
||||
///
|
||||
/// A foreground alpha of 11 ([`NCCELL_ALPHA_HIGHCONTRAST`]) requests high-contrast
|
||||
/// text (relative to the computed background).
|
||||
/// A background alpha of 11 is currently forbidden.
|
||||
///
|
||||
/// ## Precedence
|
||||
///
|
||||
/// - Default color takes precedence over palette or RGB, and cannot be used with
|
||||
/// transparency.
|
||||
/// - Indexed palette takes precedence over RGB. It cannot meaningfully set
|
||||
/// transparency, but it can be mixed into a cascading color.
|
||||
/// - RGB is used if neither default terminal colors nor palette indexing are in
|
||||
/// play, and fully supports all transparency options.
|
||||
///
|
||||
pub type NcCell = crate::bindings::bindgen::cell;
|
||||
|
||||
/// Is the background [NcChannel] of this [NcCell] using an
|
||||
/// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn cell_bg_palindex_p(cell: &NcCell) -> bool {
|
||||
channels_bg_palindex_p(cell.channels)
|
||||
}
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground or background color will be a composite between
|
||||
/// its color and the `NcCell`s' corresponding colors underneath it
|
||||
pub const NCCELL_ALPHA_BLEND: u32 = crate::bindings::bindgen::CELL_ALPHA_BLEND;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground color will be high-contrast (relative to the
|
||||
/// computed background). Background cannot be highcontrast
|
||||
pub const NCCELL_ALPHA_HIGHCONTRAST: u32 = crate::bindings::bindgen::CELL_ALPHA_HIGHCONTRAST;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground or background color is used unchanged
|
||||
pub const NCCELL_ALPHA_OPAQUE: u32 = crate::bindings::bindgen::CELL_ALPHA_OPAQUE;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground or background color is derived entirely from the
|
||||
/// `NcCell`s underneath it
|
||||
pub const NCCELL_ALPHA_TRANSPARENT: u32 = crate::bindings::bindgen::CELL_ALPHA_TRANSPARENT;
|
||||
|
||||
/// If this bit is set, we are *not* using the default background color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BGDEFAULT_MASK: u32 = crate::bindings::bindgen::CELL_BGDEFAULT_MASK;
|
||||
|
||||
/// Extract these bits to get the background alpha mask
|
||||
/// ([`NcAlphaBits`])
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BG_ALPHA_MASK: u32 = crate::bindings::bindgen::CELL_BG_ALPHA_MASK;
|
||||
|
||||
/// If this bit *and* [`NCCELL_BGDEFAULT_MASK`] are set, we're using a
|
||||
/// palette-indexed background color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BG_PALETTE: u32 = crate::bindings::bindgen::CELL_BG_PALETTE;
|
||||
|
||||
/// Extract these bits to get the background [`NcRgb`][crate::NcRgb] value
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BG_RGB_MASK: u32 = crate::bindings::bindgen::CELL_BG_RGB_MASK;
|
||||
|
||||
/// If this bit is set, we are *not* using the default foreground color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BGDEFAULT_MASK`];
|
||||
pub const NCCELL_FGDEFAULT_MASK: u64 = crate::bindings::bindgen::CELL_FGDEFAULT_MASK;
|
||||
|
||||
/// Extract these bits to get the foreground alpha mask
|
||||
/// ([`NcAlphaBits`])
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_ALPHA_MASK`];
|
||||
pub const NCCELL_FG_ALPHA_MASK: u64 = crate::bindings::bindgen::CELL_FG_ALPHA_MASK;
|
||||
|
||||
/// If this bit *and* [`NCCELL_FGDEFAULT_MASK`] are set, we're using a
|
||||
/// palette-indexed background color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_PALETTE`];
|
||||
pub const NCCELL_FG_PALETTE: u64 = crate::bindings::bindgen::CELL_FG_PALETTE;
|
||||
|
||||
/// Extract these bits to get the foreground [`NcRgb`][crate::NcRgb] value
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_RGB_MASK`];
|
||||
pub const NCCELL_FG_RGB_MASK: u64 = crate::bindings::bindgen::CELL_FG_RGB_MASK;
|
||||
|
||||
/// Indicates the glyph is entirely foreground
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
pub const NCCELL_NOBACKGROUND_MASK: u64 = crate::bindings::bindgen::CELL_NOBACKGROUND_MASK;
|
||||
|
||||
/// If this bit is set, the cell is part of a multicolumn glyph.
|
||||
///
|
||||
/// Whether a cell is the left or right side of the glyph can be determined
|
||||
/// by checking whether ->gcluster is zero.
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
pub const NCCELL_WIDEASIAN_MASK: u64 = crate::bindings::bindgen::CELL_WIDEASIAN_MASK as u64;
|
||||
|
||||
// NcEgc
|
||||
//
|
||||
/// Extended Grapheme Cluster. A 32-bit [`char`]-like type
|
||||
///
|
||||
/// This 32 bit char, together with the associated plane's associated egcpool,
|
||||
/// completely define this cell's `NcEgc`. Unless the `NcEgc` requires more than
|
||||
/// four bytes to encode as UTF-8, it will be inlined here:
|
||||
///
|
||||
/// ## Diagram 1
|
||||
///
|
||||
/// ```txt
|
||||
/// UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU
|
||||
/// extended grapheme cluster <= 4bytes
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: uint32_t`
|
||||
///
|
||||
/// If more than four bytes are required, it will be spilled into the egcpool.
|
||||
/// In either case, there's a NUL-terminated string available without copying,
|
||||
/// because (1) the egcpool is all NUL-terminated sequences and (2) the fifth
|
||||
/// byte of this struct (the GClusterBackStop field, see below) is
|
||||
/// guaranteed to be zero, as are any unused bytes in gcluster.
|
||||
///
|
||||
/// A spilled `NcEgc` is indicated by the value `0x01iiiiii`. This cannot alias a
|
||||
/// true supra-ASCII NcEgc, because UTF-8 only encodes bytes <= 0x80 when they
|
||||
/// 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):
|
||||
///
|
||||
/// ## Diagram 2
|
||||
///
|
||||
/// ```txt
|
||||
/// 00000001 iiiiiiii iiiiiiii iiiiiiii
|
||||
/// sign 24bit index to egcpool
|
||||
/// ```
|
||||
/// `type in C: uint32_t`
|
||||
///
|
||||
/// 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 `NcEgc` is <= 4 bytes and inlined, is still interpreted as
|
||||
/// 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.
|
||||
///
|
||||
/// ## Links
|
||||
///
|
||||
/// - [Grapheme Cluster
|
||||
/// Boundaries](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
|
||||
///
|
||||
///
|
||||
pub type NcEgc = char;
|
||||
|
||||
// NcEgcBackStop
|
||||
/// An `u8` always at zero, part of the [`NcCell`] struct
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// 00000000
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: uint_8t`
|
||||
///
|
||||
pub type NcEgcBackstop = u8;
|
||||
|
||||
// NcStyleMask
|
||||
///
|
||||
/// An `u16` of `NCSTYLE_*` boolean styling attribute flags
|
||||
///
|
||||
/// ## Attributes
|
||||
///
|
||||
/// - [`NCSTYLE_BLINK`]
|
||||
/// - [`NCSTYLE_BOLD`]
|
||||
/// - [`NCSTYLE_DIM`]
|
||||
/// - [`NCSTYLE_INVIS`]
|
||||
/// - [`NCSTYLE_ITALIC`]
|
||||
/// - [`NCSTYLE_MASK`]
|
||||
/// - [`NCSTYLE_NONE`]
|
||||
/// - [`NCSTYLE_PROTECT`]
|
||||
/// - [`NCSTYLE_REVERSE`]
|
||||
/// - [`NCSTYLE_STANDOUT`]
|
||||
/// - [`NCSTYLE_STRUCK`]
|
||||
/// - [`NCSTYLE_UNDERLINE`]
|
||||
///
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// 11111111 11111111
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: uint16_t`
|
||||
///
|
||||
pub type NcStyleMask = u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_BLINK: u16 = crate::bindings::bindgen::NCSTYLE_BLINK as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_BOLD: u16 = crate::bindings::bindgen::NCSTYLE_BOLD as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_DIM: u16 = crate::bindings::bindgen::NCSTYLE_DIM as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_INVIS: u16 = crate::bindings::bindgen::NCSTYLE_INVIS as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_ITALIC: u16 = crate::bindings::bindgen::NCSTYLE_ITALIC as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_MASK: u16 = crate::bindings::bindgen::NCSTYLE_MASK as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_NONE: u16 = crate::bindings::bindgen::NCSTYLE_NONE as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_PROTECT: u16 = crate::bindings::bindgen::NCSTYLE_PROTECT as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_REVERSE: u16 = crate::bindings::bindgen::NCSTYLE_REVERSE as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_STANDOUT: u16 = crate::bindings::bindgen::NCSTYLE_STANDOUT as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_STRUCK: u16 = crate::bindings::bindgen::NCSTYLE_STRUCK as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_UNDERLINE: u16 = crate::bindings::bindgen::NCSTYLE_UNDERLINE as u16;
|
||||
|
434
rust/src/cells/reimplemented.rs
Normal file
434
rust/src/cells/reimplemented.rs
Normal file
@ -0,0 +1,434 @@
|
||||
//! `cell*_*` reimplemented functions.
|
||||
|
||||
use libc::strcmp;
|
||||
|
||||
use crate::{
|
||||
cell_extended_gcluster, cell_load, cell_release, channels_bchannel, channels_bg_alpha,
|
||||
channels_bg_default_p, channels_bg_palindex_p, channels_bg_rgb, channels_bg_rgb8,
|
||||
channels_fchannel, channels_fg_alpha, channels_fg_default_p, channels_fg_palindex_p,
|
||||
channels_fg_rgb, channels_fg_rgb8, channels_set_bchannel, channels_set_bg_alpha,
|
||||
channels_set_bg_default, channels_set_bg_rgb, channels_set_bg_rgb8, channels_set_fchannel,
|
||||
channels_set_fg_alpha, channels_set_fg_default, channels_set_fg_rgb, channels_set_fg_rgb8,
|
||||
NcAlphaBits, NcCell, NcChannel, NcChannelPair, NcColor, NcEgc, NcPaletteIndex, NcPlane,
|
||||
NcResult, NcRgb, NcStyleMask, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE,
|
||||
NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, NCCELL_NOBACKGROUND_MASK, NCCELL_WIDEASIAN_MASK,
|
||||
NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK,
|
||||
};
|
||||
|
||||
/// Same as [cell_load], plus blasts the styling with 'style' and 'channels'.
|
||||
///
|
||||
/// - Breaks the UTF-8 string in 'gcluster' down, setting up the cell 'cell'.
|
||||
/// - Returns the number of bytes copied out of 'gcluster', or -1 on failure.
|
||||
/// - The styling of the cell is left untouched, but any resources are released.
|
||||
/// - Blasts the styling with 'style' and 'channels'.
|
||||
///
|
||||
#[allow(unused_unsafe)]
|
||||
pub unsafe fn cell_prime(
|
||||
plane: &mut NcPlane,
|
||||
cell: &mut NcCell,
|
||||
gcluster: NcEgc,
|
||||
style: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
) -> NcResult {
|
||||
cell.stylemask = style;
|
||||
cell.channels = channels;
|
||||
unsafe { cell_load(plane, cell, gcluster as u32 as *const i8) }
|
||||
}
|
||||
|
||||
/// Loads up six cells with the [NcEgc]s necessary to draw a box.
|
||||
///
|
||||
/// Returns [NCRESULT_OK] on success, [NCRESULT_ERR] on error.
|
||||
///
|
||||
/// On error, any [NcCell]s this function might have loaded before the error
|
||||
/// are [cell_release]d. There must be at least six [NcEgc]s in gcluster.
|
||||
///
|
||||
#[allow(unused_unsafe)]
|
||||
pub unsafe fn cells_load_box(
|
||||
plane: &mut NcPlane,
|
||||
style: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ul: &mut NcCell,
|
||||
ur: &mut NcCell,
|
||||
ll: &mut NcCell,
|
||||
lr: &mut NcCell,
|
||||
hl: &mut NcCell,
|
||||
vl: &mut NcCell,
|
||||
gcluster: NcEgc,
|
||||
) -> NcResult {
|
||||
// mutable copy for pointer arithmetics:
|
||||
let mut gclu = gcluster as u32 as *const i8;
|
||||
let mut ulen: NcResult;
|
||||
|
||||
ulen = unsafe { cell_prime(plane, ul, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, ur, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, ll, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, lr, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, hl, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
let _gclu = unsafe { gclu.offset(ulen as isize) };
|
||||
ulen = unsafe { cell_prime(plane, vl, gcluster, style, channels) };
|
||||
|
||||
if ulen > 0 {
|
||||
return NCRESULT_OK;
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, hl);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, lr);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, ll);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, ur);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
cell_release(plane, ul);
|
||||
}
|
||||
}
|
||||
NCRESULT_ERR
|
||||
}
|
||||
|
||||
/// Initializes (zeroes out) an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_init(cell: &mut NcCell) {
|
||||
*cell = unsafe { core::mem::zeroed() }
|
||||
}
|
||||
|
||||
/// Sets *just* the specified [NcStyleMask] bits for an [NcCell],
|
||||
/// whether they're actively supported or not.
|
||||
#[inline]
|
||||
pub fn cell_styles_set(cell: &mut NcCell, stylebits: NcStyleMask) {
|
||||
cell.stylemask = stylebits & NCSTYLE_MASK as u16;
|
||||
}
|
||||
|
||||
/// Extracts the [NcStyleMask] bits from an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_styles(cell: &NcCell) -> NcStyleMask {
|
||||
cell.stylemask
|
||||
}
|
||||
|
||||
/// Adds the specified [NcStyleMask] bits to an [NcCell]'s existing spec.,
|
||||
/// whether they're actively supported or not.
|
||||
#[inline]
|
||||
pub fn cell_styles_on(cell: &mut NcCell, stylebits: NcStyleMask) {
|
||||
cell.stylemask |= stylebits & NCSTYLE_MASK as u16;
|
||||
}
|
||||
|
||||
/// Removes the specified [NcStyleMask] bits from an [NcCell]'s existing spec.
|
||||
#[inline]
|
||||
pub fn cell_styles_off(cell: &mut NcCell, stylebits: NcStyleMask) {
|
||||
cell.stylemask &= !(stylebits & NCSTYLE_MASK as u16);
|
||||
}
|
||||
|
||||
/// Indicates to use the "default color" for the **foreground** [NcChannel]
|
||||
/// of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_fg_default(cell: &mut NcCell) {
|
||||
channels_set_fg_default(&mut cell.channels);
|
||||
}
|
||||
|
||||
/// Indicates to use the "default color" for the **background** [NcChannel]
|
||||
/// of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_bg_default(cell: &mut NcCell) {
|
||||
channels_set_bg_default(&mut cell.channels);
|
||||
}
|
||||
|
||||
/// Sets the foreground [NcAlphaBits] of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_fg_alpha(cell: &mut NcCell, alpha: NcAlphaBits) {
|
||||
channels_set_fg_alpha(&mut cell.channels, alpha);
|
||||
}
|
||||
|
||||
/// Sets the background [NcAlphaBits] of an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_set_bg_alpha(cell: &mut NcCell, alpha: NcAlphaBits) {
|
||||
channels_set_bg_alpha(&mut cell.channels, alpha);
|
||||
}
|
||||
|
||||
/// Does the [NcCell] contain an East Asian Wide codepoint?
|
||||
// NOTE: remove casting when fixed:
|
||||
// https://github.com/rust-lang/rust-bindgen/issues/1875
|
||||
#[inline]
|
||||
pub fn cell_double_wide_p(cell: &NcCell) -> bool {
|
||||
(cell.channels & NCCELL_WIDEASIAN_MASK as NcChannelPair) != 0
|
||||
}
|
||||
|
||||
/// Is this the right half of a wide character?
|
||||
#[inline]
|
||||
pub fn cell_wide_right_p(cell: &NcCell) -> bool {
|
||||
cell_double_wide_p(cell) && cell.gcluster == 0
|
||||
}
|
||||
|
||||
/// Is this the left half of a wide character?
|
||||
#[inline]
|
||||
pub fn cell_wide_left_p(cell: &NcCell) -> bool {
|
||||
cell_double_wide_p(cell) && cell.gcluster != 0
|
||||
}
|
||||
|
||||
/// Copies the UTF8-encoded [NcEgc] out of the cell, whether simple
|
||||
/// or complex.
|
||||
///
|
||||
/// The result is not tied to the [NcPlane], and persists
|
||||
/// across erases and destruction.
|
||||
#[inline]
|
||||
pub fn cell_strdup(plane: &NcPlane, cell: &NcCell) -> NcEgc {
|
||||
core::char::from_u32(unsafe { libc::strdup(cell_extended_gcluster(plane, cell)) } as i32 as u32)
|
||||
.expect("wrong char")
|
||||
|
||||
// unsafer option B (maybe faster, TODO: bench)
|
||||
// unsafe {
|
||||
// core::char::from_u32_unchecked(libc::strdup(cell_extended_gcluster(plane, cell)) as i32 as u32)
|
||||
// }
|
||||
}
|
||||
|
||||
/// Saves the [NcStyleMask] and the [NcChannelPair], and returns the [NcEgc]
|
||||
/// (the three elements of an [NcCell]).
|
||||
#[inline]
|
||||
pub fn cell_extract(
|
||||
plane: &NcPlane,
|
||||
cell: &NcCell,
|
||||
stylemask: &mut NcStyleMask,
|
||||
channels: &mut NcChannelPair,
|
||||
) -> NcEgc {
|
||||
if *stylemask != 0 {
|
||||
*stylemask = cell.stylemask;
|
||||
}
|
||||
if *channels != 0 {
|
||||
*channels = cell.channels;
|
||||
}
|
||||
cell_strdup(plane, cell)
|
||||
}
|
||||
|
||||
/// Returns true if the two cells are distinct [NcEgc]s, attributes, or channels
|
||||
///
|
||||
/// The actual egcpool index needn't be the same--indeed, the planes needn't even
|
||||
/// be the same. Only the expanded NcEgc must be equal. The NcEgc must be bit-equal;
|
||||
// NOTE: FIXME: it would probably be better to test whether they're Unicode-equal
|
||||
#[inline]
|
||||
pub fn cellcmp(plane1: &NcPlane, cell1: &NcCell, plane2: &NcPlane, cell2: &NcCell) -> bool {
|
||||
if cell1.stylemask != cell2.stylemask {
|
||||
return true;
|
||||
}
|
||||
if cell1.channels != cell2.channels {
|
||||
return true;
|
||||
}
|
||||
unsafe {
|
||||
strcmp(
|
||||
cell_extended_gcluster(plane1, cell1),
|
||||
cell_extended_gcluster(plane2, cell2),
|
||||
) != 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a 7-bit char into the [NcCell].
|
||||
// NOTE: Unlike the original C function this doesn't return anything.
|
||||
// REMINDER: remove casting for NCCELL_WIDEASIAN_MASK when fixed: https://github.com/rust-lang/rust-bindgen/issues/1875
|
||||
#[inline]
|
||||
pub fn cell_load_char(plane: &mut NcPlane, cell: &mut NcCell, ch: NcEgc) /* -> i32 */
|
||||
{
|
||||
unsafe {
|
||||
cell_release(plane, cell);
|
||||
}
|
||||
cell.channels &= !(NCCELL_WIDEASIAN_MASK as NcChannelPair | NCCELL_NOBACKGROUND_MASK);
|
||||
cell.gcluster = ch as u32;
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit background [NcChannel] from an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_bchannel(cell: &NcCell) -> NcChannel {
|
||||
channels_bchannel(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit foreground [NcChannel] from an [NcCell].
|
||||
#[inline]
|
||||
pub fn cell_fchannel(cell: &NcCell) -> NcChannel {
|
||||
channels_fchannel(cell.channels)
|
||||
}
|
||||
|
||||
/// Sets the 32-bit background [NcChannel] of an [NcCell] and returns its new
|
||||
/// [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn cell_set_bchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair {
|
||||
channels_set_bchannel(&mut cell.channels, channel)
|
||||
}
|
||||
|
||||
/// Sets the 32-bit foreground [NcChannel] of an [NcCell] and returns its new
|
||||
/// [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn cell_set_fchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair {
|
||||
channels_set_fchannel(&mut cell.channels, channel)
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcCell]
|
||||
/// (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_fg_rgb(cell: &NcCell) -> NcRgb {
|
||||
channels_fg_rgb(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcCell]
|
||||
/// (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_bg_rgb(cell: &NcCell) -> NcRgb {
|
||||
channels_bg_rgb(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcAlphaBits] from an [NcCell] (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_fg_alpha(cell: &NcCell) -> NcAlphaBits {
|
||||
channels_fg_alpha(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcAlphaBits] from an [NcCell] (shifted to LSBs).
|
||||
#[inline]
|
||||
pub fn cell_bg_alpha(cell: &NcCell) -> NcAlphaBits {
|
||||
channels_bg_alpha(cell.channels)
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcCell] and saves it
|
||||
/// split into three [NcColor] 8-bit components. Also returns the corresponding
|
||||
/// [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn cell_fg_rgb8(
|
||||
cell: &NcCell,
|
||||
red: &mut NcColor,
|
||||
green: &mut NcColor,
|
||||
blue: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channels_fg_rgb8(cell.channels, red, green, blue)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcCell] and saves it
|
||||
/// split into three [NcColor] 8-bit components. Also returns the corresponding
|
||||
/// [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn cell_bg_rgb8(
|
||||
cell: &NcCell,
|
||||
red: &mut NcColor,
|
||||
green: &mut NcColor,
|
||||
blue: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channels_bg_rgb8(cell.channels, red, green, blue)
|
||||
}
|
||||
|
||||
/// Sets the RGB [NcColor] components for the foreground [NcChannel] of an
|
||||
/// [NcCell], and marks it as not using the default color.
|
||||
#[inline]
|
||||
pub fn cell_set_fg_rgb8(cell: &mut NcCell, red: NcColor, green: NcColor, blue: NcColor) {
|
||||
channels_set_fg_rgb8(&mut cell.channels, red, green, blue);
|
||||
}
|
||||
|
||||
/// Sets the 24-bit [NcRgb] value for the foreground [NcChannel] of an
|
||||
/// [NcCell], and marks it as not using the default color.
|
||||
#[inline]
|
||||
pub fn cell_set_fg_rgb(cell: &mut NcCell, rgb: NcRgb) {
|
||||
channels_set_fg_rgb(&mut cell.channels, rgb);
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s foreground [NcPaletteIndex].
|
||||
///
|
||||
/// Also sets [NCCELL_FG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_FGDEFAULT_MASK].
|
||||
///
|
||||
// NOTE: unlike the original C function, this one can't fail
|
||||
#[inline]
|
||||
pub fn cell_set_fg_palindex(cell: &mut NcCell, index: NcPaletteIndex) {
|
||||
cell.channels |= NCCELL_FGDEFAULT_MASK;
|
||||
cell.channels |= NCCELL_FG_PALETTE;
|
||||
cell_set_fg_alpha(cell, NCCELL_ALPHA_OPAQUE);
|
||||
cell.channels &= 0xff000000ffffffff as NcChannelPair;
|
||||
cell.channels |= (index as NcChannelPair) << 32;
|
||||
}
|
||||
|
||||
/// Returns the [NcPaletteIndex] of the foreground [NcChannel] of the
|
||||
/// [NcCell]
|
||||
#[inline]
|
||||
pub fn cell_fg_palindex(cell: &NcCell) -> NcPaletteIndex {
|
||||
((cell.channels & 0xff00000000 as NcChannelPair) >> 32) as NcPaletteIndex
|
||||
}
|
||||
|
||||
/// Sets the [NcColor] 8-bit RGB components of the background [NcChannel]
|
||||
/// of the [NcCell], and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn cell_set_bg_rgb8(cell: &mut NcCell, red: NcColor, green: NcColor, blue: NcColor) {
|
||||
channels_set_bg_rgb8(&mut cell.channels, red, green, blue);
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit value for the background [NcChannel] of this
|
||||
/// [NcCell], and marks it as not using the default color.
|
||||
#[inline]
|
||||
pub fn cell_set_bg_rgb(cell: &mut NcCell, rgb: NcRgb) {
|
||||
channels_set_bg_rgb(&mut cell.channels, rgb);
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s background [NcPaletteIndex].
|
||||
///
|
||||
/// Also sets [NCCELL_BG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_BGDEFAULT_MASK].
|
||||
///
|
||||
// NOTE: unlike the original C function, this one can't fail
|
||||
#[inline]
|
||||
pub fn cell_set_bg_palindex(cell: &mut NcCell, index: NcPaletteIndex) {
|
||||
cell.channels |= NCCELL_BGDEFAULT_MASK as NcChannelPair;
|
||||
cell.channels |= NCCELL_BG_PALETTE as NcChannelPair;
|
||||
cell_set_bg_alpha(cell, NCCELL_ALPHA_OPAQUE);
|
||||
cell.channels &= 0xffffffffff000000;
|
||||
cell.channels |= index as NcChannelPair;
|
||||
}
|
||||
|
||||
/// Returns the [NcPaletteIndex] of the background [NcChannel] of the [NcCell]
|
||||
#[inline]
|
||||
pub fn cell_bg_palindex(cell: &NcCell) -> NcPaletteIndex {
|
||||
(cell.channels & 0xff) as NcPaletteIndex
|
||||
}
|
||||
|
||||
/// Is the foreground [NcChannel] of this [NcCell] using the
|
||||
/// "default foreground color"?
|
||||
#[inline]
|
||||
pub fn cell_fg_default_p(cell: &NcCell) -> bool {
|
||||
channels_fg_default_p(cell.channels)
|
||||
}
|
||||
|
||||
/// Is the foreground [NcChannel] of this [NcCell] using an
|
||||
/// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn cell_fg_palindex_p(cell: &NcCell) -> bool {
|
||||
channels_fg_palindex_p(cell.channels)
|
||||
}
|
||||
|
||||
/// Is the background [NcChannel] of this [NcCell] using the
|
||||
/// "default background color"?
|
||||
///
|
||||
/// The "default background color" must generally be used to take advantage of
|
||||
/// terminal-effected transparency.
|
||||
#[inline]
|
||||
pub fn cell_bg_default_p(cell: &NcCell) -> bool {
|
||||
channels_bg_default_p(cell.channels)
|
||||
}
|
||||
|
||||
/// Is the background [NcChannel] of this [NcCell] using an
|
||||
/// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn cell_bg_palindex_p(cell: &NcCell) -> bool {
|
||||
channels_bg_palindex_p(cell.channels)
|
||||
}
|
15
rust/src/cells/test/methods.rs
Normal file
15
rust/src/cells/test/methods.rs
Normal file
@ -0,0 +1,15 @@
|
||||
//! Test `NcCell` methods and associated functions.
|
||||
|
||||
use crate::NcCell;
|
||||
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn constructors() {
|
||||
let _c1 = NcCell::new();
|
||||
|
||||
let _c2 = NcCell::with_7bitchar('C');
|
||||
|
||||
let _c3 = NcCell::with_all('c', 0, 0);
|
||||
}
|
7
rust/src/cells/test/mod.rs
Normal file
7
rust/src/cells/test/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
//! `NcCell` tests
|
||||
|
||||
#[cfg(test)]
|
||||
mod methods;
|
||||
|
||||
#[cfg(test)]
|
||||
mod reimplemented;
|
@ -1,18 +1,8 @@
|
||||
//! [`NcCell`] tests
|
||||
|
||||
use crate::NcCell;
|
||||
//! Test `cell*_*` reimplemented functions
|
||||
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn constructors() {
|
||||
let _c1 = NcCell::new();
|
||||
|
||||
let _c2 = NcCell::with_7bitchar('C');
|
||||
|
||||
let _c3 = NcCell::with_all('c', 0, 0);
|
||||
}
|
||||
use crate::NcCell;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
@ -1,327 +0,0 @@
|
||||
#[allow(unused_imports)] // for docblocks
|
||||
use crate::{NcAlphaBits, NcChannel, NcPlane};
|
||||
|
||||
// NcCell
|
||||
/// A coordinate on an [`NcPlane`] storing 128 bits of data
|
||||
///
|
||||
/// An `NcCell` corresponds to a single character cell on some [`NcPlane`],
|
||||
/// which can be occupied by a single [`NcChar`] grapheme cluster (some root
|
||||
/// spacing glyph, along with possible combining characters, which might span
|
||||
/// multiple columns).
|
||||
///
|
||||
/// At any `NcCell`, we can have a theoretically arbitrarily long UTF-8 string,
|
||||
/// a foreground color, a background color, and an [`NcStyleMask`] attribute set.
|
||||
///
|
||||
/// Valid grapheme cluster contents include:
|
||||
///
|
||||
/// - A NUL terminator,
|
||||
/// - A single [control character](https://en.wikipedia.org/wiki/Control_character),
|
||||
/// followed by a NUL terminator,
|
||||
/// - At most one [spacing
|
||||
/// character](https://en.wikipedia.org/wiki/Graphic_character#Spacing_character),
|
||||
/// followed by zero or more nonspacing characters, followed by a NUL terminator.
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// NcCell: 128 bits structure comprised of the following 5 elements:
|
||||
///
|
||||
/// GCLUSTER GCLUSTER GCLUSTER GCLUSTER 1. NcChar
|
||||
/// 00000000 ~~~~~~~~ 11111111 11111111 2. NcCharBackstop + 3. reserved + 4. NcStyleMask
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB 5. NcChannelPair
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB |
|
||||
///
|
||||
/// 1. (32b) Extended Grapheme Cluster, presented either as:
|
||||
///
|
||||
/// 1.1. An NcChar of up to 4 bytes:
|
||||
/// UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU
|
||||
///
|
||||
/// 1.2. A `0x01` in the first byte, plus 3 bytes with a 24b address to an egcpool:
|
||||
/// 00000001 IIIIIIII IIIIIIII IIIIIIII
|
||||
///
|
||||
/// 2. (8b) Backstop (zero)
|
||||
/// 00000000
|
||||
///
|
||||
/// 3. (8b) reserved (ought to be zero)
|
||||
/// ~~~~~~~~
|
||||
///
|
||||
/// 4. (16b) NcStyleMask
|
||||
/// 11111111 11111111
|
||||
///
|
||||
/// 5. (64b) NcChannelPair
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB|~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: cell (struct)`
|
||||
///
|
||||
/// ## Size
|
||||
///
|
||||
/// Multi-column characters can only have a single style/color throughout.
|
||||
/// [`wcwidth()`](https://www.man7.org/linux/man-pages/man3/wcwidth.3.html)
|
||||
/// is not reliable. It's just quoting whether or not the [`NcChar`]
|
||||
/// contains a "Wide Asian" double-width character.
|
||||
/// This is set for some things, like most emoji, and not set for
|
||||
/// other things, like cuneiform.
|
||||
///
|
||||
/// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
|
||||
/// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB.
|
||||
/// Dynamic requirements (the egcpool) can add up to 16MB to an ncplane, but
|
||||
/// such large pools are unlikely in common use.
|
||||
///
|
||||
/// ## Alpha Compositing
|
||||
///
|
||||
/// We implement some small alpha compositing. Foreground and background both
|
||||
/// have two bits of inverted alpha. The actual grapheme written to a cell is
|
||||
/// the topmost non-zero grapheme.
|
||||
///
|
||||
/// - If its alpha is 00 ([`NCCELL_ALPHA_OPAQUE`]) its foreground color is used unchanged.
|
||||
///
|
||||
/// - If its alpha is 10 ([`NCCELL_ALPHA_TRANSPARENT`]) its foreground color is derived
|
||||
/// entirely from cells underneath it.
|
||||
///
|
||||
/// - If its alpha is 01 ([`NCCELL_ALPHA_BLEND`]) the result will be a composite.
|
||||
///
|
||||
/// Likewise for the background. If the bottom of a coordinate's zbuffer is
|
||||
/// reached with a cumulative alpha of zero, the default is used. In this way,
|
||||
/// a terminal configured with transparent background can be supported through
|
||||
/// multiple occluding ncplanes.
|
||||
///
|
||||
/// A foreground alpha of 11 ([`NCCELL_ALPHA_HIGHCONTRAST`]) requests high-contrast
|
||||
/// text (relative to the computed background).
|
||||
/// A background alpha of 11 is currently forbidden.
|
||||
///
|
||||
/// ## Precedence
|
||||
///
|
||||
/// - Default color takes precedence over palette or RGB, and cannot be used with
|
||||
/// transparency.
|
||||
/// - Indexed palette takes precedence over RGB. It cannot meaningfully set
|
||||
/// transparency, but it can be mixed into a cascading color.
|
||||
/// - RGB is used if neither default terminal colors nor palette indexing are in
|
||||
/// play, and fully supports all transparency options.
|
||||
///
|
||||
pub type NcCell = crate::bindings::bindgen::cell;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground or background color will be a composite between
|
||||
/// its color and the `NcCell`s' corresponding colors underneath it
|
||||
pub const NCCELL_ALPHA_BLEND: u32 = crate::bindings::bindgen::CELL_ALPHA_BLEND;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground color will be high-contrast (relative to the
|
||||
/// computed background). Background cannot be highcontrast
|
||||
pub const NCCELL_ALPHA_HIGHCONTRAST: u32 = crate::bindings::bindgen::CELL_ALPHA_HIGHCONTRAST;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground or background color is used unchanged
|
||||
pub const NCCELL_ALPHA_OPAQUE: u32 = crate::bindings::bindgen::CELL_ALPHA_OPAQUE;
|
||||
|
||||
/// [`NcAlphaBits`] bits indicating
|
||||
/// [`NcCell`]'s foreground or background color is derived entirely from the
|
||||
/// `NcCell`s underneath it
|
||||
pub const NCCELL_ALPHA_TRANSPARENT: u32 = crate::bindings::bindgen::CELL_ALPHA_TRANSPARENT;
|
||||
|
||||
/// If this bit is set, we are *not* using the default background color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BGDEFAULT_MASK: u32 = crate::bindings::bindgen::CELL_BGDEFAULT_MASK;
|
||||
|
||||
/// Extract these bits to get the background alpha mask
|
||||
/// ([`NcAlphaBits`])
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BG_ALPHA_MASK: u32 = crate::bindings::bindgen::CELL_BG_ALPHA_MASK;
|
||||
|
||||
/// If this bit *and* [`NCCELL_BGDEFAULT_MASK`] are set, we're using a
|
||||
/// palette-indexed background color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BG_PALETTE: u32 = crate::bindings::bindgen::CELL_BG_PALETTE;
|
||||
|
||||
/// Extract these bits to get the background [`NcRgb`][crate::NcRgb] value
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: This can also be used against a single [`NcChannel`]
|
||||
pub const NCCELL_BG_RGB_MASK: u32 = crate::bindings::bindgen::CELL_BG_RGB_MASK;
|
||||
|
||||
/// If this bit is set, we are *not* using the default foreground color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BGDEFAULT_MASK`];
|
||||
pub const NCCELL_FGDEFAULT_MASK: u64 = crate::bindings::bindgen::CELL_FGDEFAULT_MASK;
|
||||
|
||||
/// Extract these bits to get the foreground alpha mask
|
||||
/// ([`NcAlphaBits`])
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_ALPHA_MASK`];
|
||||
pub const NCCELL_FG_ALPHA_MASK: u64 = crate::bindings::bindgen::CELL_FG_ALPHA_MASK;
|
||||
|
||||
/// If this bit *and* [`NCCELL_FGDEFAULT_MASK`] are set, we're using a
|
||||
/// palette-indexed background color
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_PALETTE`];
|
||||
pub const NCCELL_FG_PALETTE: u64 = crate::bindings::bindgen::CELL_FG_PALETTE;
|
||||
|
||||
/// Extract these bits to get the foreground [`NcRgb`][crate::NcRgb] value
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
///
|
||||
/// NOTE: When working with a single [`NcChannel`] use [`NCCELL_BG_RGB_MASK`];
|
||||
pub const NCCELL_FG_RGB_MASK: u64 = crate::bindings::bindgen::CELL_FG_RGB_MASK;
|
||||
|
||||
/// Indicates the glyph is entirely foreground
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
pub const NCCELL_NOBACKGROUND_MASK: u64 = crate::bindings::bindgen::CELL_NOBACKGROUND_MASK;
|
||||
|
||||
/// If this bit is set, the cell is part of a multicolumn glyph.
|
||||
///
|
||||
/// Whether a cell is the left or right side of the glyph can be determined
|
||||
/// by checking whether ->gcluster is zero.
|
||||
///
|
||||
/// See the detailed diagram at [`NcChannelPair`][crate::NcChannelPair]
|
||||
pub const NCCELL_WIDEASIAN_MASK: u64 = crate::bindings::bindgen::CELL_WIDEASIAN_MASK as u64;
|
||||
|
||||
// NcChar
|
||||
//
|
||||
/// Extended Grapheme Cluster. A 32-bit [`char`]-like type
|
||||
///
|
||||
/// This 32 bit char, together with the associated plane's associated egcpool,
|
||||
/// completely define this cell's `NcChar`. Unless the `NcChar` requires more than
|
||||
/// four bytes to encode as UTF-8, it will be inlined here:
|
||||
///
|
||||
/// ## Diagram 1
|
||||
///
|
||||
/// ```txt
|
||||
/// UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU
|
||||
/// extended grapheme cluster <= 4bytes
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: uint32_t`
|
||||
///
|
||||
/// If more than four bytes are required, it will be spilled into the egcpool.
|
||||
/// In either case, there's a NUL-terminated string available without copying,
|
||||
/// because (1) the egcpool is all NUL-terminated sequences and (2) the fifth
|
||||
/// byte of this struct (the GClusterBackStop field, see below) is
|
||||
/// guaranteed to be zero, as are any unused bytes in gcluster.
|
||||
///
|
||||
/// A spilled `NcChar` is indicated by the value `0x01iiiiii`. This cannot alias a
|
||||
/// true supra-ASCII NcChar, because UTF-8 only encodes bytes <= 0x80 when they
|
||||
/// 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):
|
||||
///
|
||||
/// ## Diagram 2
|
||||
///
|
||||
/// ```txt
|
||||
/// 00000001 iiiiiiii iiiiiiii iiiiiiii
|
||||
/// sign 24bit index to egcpool
|
||||
/// ```
|
||||
/// `type in C: uint32_t`
|
||||
///
|
||||
/// 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 `NcChar` is <= 4 bytes and inlined, is still interpreted as
|
||||
/// 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.
|
||||
///
|
||||
/// ## Links
|
||||
///
|
||||
/// - [Grapheme Cluster
|
||||
/// Boundaries](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
|
||||
///
|
||||
///
|
||||
pub type NcChar = char;
|
||||
|
||||
// NcCharBackStop
|
||||
/// An `u8` always at zero, part of the [`NcCell`] struct
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// 00000000
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: uint_8t`
|
||||
///
|
||||
pub type NcCharBackstop = u8;
|
||||
|
||||
// NcStyleMask
|
||||
///
|
||||
/// An `u16` of `NCSTYLE_*` boolean styling attribute flags
|
||||
///
|
||||
/// ## Attributes
|
||||
///
|
||||
/// - [`NCSTYLE_BLINK`]
|
||||
/// - [`NCSTYLE_BOLD`]
|
||||
/// - [`NCSTYLE_DIM`]
|
||||
/// - [`NCSTYLE_INVIS`]
|
||||
/// - [`NCSTYLE_ITALIC`]
|
||||
/// - [`NCSTYLE_MASK`]
|
||||
/// - [`NCSTYLE_NONE`]
|
||||
/// - [`NCSTYLE_PROTECT`]
|
||||
/// - [`NCSTYLE_REVERSE`]
|
||||
/// - [`NCSTYLE_STANDOUT`]
|
||||
/// - [`NCSTYLE_STRUCK`]
|
||||
/// - [`NCSTYLE_UNDERLINE`]
|
||||
///
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// 11111111 11111111
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: uint16_t`
|
||||
///
|
||||
pub type NcStyleMask = u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_BLINK: u16 = crate::bindings::bindgen::NCSTYLE_BLINK as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_BOLD: u16 = crate::bindings::bindgen::NCSTYLE_BOLD as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_DIM: u16 = crate::bindings::bindgen::NCSTYLE_DIM as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_INVIS: u16 = crate::bindings::bindgen::NCSTYLE_INVIS as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_ITALIC: u16 = crate::bindings::bindgen::NCSTYLE_ITALIC as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_MASK: u16 = crate::bindings::bindgen::NCSTYLE_MASK as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_NONE: u16 = crate::bindings::bindgen::NCSTYLE_NONE as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_PROTECT: u16 = crate::bindings::bindgen::NCSTYLE_PROTECT as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_REVERSE: u16 = crate::bindings::bindgen::NCSTYLE_REVERSE as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_STANDOUT: u16 = crate::bindings::bindgen::NCSTYLE_STANDOUT as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_STRUCK: u16 = crate::bindings::bindgen::NCSTYLE_STRUCK as u16;
|
||||
|
||||
///
|
||||
pub const NCSTYLE_UNDERLINE: u16 = crate::bindings::bindgen::NCSTYLE_UNDERLINE as u16;
|
@ -1,47 +0,0 @@
|
||||
//! Handy [NcCell] constructors
|
||||
|
||||
pub use crate::{NcCell, NcPlane, NcChannelPair, NcCharBackstop, NcStyleMask, cell_load, NCRESULT_ERR, cstring};
|
||||
|
||||
impl NcCell {
|
||||
/// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair].
|
||||
#[inline]
|
||||
pub const fn with_all(ch: char, stylemask: NcStyleMask, channels: NcChannelPair) -> Self {
|
||||
NcCell {
|
||||
gcluster: ch as u32,
|
||||
gcluster_backstop: 0 as NcCharBackstop,
|
||||
reserved: 0,
|
||||
stylemask,
|
||||
channels,
|
||||
}
|
||||
}
|
||||
|
||||
/// New NcCell, expects a 7-bit [char].
|
||||
///
|
||||
/// See also `with_char`.
|
||||
#[inline]
|
||||
pub const fn with_7bitchar(ch: char) -> Self {
|
||||
Self::with_all(ch, 0 as NcStyleMask, 0 as NcChannelPair)
|
||||
}
|
||||
|
||||
/// New NcCell, expects an [NcPlane] and a utf-8 [char].
|
||||
///
|
||||
/// See also `with_7bitchar`.
|
||||
#[inline]
|
||||
pub fn with_char(plane: &mut NcPlane, ch: char) -> Self {
|
||||
let mut cell = Self::new();
|
||||
let result = unsafe {
|
||||
cell_load(plane,
|
||||
&mut cell,
|
||||
cstring![ch.to_string()],
|
||||
)
|
||||
};
|
||||
debug_assert_ne![NCRESULT_ERR, result];
|
||||
cell
|
||||
}
|
||||
|
||||
/// New NcCell, blank.
|
||||
#[inline]
|
||||
pub const fn new() -> Self {
|
||||
Self::with_7bitchar(0 as char)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
//! [`NcChannel`] & [`NcChannelPair`] `channel*_*` static fn reimplementations
|
||||
//! `NcChannel*`
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// - The channel components are u8 instead of u32.
|
||||
@ -13,367 +13,227 @@
|
||||
// - `channels_set_bg_rgb8_clipped()`
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// functions already exported by bindgen : 0
|
||||
// functions manually reimplemented: 39
|
||||
// ------------------------------------------
|
||||
//
|
||||
// static inline functions total: 39
|
||||
// ------------------------------------------ (implement / remaining)
|
||||
// (X) wont: 3
|
||||
// (+) done: 34 / 2
|
||||
// (W) wrap: 0 / 36
|
||||
// (#) test: 19 / 17
|
||||
// ------------------------------------------
|
||||
//# channel_alpha
|
||||
//# channel_b
|
||||
//# channel_default_p
|
||||
//# channel_g
|
||||
//# channel_palindex_p
|
||||
//# channel_r
|
||||
//# channel_rgb8
|
||||
//# channels_bchannel
|
||||
//+ channels_bg_alpha
|
||||
//+ channels_bg_default_p
|
||||
//# channels_bg_palindex_p
|
||||
//+ channels_bg_rgb
|
||||
//+ channels_bg_rgb8
|
||||
//# channels_combine
|
||||
//+ channel_set
|
||||
//# channel_set_alpha
|
||||
//# channel_set_default
|
||||
//# channel_set_rgb8
|
||||
//X channel_set_rgb_clipped
|
||||
//# channels_fchannel
|
||||
//+ channels_fg_alpha
|
||||
//+ channels_fg_default_p
|
||||
//# channels_fg_palindex_p
|
||||
//+ channels_fg_rgb
|
||||
//+ channels_fg_rgb8
|
||||
//# channels_set_bchannel
|
||||
//+ channels_set_bg_alpha
|
||||
//+ channels_set_bg_default
|
||||
//# channels_set_bg_palindex
|
||||
//+ channels_set_bg_rgb
|
||||
//+ channels_set_bg_rgb8
|
||||
//X channels_set_bg_rgb8_clipped
|
||||
//# channels_set_fchannel
|
||||
//+ channels_set_fg_alpha
|
||||
//+ channels_set_fg_default
|
||||
//# channels_set_fg_palindex
|
||||
//+ channels_set_fg_rgb
|
||||
//+ channels_set_fg_rgb8
|
||||
//X channels_set_fg_rgb8_clipped
|
||||
// # channel_alpha
|
||||
// # channel_b
|
||||
// # channel_default_p
|
||||
// # channel_g
|
||||
// # channel_palindex_p
|
||||
// # channel_r
|
||||
// # channel_rgb8
|
||||
// # channels_bchannel
|
||||
// + channels_bg_alpha
|
||||
// + channels_bg_default_p
|
||||
// # channels_bg_palindex_p
|
||||
// + channels_bg_rgb
|
||||
// + channels_bg_rgb8
|
||||
// # channels_combine
|
||||
// + channel_set
|
||||
// # channel_set_alpha
|
||||
// # channel_set_default
|
||||
// # channel_set_rgb8
|
||||
// X channel_set_rgb_clipped
|
||||
// # channels_fchannel
|
||||
// + channels_fg_alpha
|
||||
// + channels_fg_default_p
|
||||
// # channels_fg_palindex_p
|
||||
// + channels_fg_rgb
|
||||
// + channels_fg_rgb8
|
||||
// # channels_set_bchannel
|
||||
// + channels_set_bg_alpha
|
||||
// + channels_set_bg_default
|
||||
// # channels_set_bg_palindex
|
||||
// + channels_set_bg_rgb
|
||||
// + channels_set_bg_rgb8
|
||||
// X channels_set_bg_rgb8_clipped
|
||||
// # channels_set_fchannel
|
||||
// + channels_set_fg_alpha
|
||||
// + channels_set_fg_default
|
||||
// # channels_set_fg_palindex
|
||||
// + channels_set_fg_rgb
|
||||
// + channels_set_fg_rgb8
|
||||
// X channels_set_fg_rgb8_clipped
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod test;
|
||||
|
||||
mod types;
|
||||
pub use types::{
|
||||
NcAlphaBits, NcBlitSet, NcChannel, NcChannelPair, NcColor, NcFadeCtx, NcPalette,
|
||||
NcPaletteIndex, NcPixel, NcRgb, NCCHANNEL_ALPHA_MASK,
|
||||
};
|
||||
mod reimplemented;
|
||||
pub use reimplemented::*;
|
||||
|
||||
use crate::{
|
||||
NCCELL_ALPHA_HIGHCONTRAST, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE,
|
||||
NCCELL_BG_RGB_MASK, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE,
|
||||
};
|
||||
|
||||
/// Extracts the [NcColor] 8-bit red component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub const fn channel_r(channel: NcChannel) -> NcColor {
|
||||
((channel & 0xff0000) >> 16) as NcColor
|
||||
}
|
||||
|
||||
/// Extracts the [NcColor] 8-bit green component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub const fn channel_g(channel: NcChannel) -> NcColor {
|
||||
((channel & 0x00ff00) >> 8) as NcColor
|
||||
}
|
||||
|
||||
/// Extracts the [NcColor] 8-bit blue component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub const fn channel_b(channel: NcChannel) -> NcColor {
|
||||
(channel & 0x0000ff) as NcColor
|
||||
}
|
||||
|
||||
/// Extracts the three [NcColor] 8-bit RGB components from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub fn channel_rgb8(
|
||||
channel: NcChannel,
|
||||
r: &mut NcColor,
|
||||
g: &mut NcColor,
|
||||
b: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
*r = channel_r(channel);
|
||||
*g = channel_g(channel);
|
||||
*b = channel_b(channel);
|
||||
channel
|
||||
}
|
||||
|
||||
/// Sets the three [NcColor] 8-bit components of a 32-bit [NcChannel], and marks
|
||||
/// it as not using the "default color". Retain the other bits unchanged.
|
||||
#[inline]
|
||||
pub fn channel_set_rgb8(channel: &mut NcChannel, r: NcColor, g: NcColor, b: NcColor) {
|
||||
let rgb: NcRgb = (r as NcChannel) << 16 | (g as NcChannel) << 8 | (b as NcChannel);
|
||||
*channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | rgb;
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit RGB value of a 32-bit [NcChannel], and marks it as
|
||||
/// not using the "default color". Retain the other bits unchanged.
|
||||
#[inline]
|
||||
pub fn channel_set(channel: &mut NcChannel, rgb: NcRgb) {
|
||||
*channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | (rgb & 0x00ffffff);
|
||||
}
|
||||
|
||||
/// Extracts the [NcAlphaBits] 2-bit component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub fn channel_alpha(channel: NcChannel) -> NcAlphaBits {
|
||||
channel & NCCHANNEL_ALPHA_MASK
|
||||
}
|
||||
|
||||
/// Sets the [NcAlphaBits] 2-bit component of a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub fn channel_set_alpha(channel: &mut NcChannel, alpha: NcAlphaBits) {
|
||||
let alpha_clean = alpha & NCCHANNEL_ALPHA_MASK;
|
||||
*channel = alpha_clean | (*channel & !NCCHANNEL_ALPHA_MASK);
|
||||
|
||||
if alpha != NCCELL_ALPHA_OPAQUE {
|
||||
// indicate that we are *not* using the default background color
|
||||
*channel |= NCCELL_BGDEFAULT_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this [NcChannel] using the "default color" rather than RGB/palette-indexed?
|
||||
#[inline]
|
||||
pub fn channel_default_p(channel: NcChannel) -> bool {
|
||||
(channel & NCCELL_BGDEFAULT_MASK) == 0
|
||||
}
|
||||
|
||||
/// Is this [NcChannel] using palette-indexed color rather than RGB?
|
||||
#[inline]
|
||||
pub fn channel_palindex_p(channel: NcChannel) -> bool {
|
||||
!(channel_default_p(channel) && (channel & NCCELL_BG_PALETTE) == 0)
|
||||
}
|
||||
|
||||
/// Marks an [NcChannel] as using its "default color", which also marks it opaque.
|
||||
#[inline]
|
||||
pub fn channel_set_default(channel: &mut NcChannel) -> NcChannel {
|
||||
*channel &= !(NCCELL_BGDEFAULT_MASK | NCCELL_ALPHA_HIGHCONTRAST);
|
||||
*channel
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit background [NcChannel] from a [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_bchannel(channels: NcChannelPair) -> NcChannel {
|
||||
(channels & 0xffffffff_u64) as NcChannel
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit foreground [NcChannel] from an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_fchannel(channels: NcChannelPair) -> NcChannel {
|
||||
channels_bchannel(channels >> 32)
|
||||
}
|
||||
|
||||
/// Sets the 32-bit background [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_bchannel(channels: &mut NcChannelPair, bchannel: NcChannel) -> NcChannelPair {
|
||||
*channels = (*channels & 0xffffffff00000000_u64) | bchannel as u64;
|
||||
*channels
|
||||
}
|
||||
|
||||
/// Sets the 32-bit foreground [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_fchannel(channels: &mut NcChannelPair, fchannel: NcChannel) -> NcChannelPair {
|
||||
*channels = (*channels & 0xffffffff_u64) | (fchannel as u64) << 32;
|
||||
*channels
|
||||
}
|
||||
|
||||
/// Combines two [NcChannel]s into a [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPair {
|
||||
let mut channels: NcChannelPair = 0;
|
||||
channels_set_fchannel(&mut channels, fchannel);
|
||||
channels_set_bchannel(&mut channels, bchannel);
|
||||
channels
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcChannelPair],
|
||||
/// shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_fg_rgb(channels: NcChannelPair) -> NcChannel {
|
||||
channels_fchannel(channels) & NCCELL_BG_RGB_MASK
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcChannelPair],
|
||||
/// shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_bg_rgb(channels: NcChannelPair) -> NcChannel {
|
||||
channels_bchannel(channels) & NCCELL_BG_RGB_MASK
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits {
|
||||
channel_alpha(channels_fchannel(channels))
|
||||
}
|
||||
|
||||
/// Extracts the background [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits {
|
||||
channel_alpha(channels_bchannel(channels))
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcChannelPair], and
|
||||
/// saves it split into three [NcColor] 8-bit components. Also returns the
|
||||
/// corresponding [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn channels_fg_rgb8(
|
||||
channels: NcChannelPair,
|
||||
r: &mut NcColor,
|
||||
g: &mut NcColor,
|
||||
b: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channel_rgb8(channels_fchannel(channels), r, g, b)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcChannelPair], and
|
||||
/// saves it split into three [NcColor] 8-bit components. Also returns the
|
||||
/// corresponding [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn channels_bg_rgb8(
|
||||
channels: NcChannelPair,
|
||||
r: &mut NcColor,
|
||||
g: &mut NcColor,
|
||||
b: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channel_rgb8(channels_bchannel(channels), r, g, b)
|
||||
}
|
||||
|
||||
/// Sets the RGB [NcColor] components for the foreground [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_fg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor) {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set_rgb8(&mut channel, r, g, b);
|
||||
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit value for the foreground [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_fg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set(&mut channel, rgb);
|
||||
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
|
||||
}
|
||||
|
||||
/// Sets the RGB [NcColor] components for the background [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_bg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor) {
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set_rgb8(&mut channel, r, g, b);
|
||||
channels_set_bchannel(channels, channel);
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit value for the background [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_bg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set(&mut channel, rgb);
|
||||
channels_set_bchannel(channels, channel);
|
||||
}
|
||||
|
||||
/// Sets the [NcAlphaBits] of the foreground [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_fg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set_alpha(&mut channel, alpha);
|
||||
*channels = (channel as NcChannelPair) << 32 | *channels & 0xffffffff_u64;
|
||||
}
|
||||
|
||||
/// Sets the [NcAlphaBits] of the background [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_bg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) {
|
||||
let mut alpha_clean = alpha;
|
||||
if alpha == NCCELL_ALPHA_HIGHCONTRAST {
|
||||
// forbidden for background alpha, so makes it opaque
|
||||
alpha_clean = NCCELL_ALPHA_OPAQUE;
|
||||
}
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set_alpha(&mut channel, alpha_clean);
|
||||
channels_set_bchannel(channels, channel);
|
||||
}
|
||||
|
||||
/// Is the foreground of an [NcChannelPair] using the "default foreground color"?
|
||||
#[inline]
|
||||
pub fn channels_fg_default_p(channels: NcChannelPair) -> bool {
|
||||
channel_default_p(channels_fchannel(channels))
|
||||
}
|
||||
|
||||
/// Is the foreground of an [NcChannelPair] using an [indexed][NcPaletteIndex]
|
||||
/// [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn channels_fg_palindex_p(channels: NcChannelPair) -> bool {
|
||||
channel_palindex_p(channels_fchannel(channels))
|
||||
}
|
||||
|
||||
/// Is the background using the "default background color"? The "default
|
||||
/// background color" must generally be used to take advantage of
|
||||
/// terminal-effected transparency.
|
||||
#[inline]
|
||||
pub fn channels_bg_default_p(channels: NcChannelPair) -> bool {
|
||||
channel_default_p(channels_bchannel(channels))
|
||||
}
|
||||
|
||||
/// Is the background of an [NcChannelPair] using an [indexed][NcPaletteIndex]
|
||||
/// [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn channels_bg_palindex_p(channels: NcChannelPair) -> bool {
|
||||
channel_palindex_p(channels_bchannel(channels))
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s background [NcPaletteIndex].
|
||||
// NcChannel
|
||||
//
|
||||
/// 32 bits of context-dependent info
|
||||
/// containing RGB + 2 bits of alpha + extra
|
||||
///
|
||||
/// Also sets [NCCELL_BG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_BGDEFAULT_MASK].
|
||||
#[inline]
|
||||
pub fn channels_set_bg_palindex(channels: &mut NcChannelPair, index: NcPaletteIndex) {
|
||||
*channels |= NCCELL_BGDEFAULT_MASK as NcChannelPair;
|
||||
*channels |= NCCELL_BG_PALETTE as NcChannelPair;
|
||||
channels_set_bg_alpha(channels, NCCELL_ALPHA_OPAQUE);
|
||||
*channels &= 0xffffffffff000000;
|
||||
*channels |= index as NcChannelPair;
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s foreground [NcPaletteIndex].
|
||||
/// It is:
|
||||
/// - a 24-bit [`NcRgb`] value
|
||||
/// - plus 8 bits divided in:
|
||||
/// - 2 bits of [`NcAlphaBits`]
|
||||
/// - 6 bits of context-dependent info
|
||||
///
|
||||
/// Also sets [NCCELL_FG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_FGDEFAULT_MASK].
|
||||
#[inline]
|
||||
pub fn channels_set_fg_palindex(channels: &mut NcChannelPair, index: NcPaletteIndex) {
|
||||
*channels |= NCCELL_FGDEFAULT_MASK;
|
||||
*channels |= NCCELL_FG_PALETTE as NcChannelPair;
|
||||
channels_set_fg_alpha(channels, NCCELL_ALPHA_OPAQUE);
|
||||
*channels &= 0xff000000ffffffff as NcChannelPair;
|
||||
*channels |= (index as NcChannelPair) << 32;
|
||||
}
|
||||
/// The context details are documented in [`NcChannelPair`]
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB
|
||||
/// ```
|
||||
/// `type in C: channel (uint32_t)`
|
||||
///
|
||||
pub type NcChannel = u32;
|
||||
|
||||
/// Marks the foreground of an [NcChannelPair] as using its "default color",
|
||||
/// and returns the new [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_fg_default(channels: &mut NcChannelPair) -> NcChannelPair {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set_default(&mut channel);
|
||||
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
|
||||
*channels
|
||||
}
|
||||
/// Extract these bits to get a channel's alpha value
|
||||
pub const NCCHANNEL_ALPHA_MASK: u32 = crate::bindings::bindgen::CHANNEL_ALPHA_MASK;
|
||||
|
||||
/// Marks the background of an [NcChannelPair] as using its "default color",
|
||||
/// and returns the new [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_bg_default(channels: &mut NcChannelPair) -> NcChannelPair {
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set_default(&mut channel);
|
||||
channels_set_bchannel(channels, channel);
|
||||
*channels
|
||||
}
|
||||
// NcAlphaBits
|
||||
//
|
||||
/// 2 bits of alpha (surrounded by context dependent bits).
|
||||
/// It is part of an [`NcChannel`].
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// ~~AA~~~~ -------- -------- --------
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: no data type`
|
||||
///
|
||||
pub type NcAlphaBits = u32;
|
||||
|
||||
// NcChannelPair
|
||||
//
|
||||
/// 64 bits containing a foreground and background [`NcChannel`]
|
||||
///
|
||||
/// At render time, both 24-bit [`NcRgb`] values are quantized down to terminal
|
||||
/// capabilities, if necessary. There's a clear path to 10-bit support should
|
||||
/// we one day need it.
|
||||
///
|
||||
/// ## Default Color
|
||||
///
|
||||
/// The "default color" is best explained by
|
||||
/// [color(3NCURSES)](https://manpages.debian.org/stretch/ncurses-doc/color.3ncurses.en.html).
|
||||
/// Ours is the same concept.
|
||||
///
|
||||
/// **Until the "not default color" bit is set, any color you load will be ignored.**
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// ~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB|~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB
|
||||
/// ↑↑↑↑↑↑↑↑↑↑↑↑ foreground ↑↑↑↑↑↑↑↑↑↑↑|↑↑↑↑↑↑↑↑↑↑↑↑ background ↑↑↑↑↑↑↑↑↑↑↑
|
||||
/// ```
|
||||
///
|
||||
/// Detailed info (specially on the context-dependent bits on each
|
||||
/// [`NcChannel`]'s 4th byte):
|
||||
///
|
||||
/// ```txt
|
||||
/// ~foreground channel~
|
||||
/// NCCELL_WIDEASIAN_MASK: part of a wide glyph ↓bits view↓ ↓hex mask↓
|
||||
/// 1······· ········ ········ ········ ········ ········ ········ ········ = 8······· ········
|
||||
///
|
||||
/// NCCELL_FGDEFAULT_MASK: foreground is NOT "default color"
|
||||
/// ·1······ ········ ········ ········ ········ ········ ········ ········ = 4······· ········
|
||||
///
|
||||
/// NCCELL_FG_ALPHA_MASK: foreground alpha (2bits)
|
||||
/// ··11···· ········ ········ ········ ········ ········ ········ ········ = 3······· ········
|
||||
///
|
||||
/// NCCELL_FG_PALETTE: foreground uses palette index
|
||||
/// ····1··· ········ ········ ········ ········ ········ ········ ········ = ·8······ ········
|
||||
///
|
||||
/// NCCELL_NOBACKGROUND_MASK: glyph is entirely foreground
|
||||
/// ·····1·· ········ ········ ········ ········ ········ ········ ········ = ·4······ ········
|
||||
///
|
||||
/// reserved, must be 0
|
||||
/// ······00 ········ ········ ········ ········ ········ ········ ········ = ·3······ ········
|
||||
///
|
||||
/// NCCELL_FG_RGB_MASK: foreground in 3x8 RGB (rrggbb)
|
||||
/// ········ 11111111 11111111 11111111 ········ ········ ········ ········ = ··FFFFFF ········
|
||||
/// ```
|
||||
|
||||
/// ```txt
|
||||
/// ~background channel~
|
||||
/// reserved, must be 0 ↓bits view↓ ↓hex mask↓
|
||||
/// ········ ········ ········ ········ 0······· ········ ········ ········ = ········ 8·······
|
||||
///
|
||||
/// NCCELL_BGDEFAULT_MASK: background is NOT "default color"
|
||||
/// ········ ········ ········ ········ ·1······ ········ ········ ········ = ········ 4·······
|
||||
///
|
||||
/// NCCELL_BG_ALPHA_MASK: background alpha (2 bits)
|
||||
/// ········ ········ ········ ········ ··11···· ········ ········ ········ = ········ 3·······
|
||||
///
|
||||
/// NCCELL_BG_PALETTE: background uses palette index
|
||||
/// ········ ········ ········ ········ ····1··· ········ ········ ········ = ········ ·8······
|
||||
///
|
||||
/// reserved, must be 0
|
||||
/// ········ ········ ········ ········ ·····000 ········ ········ ········ = ········ ·7······
|
||||
///
|
||||
/// NCCELL_BG_RGB_MASK: background in 3x8 RGB (rrggbb)
|
||||
/// 0········ ········ ········ ········ ········11111111 11111111 11111111 = ········ ··FFFFFF
|
||||
/// ```
|
||||
/// `type in C: channels (uint64_t)`
|
||||
///
|
||||
/// ## `NcCell` Mask Flags
|
||||
///
|
||||
/// - [`NCCELL_BGDEFAULT_MASK`][crate::NCCELL_BGDEFAULT_MASK]
|
||||
/// - [`NCCELL_BG_ALPHA_MASK`][crate::NCCELL_BG_ALPHA_MASK]
|
||||
/// - [`NCCELL_BG_PALETTE`][crate::NCCELL_BG_PALETTE]
|
||||
/// - [`NCCELL_BG_RGB_MASK`][crate::NCCELL_BG_RGB_MASK]
|
||||
/// - [`NCCELL_FGDEFAULT_MASK`][crate::NCCELL_FGDEFAULT_MASK]
|
||||
/// - [`NCCELL_FG_ALPHA_MASK`][crate::NCCELL_FG_ALPHA_MASK]
|
||||
/// - [`NCCELL_FG_PALETTE`][crate::NCCELL_FG_PALETTE]
|
||||
/// - [`NCCELL_FG_RGB_MASK`][crate::NCCELL_FG_RGB_MASK]
|
||||
/// - [`NCCELL_NOBACKGROUND_MASK`][crate::NCCELL_NOBACKGROUND_MASK]
|
||||
/// - [`NCCELL_WIDEASIAN_MASK`][crate::NCCELL_WIDEASIAN_MASK]
|
||||
///
|
||||
pub type NcChannelPair = u64;
|
||||
|
||||
// NcRgb
|
||||
//
|
||||
/// 24 bits broken into 3x 8bpp channels.
|
||||
///
|
||||
/// Unlike with [`NcChannel`], operations involving `NcRgb` ignores the last 4th byte
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// -------- RRRRRRRR GGGGGGGG BBBBBBBB
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: no data type`
|
||||
///
|
||||
pub type NcRgb = u32;
|
||||
|
||||
// NcColor
|
||||
//
|
||||
/// 8 bits representing a R/G/B color or alpha channel
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// CCCCCCCC (1 Byte)
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: no data type`
|
||||
///
|
||||
pub type NcColor = u8;
|
||||
|
||||
/// Context for a palette fade operation
|
||||
pub type NcFadeCtx = crate::bindings::bindgen::ncfadectx;
|
||||
|
||||
/// the [NcEgc][crate::NcEgc] which form the various levels of a given geometry.
|
||||
///
|
||||
/// If the geometry is wide, things are arranged with the rightmost side
|
||||
/// increasing most quickly, i.e. it can be indexed as height arrays of
|
||||
/// 1 + height glyphs.
|
||||
/// i.e. The first five braille EGCs are all 0 on the left,
|
||||
/// [0..4] on the right.
|
||||
///
|
||||
/// `type in C: blitset (struct)`
|
||||
///
|
||||
pub type NcBlitSet = crate::bindings::bindgen::blitset;
|
||||
|
309
rust/src/channel/reimplemented.rs
Normal file
309
rust/src/channel/reimplemented.rs
Normal file
@ -0,0 +1,309 @@
|
||||
//! `channel*_*` reimplemented functions.
|
||||
|
||||
use crate::{
|
||||
NcAlphaBits, NcChannel, NcChannelPair, NcColor, NcPaletteIndex, NcRgb,
|
||||
NCCELL_ALPHA_HIGHCONTRAST, NCCELL_ALPHA_OPAQUE, NCCELL_BGDEFAULT_MASK, NCCELL_BG_PALETTE,
|
||||
NCCELL_BG_RGB_MASK, NCCELL_FGDEFAULT_MASK, NCCELL_FG_PALETTE, NCCHANNEL_ALPHA_MASK,
|
||||
};
|
||||
|
||||
/// Extracts the [NcColor] 8-bit red component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub const fn channel_r(channel: NcChannel) -> NcColor {
|
||||
((channel & 0xff0000) >> 16) as NcColor
|
||||
}
|
||||
|
||||
/// Extracts the [NcColor] 8-bit green component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub const fn channel_g(channel: NcChannel) -> NcColor {
|
||||
((channel & 0x00ff00) >> 8) as NcColor
|
||||
}
|
||||
|
||||
/// Extracts the [NcColor] 8-bit blue component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub const fn channel_b(channel: NcChannel) -> NcColor {
|
||||
(channel & 0x0000ff) as NcColor
|
||||
}
|
||||
|
||||
/// Extracts the three [NcColor] 8-bit RGB components from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub fn channel_rgb8(
|
||||
channel: NcChannel,
|
||||
r: &mut NcColor,
|
||||
g: &mut NcColor,
|
||||
b: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
*r = channel_r(channel);
|
||||
*g = channel_g(channel);
|
||||
*b = channel_b(channel);
|
||||
channel
|
||||
}
|
||||
|
||||
/// Sets the three [NcColor] 8-bit components of a 32-bit [NcChannel], and marks
|
||||
/// it as not using the "default color". Retain the other bits unchanged.
|
||||
#[inline]
|
||||
pub fn channel_set_rgb8(channel: &mut NcChannel, r: NcColor, g: NcColor, b: NcColor) {
|
||||
let rgb: NcRgb = (r as NcChannel) << 16 | (g as NcChannel) << 8 | (b as NcChannel);
|
||||
*channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | rgb;
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit RGB value of a 32-bit [NcChannel], and marks it as
|
||||
/// not using the "default color". Retain the other bits unchanged.
|
||||
#[inline]
|
||||
pub fn channel_set(channel: &mut NcChannel, rgb: NcRgb) {
|
||||
*channel = (*channel & !NCCELL_BG_RGB_MASK) | NCCELL_BGDEFAULT_MASK | (rgb & 0x00ffffff);
|
||||
}
|
||||
|
||||
/// Extracts the [NcAlphaBits] 2-bit component from a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub fn channel_alpha(channel: NcChannel) -> NcAlphaBits {
|
||||
channel & NCCHANNEL_ALPHA_MASK
|
||||
}
|
||||
|
||||
/// Sets the [NcAlphaBits] 2-bit component of a 32-bit [NcChannel].
|
||||
#[inline]
|
||||
pub fn channel_set_alpha(channel: &mut NcChannel, alpha: NcAlphaBits) {
|
||||
let alpha_clean = alpha & NCCHANNEL_ALPHA_MASK;
|
||||
*channel = alpha_clean | (*channel & !NCCHANNEL_ALPHA_MASK);
|
||||
|
||||
if alpha != NCCELL_ALPHA_OPAQUE {
|
||||
// indicate that we are *not* using the default background color
|
||||
*channel |= NCCELL_BGDEFAULT_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this [NcChannel] using the "default color" rather than RGB/palette-indexed?
|
||||
#[inline]
|
||||
pub fn channel_default_p(channel: NcChannel) -> bool {
|
||||
(channel & NCCELL_BGDEFAULT_MASK) == 0
|
||||
}
|
||||
|
||||
/// Is this [NcChannel] using palette-indexed color rather than RGB?
|
||||
#[inline]
|
||||
pub fn channel_palindex_p(channel: NcChannel) -> bool {
|
||||
!(channel_default_p(channel) && (channel & NCCELL_BG_PALETTE) == 0)
|
||||
}
|
||||
|
||||
/// Marks an [NcChannel] as using its "default color", which also marks it opaque.
|
||||
#[inline]
|
||||
pub fn channel_set_default(channel: &mut NcChannel) -> NcChannel {
|
||||
*channel &= !(NCCELL_BGDEFAULT_MASK | NCCELL_ALPHA_HIGHCONTRAST);
|
||||
*channel
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit background [NcChannel] from a [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_bchannel(channels: NcChannelPair) -> NcChannel {
|
||||
(channels & 0xffffffff_u64) as NcChannel
|
||||
}
|
||||
|
||||
/// Extracts the 32-bit foreground [NcChannel] from an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_fchannel(channels: NcChannelPair) -> NcChannel {
|
||||
channels_bchannel(channels >> 32)
|
||||
}
|
||||
|
||||
/// Sets the 32-bit background [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_bchannel(channels: &mut NcChannelPair, bchannel: NcChannel) -> NcChannelPair {
|
||||
*channels = (*channels & 0xffffffff00000000_u64) | bchannel as u64;
|
||||
*channels
|
||||
}
|
||||
|
||||
/// Sets the 32-bit foreground [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_fchannel(channels: &mut NcChannelPair, fchannel: NcChannel) -> NcChannelPair {
|
||||
*channels = (*channels & 0xffffffff_u64) | (fchannel as u64) << 32;
|
||||
*channels
|
||||
}
|
||||
|
||||
/// Combines two [NcChannel]s into a [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPair {
|
||||
let mut channels: NcChannelPair = 0;
|
||||
channels_set_fchannel(&mut channels, fchannel);
|
||||
channels_set_bchannel(&mut channels, bchannel);
|
||||
channels
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcChannelPair],
|
||||
/// shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_fg_rgb(channels: NcChannelPair) -> NcChannel {
|
||||
channels_fchannel(channels) & NCCELL_BG_RGB_MASK
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcChannelPair],
|
||||
/// shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_bg_rgb(channels: NcChannelPair) -> NcChannel {
|
||||
channels_bchannel(channels) & NCCELL_BG_RGB_MASK
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits {
|
||||
channel_alpha(channels_fchannel(channels))
|
||||
}
|
||||
|
||||
/// Extracts the background [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits {
|
||||
channel_alpha(channels_bchannel(channels))
|
||||
}
|
||||
|
||||
/// Extracts the foreground [NcRgb] 24-bit value from an [NcChannelPair], and
|
||||
/// saves it split into three [NcColor] 8-bit components. Also returns the
|
||||
/// corresponding [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn channels_fg_rgb8(
|
||||
channels: NcChannelPair,
|
||||
r: &mut NcColor,
|
||||
g: &mut NcColor,
|
||||
b: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channel_rgb8(channels_fchannel(channels), r, g, b)
|
||||
}
|
||||
|
||||
/// Extracts the background [NcRgb] 24-bit value from an [NcChannelPair], and
|
||||
/// saves it split into three [NcColor] 8-bit components. Also returns the
|
||||
/// corresponding [NcChannel] (which can have some extra bits set).
|
||||
#[inline]
|
||||
pub fn channels_bg_rgb8(
|
||||
channels: NcChannelPair,
|
||||
r: &mut NcColor,
|
||||
g: &mut NcColor,
|
||||
b: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channel_rgb8(channels_bchannel(channels), r, g, b)
|
||||
}
|
||||
|
||||
/// Sets the RGB [NcColor] components for the foreground [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_fg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor) {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set_rgb8(&mut channel, r, g, b);
|
||||
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit value for the foreground [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_fg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set(&mut channel, rgb);
|
||||
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
|
||||
}
|
||||
|
||||
/// Sets the RGB [NcColor] components for the background [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_bg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor, b: NcColor) {
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set_rgb8(&mut channel, r, g, b);
|
||||
channels_set_bchannel(channels, channel);
|
||||
}
|
||||
|
||||
/// Sets the [NcRgb] 24-bit value for the background [NcChannel] of an
|
||||
/// [NcChannelPair] 64-bit variable, and marks it as not using the "default color".
|
||||
#[inline]
|
||||
pub fn channels_set_bg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set(&mut channel, rgb);
|
||||
channels_set_bchannel(channels, channel);
|
||||
}
|
||||
|
||||
/// Sets the [NcAlphaBits] of the foreground [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_fg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set_alpha(&mut channel, alpha);
|
||||
*channels = (channel as NcChannelPair) << 32 | *channels & 0xffffffff_u64;
|
||||
}
|
||||
|
||||
/// Sets the [NcAlphaBits] of the background [NcChannel] of an [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_bg_alpha(channels: &mut NcChannelPair, alpha: NcAlphaBits) {
|
||||
let mut alpha_clean = alpha;
|
||||
if alpha == NCCELL_ALPHA_HIGHCONTRAST {
|
||||
// forbidden for background alpha, so makes it opaque
|
||||
alpha_clean = NCCELL_ALPHA_OPAQUE;
|
||||
}
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set_alpha(&mut channel, alpha_clean);
|
||||
channels_set_bchannel(channels, channel);
|
||||
}
|
||||
|
||||
/// Is the foreground of an [NcChannelPair] using the "default foreground color"?
|
||||
#[inline]
|
||||
pub fn channels_fg_default_p(channels: NcChannelPair) -> bool {
|
||||
channel_default_p(channels_fchannel(channels))
|
||||
}
|
||||
|
||||
/// Is the foreground of an [NcChannelPair] using an [indexed][NcPaletteIndex]
|
||||
/// [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn channels_fg_palindex_p(channels: NcChannelPair) -> bool {
|
||||
channel_palindex_p(channels_fchannel(channels))
|
||||
}
|
||||
|
||||
/// Is the background using the "default background color"? The "default
|
||||
/// background color" must generally be used to take advantage of
|
||||
/// terminal-effected transparency.
|
||||
#[inline]
|
||||
pub fn channels_bg_default_p(channels: NcChannelPair) -> bool {
|
||||
channel_default_p(channels_bchannel(channels))
|
||||
}
|
||||
|
||||
/// Is the background of an [NcChannelPair] using an [indexed][NcPaletteIndex]
|
||||
/// [NcPalette][crate::NcPalette] color?
|
||||
#[inline]
|
||||
pub fn channels_bg_palindex_p(channels: NcChannelPair) -> bool {
|
||||
channel_palindex_p(channels_bchannel(channels))
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s background [NcPaletteIndex].
|
||||
///
|
||||
/// Also sets [NCCELL_BG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_BGDEFAULT_MASK].
|
||||
#[inline]
|
||||
pub fn channels_set_bg_palindex(channels: &mut NcChannelPair, index: NcPaletteIndex) {
|
||||
*channels |= NCCELL_BGDEFAULT_MASK as NcChannelPair;
|
||||
*channels |= NCCELL_BG_PALETTE as NcChannelPair;
|
||||
channels_set_bg_alpha(channels, NCCELL_ALPHA_OPAQUE);
|
||||
*channels &= 0xffffffffff000000;
|
||||
*channels |= index as NcChannelPair;
|
||||
}
|
||||
|
||||
/// Sets an [NcCell]'s foreground [NcPaletteIndex].
|
||||
///
|
||||
/// Also sets [NCCELL_FG_PALETTE] and [NCCELL_ALPHA_OPAQUE],
|
||||
/// and clears out [NCCELL_FGDEFAULT_MASK].
|
||||
#[inline]
|
||||
pub fn channels_set_fg_palindex(channels: &mut NcChannelPair, index: NcPaletteIndex) {
|
||||
*channels |= NCCELL_FGDEFAULT_MASK;
|
||||
*channels |= NCCELL_FG_PALETTE as NcChannelPair;
|
||||
channels_set_fg_alpha(channels, NCCELL_ALPHA_OPAQUE);
|
||||
*channels &= 0xff000000ffffffff as NcChannelPair;
|
||||
*channels |= (index as NcChannelPair) << 32;
|
||||
}
|
||||
|
||||
/// Marks the foreground of an [NcChannelPair] as using its "default color",
|
||||
/// and returns the new [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_fg_default(channels: &mut NcChannelPair) -> NcChannelPair {
|
||||
let mut channel = channels_fchannel(*channels);
|
||||
channel_set_default(&mut channel);
|
||||
*channels = (channel as u64) << 32 | *channels & 0xffffffff_u64;
|
||||
*channels
|
||||
}
|
||||
|
||||
/// Marks the background of an [NcChannelPair] as using its "default color",
|
||||
/// and returns the new [NcChannelPair].
|
||||
#[inline]
|
||||
pub fn channels_set_bg_default(channels: &mut NcChannelPair) -> NcChannelPair {
|
||||
let mut channel = channels_bchannel(*channels);
|
||||
channel_set_default(&mut channel);
|
||||
channels_set_bchannel(channels, channel);
|
||||
*channels
|
||||
}
|
10
rust/src/channel/test/methods.rs
Normal file
10
rust/src/channel/test/methods.rs
Normal file
@ -0,0 +1,10 @@
|
||||
//! Test `NcChannel*` methods and associated functions.
|
||||
|
||||
// use crate::{NcChannel, NcChannelPair};
|
||||
//
|
||||
// use serial_test::serial;
|
||||
//
|
||||
// #[test]
|
||||
// #[serial]
|
||||
// fn () {
|
||||
// }
|
7
rust/src/channel/test/mod.rs
Normal file
7
rust/src/channel/test/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
//! `NcChannel*` tests.
|
||||
|
||||
#[cfg(test)]
|
||||
mod methods;
|
||||
|
||||
#[cfg(test)]
|
||||
mod reimplemented;
|
@ -1,12 +1,12 @@
|
||||
//! [`NcChannel`] & [`NcChannelPair`] tests
|
||||
//! Test `channel*_*` reimplemented functions.
|
||||
|
||||
use serial_test::serial;
|
||||
|
||||
use crate::{
|
||||
NcChannel, NcChannelPair, NCCELL_ALPHA_BLEND, NCCELL_ALPHA_HIGHCONTRAST, NCCELL_ALPHA_OPAQUE,
|
||||
NCCELL_ALPHA_TRANSPARENT,
|
||||
};
|
||||
|
||||
use serial_test::serial;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn channel_r() {
|
@ -1,211 +0,0 @@
|
||||
#[allow(unused_imports)] // for docblocks
|
||||
use crate::NcChar;
|
||||
|
||||
// NcChannel
|
||||
//
|
||||
/// 32 bits of context-dependent info
|
||||
/// containing RGB + 2 bits of alpha + extra
|
||||
///
|
||||
/// It is:
|
||||
/// - a 24-bit [`NcRgb`] value
|
||||
/// - plus 8 bits divided in:
|
||||
/// - 2 bits of [`NcAlphaBits`]
|
||||
/// - 6 bits of context-dependent info
|
||||
///
|
||||
/// The context details are documented in [`NcChannelPair`]
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// ~~AA~~~~ RRRRRRRR GGGGGGGG BBBBBBBB
|
||||
/// ```
|
||||
/// `type in C: channel (uint32_t)`
|
||||
///
|
||||
pub type NcChannel = u32;
|
||||
|
||||
/// Extract these bits to get a channel's alpha value
|
||||
pub const NCCHANNEL_ALPHA_MASK: u32 = crate::bindings::bindgen::CHANNEL_ALPHA_MASK;
|
||||
|
||||
// NcAlphaBits
|
||||
//
|
||||
/// 2 bits of alpha (surrounded by context dependent bits).
|
||||
/// It is part of an [`NcChannel`].
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// ~~AA~~~~ -------- -------- --------
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: no data type`
|
||||
///
|
||||
pub type NcAlphaBits = u32;
|
||||
|
||||
// NcChannelPair
|
||||
//
|
||||
/// 64 bits containing a foreground and background [`NcChannel`]
|
||||
///
|
||||
/// At render time, both 24-bit [`NcRgb`] values are quantized down to terminal
|
||||
/// capabilities, if necessary. There's a clear path to 10-bit support should
|
||||
/// we one day need it.
|
||||
///
|
||||
/// ## Default Color
|
||||
///
|
||||
/// The "default color" is best explained by
|
||||
/// [color(3NCURSES)](https://manpages.debian.org/stretch/ncurses-doc/color.3ncurses.en.html).
|
||||
/// Ours is the same concept.
|
||||
///
|
||||
/// **Until the "not default color" bit is set, any color you load will be ignored.**
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// ~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB|~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB
|
||||
/// ↑↑↑↑↑↑↑↑↑↑↑↑ foreground ↑↑↑↑↑↑↑↑↑↑↑|↑↑↑↑↑↑↑↑↑↑↑↑ background ↑↑↑↑↑↑↑↑↑↑↑
|
||||
/// ```
|
||||
///
|
||||
/// Detailed info (specially on the context-dependent bits on each
|
||||
/// [`NcChannel`]'s 4th byte):
|
||||
///
|
||||
/// ```txt
|
||||
/// ~foreground channel~
|
||||
/// NCCELL_WIDEASIAN_MASK: part of a wide glyph ↓bits view↓ ↓hex mask↓
|
||||
/// 1······· ········ ········ ········ ········ ········ ········ ········ = 8······· ········
|
||||
///
|
||||
/// NCCELL_FGDEFAULT_MASK: foreground is NOT "default color"
|
||||
/// ·1······ ········ ········ ········ ········ ········ ········ ········ = 4······· ········
|
||||
///
|
||||
/// NCCELL_FG_ALPHA_MASK: foreground alpha (2bits)
|
||||
/// ··11···· ········ ········ ········ ········ ········ ········ ········ = 3······· ········
|
||||
///
|
||||
/// NCCELL_FG_PALETTE: foreground uses palette index
|
||||
/// ····1··· ········ ········ ········ ········ ········ ········ ········ = ·8······ ········
|
||||
///
|
||||
/// NCCELL_NOBACKGROUND_MASK: glyph is entirely foreground
|
||||
/// ·····1·· ········ ········ ········ ········ ········ ········ ········ = ·4······ ········
|
||||
///
|
||||
/// reserved, must be 0
|
||||
/// ······00 ········ ········ ········ ········ ········ ········ ········ = ·3······ ········
|
||||
///
|
||||
/// NCCELL_FG_RGB_MASK: foreground in 3x8 RGB (rrggbb)
|
||||
/// ········ 11111111 11111111 11111111 ········ ········ ········ ········ = ··FFFFFF ········
|
||||
/// ```
|
||||
|
||||
/// ```txt
|
||||
/// ~background channel~
|
||||
/// reserved, must be 0 ↓bits view↓ ↓hex mask↓
|
||||
/// ········ ········ ········ ········ 0······· ········ ········ ········ = ········ 8·······
|
||||
///
|
||||
/// NCCELL_BGDEFAULT_MASK: background is NOT "default color"
|
||||
/// ········ ········ ········ ········ ·1······ ········ ········ ········ = ········ 4·······
|
||||
///
|
||||
/// NCCELL_BG_ALPHA_MASK: background alpha (2 bits)
|
||||
/// ········ ········ ········ ········ ··11···· ········ ········ ········ = ········ 3·······
|
||||
///
|
||||
/// NCCELL_BG_PALETTE: background uses palette index
|
||||
/// ········ ········ ········ ········ ····1··· ········ ········ ········ = ········ ·8······
|
||||
///
|
||||
/// reserved, must be 0
|
||||
/// ········ ········ ········ ········ ·····000 ········ ········ ········ = ········ ·7······
|
||||
///
|
||||
/// NCCELL_BG_RGB_MASK: background in 3x8 RGB (rrggbb)
|
||||
/// 0········ ········ ········ ········ ········11111111 11111111 11111111 = ········ ··FFFFFF
|
||||
/// ```
|
||||
/// `type in C: channels (uint64_t)`
|
||||
///
|
||||
/// ## `NcCell` Mask Flags
|
||||
///
|
||||
/// - [`NCCELL_BGDEFAULT_MASK`][crate::NCCELL_BGDEFAULT_MASK]
|
||||
/// - [`NCCELL_BG_ALPHA_MASK`][crate::NCCELL_BG_ALPHA_MASK]
|
||||
/// - [`NCCELL_BG_PALETTE`][crate::NCCELL_BG_PALETTE]
|
||||
/// - [`NCCELL_BG_RGB_MASK`][crate::NCCELL_BG_RGB_MASK]
|
||||
/// - [`NCCELL_FGDEFAULT_MASK`][crate::NCCELL_FGDEFAULT_MASK]
|
||||
/// - [`NCCELL_FG_ALPHA_MASK`][crate::NCCELL_FG_ALPHA_MASK]
|
||||
/// - [`NCCELL_FG_PALETTE`][crate::NCCELL_FG_PALETTE]
|
||||
/// - [`NCCELL_FG_RGB_MASK`][crate::NCCELL_FG_RGB_MASK]
|
||||
/// - [`NCCELL_NOBACKGROUND_MASK`][crate::NCCELL_NOBACKGROUND_MASK]
|
||||
/// - [`NCCELL_WIDEASIAN_MASK`][crate::NCCELL_WIDEASIAN_MASK]
|
||||
///
|
||||
pub type NcChannelPair = u64;
|
||||
|
||||
// NcRgb
|
||||
//
|
||||
/// 24 bits broken into 3x 8bpp channels.
|
||||
///
|
||||
/// Unlike with [`NcChannel`], operations involving `NcRgb` ignores the last 4th byte
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// -------- RRRRRRRR GGGGGGGG BBBBBBBB
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: no data type`
|
||||
///
|
||||
pub type NcRgb = u32;
|
||||
|
||||
// NcColor
|
||||
//
|
||||
/// 8 bits representing a R/G/B color or alpha channel
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// CCCCCCCC (1 Byte)
|
||||
/// ```
|
||||
///
|
||||
/// `type in C: no data type`
|
||||
///
|
||||
pub type NcColor = u8;
|
||||
|
||||
// NcPixel (RGBA)
|
||||
/// 32 bits broken into RGB + 8-bit alpha
|
||||
///
|
||||
/// NcPixel has 8 bits of alpha, more or less linear, contributing
|
||||
/// directly to the usual alpha blending equation.
|
||||
///
|
||||
/// We map the 8 bits of alpha to 2 bits of alpha via a level function:
|
||||
/// https://nick-black.com/dankwiki/index.php?title=Notcurses#Transparency.2FContrasting
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// AAAAAAAA GGGGGGGG BBBBBBBB RRRRRRRR
|
||||
/// ```
|
||||
/// `type in C: ncpixel (uint32_t)`
|
||||
///
|
||||
// NOTE: the order of the colors is different than in NcChannel.
|
||||
pub type NcPixel = u32;
|
||||
|
||||
/// NcPalette structure consisting of an array of 256 [`NcChannel`]s.
|
||||
///
|
||||
/// See also [NcPaletteIndex].
|
||||
///
|
||||
/// Some terminals only support 256 colors, but allow the full
|
||||
/// palette to be specified with arbitrary RGB colors. In all cases, it's more
|
||||
/// performant to use indexed colors, since it's much less data to write to the
|
||||
/// terminal. If you can limit yourself to 256 colors, that's probably best.
|
||||
///
|
||||
/// `type in C: ncpalette256 (struct)`
|
||||
///
|
||||
pub type NcPalette = crate::bindings::bindgen::palette256;
|
||||
|
||||
/// 8-bit value used for indexing into a [`NcPalette`]
|
||||
///
|
||||
pub type NcPaletteIndex = u8;
|
||||
|
||||
/// Context for a palette fade operation
|
||||
pub type NcFadeCtx = crate::bindings::bindgen::ncfadectx;
|
||||
|
||||
/// the [`NcChar`] which form the various levels
|
||||
/// of a given geometry.
|
||||
///
|
||||
/// If the geometry is wide, things are arranged with the rightmost side
|
||||
/// increasing most quickly, i.e. it can be indexed as height arrays of
|
||||
/// 1 + height glyphs.
|
||||
/// i.e. The first five braille EGCs are all 0 on the left,
|
||||
/// [0..4] on the right.
|
||||
///
|
||||
/// `type in C: blitset (struct)`
|
||||
///
|
||||
pub type NcBlitSet = crate::bindings::bindgen::blitset;
|
@ -1,3 +1,5 @@
|
||||
//! `NcDirect` methods and associated functions.
|
||||
|
||||
use crate::{ncdirect_init, NcDirect, NcDirectFlags};
|
||||
use core::ptr::{null, null_mut};
|
||||
|
||||
@ -26,9 +28,9 @@ impl NcDirect {
|
||||
}
|
||||
}
|
||||
|
||||
// Explicitly implementing both `Drop` and `Copy` trait on a type is currently
|
||||
// disallowed (rustc --explain E0184)
|
||||
// https://github.com/rust-lang/rust/issues/20126
|
||||
// NOTE: Explicitly implementing both `Drop` and `Copy` trait on a type is
|
||||
// currently disallowed (rustc --explain E0184)
|
||||
// See: https://github.com/rust-lang/rust/issues/20126
|
||||
//
|
||||
// impl Drop for NcDirect {
|
||||
// fn drop(&mut self) {
|
@ -1,53 +1,74 @@
|
||||
//! `NcDirect`
|
||||
|
||||
// functions already exported by bindgen : 38
|
||||
// ------------------------------------------ (done / remaining)
|
||||
// (#) unit tests: 0 / 38
|
||||
// ------------------------------------------
|
||||
// ncdirect_bg_default
|
||||
// ncdirect_bg_palindex
|
||||
// ncdirect_bg_rgb
|
||||
// ncdirect_box
|
||||
// ncdirect_canopen_images
|
||||
// ncdirect_canutf8
|
||||
// ncdirect_clear
|
||||
// ncdirect_cursor_disable
|
||||
// ncdirect_cursor_down
|
||||
// ncdirect_cursor_enable
|
||||
// ncdirect_cursor_left
|
||||
// ncdirect_cursor_move_yx
|
||||
// ncdirect_cursor_pop
|
||||
// ncdirect_cursor_push
|
||||
// ncdirect_cursor_right
|
||||
// ncdirect_cursor_up
|
||||
// ncdirect_cursor_yx
|
||||
// ncdirect_dim_x
|
||||
// ncdirect_dim_y
|
||||
// ncdirect_double_box
|
||||
// ncdirect_fg_default
|
||||
// ncdirect_fg_palindex
|
||||
// ncdirect_fg_rgb
|
||||
// ncdirect_flush
|
||||
// ncdirect_getc
|
||||
// ncdirect_hline_interp
|
||||
// ncdirect_init // wrapped at _new() & _with_flags()
|
||||
// ncdirect_inputready_fd
|
||||
// ncdirect_palette_size
|
||||
// ncdirect_printf_aligned
|
||||
// ncdirect_putstr
|
||||
// ncdirect_render_image
|
||||
// ncdirect_rounded_box
|
||||
// ncdirect_stop
|
||||
// ncdirect_styles_off
|
||||
// ncdirect_styles_on
|
||||
// ncdirect_styles_set
|
||||
// ncdirect_vline_interp
|
||||
// (W) wrap: 1 / 37
|
||||
// (#) test: 0 / 38
|
||||
// ------------------------------------------
|
||||
// ncdirect_bg_default
|
||||
// ncdirect_bg_palindex
|
||||
// ncdirect_bg_rgb
|
||||
// ncdirect_box
|
||||
// ncdirect_canopen_images
|
||||
// ncdirect_canutf8
|
||||
// ncdirect_clear
|
||||
// ncdirect_cursor_disable
|
||||
// ncdirect_cursor_down
|
||||
// ncdirect_cursor_enable
|
||||
// ncdirect_cursor_left
|
||||
// ncdirect_cursor_move_yx
|
||||
// ncdirect_cursor_pop
|
||||
// ncdirect_cursor_push
|
||||
// ncdirect_cursor_right
|
||||
// ncdirect_cursor_up
|
||||
// ncdirect_cursor_yx
|
||||
// ncdirect_dim_x
|
||||
// ncdirect_dim_y
|
||||
// ncdirect_double_box
|
||||
// ncdirect_fg_default
|
||||
// ncdirect_fg_palindex
|
||||
// ncdirect_fg_rgb
|
||||
// ncdirect_flush
|
||||
// ncdirect_getc
|
||||
// ncdirect_hline_interp
|
||||
//W ncdirect_init
|
||||
// ncdirect_inputready_fd
|
||||
// ncdirect_palette_size
|
||||
// ncdirect_printf_aligned
|
||||
// ncdirect_putstr
|
||||
// ncdirect_render_image
|
||||
// ncdirect_rounded_box
|
||||
// ncdirect_stop
|
||||
// ncdirect_styles_off
|
||||
// ncdirect_styles_on
|
||||
// ncdirect_styles_set
|
||||
// ncdirect_vline_interp
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod test;
|
||||
|
||||
mod types;
|
||||
pub use types::{
|
||||
NcDirect, NcDirectFlags, NCDIRECT_OPTION_INHIBIT_CBREAK, NCDIRECT_OPTION_INHIBIT_SETLOCALE,
|
||||
};
|
||||
mod methods;
|
||||
|
||||
mod wrapped;
|
||||
pub use wrapped::*;
|
||||
/// Minimal notcurses instances for styling text
|
||||
pub type NcDirect = crate::bindings::bindgen::ncdirect;
|
||||
|
||||
/// Flags (options) for [`NcDirect`]
|
||||
pub type NcDirectFlags = u64;
|
||||
|
||||
/// Flag that avoids placing the terminal into cbreak mode
|
||||
/// (disabling echo and line buffering)
|
||||
///
|
||||
pub const NCDIRECT_OPTION_INHIBIT_CBREAK: NcDirectFlags =
|
||||
crate::bindings::bindgen::NCDIRECT_OPTION_INHIBIT_CBREAK as NcDirectFlags;
|
||||
|
||||
/// Flag that avoids calling setlocale(LC_ALL, NULL)
|
||||
///
|
||||
/// If the result is either "C" or "POSIX", it will print a
|
||||
/// diagnostic to stderr, and then call setlocale(LC_ALL, "").
|
||||
///
|
||||
/// This will attempt to set the locale based off the LANG
|
||||
/// environment variable. Your program should call setlocale(3)
|
||||
/// itself, usually as one of the first lines.
|
||||
///
|
||||
pub const NCDIRECT_OPTION_INHIBIT_SETLOCALE: NcDirectFlags =
|
||||
crate::bindings::bindgen::NCDIRECT_OPTION_INHIBIT_SETLOCALE as NcDirectFlags;
|
||||
|
@ -1,25 +0,0 @@
|
||||
//! Types related with `NcDirect`
|
||||
|
||||
/// Minimal notcurses instances for styling text
|
||||
pub type NcDirect = crate::bindings::bindgen::ncdirect;
|
||||
|
||||
/// Flags (options) for [`NcDirect`]
|
||||
pub type NcDirectFlags = u64;
|
||||
|
||||
/// Flag that avoids placing the terminal into cbreak mode
|
||||
/// (disabling echo and line buffering)
|
||||
///
|
||||
pub const NCDIRECT_OPTION_INHIBIT_CBREAK: NcDirectFlags =
|
||||
crate::bindings::bindgen::NCDIRECT_OPTION_INHIBIT_CBREAK as NcDirectFlags;
|
||||
|
||||
/// Flag that avoids calling setlocale(LC_ALL, NULL)
|
||||
///
|
||||
/// If the result is either "C" or "POSIX", it will print a
|
||||
/// diagnostic to stderr, and then call setlocale(LC_ALL, "").
|
||||
///
|
||||
/// This will attempt to set the locale based off the LANG
|
||||
/// environment variable. Your program should call setlocale(3)
|
||||
/// itself, usually as one of the first lines.
|
||||
///
|
||||
pub const NCDIRECT_OPTION_INHIBIT_SETLOCALE: NcDirectFlags =
|
||||
crate::bindings::bindgen::NCDIRECT_OPTION_INHIBIT_SETLOCALE as NcDirectFlags;
|
@ -1,12 +1,11 @@
|
||||
// functions already exported by bindgen : 0
|
||||
// -----------------------------------------
|
||||
//
|
||||
// static inline functions total: 1
|
||||
// ------------------------------------------ (done / remaining)
|
||||
//! `NcInput`
|
||||
|
||||
// functions manually reimplemented: 1
|
||||
// ------------------------------------------
|
||||
// (+) done: 1 / 0
|
||||
// (#) test: 0 / 1
|
||||
// ------------------------------------------
|
||||
//+ ncinput_equal_p
|
||||
// + ncinput_equal_p
|
||||
|
||||
/// Reads and decodes input events
|
||||
///
|
||||
@ -16,7 +15,7 @@
|
||||
/// To exit, generate EOF (usually Ctrl+‘d’).
|
||||
pub type NcInput = crate::bindings::bindgen::ncinput;
|
||||
|
||||
/// Compare two ncinput structs for data equality by doing a field-by-field
|
||||
/// Compares two ncinput structs for data equality by doing a field-by-field
|
||||
/// comparison for equality (excepting seqnum).
|
||||
///
|
||||
/// Returns true if the two are data-equivalent.
|
||||
@ -31,6 +30,7 @@ pub fn ncinput_equal_p(n1: NcInput, n2: NcInput) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// New `NcInput`.
|
||||
impl NcInput {
|
||||
pub fn new() -> NcInput {
|
||||
NcInput {
|
||||
|
@ -1,13 +1,10 @@
|
||||
// functions already exported by bindgen : 0
|
||||
// functions manually reimplemented: 2
|
||||
// ------------------------------------------
|
||||
//
|
||||
// static inline functions total: 2
|
||||
// ------------------------------------------ (done / remaining)
|
||||
// (+) done: 2 / 0
|
||||
// (#) test: 0 / 2
|
||||
// ------------------------------------------
|
||||
//+ nckey_mouse_p
|
||||
//+ nckey_supppuab_p
|
||||
// + nckey_mouse_p
|
||||
// + nckey_supppuab_p
|
||||
|
||||
use crate::{NCKEY_BUTTON1, NCKEY_RELEASE};
|
||||
|
||||
@ -26,15 +23,3 @@ pub fn nckey_supppuab_p(w: u32) -> bool {
|
||||
pub fn nckey_mouse_p(r: u32) -> bool {
|
||||
r >= NCKEY_BUTTON1 && r <= NCKEY_RELEASE
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::nc;
|
||||
// use serial_test::serial;
|
||||
/*
|
||||
#[test]
|
||||
#[serial]
|
||||
fn () {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
|
||||
mod bindings;
|
||||
#[doc(inline)]
|
||||
pub use bindings::*;
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Macros
|
||||
|
||||
// General Utility Macros ------------------------------------------------------
|
||||
|
||||
/// Sleeps for $ms milliseconds
|
||||
#[macro_export]
|
||||
macro_rules! sleep {
|
||||
@ -13,5 +15,5 @@ macro_rules! sleep {
|
||||
macro_rules! cstring {
|
||||
($s:expr) => {
|
||||
std::ffi::CString::new($s).unwrap().as_ptr();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Handy [`Notcurses`] and [`NotcursesOptions`] constructors
|
||||
//! `Notcurses*` methods and associated functions.
|
||||
|
||||
use core::ptr::{null, null_mut};
|
||||
|
||||
@ -7,7 +7,8 @@ use crate::{
|
||||
NCOPTION_SUPPRESS_BANNERS,
|
||||
};
|
||||
use crate::{
|
||||
notcurses_stdplane, NcPlane, notcurses_stop, NcResult, notcurses_render,
|
||||
notcurses_render, notcurses_stdplane, notcurses_stdplane_const, notcurses_stop, NcPlane,
|
||||
NcResult,
|
||||
};
|
||||
|
||||
/// # `NotcursesOptions` Constructors
|
||||
@ -113,21 +114,34 @@ impl Notcurses {
|
||||
|
||||
/// # `Notcurses` methods
|
||||
impl Notcurses {
|
||||
// reference, ... I need an NcPlane from this...
|
||||
// pub fn stdplane_mut2(&mut self) -> *mut NcPlane {
|
||||
// unsafe { notcurses_stdplane(self) }
|
||||
// }
|
||||
|
||||
///
|
||||
pub fn stdplane_mut(&mut self) -> NcPlane {
|
||||
unsafe { *notcurses_stdplane(self) }
|
||||
//notcurses_stdplane_const //???
|
||||
/// Returns a mutable reference to the standard [NcPlane] for this terminal.
|
||||
///
|
||||
/// The standard plane always exists, and its origin is always at the
|
||||
/// uppermost, leftmost cell.
|
||||
pub fn stdplane_mut<'a>(&mut self) -> &'a mut NcPlane {
|
||||
unsafe { &mut *notcurses_stdplane(self) }
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a reference to the standard [NcPlane] for this terminal.
|
||||
///
|
||||
/// The standard plane always exists, and its origin is always at the
|
||||
/// uppermost, leftmost cell.
|
||||
pub fn stdplane<'a>(&self) -> &'a NcPlane {
|
||||
unsafe { &*notcurses_stdplane_const(self) }
|
||||
}
|
||||
|
||||
///
|
||||
pub fn stop(&mut self) -> NcResult {
|
||||
unsafe { notcurses_stop(self) }
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
pub fn render(&mut self) -> NcResult {
|
||||
unsafe { notcurses_render(self) }
|
||||
}
|
||||
|
||||
}
|
@ -1,159 +1,173 @@
|
||||
//! `Notcurses`
|
||||
|
||||
// functions already exported by bindgen : 39
|
||||
// ----------------------------------------- (done / remaining)
|
||||
// ------------------------------------------
|
||||
// (#) unit tests: 10 / 29
|
||||
// ------------------------------------------
|
||||
// notcurses_at_yx
|
||||
// notcurses_bottom
|
||||
//# notcurses_canchangecolor
|
||||
//# notcurses_canfade
|
||||
//# notcurses_canopen_images
|
||||
//# notcurses_canopen_videos
|
||||
//# notcurses_cansixel
|
||||
//# notcurses_cantruecolor
|
||||
//# notcurses_canutf8
|
||||
// notcurses_cursor_disable
|
||||
// notcurses_cursor_enable
|
||||
//# notcurses_debug
|
||||
//# notcurses_drop_planes
|
||||
// notcurses_getc
|
||||
//# notcurses_init
|
||||
// notcurses_inputready_fd
|
||||
// notcurses_lex_blitter
|
||||
// notcurses_lex_margins
|
||||
// notcurses_lex_scalemode
|
||||
// notcurses_mouse_disable
|
||||
// notcurses_mouse_enable
|
||||
// notcurses_palette_size
|
||||
// notcurses_refresh
|
||||
// notcurses_render
|
||||
// notcurses_render_to_buffer
|
||||
// notcurses_render_to_file
|
||||
// notcurses_stats
|
||||
// notcurses_stats_alloc
|
||||
// notcurses_stats_reset
|
||||
// notcurses_stdplane
|
||||
// notcurses_stdplane_const
|
||||
//# notcurses_stop
|
||||
// notcurses_str_blitter
|
||||
// notcurses_str_scalemode
|
||||
// notcurses_supported_styles
|
||||
// notcurses_top
|
||||
// notcurses_ucs32_to_utf8
|
||||
// notcurses_version
|
||||
// notcurses_version_components
|
||||
// notcurses_at_yx
|
||||
// notcurses_bottom
|
||||
// # notcurses_canchangecolor
|
||||
// # notcurses_canfade
|
||||
// # notcurses_canopen_images
|
||||
// # notcurses_canopen_videos
|
||||
// # notcurses_cansixel
|
||||
// # notcurses_cantruecolor
|
||||
// # notcurses_canutf8
|
||||
// notcurses_cursor_disable
|
||||
// notcurses_cursor_enable
|
||||
// # notcurses_debug
|
||||
// # notcurses_drop_planes
|
||||
// notcurses_getc
|
||||
// # notcurses_init
|
||||
// notcurses_inputready_fd
|
||||
// notcurses_lex_blitter
|
||||
// notcurses_lex_margins
|
||||
// notcurses_lex_scalemode
|
||||
// notcurses_mouse_disable
|
||||
// notcurses_mouse_enable
|
||||
// notcurses_palette_size
|
||||
// notcurses_refresh
|
||||
// notcurses_render
|
||||
// notcurses_render_to_buffer
|
||||
// notcurses_render_to_file
|
||||
// notcurses_stats
|
||||
// notcurses_stats_alloc
|
||||
// notcurses_stats_reset
|
||||
// notcurses_stdplane
|
||||
// notcurses_stdplane_const
|
||||
// # notcurses_stop
|
||||
// notcurses_str_blitter
|
||||
// notcurses_str_scalemode
|
||||
// notcurses_supported_styles
|
||||
// notcurses_top
|
||||
// notcurses_ucs32_to_utf8
|
||||
// notcurses_version
|
||||
// notcurses_version_components
|
||||
//
|
||||
// static inline functions total: 6
|
||||
// ----------------------------------------- (done / remaining)
|
||||
// functions manually reimplemented: 6
|
||||
// -----------------------------------------
|
||||
// (+) implement : 6 / 0
|
||||
// (#) unit tests: 0 / 6
|
||||
// -----------------------------------------
|
||||
//# notcurses_align
|
||||
//+ notcurses_getc_blocking
|
||||
//+ notcurses_getc_nblock
|
||||
//+ notcurses_stddim_yx
|
||||
//+ notcurses_stddim_yx_const
|
||||
//+ notcurses_term_dim_yx
|
||||
// # notcurses_align
|
||||
// + notcurses_getc_blocking
|
||||
// + notcurses_getc_nblock
|
||||
// + notcurses_stddim_yx
|
||||
// + notcurses_stddim_yx_const
|
||||
// + notcurses_term_dim_yx
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod test;
|
||||
|
||||
mod types;
|
||||
pub use types::{
|
||||
NcLogLevel, Notcurses, NotcursesOptions, NCLOGLEVEL_DEBUG, NCLOGLEVEL_ERROR, NCLOGLEVEL_FATAL,
|
||||
NCLOGLEVEL_INFO, NCLOGLEVEL_PANIC, NCLOGLEVEL_SILENT, NCLOGLEVEL_TRACE, NCLOGLEVEL_VERBOSE,
|
||||
NCLOGLEVEL_WARNING, NCOPTION_INHIBIT_SETLOCALE, NCOPTION_NO_ALTERNATE_SCREEN,
|
||||
NCOPTION_NO_FONT_CHANGES, NCOPTION_NO_QUIT_SIGHANDLERS, NCOPTION_NO_WINCH_SIGHANDLER,
|
||||
NCOPTION_SUPPRESS_BANNERS, NCOPTION_VERIFY_SIXEL,
|
||||
};
|
||||
mod methods;
|
||||
mod reimplemented;
|
||||
pub use reimplemented::*;
|
||||
|
||||
mod wrapped;
|
||||
pub use wrapped::*;
|
||||
/// The main struct of the (full mode) TUI library
|
||||
///
|
||||
/// Notcurses builds atop the terminfo abstraction layer to
|
||||
/// provide reasonably portable vivid character displays.
|
||||
///
|
||||
pub type Notcurses = crate::bindings::bindgen::notcurses;
|
||||
|
||||
use core::ptr::null;
|
||||
/// Options struct for [`Notcurses`]
|
||||
pub type NotcursesOptions = crate::bindings::bindgen::notcurses_options;
|
||||
|
||||
use crate::{
|
||||
// NOTE: can't use libc::sigset_t with notcurses_getc(()
|
||||
bindings::{sigemptyset, sigfillset, sigset_t},
|
||||
ncplane_dim_yx,
|
||||
notcurses_getc,
|
||||
notcurses_stdplane,
|
||||
notcurses_stdplane_const,
|
||||
NcAlign,
|
||||
NcInput,
|
||||
NcPlane,
|
||||
NcTime,
|
||||
NCALIGN_CENTER,
|
||||
NCALIGN_LEFT,
|
||||
};
|
||||
/// Do not call setlocale()
|
||||
///
|
||||
/// notcurses_init() will call setlocale() to inspect the current locale. If
|
||||
/// that locale is "C" or "POSIX", it will call setlocale(LC_ALL, "") to set
|
||||
/// the locale according to the LANG environment variable. Ideally, this will
|
||||
/// result in UTF8 being enabled, even if the client app didn't call
|
||||
/// setlocale() itself. Unless you're certain that you're invoking setlocale()
|
||||
/// prior to notcurses_init(), you should not set this bit. Even if you are
|
||||
/// invoking setlocale(), this behavior shouldn't be an issue unless you're
|
||||
/// doing something weird (setting a locale not based on LANG).
|
||||
pub const NCOPTION_INHIBIT_SETLOCALE: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_INHIBIT_SETLOCALE as u64;
|
||||
|
||||
/// return the offset into 'availcols' at which 'cols' ought be output given the requirements of 'align'
|
||||
#[inline]
|
||||
pub fn notcurses_align(availcols: i32, align: NcAlign, cols: i32) -> i32 {
|
||||
if align == NCALIGN_LEFT {
|
||||
return 0;
|
||||
}
|
||||
if cols > availcols {
|
||||
return 0;
|
||||
}
|
||||
if align == NCALIGN_CENTER {
|
||||
return (availcols - cols) / 2;
|
||||
}
|
||||
availcols - cols // NCALIGN_RIGHT
|
||||
}
|
||||
/// Do not enter alternate mode.
|
||||
///
|
||||
/// If smcup/rmcup capabilities are indicated, Notcurses defaults to making use
|
||||
/// of the "alternate screen". This flag inhibits use of smcup/rmcup.
|
||||
pub const NCOPTION_NO_ALTERNATE_SCREEN: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_NO_ALTERNATE_SCREEN as u64;
|
||||
|
||||
/// 'input' may be NULL if the caller is uninterested in event details.
|
||||
/// If no event is ready, returns 0.
|
||||
// TODO: use pakr-signals
|
||||
#[inline]
|
||||
pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char {
|
||||
unsafe {
|
||||
let mut sigmask = sigset_t { __val: [0; 16] };
|
||||
sigfillset(&mut sigmask);
|
||||
let ts = NcTime {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
};
|
||||
core::char::from_u32_unchecked(notcurses_getc(nc, &ts, &mut sigmask, input))
|
||||
}
|
||||
}
|
||||
/// Do not modify the font.
|
||||
///
|
||||
/// Notcurses might attempt to change the font slightly, to support certain
|
||||
/// glyphs (especially on the Linux console). If this is set, no such
|
||||
/// modifications will be made. Note that font changes will not affect anything
|
||||
/// but the virtual console/terminal in which Notcurses is running.
|
||||
pub const NCOPTION_NO_FONT_CHANGES: u64 = crate::bindings::bindgen::NCOPTION_NO_FONT_CHANGES as u64;
|
||||
|
||||
/// 'input' may be NULL if the caller is uninterested in event details.
|
||||
/// Blocks until an event is processed or a signal is received.
|
||||
#[inline]
|
||||
pub fn notcurses_getc_nblocking(nc: &mut Notcurses, input: &mut NcInput) -> char {
|
||||
unsafe {
|
||||
let mut sigmask = sigset_t { __val: [0; 16] };
|
||||
sigemptyset(&mut sigmask);
|
||||
core::char::from_u32_unchecked(notcurses_getc(nc, null(), &mut sigmask, input))
|
||||
}
|
||||
}
|
||||
/// Do not handle SIG{ING, SEGV, ABRT, QUIT}
|
||||
///
|
||||
/// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
||||
/// restores the screen, and then calls the old signal handler. Set to inhibit
|
||||
/// registration of these signal handlers.
|
||||
pub const NCOPTION_NO_QUIT_SIGHANDLERS: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_NO_QUIT_SIGHANDLERS as u64;
|
||||
|
||||
/// notcurses_stdplane(), plus free bonus dimensions written to non-NULL y/x!
|
||||
#[inline]
|
||||
pub fn notcurses_stddim_yx(nc: &mut Notcurses, y: &mut i32, x: &mut i32) -> NcPlane {
|
||||
unsafe {
|
||||
let s = notcurses_stdplane(nc);
|
||||
ncplane_dim_yx(s, y, x);
|
||||
*s
|
||||
}
|
||||
}
|
||||
/// Do not handle SIGWINCH
|
||||
///
|
||||
/// We typically install a signal handler for SIGWINCH that generates a resize
|
||||
/// event in the notcurses_getc() queue. Set to inhibit this handler
|
||||
pub const NCOPTION_NO_WINCH_SIGHANDLER: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_NO_WINCH_SIGHANDLER as u64;
|
||||
|
||||
/// notcurses_stdplane_const(), plus free bonus dimensions written to non-NULL y/x!
|
||||
#[inline]
|
||||
pub fn notcurses_stddim_yx_const(nc: &Notcurses, y: &mut i32, x: &mut i32) -> NcPlane {
|
||||
unsafe {
|
||||
let s = notcurses_stdplane_const(nc);
|
||||
ncplane_dim_yx(s, y, x);
|
||||
*s
|
||||
}
|
||||
}
|
||||
/// Do not print banners
|
||||
///
|
||||
/// Notcurses typically prints version info in notcurses_init() and performance
|
||||
/// info in notcurses_stop(). This inhibits that output.
|
||||
pub const NCOPTION_SUPPRESS_BANNERS: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_SUPPRESS_BANNERS as u64;
|
||||
|
||||
/// Return our current idea of the terminal dimensions in rows and cols.
|
||||
#[inline]
|
||||
pub fn notcurses_term_dim_yx(nc: &Notcurses, rows: &mut u32, cols: &mut u32) {
|
||||
unsafe {
|
||||
let mut irows = *rows as i32;
|
||||
let mut icols = *cols as i32;
|
||||
ncplane_dim_yx(notcurses_stdplane_const(nc), &mut irows, &mut icols);
|
||||
}
|
||||
}
|
||||
/// Test for Sixel support
|
||||
///
|
||||
/// Checking for Sixel support requires writing an escape, and then reading an
|
||||
/// inline reply from the terminal. Since this can interact poorly with actual
|
||||
/// user input, it's not done unless Sixel will actually be used. Set this flag
|
||||
/// to unconditionally test for Sixel support in notcurses_init().
|
||||
pub const NCOPTION_VERIFY_SIXEL: u64 = crate::bindings::bindgen::NCOPTION_VERIFY_SIXEL as u64;
|
||||
|
||||
// NcLogLevel ------------------------------------------------------------------
|
||||
|
||||
/// Log level for [`NotcursesOptions`]
|
||||
///
|
||||
/// These log levels consciously map cleanly to those of libav; Notcurses itself
|
||||
/// does not use this full granularity. The log level does not affect the opening
|
||||
/// and closing banners, which can be disabled via the `NotcursesOptions`
|
||||
/// `NCOPTION_SUPPRESS_BANNERS`.
|
||||
/// Note that if stderr is connected to the same terminal on which we're
|
||||
/// rendering, any kind of logging will disrupt the output.
|
||||
pub type NcLogLevel = crate::bindings::bindgen::ncloglevel_e;
|
||||
|
||||
/// this is honestly a bit much
|
||||
pub const NCLOGLEVEL_DEBUG: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_DEBUG;
|
||||
|
||||
/// we can't keep doin' this, but we can do other things
|
||||
pub const NCLOGLEVEL_ERROR: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_ERROR;
|
||||
|
||||
/// we're hanging around, but we've had a horrible fault
|
||||
pub const NCLOGLEVEL_FATAL: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_FATAL;
|
||||
|
||||
/// "detailed information
|
||||
pub const NCLOGLEVEL_INFO: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_INFO;
|
||||
|
||||
/// print diagnostics immediately related to crashing
|
||||
pub const NCLOGLEVEL_PANIC: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_PANIC;
|
||||
|
||||
/// default. print nothing once fullscreen service begins
|
||||
pub const NCLOGLEVEL_SILENT: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_SILENT;
|
||||
|
||||
/// there's probably a better way to do what you want
|
||||
pub const NCLOGLEVEL_TRACE: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_TRACE;
|
||||
|
||||
/// "detailed information
|
||||
pub const NCLOGLEVEL_VERBOSE: NcLogLevel =
|
||||
crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_VERBOSE;
|
||||
|
||||
/// you probably don't want what's happening to happen
|
||||
pub const NCLOGLEVEL_WARNING: NcLogLevel =
|
||||
crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_WARNING;
|
||||
|
100
rust/src/notcurses/reimplemented.rs
Normal file
100
rust/src/notcurses/reimplemented.rs
Normal file
@ -0,0 +1,100 @@
|
||||
//! `notcurses_*` reimplemented functions.
|
||||
|
||||
// pub use types::{
|
||||
// NcLogLevel, Notcurses, NotcursesOptions, NCLOGLEVEL_DEBUG, NCLOGLEVEL_ERROR, NCLOGLEVEL_FATAL,
|
||||
// NCLOGLEVEL_INFO, NCLOGLEVEL_PANIC, NCLOGLEVEL_SILENT, NCLOGLEVEL_TRACE, NCLOGLEVEL_VERBOSE,
|
||||
// NCLOGLEVEL_WARNING, NCOPTION_INHIBIT_SETLOCALE, NCOPTION_NO_ALTERNATE_SCREEN,
|
||||
// NCOPTION_NO_FONT_CHANGES, NCOPTION_NO_QUIT_SIGHANDLERS, NCOPTION_NO_WINCH_SIGHANDLER,
|
||||
// NCOPTION_SUPPRESS_BANNERS, NCOPTION_VERIFY_SIXEL,
|
||||
// };
|
||||
//
|
||||
|
||||
use core::ptr::null;
|
||||
|
||||
use crate::{
|
||||
// NOTE: can't use libc::sigset_t with notcurses_getc(()
|
||||
bindings::{sigemptyset, sigfillset, sigset_t},
|
||||
ncplane_dim_yx,
|
||||
notcurses_getc,
|
||||
notcurses_stdplane,
|
||||
notcurses_stdplane_const,
|
||||
NcAlign,
|
||||
NcInput,
|
||||
NcPlane,
|
||||
NcTime,
|
||||
Notcurses,
|
||||
NCALIGN_CENTER,
|
||||
NCALIGN_LEFT,
|
||||
};
|
||||
|
||||
/// return the offset into 'availcols' at which 'cols' ought be output given the requirements of 'align'
|
||||
#[inline]
|
||||
pub fn notcurses_align(availcols: i32, align: NcAlign, cols: i32) -> i32 {
|
||||
if align == NCALIGN_LEFT {
|
||||
return 0;
|
||||
}
|
||||
if cols > availcols {
|
||||
return 0;
|
||||
}
|
||||
if align == NCALIGN_CENTER {
|
||||
return (availcols - cols) / 2;
|
||||
}
|
||||
availcols - cols // NCALIGN_RIGHT
|
||||
}
|
||||
|
||||
/// 'input' may be NULL if the caller is uninterested in event details.
|
||||
/// If no event is ready, returns 0.
|
||||
// TODO: use pakr-signals
|
||||
#[inline]
|
||||
pub fn notcurses_getc_nblock(nc: &mut Notcurses, input: &mut NcInput) -> char {
|
||||
unsafe {
|
||||
let mut sigmask = sigset_t { __val: [0; 16] };
|
||||
sigfillset(&mut sigmask);
|
||||
let ts = NcTime {
|
||||
tv_sec: 0,
|
||||
tv_nsec: 0,
|
||||
};
|
||||
core::char::from_u32_unchecked(notcurses_getc(nc, &ts, &mut sigmask, input))
|
||||
}
|
||||
}
|
||||
|
||||
/// 'input' may be NULL if the caller is uninterested in event details.
|
||||
/// Blocks until an event is processed or a signal is received.
|
||||
#[inline]
|
||||
pub fn notcurses_getc_nblocking(nc: &mut Notcurses, input: &mut NcInput) -> char {
|
||||
unsafe {
|
||||
let mut sigmask = sigset_t { __val: [0; 16] };
|
||||
sigemptyset(&mut sigmask);
|
||||
core::char::from_u32_unchecked(notcurses_getc(nc, null(), &mut sigmask, input))
|
||||
}
|
||||
}
|
||||
|
||||
/// notcurses_stdplane(), plus free bonus dimensions written to non-NULL y/x!
|
||||
#[inline]
|
||||
pub fn notcurses_stddim_yx(nc: &mut Notcurses, y: &mut i32, x: &mut i32) -> NcPlane {
|
||||
unsafe {
|
||||
let s = notcurses_stdplane(nc);
|
||||
ncplane_dim_yx(s, y, x);
|
||||
*s
|
||||
}
|
||||
}
|
||||
|
||||
/// notcurses_stdplane_const(), plus free bonus dimensions written to non-NULL y/x!
|
||||
#[inline]
|
||||
pub fn notcurses_stddim_yx_const(nc: &Notcurses, y: &mut i32, x: &mut i32) -> NcPlane {
|
||||
unsafe {
|
||||
let s = notcurses_stdplane_const(nc);
|
||||
ncplane_dim_yx(s, y, x);
|
||||
*s
|
||||
}
|
||||
}
|
||||
|
||||
/// Return our current idea of the terminal dimensions in rows and cols.
|
||||
#[inline]
|
||||
pub fn notcurses_term_dim_yx(nc: &Notcurses, rows: &mut u32, cols: &mut u32) {
|
||||
unsafe {
|
||||
let mut irows = *rows as i32;
|
||||
let mut icols = *cols as i32;
|
||||
ncplane_dim_yx(notcurses_stdplane_const(nc), &mut irows, &mut icols);
|
||||
}
|
||||
}
|
4
rust/src/notcurses/test/methods.rs
Normal file
4
rust/src/notcurses/test/methods.rs
Normal file
@ -0,0 +1,4 @@
|
||||
//! Test `Notcurses` methods and associated functions.
|
||||
|
||||
// use crate::Notcurses;
|
||||
// use serial_test::serial;
|
7
rust/src/notcurses/test/mod.rs
Normal file
7
rust/src/notcurses/test/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
//! `Notcurses` tests.
|
||||
|
||||
#[cfg(test)]
|
||||
mod methods;
|
||||
|
||||
#[cfg(test)]
|
||||
mod reimplemented;
|
@ -1,4 +1,4 @@
|
||||
//! [`Notcurses`] tests
|
||||
//! Test `notcurses_*` reimplemented functions.
|
||||
|
||||
use serial_test::serial;
|
||||
use std::io::Read;
|
@ -1,110 +0,0 @@
|
||||
//! Types related with `Notcurses`
|
||||
|
||||
/// The main struct of the (full mode) TUI library
|
||||
///
|
||||
/// Notcurses builds atop the terminfo abstraction layer to
|
||||
/// provide reasonably portable vivid character displays.
|
||||
///
|
||||
pub type Notcurses = crate::bindings::bindgen::notcurses;
|
||||
|
||||
/// Options struct for [`Notcurses`]
|
||||
pub type NotcursesOptions = crate::bindings::bindgen::notcurses_options;
|
||||
|
||||
/// Do not call setlocale()
|
||||
///
|
||||
/// notcurses_init() will call setlocale() to inspect the current locale. If
|
||||
/// that locale is "C" or "POSIX", it will call setlocale(LC_ALL, "") to set
|
||||
/// the locale according to the LANG environment variable. Ideally, this will
|
||||
/// result in UTF8 being enabled, even if the client app didn't call
|
||||
/// setlocale() itself. Unless you're certain that you're invoking setlocale()
|
||||
/// prior to notcurses_init(), you should not set this bit. Even if you are
|
||||
/// invoking setlocale(), this behavior shouldn't be an issue unless you're
|
||||
/// doing something weird (setting a locale not based on LANG).
|
||||
pub const NCOPTION_INHIBIT_SETLOCALE: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_INHIBIT_SETLOCALE as u64;
|
||||
|
||||
/// Do not enter alternate mode.
|
||||
///
|
||||
/// If smcup/rmcup capabilities are indicated, Notcurses defaults to making use
|
||||
/// of the "alternate screen". This flag inhibits use of smcup/rmcup.
|
||||
pub const NCOPTION_NO_ALTERNATE_SCREEN: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_NO_ALTERNATE_SCREEN as u64;
|
||||
|
||||
/// Do not modify the font.
|
||||
///
|
||||
/// Notcurses might attempt to change the font slightly, to support certain
|
||||
/// glyphs (especially on the Linux console). If this is set, no such
|
||||
/// modifications will be made. Note that font changes will not affect anything
|
||||
/// but the virtual console/terminal in which Notcurses is running.
|
||||
pub const NCOPTION_NO_FONT_CHANGES: u64 = crate::bindings::bindgen::NCOPTION_NO_FONT_CHANGES as u64;
|
||||
|
||||
/// Do not handle SIG{ING, SEGV, ABRT, QUIT}
|
||||
///
|
||||
/// We typically install a signal handler for SIG{INT, SEGV, ABRT, QUIT} that
|
||||
/// restores the screen, and then calls the old signal handler. Set to inhibit
|
||||
/// registration of these signal handlers.
|
||||
pub const NCOPTION_NO_QUIT_SIGHANDLERS: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_NO_QUIT_SIGHANDLERS as u64;
|
||||
|
||||
/// Do not handle SIGWINCH
|
||||
///
|
||||
/// We typically install a signal handler for SIGWINCH that generates a resize
|
||||
/// event in the notcurses_getc() queue. Set to inhibit this handler
|
||||
pub const NCOPTION_NO_WINCH_SIGHANDLER: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_NO_WINCH_SIGHANDLER as u64;
|
||||
|
||||
/// Do not print banners
|
||||
///
|
||||
/// Notcurses typically prints version info in notcurses_init() and performance
|
||||
/// info in notcurses_stop(). This inhibits that output.
|
||||
pub const NCOPTION_SUPPRESS_BANNERS: u64 =
|
||||
crate::bindings::bindgen::NCOPTION_SUPPRESS_BANNERS as u64;
|
||||
|
||||
/// Test for Sixel support
|
||||
///
|
||||
/// Checking for Sixel support requires writing an escape, and then reading an
|
||||
/// inline reply from the terminal. Since this can interact poorly with actual
|
||||
/// user input, it's not done unless Sixel will actually be used. Set this flag
|
||||
/// to unconditionally test for Sixel support in notcurses_init().
|
||||
pub const NCOPTION_VERIFY_SIXEL: u64 = crate::bindings::bindgen::NCOPTION_VERIFY_SIXEL as u64;
|
||||
|
||||
// NcLogLevel ------------------------------------------------------------------
|
||||
|
||||
/// Log level for [`NotcursesOptions`]
|
||||
///
|
||||
/// These log levels consciously map cleanly to those of libav; Notcurses itself
|
||||
/// does not use this full granularity. The log level does not affect the opening
|
||||
/// and closing banners, which can be disabled via the `NotcursesOptions`
|
||||
/// `NCOPTION_SUPPRESS_BANNERS`.
|
||||
/// Note that if stderr is connected to the same terminal on which we're
|
||||
/// rendering, any kind of logging will disrupt the output.
|
||||
pub type NcLogLevel = crate::bindings::bindgen::ncloglevel_e;
|
||||
|
||||
/// this is honestly a bit much
|
||||
pub const NCLOGLEVEL_DEBUG: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_DEBUG;
|
||||
|
||||
/// we can't keep doin' this, but we can do other things
|
||||
pub const NCLOGLEVEL_ERROR: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_ERROR;
|
||||
|
||||
/// we're hanging around, but we've had a horrible fault
|
||||
pub const NCLOGLEVEL_FATAL: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_FATAL;
|
||||
|
||||
/// "detailed information
|
||||
pub const NCLOGLEVEL_INFO: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_INFO;
|
||||
|
||||
/// print diagnostics immediately related to crashing
|
||||
pub const NCLOGLEVEL_PANIC: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_PANIC;
|
||||
|
||||
/// default. print nothing once fullscreen service begins
|
||||
pub const NCLOGLEVEL_SILENT: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_SILENT;
|
||||
|
||||
/// there's probably a better way to do what you want
|
||||
pub const NCLOGLEVEL_TRACE: NcLogLevel = crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_TRACE;
|
||||
|
||||
/// "detailed information
|
||||
pub const NCLOGLEVEL_VERBOSE: NcLogLevel =
|
||||
crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_VERBOSE;
|
||||
|
||||
/// you probably don't want what's happening to happen
|
||||
pub const NCLOGLEVEL_WARNING: NcLogLevel =
|
||||
crate::bindings::bindgen::ncloglevel_e_NCLOGLEVEL_WARNING;
|
42
rust/src/palette/mod.rs
Normal file
42
rust/src/palette/mod.rs
Normal file
@ -0,0 +1,42 @@
|
||||
//! `NcPalette*`
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Now none of these functions can't fail and therefore don't return errors.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// functions already exported by bindgen : 3
|
||||
// -----------------------------------------
|
||||
// (#) unit tests: 0 / 3
|
||||
// -----------------------------------------
|
||||
// palette256_free
|
||||
// palette256_new
|
||||
// palette256_use
|
||||
//
|
||||
// functions manually reimplemented: 3
|
||||
// -----------------------------------------
|
||||
// (+) implement : 3 / 0
|
||||
// (#) unit tests: 0 / 3
|
||||
// -----------------------------------------
|
||||
// + palette256_get_rgb
|
||||
// + palette256_set
|
||||
// + palette256_set_rgb
|
||||
|
||||
pub mod reimplemented;
|
||||
pub use reimplemented::*;
|
||||
|
||||
/// NcPalette structure consisting of an array of 256 [`NcChannel`]s.
|
||||
///
|
||||
/// See also [NcPaletteIndex].
|
||||
///
|
||||
/// Some terminals only support 256 colors, but allow the full
|
||||
/// palette to be specified with arbitrary RGB colors. In all cases, it's more
|
||||
/// performant to use indexed colors, since it's much less data to write to the
|
||||
/// terminal. If you can limit yourself to 256 colors, that's probably best.
|
||||
///
|
||||
/// `type in C: ncpalette256 (struct)`
|
||||
///
|
||||
pub type NcPalette = crate::bindings::bindgen::palette256;
|
||||
|
||||
/// 8-bit value used for indexing into a [`NcPalette`]
|
||||
///
|
||||
pub type NcPaletteIndex = u8;
|
@ -1,21 +1,4 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// Now none of these functions can't fail and therefore don't return errors.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// functions already exported by bindgen : 3
|
||||
// -----------------------------------------
|
||||
// palette256_free
|
||||
// palette256_new
|
||||
// palette256_use
|
||||
//
|
||||
// static inline functions total: 3
|
||||
// ----------------------------------------- (done / remaining)
|
||||
// (+) implement : 3 / 0
|
||||
// (#) unit tests: 0 / 3
|
||||
// -----------------------------------------
|
||||
//+ palette256_get_rgb
|
||||
//+ palette256_set
|
||||
//+ palette256_set_rgb
|
||||
//! `palette256_*` reimplemented functions.
|
||||
|
||||
use crate::{
|
||||
channel_rgb8, channel_set, channel_set_rgb8, NcChannel, NcColor, NcPalette, NcPaletteIndex,
|
||||
@ -51,15 +34,3 @@ pub fn palette256_get_rgb(
|
||||
) -> NcChannel {
|
||||
channel_rgb8(palette.chans[idx as usize], red, green, blue)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::nc;
|
||||
// use serial_test::serial;
|
||||
/*
|
||||
#[test]
|
||||
#[serial]
|
||||
fn () {
|
||||
}
|
||||
*/
|
||||
}
|
@ -7,34 +7,42 @@
|
||||
//
|
||||
// - NOTE: None of the functions can't fail anymore and don't have to return an error.
|
||||
//
|
||||
//
|
||||
// functions already exported by bindgen : 0
|
||||
// -----------------------------------------
|
||||
//
|
||||
// static inline functions total: 10
|
||||
// ------------------------------------------ (done / remaining)
|
||||
// functions manually reimplemented: 10
|
||||
// ------------------------------------------
|
||||
// (+) implement : 10 / 0
|
||||
// (#) unit tests: 0 / 10
|
||||
// ------------------------------------------
|
||||
//+ ncpixel
|
||||
//+ ncpixel_a
|
||||
//+ ncpixel_b
|
||||
//+ ncpixel_g
|
||||
//+ ncpixel_r
|
||||
//+ ncpixel_set_a
|
||||
//+ ncpixel_set_b
|
||||
//+ ncpixel_set_g
|
||||
//+ ncpixel_set_r
|
||||
//+ ncpixel_set_rgb
|
||||
// + ncpixel
|
||||
// + ncpixel_a
|
||||
// + ncpixel_b
|
||||
// + ncpixel_g
|
||||
// + ncpixel_r
|
||||
// + ncpixel_set_a
|
||||
// + ncpixel_set_b
|
||||
// + ncpixel_set_g
|
||||
// + ncpixel_set_r
|
||||
// + ncpixel_set_rgb
|
||||
|
||||
use crate::{NcColor, NcPixel};
|
||||
use crate::NcColor;
|
||||
|
||||
// NcPixel Structure:
|
||||
//
|
||||
// 0xff000000 8 bit Alpha
|
||||
// 0x00ff0000 8 bit Green
|
||||
// 0x0000ff00 8 bit Blue
|
||||
// 0x000000ff 8 bit Red
|
||||
// NcPixel (RGBA)
|
||||
/// 32 bits broken into RGB + 8-bit alpha
|
||||
///
|
||||
/// NcPixel has 8 bits of alpha, more or less linear, contributing
|
||||
/// directly to the usual alpha blending equation.
|
||||
///
|
||||
/// We map the 8 bits of alpha to 2 bits of alpha via a level function:
|
||||
/// https://nick-black.com/dankwiki/index.php?title=Notcurses#Transparency.2FContrasting
|
||||
///
|
||||
/// ## Diagram
|
||||
///
|
||||
/// ```txt
|
||||
/// AAAAAAAA GGGGGGGG BBBBBBBB RRRRRRRR
|
||||
/// ```
|
||||
/// `type in C: ncpixel (uint32_t)`
|
||||
///
|
||||
// NOTE: the order of the colors is different than in NcChannel.
|
||||
pub type NcPixel = u32;
|
||||
|
||||
/// Get an RGB pixel from RGB values
|
||||
pub fn ncpixel(r: NcColor, g: NcColor, b: NcColor) -> NcPixel {
|
||||
@ -87,15 +95,3 @@ pub fn ncpixel_set_rgb(pixel: &mut NcPixel, red: NcColor, green: NcColor, blue:
|
||||
ncpixel_set_g(pixel, green);
|
||||
ncpixel_set_b(pixel, blue);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::nc;
|
||||
// use serial_test::serial;
|
||||
/*
|
||||
#[test]
|
||||
#[serial]
|
||||
fn () {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Handy [`NcPlane`] and [`NcPlaneOptions`] constructors
|
||||
//! `NcPlane*` methods and associated functions.
|
||||
|
||||
use core::ptr::{null, null_mut};
|
||||
|
||||
@ -10,7 +10,8 @@ use crate::{
|
||||
|
||||
// for methods
|
||||
use crate::{
|
||||
NcCell, NcResult, ncplane_cursor_yx, ncplane_dim_yx, ncplane_erase, ncplane_putc, ncplane_putc_yx,
|
||||
ncpile_bottom, ncpile_top, ncplane_cursor_yx, ncplane_dim_yx, ncplane_erase, ncplane_putc,
|
||||
ncplane_putc_yx, NcCell, NcResult,
|
||||
};
|
||||
|
||||
/// # `NcPlaneOptions` Constructors
|
||||
@ -104,6 +105,11 @@ impl NcPlane {
|
||||
|
||||
/// # `NcPlane` Methods
|
||||
impl NcPlane {
|
||||
/// Returns the bottommost [NcPlane] of the pile that contains this [NnPlane].
|
||||
pub fn bottom<'a>(&mut self) -> &'a mut NcPlane {
|
||||
unsafe { &mut *ncpile_bottom(self) }
|
||||
}
|
||||
|
||||
/// Returns the current position of the cursor within the [NcPlane].
|
||||
///
|
||||
/// Unlike [ncplane_cursor_yx] which uses `i32`, this uses [u32].
|
||||
@ -112,7 +118,7 @@ impl NcPlane {
|
||||
// FIXME: CHECK for NULL and return Some() or None.
|
||||
pub fn cursor_yx(&self) -> (u32, u32) {
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {ncplane_cursor_yx(self, &mut y, &mut x)};
|
||||
unsafe { ncplane_cursor_yx(self, &mut y, &mut x) };
|
||||
(y as u32, x as u32)
|
||||
}
|
||||
|
||||
@ -131,7 +137,7 @@ impl NcPlane {
|
||||
/// Unlike [ncplane_dim_yx] which uses `i32`, this uses [u32].
|
||||
pub fn dim_yx(&self) -> (u32, u32) {
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {ncplane_dim_yx(self, &mut y, &mut x)};
|
||||
unsafe { ncplane_dim_yx(self, &mut y, &mut x) };
|
||||
(y as u32, x as u32)
|
||||
}
|
||||
|
||||
@ -158,9 +164,14 @@ impl NcPlane {
|
||||
pub fn putc_yx(&mut self, y: i32, x: i32, cell: &NcCell) -> NcResult {
|
||||
unsafe { ncplane_putc_yx(self, y, x, cell) }
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
pub fn putc(&mut self, cell: &NcCell) -> NcResult {
|
||||
ncplane_putc(self, cell)
|
||||
}
|
||||
|
||||
/// Returns the topmost [NcPlane] of the pile that contains this [NnPlane].
|
||||
pub fn top<'a>(&mut self) -> &'a mut NcPlane {
|
||||
unsafe { &mut *ncpile_top(self) }
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
644
rust/src/plane/reimplemented.rs
Normal file
644
rust/src/plane/reimplemented.rs
Normal file
@ -0,0 +1,644 @@
|
||||
//! `ncplane_*` reimplemented functions.
|
||||
|
||||
use core::{ffi::c_void, ptr::null_mut};
|
||||
use libc::free;
|
||||
use std::ffi::CString;
|
||||
|
||||
use crate::{
|
||||
bindgen::__va_list_tag, cell_load, cell_release, cells_double_box, cells_rounded_box,
|
||||
channels_bchannel, channels_bg_alpha, channels_bg_default_p, channels_bg_rgb, channels_bg_rgb8,
|
||||
channels_fchannel, channels_fg_alpha, channels_fg_default_p, channels_fg_rgb, channels_fg_rgb8,
|
||||
ncplane_at_cursor, ncplane_at_yx, ncplane_box, ncplane_channels, ncplane_cursor_move_yx,
|
||||
ncplane_cursor_yx, ncplane_dim_yx, ncplane_gradient, ncplane_hline_interp, ncplane_putc_yx,
|
||||
ncplane_putegc_yx, ncplane_putnstr_yx, ncplane_putstr_yx, ncplane_resize, ncplane_styles,
|
||||
ncplane_vline_interp, ncplane_vprintf_yx, notcurses_align, NcAlign, NcAlphaBits, NcCell,
|
||||
NcChannel, NcChannelPair, NcColor, NcPlane, NcResult, NcStyleMask, NCRESULT_ERR, NCRESULT_OK,
|
||||
};
|
||||
|
||||
/// Return the column at which 'cols' columns ought start in order to be aligned
|
||||
/// according to 'align' within ncplane 'n'. Returns INT_MAX on invalid 'align'.
|
||||
/// Undefined behavior on negative 'cols'.
|
||||
//
|
||||
// NOTE: [leave cols as i32](https://github.com/dankamongmen/notcurses/issues/904)
|
||||
#[inline]
|
||||
pub fn ncplane_align(plane: &NcPlane, align: NcAlign, cols: i32) -> i32 {
|
||||
notcurses_align(ncplane_dim_x(plane), align, cols)
|
||||
}
|
||||
|
||||
/// Retrieve the current contents of the cell under the cursor into 'cell'.
|
||||
/// This cell is invalidated if the associated plane is destroyed.
|
||||
#[inline]
|
||||
pub fn ncplane_at_cursor_cell(plane: &mut NcPlane, cell: &mut NcCell) -> NcResult {
|
||||
let mut egc = unsafe { ncplane_at_cursor(plane, &mut cell.stylemask, &mut cell.channels) };
|
||||
if egc.is_null() {
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let result: NcResult = unsafe { cell_load(plane, cell, egc) };
|
||||
if result != NCRESULT_OK {
|
||||
unsafe {
|
||||
free(&mut egc as *mut _ as *mut c_void);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Retrieve the current contents of the specified cell into 'cell'.
|
||||
/// This cell is invalidated if the associated plane is destroyed.
|
||||
#[inline]
|
||||
pub fn ncplane_at_yx_cell(plane: &mut NcPlane, y: i32, x: i32, cell: &mut NcCell) -> NcResult {
|
||||
let mut egc = unsafe { ncplane_at_yx(plane, y, x, &mut cell.stylemask, &mut cell.channels) };
|
||||
if egc.is_null() {
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let channels = cell.channels; // need to preserve wide flag
|
||||
let result: NcResult = unsafe { cell_load(plane, cell, egc) };
|
||||
cell.channels = channels;
|
||||
unsafe {
|
||||
free(&mut egc as *mut _ as *mut c_void);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Draw a box with its upper-left corner at the current cursor position, having
|
||||
/// dimensions 'ylen'x'xlen'. See ncplane_box() for more information. The
|
||||
/// minimum box size is 2x2, and it cannot be drawn off-screen.
|
||||
#[inline]
|
||||
pub fn ncplane_box_sized(
|
||||
plane: &mut NcPlane,
|
||||
ul: &NcCell,
|
||||
ur: &NcCell,
|
||||
ll: &NcCell,
|
||||
lr: &NcCell,
|
||||
hline: &NcCell,
|
||||
vline: &NcCell,
|
||||
ylen: i32,
|
||||
xlen: i32,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_cursor_yx(plane, &mut y, &mut x);
|
||||
ncplane_box(
|
||||
plane,
|
||||
ul,
|
||||
ur,
|
||||
ll,
|
||||
lr,
|
||||
hline,
|
||||
vline,
|
||||
y + ylen - 1,
|
||||
x + xlen - 1,
|
||||
ctlword,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_dim_x(plane: &NcPlane) -> i32 {
|
||||
unsafe {
|
||||
let mut x = 0;
|
||||
ncplane_dim_yx(plane, null_mut(), &mut x);
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_dim_y(plane: &NcPlane) -> i32 {
|
||||
unsafe {
|
||||
let mut y = 0;
|
||||
ncplane_dim_yx(plane, &mut y, null_mut());
|
||||
y
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_double_box(
|
||||
plane: &mut NcPlane,
|
||||
stylemask: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ystop: i32,
|
||||
xstop: i32,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
#[allow(unused_assignments)]
|
||||
let mut ret = NCRESULT_OK;
|
||||
|
||||
let mut ul = NcCell::new();
|
||||
let mut ur = NcCell::new();
|
||||
let mut ll = NcCell::new();
|
||||
let mut lr = NcCell::new();
|
||||
let mut hl = NcCell::new();
|
||||
let mut vl = NcCell::new();
|
||||
|
||||
unsafe {
|
||||
ret = cells_double_box(
|
||||
plane,
|
||||
stylemask as u32,
|
||||
channels,
|
||||
&mut ul,
|
||||
&mut ur,
|
||||
&mut ll,
|
||||
&mut lr,
|
||||
&mut hl,
|
||||
&mut vl,
|
||||
);
|
||||
if ret == NCRESULT_OK {
|
||||
ret = ncplane_box(plane, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
|
||||
}
|
||||
|
||||
cell_release(plane, &mut ul);
|
||||
cell_release(plane, &mut ur);
|
||||
cell_release(plane, &mut ll);
|
||||
cell_release(plane, &mut lr);
|
||||
cell_release(plane, &mut hl);
|
||||
cell_release(plane, &mut vl);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_double_box_sized(
|
||||
plane: &mut NcPlane,
|
||||
stylemask: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ylen: i32,
|
||||
xlen: i32,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_cursor_yx(plane, &mut y, &mut x);
|
||||
}
|
||||
ncplane_double_box(
|
||||
plane,
|
||||
stylemask,
|
||||
channels,
|
||||
y + ylen - 1,
|
||||
x + xlen - 1,
|
||||
ctlword,
|
||||
)
|
||||
}
|
||||
|
||||
/// On error, return the negative number of cells drawn.
|
||||
#[inline]
|
||||
pub fn ncplane_hline(plane: &mut NcPlane, cell: &NcCell, len: i32) -> i32 {
|
||||
unsafe { ncplane_hline_interp(plane, cell, len, cell.channels, cell.channels) }
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_perimeter(
|
||||
plane: &mut NcPlane,
|
||||
ul: &NcCell,
|
||||
ur: &NcCell,
|
||||
ll: &NcCell,
|
||||
lr: &NcCell,
|
||||
hline: &NcCell,
|
||||
vline: &NcCell,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
unsafe {
|
||||
ncplane_cursor_move_yx(plane, 0, 0);
|
||||
let (mut dimy, mut dimx) = (0, 0);
|
||||
ncplane_dim_yx(plane, &mut dimy, &mut dimx);
|
||||
ncplane_box_sized(plane, ul, ur, ll, lr, hline, vline, dimy, dimx, ctlword)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_perimeter_double(
|
||||
plane: &mut NcPlane,
|
||||
stylemask: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
if unsafe { ncplane_cursor_move_yx(plane, 0, 0) } != NCRESULT_OK {
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let (mut dimy, mut dimx) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_dim_yx(plane, &mut dimy, &mut dimx);
|
||||
}
|
||||
let mut ul = NcCell::new();
|
||||
let mut ur = NcCell::new();
|
||||
let mut ll = NcCell::new();
|
||||
let mut lr = NcCell::new();
|
||||
let mut hl = NcCell::new();
|
||||
let mut vl = NcCell::new();
|
||||
if unsafe {
|
||||
cells_double_box(
|
||||
plane,
|
||||
stylemask as u32,
|
||||
channels,
|
||||
&mut ul,
|
||||
&mut ur,
|
||||
&mut ll,
|
||||
&mut lr,
|
||||
&mut hl,
|
||||
&mut vl,
|
||||
)
|
||||
} != NCRESULT_OK
|
||||
{
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let ret = ncplane_box_sized(plane, &ul, &ur, &ll, &lr, &hl, &vl, dimy, dimx, ctlword);
|
||||
unsafe {
|
||||
cell_release(plane, &mut ul);
|
||||
cell_release(plane, &mut ur);
|
||||
cell_release(plane, &mut ll);
|
||||
cell_release(plane, &mut lr);
|
||||
cell_release(plane, &mut hl);
|
||||
cell_release(plane, &mut vl);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_perimeter_rounded(
|
||||
plane: &mut NcPlane,
|
||||
stylemask: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
if unsafe { ncplane_cursor_move_yx(plane, 0, 0) } != NCRESULT_OK {
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let (mut dimy, mut dimx) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_dim_yx(plane, &mut dimy, &mut dimx);
|
||||
}
|
||||
let mut ul = NcCell::new();
|
||||
let mut ur = NcCell::new();
|
||||
let mut ll = NcCell::new();
|
||||
let mut lr = NcCell::new();
|
||||
let mut hl = NcCell::new();
|
||||
let mut vl = NcCell::new();
|
||||
if unsafe {
|
||||
cells_rounded_box(
|
||||
plane,
|
||||
stylemask as u32,
|
||||
channels,
|
||||
&mut ul,
|
||||
&mut ur,
|
||||
&mut ll,
|
||||
&mut lr,
|
||||
&mut hl,
|
||||
&mut vl,
|
||||
)
|
||||
} != NCRESULT_OK
|
||||
{
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let ret = ncplane_box_sized(plane, &ul, &ur, &ll, &lr, &hl, &vl, dimy, dimx, ctlword);
|
||||
unsafe {
|
||||
cell_release(plane, &mut ul);
|
||||
cell_release(plane, &mut ur);
|
||||
cell_release(plane, &mut ll);
|
||||
cell_release(plane, &mut lr);
|
||||
cell_release(plane, &mut hl);
|
||||
cell_release(plane, &mut vl);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
/// Call ncplane_putc_yx() for the current cursor location.
|
||||
#[inline]
|
||||
pub fn ncplane_putc(plane: &mut NcPlane, cell: &NcCell) -> NcResult {
|
||||
unsafe { ncplane_putc_yx(plane, -1, -1, cell) }
|
||||
}
|
||||
|
||||
/// Call ncplane_putchar_yx() at the current cursor location.
|
||||
#[inline]
|
||||
pub fn ncplane_putchar(plane: &mut NcPlane, c: char) -> NcResult {
|
||||
ncplane_putchar_yx(plane, -1, -1, c)
|
||||
}
|
||||
|
||||
/// Replace the EGC underneath us, but retain the styling. The current styling
|
||||
/// of the plane will not be changed.
|
||||
///
|
||||
/// Replace the cell at the specified coordinates with the provided 7-bit char
|
||||
/// 'c'. Advance the cursor by 1. On success, returns 1. On failure, returns -1.
|
||||
/// This works whether the underlying char is signed or unsigned.
|
||||
#[inline]
|
||||
// TODO: test char is < 8bit (currently 32bit)
|
||||
pub fn ncplane_putchar_yx(plane: &mut NcPlane, y: i32, x: i32, c: char) -> NcResult {
|
||||
unsafe {
|
||||
let ce = NcCell::with_all(c, ncplane_styles(plane), ncplane_channels(plane));
|
||||
ncplane_putc_yx(plane, y, x, &ce)
|
||||
}
|
||||
}
|
||||
|
||||
/// Call ncplane_putegc() at the current cursor location.
|
||||
#[inline]
|
||||
pub fn ncplane_putegc(plane: &mut NcPlane, gcluster: i8, sbytes: &mut i32) -> NcResult {
|
||||
unsafe { ncplane_putegc_yx(plane, -1, -1, &gcluster, sbytes) }
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_putstr(plane: &mut NcPlane, string: &str) -> NcResult {
|
||||
unsafe {
|
||||
ncplane_putstr_yx(
|
||||
plane,
|
||||
-1,
|
||||
-1,
|
||||
CString::new(string.as_bytes())
|
||||
.expect("Bad string")
|
||||
.as_ptr(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_putnstr(plane: &mut NcPlane, size: u64, gclustarr: &[u8]) -> NcResult {
|
||||
unsafe {
|
||||
ncplane_putnstr_yx(
|
||||
plane,
|
||||
-1,
|
||||
-1,
|
||||
size,
|
||||
CString::new(gclustarr).expect("Bad string").as_ptr(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Resize the plane, retaining what data we can (everything, unless we're
|
||||
/// shrinking in some dimension). Keep the origin where it is.
|
||||
#[inline]
|
||||
pub fn ncplane_resize_simple(plane: &mut NcPlane, ylen: i32, xlen: i32) -> NcResult {
|
||||
let (mut oldy, mut oldx) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_dim_yx(plane, &mut oldy, &mut oldx);
|
||||
}
|
||||
let keepleny = {
|
||||
if oldy > ylen {
|
||||
ylen
|
||||
} else {
|
||||
oldy
|
||||
}
|
||||
};
|
||||
let keeplenx = {
|
||||
if oldx > xlen {
|
||||
xlen
|
||||
} else {
|
||||
oldx
|
||||
}
|
||||
};
|
||||
unsafe { ncplane_resize(plane, 0, 0, keepleny, keeplenx, 0, 0, ylen, xlen) }
|
||||
}
|
||||
|
||||
///
|
||||
/// On error, return the negative number of cells drawn.
|
||||
#[inline]
|
||||
pub fn ncplane_vline(plane: &mut NcPlane, cell: &NcCell, len: i32) -> i32 {
|
||||
unsafe { ncplane_vline_interp(plane, cell, len, cell.channels, cell.channels) }
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_vprintf(plane: &mut NcPlane, format: &str, ap: &mut __va_list_tag) -> NcResult {
|
||||
unsafe {
|
||||
ncplane_vprintf_yx(
|
||||
plane,
|
||||
-1,
|
||||
-1,
|
||||
CString::new(format).expect("Bad string").as_ptr(),
|
||||
ap,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a gradient with its upper-left corner at the current cursor position,
|
||||
/// having dimensions 'ylen'x'xlen'. See ncplane_gradient for more information.
|
||||
/// static inline int
|
||||
// XXX receive cells as u32? https://github.com/dankamongmen/notcurses/issues/920
|
||||
#[inline]
|
||||
pub fn ncplane_gradient_sized(
|
||||
plane: &mut NcPlane,
|
||||
egc: &[u8],
|
||||
stylemask: NcStyleMask,
|
||||
ul: u64,
|
||||
ur: u64,
|
||||
ll: u64,
|
||||
lr: u64,
|
||||
ylen: i32,
|
||||
xlen: i32,
|
||||
) -> NcResult {
|
||||
if ylen < 1 || xlen < 1 {
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_cursor_yx(plane, &mut y, &mut x);
|
||||
ncplane_gradient(
|
||||
plane,
|
||||
CString::new(egc).expect("Bad EGC").as_ptr(),
|
||||
stylemask as u32,
|
||||
ul,
|
||||
ur,
|
||||
ll,
|
||||
lr,
|
||||
y + ylen - 1,
|
||||
x + xlen - 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract the 32-bit working foreground channel from an ncplane.
|
||||
#[inline]
|
||||
pub fn ncplane_fchannel(plane: &NcPlane) -> NcChannel {
|
||||
channels_fchannel(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Extract the 32-bit working background channel from an ncplane.
|
||||
#[inline]
|
||||
pub fn ncplane_bchannel(plane: &NcPlane) -> NcChannel {
|
||||
channels_bchannel(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Extract 24 bits of working foreground RGB from an ncplane, shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcChannel {
|
||||
channels_fg_rgb(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Extract 24 bits of working background RGB from an ncplane, shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcChannel {
|
||||
channels_bg_rgb(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Extract 2 bits of foreground alpha from 'struct ncplane', shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn ncplane_fg_alpha(plane: &NcPlane) -> NcAlphaBits {
|
||||
channels_fg_alpha(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Extract 2 bits of background alpha from 'struct ncplane', shifted to LSBs.
|
||||
#[inline]
|
||||
pub fn ncplane_bg_alpha(plane: &NcPlane) -> NcAlphaBits {
|
||||
channels_bg_alpha(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Is the plane's foreground using the "default foreground color"?
|
||||
#[inline]
|
||||
pub fn ncplane_fg_default_p(plane: &NcPlane) -> bool {
|
||||
channels_fg_default_p(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Is the plane's background using the "default background color"?
|
||||
#[inline]
|
||||
pub fn ncplane_bg_default_p(plane: &NcPlane) -> bool {
|
||||
channels_bg_default_p(unsafe { ncplane_channels(plane) })
|
||||
}
|
||||
|
||||
/// Extract 24 bits of foreground RGB from a plane, split into components.
|
||||
#[inline]
|
||||
pub fn ncplane_fg_rgb8(
|
||||
plane: &NcPlane,
|
||||
red: &mut NcColor,
|
||||
green: &mut NcColor,
|
||||
blue: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channels_fg_rgb8(unsafe { ncplane_channels(plane) }, red, green, blue)
|
||||
}
|
||||
|
||||
/// Extract 24 bits of background RGB from a plane, split into components.
|
||||
#[inline]
|
||||
pub fn ncplane_bg_rgb8(
|
||||
plane: &NcPlane,
|
||||
red: &mut NcColor,
|
||||
green: &mut NcColor,
|
||||
blue: &mut NcColor,
|
||||
) -> NcChannel {
|
||||
channels_bg_rgb8(unsafe { ncplane_channels(plane) }, red, green, blue)
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_rounded_box(
|
||||
plane: &mut NcPlane,
|
||||
stylemask: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ystop: i32,
|
||||
xstop: i32,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
#[allow(unused_assignments)]
|
||||
let mut ret = NCRESULT_OK;
|
||||
|
||||
let mut ul = NcCell::new();
|
||||
let mut ur = NcCell::new();
|
||||
let mut ll = NcCell::new();
|
||||
let mut lr = NcCell::new();
|
||||
let mut hl = NcCell::new();
|
||||
let mut vl = NcCell::new();
|
||||
|
||||
unsafe {
|
||||
ret = cells_rounded_box(
|
||||
plane,
|
||||
stylemask as u32,
|
||||
channels,
|
||||
&mut ul,
|
||||
&mut ur,
|
||||
&mut ll,
|
||||
&mut lr,
|
||||
&mut hl,
|
||||
&mut vl,
|
||||
);
|
||||
if ret == NCRESULT_OK {
|
||||
ret = ncplane_box(plane, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
|
||||
}
|
||||
cell_release(plane, &mut ul);
|
||||
cell_release(plane, &mut ur);
|
||||
cell_release(plane, &mut ll);
|
||||
cell_release(plane, &mut lr);
|
||||
cell_release(plane, &mut hl);
|
||||
cell_release(plane, &mut vl);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
///
|
||||
#[inline]
|
||||
pub fn ncplane_rounded_box_sized(
|
||||
plane: &mut NcPlane,
|
||||
stylemask: NcStyleMask,
|
||||
channels: NcChannelPair,
|
||||
ylen: i32,
|
||||
xlen: i32,
|
||||
ctlword: u32,
|
||||
) -> NcResult {
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {
|
||||
ncplane_cursor_yx(plane, &mut y, &mut x);
|
||||
}
|
||||
ncplane_rounded_box(
|
||||
plane,
|
||||
stylemask,
|
||||
channels,
|
||||
y + ylen - 1,
|
||||
x + xlen - 1,
|
||||
ctlword,
|
||||
)
|
||||
}
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf(struct ncplane* n, const char* format, ...)
|
||||
// __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf(struct ncplane* n, const char* format, ...){
|
||||
// va_list va;
|
||||
// va_start(va, format);
|
||||
// int ret = ncplane_vprintf(n, format, va);
|
||||
// va_end(va);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf_yx(struct ncplane* n, int y, int x, const char* format, ...)
|
||||
// __attribute__ ((format (printf, 4, 5)));
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf_yx(struct ncplane* n, int y, int x, const char* format, ...){
|
||||
// va_list va;
|
||||
// va_start(va, format);
|
||||
// int ret = ncplane_vprintf_yx(n, y, x, format, va);
|
||||
// va_end(va);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf_aligned(struct ncplane* n, int y, ncalign_e align,
|
||||
// const char* format, ...)
|
||||
// __attribute__ ((format (printf, 4, 5)));
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf_aligned(struct ncplane* n, int y, ncalign_e align, const char* format, ...){
|
||||
// va_list va;
|
||||
// va_start(va, format);
|
||||
// int ret = ncplane_vprintf_aligned(n, y, align, format, va);
|
||||
// va_end(va);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf_stained(struct ncplane* n, const char* format, ...)
|
||||
// __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
// static inline int
|
||||
// ncplane_printf_stained(struct ncplane* n, const char* format, ...){
|
||||
// va_list va;
|
||||
// va_start(va, format);
|
||||
// int ret = ncplane_vprintf_stained(n, format, va);
|
||||
// va_end(va);
|
||||
// return ret;
|
||||
// }
|
4
rust/src/plane/test/methods.rs
Normal file
4
rust/src/plane/test/methods.rs
Normal file
@ -0,0 +1,4 @@
|
||||
//! Test `NcPlane` methods and associated functions.
|
||||
|
||||
// use crate::NcPlane;
|
||||
// use serial_test::serial;
|
7
rust/src/plane/test/mod.rs
Normal file
7
rust/src/plane/test/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
//! `NcPlane` tests.
|
||||
|
||||
#[cfg(test)]
|
||||
mod methods;
|
||||
|
||||
#[cfg(test)]
|
||||
mod reimplemented;
|
@ -1,4 +1,4 @@
|
||||
//! [`NcPlane`] tests
|
||||
//! Test `ncplane_*` reimplemented functions.
|
||||
|
||||
use crate::{notcurses_stop, NcPlane, NcPlaneOptions, Notcurses, NCRESULT_OK};
|
||||
use serial_test::serial;
|
||||
@ -233,3 +233,25 @@ fn ncplane_erase() {
|
||||
notcurses_stop(nc);
|
||||
}
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// #[serial]
|
||||
// fn ncplane_at_cursor() {
|
||||
// unsafe {
|
||||
// let nc = Notcurses::new();
|
||||
// let plane = NcPlane::new(nc, 0, 0, 20, 20);
|
||||
//
|
||||
// notcurses_stop(nc);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// #[serial]
|
||||
// fn ncplane_at_cursor_cell() {
|
||||
// unsafe {
|
||||
// let nc = Notcurses::new();
|
||||
// let plane = NcPlane::new(nc, 0, 0, 20, 20);
|
||||
//
|
||||
// notcurses_stop(nc);
|
||||
// }
|
||||
// }
|
@ -1,156 +0,0 @@
|
||||
#[allow(unused_imports)] // for docblocks
|
||||
use crate::NCCELL_ALPHA_BLEND;
|
||||
|
||||
// NcPlane
|
||||
/// Fundamental drawing surface.
|
||||
///
|
||||
/// Unites a:
|
||||
/// - CellMatrix
|
||||
/// - EgcPool
|
||||
///
|
||||
/// `type in C: ncplane (struct)`
|
||||
///
|
||||
///
|
||||
/// ## Piles
|
||||
///
|
||||
/// A single notcurses context is made up of one or more piles.
|
||||
///
|
||||
/// A pile is a set of one or more ncplanes, including the partial orderings
|
||||
/// made up of their binding and z-axis pointers.
|
||||
///
|
||||
/// A pile has a top and bottom ncplane (this might be a single plane),
|
||||
/// and one or more root planes (planes which are bound to themselves).
|
||||
///
|
||||
/// Multiple threads can concurrently operate on distinct piles, even changing
|
||||
/// one while rendering another.
|
||||
///
|
||||
/// Each plane is part of one and only one pile. By default, a plane is part of
|
||||
/// the same pile containing that plane to which it is bound.
|
||||
///
|
||||
/// If ncpile_create is used in the place of ncplane_create, the returned plane
|
||||
/// becomes the root plane, top, and bottom of a new pile. As a root plane,
|
||||
/// it is bound to itself.
|
||||
///
|
||||
/// A new pile can also be created by reparenting a plane to itself,
|
||||
/// though if the plane is already a root plane, this is a no-op.
|
||||
///
|
||||
/// When a plane is moved to a different pile (whether new or preexisting),
|
||||
/// any planes which were bound to it are rebound to its previous parent.
|
||||
/// If the plane was a root plane of some pile, any bound planes become root
|
||||
/// planes. The new plane is placed immediately atop its new parent on its new
|
||||
/// pile's z-axis. When ncplane_reparent_family() is used, all planes bound to
|
||||
/// the reparented plane are moved along with it. Their relative z-order is maintained.
|
||||
///
|
||||
pub type NcPlane = crate::bindings::bindgen::ncplane;
|
||||
|
||||
/// Options struct for [`NcPlane`]
|
||||
pub type NcPlaneOptions = crate::bindings::bindgen::ncplane_options;
|
||||
|
||||
/// Horizontal alignment relative to the parent plane. Set alignment in 'x'.
|
||||
pub const NCPLANE_OPTION_HORALIGNED: u64 =
|
||||
crate::bindings::bindgen::NCPLANE_OPTION_HORALIGNED as u64;
|
||||
|
||||
/// I/O wrapper to dump file descriptor to [`NcPlane`]
|
||||
///
|
||||
/// `type in C: ncfdplane (struct)`
|
||||
pub type NcFdPlane = crate::bindings::bindgen::ncfdplane;
|
||||
|
||||
/// Options struct for [`NcFdPlane`]
|
||||
///
|
||||
/// `type in C: ncplane_options (struct)`
|
||||
pub type NcFdPlaneOptions = crate::bindings::bindgen::ncfdplane_options;
|
||||
|
||||
/// Alignment within a plane or terminal.
|
||||
/// Left/right-justified, or centered.
|
||||
pub type NcAlign = crate::bindings::bindgen::ncalign_e;
|
||||
|
||||
/// Left alignment within an [`NcPlane`] or terminal.
|
||||
pub const NCALIGN_LEFT: NcAlign = crate::bindings::bindgen::ncalign_e_NCALIGN_LEFT;
|
||||
|
||||
/// Right alignment within an [`NcPlane`] or terminal.
|
||||
pub const NCALIGN_RIGHT: NcAlign = crate::bindings::bindgen::ncalign_e_NCALIGN_RIGHT;
|
||||
|
||||
/// Center alignment within an [`NcPlane`] or terminal.
|
||||
pub const NCALIGN_CENTER: NcAlign = crate::bindings::bindgen::ncalign_e_NCALIGN_CENTER;
|
||||
|
||||
/// Do not align an [`NcPlane`] or terminal.
|
||||
pub const NCALIGN_UNALIGNED: NcAlign = crate::bindings::bindgen::ncalign_e_NCALIGN_UNALIGNED;
|
||||
|
||||
/// Blitter Mode (`NCBLIT_*`)
|
||||
///
|
||||
/// We never blit full blocks, but instead spaces (more efficient) with the
|
||||
/// background set to the desired foreground.
|
||||
///
|
||||
/// ## Modes
|
||||
///
|
||||
/// - [`NCBLIT_1x1`]
|
||||
/// - [`NCBLIT_2x1`]
|
||||
/// - [`NCBLIT_2x2`]
|
||||
/// - [`NCBLIT_3x2`]
|
||||
/// - [`NCBLIT_4x1`]
|
||||
/// - [`NCBLIT_8x1`]
|
||||
/// - [`NCBLIT_BRAILLE`]
|
||||
/// - [`NCBLIT_DEFAULT`]
|
||||
/// - [`NCBLIT_SIXEL`]
|
||||
///
|
||||
pub type NcBlitter = crate::bindings::bindgen::ncblitter_e;
|
||||
|
||||
/// [`NcBlitter`] mode using: space, compatible with ASCII
|
||||
pub const NCBLIT_1x1: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_1x1;
|
||||
|
||||
/// [`NcBlitter`] mode using: halves + 1x1 (space)
|
||||
/// ▄▀
|
||||
pub const NCBLIT_2x1: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_2x1;
|
||||
|
||||
/// [`NcBlitter`] mode using: quadrants + 2x1
|
||||
/// ▗▐ ▖▀▟▌▙
|
||||
pub const NCBLIT_2x2: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_2x2;
|
||||
|
||||
/// [`NcBlitter`] mode using: sextants
|
||||
/// 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻
|
||||
pub const NCBLIT_3x2: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_3x2;
|
||||
|
||||
/// [`NcBlitter`] mode using: four vertical levels
|
||||
/// █▆▄▂
|
||||
pub const NCBLIT_4x1: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_4x1;
|
||||
|
||||
/// [`NcBlitter`] mode using: eight vertical levels
|
||||
/// █▇▆▅▄▃▂▁
|
||||
pub const NCBLIT_8x1: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_8x1;
|
||||
|
||||
/// [`NcBlitter`] mode using: 4 rows, 2 cols (braille)
|
||||
/// ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿
|
||||
pub const NCBLIT_BRAILLE: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_BRAILLE;
|
||||
|
||||
/// [`NcBlitter`] mode where the blitter is automatically chosen
|
||||
pub const NCBLIT_DEFAULT: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_DEFAULT;
|
||||
|
||||
/// [`NcBlitter`] mode (not yet implemented)
|
||||
pub const NCBLIT_SIXEL: NcBlitter = crate::bindings::bindgen::ncblitter_e_NCBLIT_SIXEL;
|
||||
|
||||
/// How to scale an [`NcVisual`] during rendering
|
||||
///
|
||||
/// - NCSCALE_NONE will apply no scaling.
|
||||
/// - NCSCALE_SCALE scales a visual to the plane's size,
|
||||
/// maintaining aspect ratio.
|
||||
/// - NCSCALE_STRETCH stretches and scales the image in an
|
||||
/// attempt to fill the entirety of the plane.
|
||||
///
|
||||
pub type NcScale = crate::bindings::bindgen::ncscale_e;
|
||||
/// Maintain original size
|
||||
pub const NCSCALE_NONE: NcScale = crate::bindings::bindgen::ncscale_e_NCSCALE_NONE;
|
||||
/// Maintain aspect ratio
|
||||
pub const NCSCALE_SCALE: NcScale = crate::bindings::bindgen::ncscale_e_NCSCALE_SCALE;
|
||||
/// Throw away aspect ratio
|
||||
pub const NCSCALE_STRETCH: NcScale = crate::bindings::bindgen::ncscale_e_NCSCALE_STRETCH;
|
||||
|
||||
/// A visual bit of multimedia opened with LibAV|OIIO
|
||||
pub type NcVisual = crate::bindings::bindgen::ncvisual;
|
||||
/// Options struct for [`NcVisual`]
|
||||
pub type NcVisualOptions = crate::bindings::bindgen::ncvisual_options;
|
||||
|
||||
/// Use [`NCCELL_ALPHA_BLEND`] with visual
|
||||
pub const NCVISUAL_OPTION_BLEND: u32 = crate::bindings::bindgen::NCVISUAL_OPTION_BLEND;
|
||||
|
||||
/// Fail rather than degrade
|
||||
pub const NCVISUAL_OPTION_NODEGRADE: u32 = crate::bindings::bindgen::NCVISUAL_OPTION_NODEGRADE;
|
@ -1,29 +1,33 @@
|
||||
//! `ncvisual`
|
||||
|
||||
// functions already exported by bindgen : 17
|
||||
// -----------------------------------------
|
||||
// ncvisual_at_yx
|
||||
// ncvisual_decode
|
||||
// ncvisual_decode_loop
|
||||
// ncvisual_destroy
|
||||
// ncvisual_from_bgra
|
||||
// ncvisual_from_file
|
||||
// ncvisual_from_plane
|
||||
// ncvisual_from_rgba
|
||||
// ncvisual_geom
|
||||
// ncvisual_polyfill_yx
|
||||
// ncvisual_render
|
||||
// ncvisual_resize
|
||||
// ncvisual_rotate
|
||||
// ncvisual_set_yx
|
||||
// ncvisual_simple_streamer
|
||||
// ncvisual_stream
|
||||
// ncvisual_subtitle
|
||||
// (#) test: 0 / 17
|
||||
// -----------------------------------------
|
||||
// ncvisual_at_yx
|
||||
// ncvisual_decode
|
||||
// ncvisual_decode_loop
|
||||
// ncvisual_destroy
|
||||
// ncvisual_from_bgra
|
||||
// ncvisual_from_file
|
||||
// ncvisual_from_plane
|
||||
// ncvisual_from_rgba
|
||||
// ncvisual_geom
|
||||
// ncvisual_polyfill_yx
|
||||
// ncvisual_render
|
||||
// ncvisual_resize
|
||||
// ncvisual_rotate
|
||||
// ncvisual_set_yx
|
||||
// ncvisual_simple_streamer
|
||||
// ncvisual_stream
|
||||
// ncvisual_subtitle
|
||||
//
|
||||
// static inline functions total: 1
|
||||
// ------------------------------------------ (done / remaining)
|
||||
// functions manually reimplemented: 1
|
||||
// ------------------------------------------
|
||||
// (+) done: 1 / 0
|
||||
// (#) test: 0 / 1
|
||||
// ------------------------------------------
|
||||
// ncvisual_default_blitter
|
||||
// + ncvisual_default_blitter
|
||||
|
||||
use crate::{NCBLIT_1x1, NCBLIT_2x1, NCBLIT_2x2, NcBlitter, NcScale, NCSCALE_STRETCH};
|
||||
|
||||
@ -41,15 +45,3 @@ pub fn ncvisual_default_blitter(utf8: bool, scale: NcScale) -> NcBlitter {
|
||||
}
|
||||
NCBLIT_1x1
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// use super::nc;
|
||||
// use serial_test::serial;
|
||||
/*
|
||||
#[test]
|
||||
#[serial]
|
||||
fn () {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
85
rust/src/widgets/menu/methods.rs
Normal file
85
rust/src/widgets/menu/methods.rs
Normal file
@ -0,0 +1,85 @@
|
||||
//! `NcMenu*` methods and associated functions.
|
||||
|
||||
use std::ffi::CString;
|
||||
|
||||
use crate::{
|
||||
ncmenu_create, NcChannelPair, NcInput, NcMenu, NcMenuItem, NcMenuOptions, NcMenuSection,
|
||||
NcPlane,
|
||||
};
|
||||
|
||||
impl NcMenu {
|
||||
/// `NcMenu` simple constructor
|
||||
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
|
||||
Self::with_options(plane, &NcMenuOptions::new())
|
||||
}
|
||||
|
||||
/// `NcMenu` constructor with options
|
||||
pub unsafe fn with_options<'a>(plane: &mut NcPlane, options: &NcMenuOptions) -> &'a mut Self {
|
||||
&mut *ncmenu_create(plane, options)
|
||||
}
|
||||
}
|
||||
|
||||
impl NcMenuOptions {
|
||||
/// `NcMenuOptions` simple constructor
|
||||
pub fn new() -> Self {
|
||||
Self::with_options(&mut [], 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
/// `NcMenuOptions` width options
|
||||
pub fn with_options(
|
||||
sections: &mut [NcMenuSection],
|
||||
count: u32,
|
||||
headerc: NcChannelPair,
|
||||
sectionc: NcChannelPair,
|
||||
flags: u64,
|
||||
) -> Self {
|
||||
Self {
|
||||
// array of 'sectioncount' `MenuSection`s
|
||||
sections: sections as *mut _ as *mut NcMenuSection, /// XXX TEST
|
||||
|
||||
// must be positive TODO
|
||||
sectioncount: count as i32,
|
||||
|
||||
// styling for header
|
||||
headerchannels: headerc,
|
||||
|
||||
// styling for sections
|
||||
sectionchannels: sectionc,
|
||||
|
||||
// flag word of NCMENU_OPTION_*
|
||||
flags: flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NcMenuItem {
|
||||
/// `NcMenuItem` simple constructor
|
||||
pub fn new(mut desc: i8, shortcut: NcInput) -> Self {
|
||||
Self {
|
||||
// utf-8 menu item, NULL for horizontal separator
|
||||
desc: &mut desc,
|
||||
|
||||
// ´NcInput´ shortcut, all should be distinct
|
||||
shortcut,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NcMenuSection {
|
||||
/// `NcMenuSection` simple constructor
|
||||
pub fn new(name: &str, itemcount: i32, items: &mut [NcMenuItem], shortcut: NcInput) -> Self {
|
||||
Self {
|
||||
// utf-8 name string
|
||||
name: CString::new(name).expect("Bad string").as_ptr() as *mut i8,
|
||||
|
||||
//
|
||||
itemcount,
|
||||
|
||||
// array of itemcount `NcMenuItem`s
|
||||
items: items as *mut _ as *mut NcMenuItem,
|
||||
|
||||
// shortcut, will be underlined if present in name
|
||||
shortcut,
|
||||
}
|
||||
}
|
||||
}
|
@ -2,101 +2,49 @@
|
||||
|
||||
// functions already exported by bindgen : 13
|
||||
// ------------------------------------------
|
||||
// ncmenu_create
|
||||
// ncmenu_destroy
|
||||
// ncmenu_item_set_status
|
||||
// ncmenu_mouse_selected
|
||||
// ncmenu_nextitem
|
||||
// ncmenu_nextsection
|
||||
// ncmenu_offer_input
|
||||
// ncmenu_plane
|
||||
// ncmenu_previtem
|
||||
// ncmenu_prevsection
|
||||
// ncmenu_rollup
|
||||
// ncmenu_selected
|
||||
// ncmenu_unroll
|
||||
// ncmenu_create
|
||||
// ncmenu_destroy
|
||||
// ncmenu_item_set_status
|
||||
// ncmenu_mouse_selected
|
||||
// ncmenu_nextitem
|
||||
// ncmenu_nextsection
|
||||
// ncmenu_offer_input
|
||||
// ncmenu_plane
|
||||
// ncmenu_previtem
|
||||
// ncmenu_prevsection
|
||||
// ncmenu_rollup
|
||||
// ncmenu_selected
|
||||
// ncmenu_unroll
|
||||
|
||||
mod types;
|
||||
pub use types::{NcMenu, NcMenuItem, NcMenuOptions, NcMenuSection};
|
||||
pub use types::{NCMENU_OPTION_BOTTOM, NCMENU_OPTION_HIDING};
|
||||
mod methods;
|
||||
|
||||
use std::ffi::CString;
|
||||
/// menus on the top or bottom rows
|
||||
///
|
||||
/// A notcurses instance supports menu bars on the top or bottom row of the true
|
||||
/// screen.
|
||||
///
|
||||
/// A menu is composed of sections, which are in turn composed of items.
|
||||
/// Either no sections are visible, and the menu is rolled up, or exactly one
|
||||
/// section is unrolled.
|
||||
///
|
||||
/// `ncmenu_rollup` places an `NcMenu` in the rolled up state.
|
||||
/// `ncmenu_unroll` rolls up any unrolled section and unrolls the specified one.
|
||||
/// `ncmenu_destroy` removes a menu bar, and frees all associated resources.
|
||||
///
|
||||
/// `type in C: ncmenu (struct)`
|
||||
pub type NcMenu = crate::bindings::bindgen::ncmenu;
|
||||
|
||||
use crate::{ncmenu_create, NcChannelPair, NcInput, NcPlane};
|
||||
/// Options struct for [`NcMenu`]
|
||||
pub type NcMenuOptions = crate::bindings::bindgen::ncmenu_options;
|
||||
|
||||
impl NcMenu {
|
||||
/// `NcMenu` simple constructor
|
||||
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
|
||||
Self::with_options(plane, &NcMenuOptions::new())
|
||||
}
|
||||
/// Item for [`NcMenu`]
|
||||
pub type NcMenuItem = crate::bindings::bindgen::ncmenu_item;
|
||||
|
||||
/// `NcMenu` constructor with options
|
||||
pub unsafe fn with_options<'a>(plane: &mut NcPlane, options: &NcMenuOptions) -> &'a mut Self {
|
||||
&mut *ncmenu_create(plane, options)
|
||||
}
|
||||
}
|
||||
/// Section for [`NcMenu`]
|
||||
pub type NcMenuSection = crate::bindings::bindgen::ncmenu_section;
|
||||
|
||||
impl NcMenuOptions {
|
||||
/// `NcMenuOptions` simple constructor
|
||||
pub fn new() -> Self {
|
||||
Self::with_options(&mut [], 0, 0, 0, 0)
|
||||
}
|
||||
/// Bottom row (as opposed to top row)
|
||||
pub const NCMENU_OPTION_BOTTOM: u32 = crate::bindings::bindgen::NCMENU_OPTION_BOTTOM;
|
||||
|
||||
/// `NcMenuOptions` width options
|
||||
pub fn with_options(
|
||||
sections: &mut [NcMenuSection],
|
||||
count: u32,
|
||||
headerc: NcChannelPair,
|
||||
sectionc: NcChannelPair,
|
||||
flags: u64,
|
||||
) -> Self {
|
||||
Self {
|
||||
// array of 'sectioncount' `MenuSection`s
|
||||
sections: sections as *mut _ as *mut NcMenuSection, /// XXX TEST
|
||||
|
||||
// must be positive TODO
|
||||
sectioncount: count as i32,
|
||||
|
||||
// styling for header
|
||||
headerchannels: headerc,
|
||||
|
||||
// styling for sections
|
||||
sectionchannels: sectionc,
|
||||
|
||||
// flag word of NCMENU_OPTION_*
|
||||
flags: flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NcMenuItem {
|
||||
/// `NcMenuItem` simple constructor
|
||||
pub fn new(mut desc: i8, shortcut: NcInput) -> Self {
|
||||
Self {
|
||||
// utf-8 menu item, NULL for horizontal separator
|
||||
desc: &mut desc,
|
||||
|
||||
// ´NcInput´ shortcut, all should be distinct
|
||||
shortcut,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NcMenuSection {
|
||||
/// `NcMenuSection` simple constructor
|
||||
pub fn new(name: &str, itemcount: i32, items: &mut [NcMenuItem], shortcut: NcInput) -> Self {
|
||||
Self {
|
||||
// utf-8 name string
|
||||
name: CString::new(name).expect("Bad string").as_ptr() as *mut i8,
|
||||
|
||||
//
|
||||
itemcount,
|
||||
|
||||
// array of itemcount `NcMenuItem`s
|
||||
items: items as *mut _ as *mut NcMenuItem,
|
||||
|
||||
// shortcut, will be underlined if present in name
|
||||
shortcut,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Hide the menu when not unrolled
|
||||
pub const NCMENU_OPTION_HIDING: u32 = crate::bindings::bindgen::NCMENU_OPTION_HIDING;
|
||||
|
@ -1,32 +0,0 @@
|
||||
//! `NcMenu` widget types
|
||||
|
||||
/// menus on the top or bottom rows
|
||||
///
|
||||
/// A notcurses instance supports menu bars on the top or bottom row of the true
|
||||
/// screen.
|
||||
///
|
||||
/// A menu is composed of sections, which are in turn composed of items.
|
||||
/// Either no sections are visible, and the menu is rolled up, or exactly one
|
||||
/// section is unrolled.
|
||||
///
|
||||
/// `ncmenu_rollup` places an `NcMenu` in the rolled up state.
|
||||
/// `ncmenu_unroll` rolls up any unrolled section and unrolls the specified one.
|
||||
/// `ncmenu_destroy` removes a menu bar, and frees all associated resources.
|
||||
///
|
||||
/// `type in C: ncmenu (struct)`
|
||||
pub type NcMenu = crate::bindings::bindgen::ncmenu;
|
||||
|
||||
/// Options struct for [`NcMenu`]
|
||||
pub type NcMenuOptions = crate::bindings::bindgen::ncmenu_options;
|
||||
|
||||
/// Item for [`NcMenu`]
|
||||
pub type NcMenuItem = crate::bindings::bindgen::ncmenu_item;
|
||||
|
||||
/// Section for [`NcMenu`]
|
||||
pub type NcMenuSection = crate::bindings::bindgen::ncmenu_section;
|
||||
|
||||
/// Bottom row (as opposed to top row)
|
||||
pub const NCMENU_OPTION_BOTTOM: u32 = crate::bindings::bindgen::NCMENU_OPTION_BOTTOM;
|
||||
|
||||
/// Hide the menu when not unrolled
|
||||
pub const NCMENU_OPTION_HIDING: u32 = crate::bindings::bindgen::NCMENU_OPTION_HIDING;
|
@ -1,5 +1,4 @@
|
||||
//! Widgets
|
||||
//!
|
||||
|
||||
mod menu;
|
||||
mod multiselector;
|
||||
|
@ -1,4 +1,10 @@
|
||||
//! `NcSelector` widget
|
||||
//! `NcMultiSelector` widget.
|
||||
|
||||
mod types;
|
||||
pub use types::{NcMultiSelector, NcMultiSelectorItem, NcMultiSelectorOptions};
|
||||
/// high-level widget for selecting items from a set
|
||||
pub type NcMultiSelector = crate::bindings::bindgen::ncmultiselector;
|
||||
|
||||
/// an item for [`NcMultiSelector`]
|
||||
pub type NcMultiSelectorItem = crate::bindings::bindgen::ncmselector_item;
|
||||
|
||||
/// Options structure for [`NcMultiSelector`]
|
||||
pub type NcMultiSelectorOptions = crate::bindings::bindgen::ncmultiselector_options;
|
||||
|
@ -1,10 +0,0 @@
|
||||
//! `NcMultiSelector` widget types
|
||||
|
||||
/// high-level widget for selecting items from a set
|
||||
pub type NcMultiSelector = crate::bindings::bindgen::ncmultiselector;
|
||||
|
||||
/// an item for [`NcMultiSelector`]
|
||||
pub type NcMultiSelectorItem = crate::bindings::bindgen::ncmselector_item;
|
||||
|
||||
/// Options structure for [`NcMultiSelector`]
|
||||
pub type NcMultiSelectorOptions = crate::bindings::bindgen::ncmultiselector_options;
|
@ -1,8 +1,27 @@
|
||||
//! `NcPlot[F|U]64` widget
|
||||
//! `NcPlot[F|U]64` widget.
|
||||
|
||||
mod types;
|
||||
pub use types::{NcPlotF64, NcPlotOptions, NcPlotU64};
|
||||
pub use types::{
|
||||
NCPLOT_OPTION_DETECTMAXONLY, NCPLOT_OPTION_EXPONENTIALD, NCPLOT_OPTION_LABELTICKSD,
|
||||
NCPLOT_OPTION_NODEGRADE, NCPLOT_OPTION_VERTICALI,
|
||||
};
|
||||
/// A histogram, bound to an [`NcPlane`][crate::NcPlane]
|
||||
/// (uses non-negative `f64`s)
|
||||
pub type NcPlotF64 = crate::bindings::bindgen::ncdplot;
|
||||
|
||||
/// A histogram, bound to an [`NcPlane`][crate::NcPlane] (uses `u64`s)
|
||||
pub type NcPlotU64 = crate::bindings::bindgen::ncuplot;
|
||||
|
||||
/// Options struct for
|
||||
/// [`NcPlotF64`] or [`NcPlotU64`]
|
||||
pub type NcPlotOptions = crate::bindings::bindgen::ncplot_options;
|
||||
|
||||
/// Use domain detection only for max
|
||||
pub const NCPLOT_OPTION_DETECTMAXONLY: u32 = crate::bindings::bindgen::NCPLOT_OPTION_DETECTMAXONLY;
|
||||
|
||||
/// Exponential dependent axis
|
||||
pub const NCPLOT_OPTION_EXPONENTIALD: u32 = crate::bindings::bindgen::NCPLOT_OPTION_EXPONENTIALD;
|
||||
|
||||
/// Show labels for dependent axis
|
||||
pub const NCPLOT_OPTION_LABELTICKSD: u32 = crate::bindings::bindgen::NCPLOT_OPTION_LABELTICKSD;
|
||||
|
||||
/// Use domain detection only for max
|
||||
pub const NCPLOT_OPTION_NODEGRADE: u32 = crate::bindings::bindgen::NCPLOT_OPTION_NODEGRADE;
|
||||
|
||||
/// Independent axis is vertical
|
||||
pub const NCPLOT_OPTION_VERTICALI: u32 = crate::bindings::bindgen::NCPLOT_OPTION_VERTICALI;
|
||||
|
@ -1,27 +0,0 @@
|
||||
//! `NcPlot[F|U]64` widget types
|
||||
|
||||
/// A histogram, bound to an [`NcPlane`][crate::NcPlane]
|
||||
/// (uses non-negative `f64`s)
|
||||
pub type NcPlotF64 = crate::bindings::bindgen::ncdplot;
|
||||
|
||||
/// A histogram, bound to an [`NcPlane`][crate::NcPlane] (uses `u64`s)
|
||||
pub type NcPlotU64 = crate::bindings::bindgen::ncuplot;
|
||||
|
||||
/// Options struct for
|
||||
/// [`NcPlotF64`] or [`NcPlotU64`]
|
||||
pub type NcPlotOptions = crate::bindings::bindgen::ncplot_options;
|
||||
|
||||
/// Use domain detection only for max
|
||||
pub const NCPLOT_OPTION_DETECTMAXONLY: u32 = crate::bindings::bindgen::NCPLOT_OPTION_DETECTMAXONLY;
|
||||
|
||||
/// Exponential dependent axis
|
||||
pub const NCPLOT_OPTION_EXPONENTIALD: u32 = crate::bindings::bindgen::NCPLOT_OPTION_EXPONENTIALD;
|
||||
|
||||
/// Show labels for dependent axis
|
||||
pub const NCPLOT_OPTION_LABELTICKSD: u32 = crate::bindings::bindgen::NCPLOT_OPTION_LABELTICKSD;
|
||||
|
||||
/// Use domain detection only for max
|
||||
pub const NCPLOT_OPTION_NODEGRADE: u32 = crate::bindings::bindgen::NCPLOT_OPTION_NODEGRADE;
|
||||
|
||||
/// Independent axis is vertical
|
||||
pub const NCPLOT_OPTION_VERTICALI: u32 = crate::bindings::bindgen::NCPLOT_OPTION_VERTICALI;
|
29
rust/src/widgets/reader/methods.rs
Normal file
29
rust/src/widgets/reader/methods.rs
Normal file
@ -0,0 +1,29 @@
|
||||
//! `NcReader*` methods and associated functions.
|
||||
|
||||
use crate::{ncreader_create, NcPlane, NcReader, NcReaderOptions};
|
||||
|
||||
impl NcReader {
|
||||
/// `NcReader` simple constructor
|
||||
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
|
||||
Self::with_options(plane, &NcReaderOptions::new())
|
||||
}
|
||||
|
||||
/// `NcReader` constructor with options
|
||||
pub unsafe fn with_options<'a>(plane: &mut NcPlane, options: &NcReaderOptions) -> &'a mut Self {
|
||||
&mut *ncreader_create(plane, options)
|
||||
}
|
||||
}
|
||||
|
||||
impl NcReaderOptions {
|
||||
/// `NcReaderOptions` simple constructor
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
// channels used for input
|
||||
tchannels: 0,
|
||||
// attributes used for input
|
||||
tattrword: 0,
|
||||
// bitfield of NCREADER_OPTION_*
|
||||
flags: 0,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +1,48 @@
|
||||
//! `NcReader` widget
|
||||
//! `NcReader` widget.
|
||||
|
||||
// functions already exported by bindgen : 11
|
||||
// ------------------------------------------
|
||||
// ncreader_clear
|
||||
// ncreader_contents
|
||||
// ncreader_create
|
||||
// ncreader_destroy
|
||||
// ncreader_move_down
|
||||
// ncreader_move_left
|
||||
// ncreader_move_right
|
||||
// ncreader_move_up
|
||||
// ncreader_offer_input
|
||||
// ncreader_plane
|
||||
// ncreader_write_egc
|
||||
//
|
||||
// static inline functions total: 0
|
||||
// -------------------------------------------
|
||||
// ncreader_clear
|
||||
// ncreader_contents
|
||||
// ncreader_create
|
||||
// ncreader_destroy
|
||||
// ncreader_move_down
|
||||
// ncreader_move_left
|
||||
// ncreader_move_right
|
||||
// ncreader_move_up
|
||||
// ncreader_offer_input
|
||||
// ncreader_plane
|
||||
// ncreader_write_egc
|
||||
|
||||
mod types;
|
||||
pub use types::{NcReader, NcReaderOptions};
|
||||
pub use types::{
|
||||
NCREADER_OPTION_CURSOR, NCREADER_OPTION_HORSCROLL, NCREADER_OPTION_NOCMDKEYS,
|
||||
NCREADER_OPTION_VERSCROLL,
|
||||
};
|
||||
mod methods;
|
||||
|
||||
use crate::{ncreader_create, NcPlane};
|
||||
/// Provides a freeform input in a (possibly multiline) region
|
||||
///
|
||||
/// Supports optional readline keybindings (opt out using
|
||||
/// NCREADER_OPTION_NOCMDKEYS flag)
|
||||
///
|
||||
/// Takes ownership of its [`NcPlane`], destroying it on any
|
||||
/// error (`ncreader_destroy`() otherwise destroys the ncplane).
|
||||
///
|
||||
/// `type in C: ncreader (struct)`
|
||||
///
|
||||
pub type NcReader = crate::bindings::bindgen::ncreader;
|
||||
|
||||
impl NcReader {
|
||||
/// `NcReader` simple constructor
|
||||
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
|
||||
Self::with_options(plane, &NcReaderOptions::new())
|
||||
}
|
||||
/// Options struct for [`NcReader`]
|
||||
///
|
||||
/// `type in C: ncreader_options (struct)`
|
||||
///
|
||||
pub type NcReaderOptions = crate::bindings::bindgen::ncreader_options;
|
||||
|
||||
/// `NcReader` constructor with options
|
||||
pub unsafe fn with_options<'a>(plane: &mut NcPlane, options: &NcReaderOptions) -> &'a mut Self {
|
||||
&mut *ncreader_create(plane, options)
|
||||
}
|
||||
}
|
||||
/// Make the terminal cursor visible across the lifetime of the ncreader, and
|
||||
/// have the ncreader manage the cursor's placement.
|
||||
pub const NCREADER_OPTION_CURSOR: u32 = crate::bindings::bindgen::NCREADER_OPTION_CURSOR;
|
||||
|
||||
impl NcReaderOptions {
|
||||
/// `NcReaderOptions` simple constructor
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
// channels used for input
|
||||
tchannels: 0,
|
||||
// attributes used for input
|
||||
tattrword: 0,
|
||||
// bitfield of NCREADER_OPTION_*
|
||||
flags: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Enable horizontal scrolling. Virtual lines can then grow arbitrarily long.
|
||||
pub const NCREADER_OPTION_HORSCROLL: u32 = crate::bindings::bindgen::NCREADER_OPTION_HORSCROLL;
|
||||
|
||||
/// Disable all editing shortcuts. By default, emacs-style keys are available.
|
||||
pub const NCREADER_OPTION_NOCMDKEYS: u32 = crate::bindings::bindgen::NCREADER_OPTION_NOCMDKEYS;
|
||||
|
||||
/// Enable vertical scrolling. You can then use arbitrarily many virtual lines.
|
||||
pub const NCREADER_OPTION_VERSCROLL: u32 = crate::bindings::bindgen::NCREADER_OPTION_VERSCROLL;
|
||||
|
@ -1,32 +0,0 @@
|
||||
//! ´NcReader´ widget types
|
||||
|
||||
/// Provides a freeform input in a (possibly multiline) region
|
||||
///
|
||||
/// Supports optional readline keybindings (opt out using
|
||||
/// NCREADER_OPTION_NOCMDKEYS flag)
|
||||
///
|
||||
/// Takes ownership of its [`NcPlane`], destroying it on any
|
||||
/// error (`ncreader_destroy`() otherwise destroys the ncplane).
|
||||
///
|
||||
/// `type in C: ncreader (struct)`
|
||||
///
|
||||
pub type NcReader = crate::bindings::bindgen::ncreader;
|
||||
|
||||
/// Options struct for [`NcReader`]
|
||||
///
|
||||
/// `type in C: ncreader_options (struct)`
|
||||
///
|
||||
pub type NcReaderOptions = crate::bindings::bindgen::ncreader_options;
|
||||
|
||||
/// Make the terminal cursor visible across the lifetime of the ncreader, and
|
||||
/// have the ncreader manage the cursor's placement.
|
||||
pub const NCREADER_OPTION_CURSOR: u32 = crate::bindings::bindgen::NCREADER_OPTION_CURSOR;
|
||||
|
||||
/// Enable horizontal scrolling. Virtual lines can then grow arbitrarily long.
|
||||
pub const NCREADER_OPTION_HORSCROLL: u32 = crate::bindings::bindgen::NCREADER_OPTION_HORSCROLL;
|
||||
|
||||
/// Disable all editing shortcuts. By default, emacs-style keys are available.
|
||||
pub const NCREADER_OPTION_NOCMDKEYS: u32 = crate::bindings::bindgen::NCREADER_OPTION_NOCMDKEYS;
|
||||
|
||||
/// Enable vertical scrolling. You can then use arbitrarily many virtual lines.
|
||||
pub const NCREADER_OPTION_VERSCROLL: u32 = crate::bindings::bindgen::NCREADER_OPTION_VERSCROLL;
|
@ -1,6 +1,32 @@
|
||||
//! `NcReel` widget
|
||||
//!
|
||||
//! `NcReel` widget.
|
||||
|
||||
mod types;
|
||||
pub use types::{NcReel, NcReelOptions, NcTablet};
|
||||
pub use types::{NCREEL_OPTION_CIRCULAR, NCREEL_OPTION_INFINITESCROLL};
|
||||
/// A wheel with `NcTablet`s on the outside
|
||||
///
|
||||
/// An `NcReel` is projected onto the 2d rendering area, showing some portion of
|
||||
/// the `NcReel`, and zero or more `NcTablet`s.
|
||||
///
|
||||
/// An `NcReel` is a `Notcurses` region devoted to displaying zero or more
|
||||
/// line-oriented, contained `NcTablet`s between which the user may navigate.
|
||||
///
|
||||
/// If at least one `NcTablet`s exists, there is a "focused tablet".
|
||||
/// As much of the focused tablet as is possible is always displayed.
|
||||
///
|
||||
/// If there is space left over, other tablets are included in the display.
|
||||
/// Tablets can come and go at any time, and can grow or shrink at any time.
|
||||
pub type NcReel = crate::bindings::bindgen::ncreel;
|
||||
|
||||
/// Options struct for [`NcReel`]
|
||||
pub type NcReelOptions = crate::bindings::bindgen::ncreel_options;
|
||||
|
||||
/// Visual tablet for [`NcReel`]
|
||||
pub type NcTablet = crate::bindings::bindgen::nctablet;
|
||||
|
||||
/// is navigation circular (does moving down from the last tablet move to the
|
||||
/// first, and vice versa)? only meaningful when infinitescroll is true. if
|
||||
/// infinitescroll is false, this must be false.
|
||||
pub const NCREEL_OPTION_CIRCULAR: u32 = crate::bindings::bindgen::NCREEL_OPTION_CIRCULAR;
|
||||
/// is scrolling infinite (can one move down or up forever, or is an end
|
||||
/// reached?). if true, 'circular' specifies how to handle the special case of
|
||||
/// an incompletely-filled reel.
|
||||
pub const NCREEL_OPTION_INFINITESCROLL: u32 =
|
||||
crate::bindings::bindgen::NCREEL_OPTION_INFINITESCROLL;
|
||||
|
@ -1,30 +0,0 @@
|
||||
/// A wheel with `NcTablet`s on the outside
|
||||
///
|
||||
/// An `NcReel` is projected onto the 2d rendering area, showing some portion of
|
||||
/// the `NcReel`, and zero or more `NcTablet`s.
|
||||
///
|
||||
/// An `NcReel` is a `Notcurses` region devoted to displaying zero or more
|
||||
/// line-oriented, contained `NcTablet`s between which the user may navigate.
|
||||
///
|
||||
/// If at least one `NcTablet`s exists, there is a "focused tablet".
|
||||
/// As much of the focused tablet as is possible is always displayed.
|
||||
///
|
||||
/// If there is space left over, other tablets are included in the display.
|
||||
/// Tablets can come and go at any time, and can grow or shrink at any time.
|
||||
pub type NcReel = crate::bindings::bindgen::ncreel;
|
||||
|
||||
/// Options struct for [`NcReel`]
|
||||
pub type NcReelOptions = crate::bindings::bindgen::ncreel_options;
|
||||
|
||||
/// Visual tablet for [`NcReel`]
|
||||
pub type NcTablet = crate::bindings::bindgen::nctablet;
|
||||
|
||||
/// is navigation circular (does moving down from the last tablet move to the
|
||||
/// first, and vice versa)? only meaningful when infinitescroll is true. if
|
||||
/// infinitescroll is false, this must be false.
|
||||
pub const NCREEL_OPTION_CIRCULAR: u32 = crate::bindings::bindgen::NCREEL_OPTION_CIRCULAR;
|
||||
/// is scrolling infinite (can one move down or up forever, or is an end
|
||||
/// reached?). if true, 'circular' specifies how to handle the special case of
|
||||
/// an incompletely-filled reel.
|
||||
pub const NCREEL_OPTION_INFINITESCROLL: u32 =
|
||||
crate::bindings::bindgen::NCREEL_OPTION_INFINITESCROLL;
|
@ -1,5 +1,10 @@
|
||||
//! `NcSelector` widget
|
||||
//!
|
||||
//! `NcSelector` widget.
|
||||
|
||||
mod types;
|
||||
pub use types::{NcSelector, NcSelectorItem, NcSelectorOptions};
|
||||
/// high-level widget for selecting one item from a set
|
||||
pub type NcSelector = crate::bindings::bindgen::ncselector;
|
||||
|
||||
/// an item for [`NcSelector`]
|
||||
pub type NcSelectorItem = crate::bindings::bindgen::ncselector_item;
|
||||
|
||||
/// Options structur for [`NcSelector`]
|
||||
pub type NcSelectorOptions = crate::bindings::bindgen::ncselector_options;
|
||||
|
@ -1,10 +0,0 @@
|
||||
//! `NcSelector` types
|
||||
|
||||
/// high-level widget for selecting one item from a set
|
||||
pub type NcSelector = crate::bindings::bindgen::ncselector;
|
||||
|
||||
/// an item for [`NcSelector`]
|
||||
pub type NcSelectorItem = crate::bindings::bindgen::ncselector_item;
|
||||
|
||||
/// Options structur for [`NcSelector`]
|
||||
pub type NcSelectorOptions = crate::bindings::bindgen::ncselector_options;
|
Loading…
x
Reference in New Issue
Block a user