rust: refactoring and corrections.

- reorder cell, ncchannel & ncplane reimplemented functions.
- minor fixes and corrections.
- improve doc comments.
This commit is contained in:
joseLuís 2020-12-04 13:31:21 +01:00
parent 0645fb3931
commit 6ad18bfa7b
9 changed files with 823 additions and 827 deletions

View File

@ -1,11 +1,10 @@
//! `NcCell` methods and associated functions.
pub use crate::{
cell_load, cstring, NcCell, NcChannelPair, NcEgcBackstop, NcPlane, NcStyleMask, NCRESULT_ERR,
use crate::{
cell_extract, cell_load, cstring, NcCell, NcChannelPair, NcEgc, NcEgcBackstop, NcPlane,
NcStyleMask, NCRESULT_ERR,
};
use crate::{cell_extract, NcEgc};
/// # `NcCell` Constructors
impl NcCell {
/// New NcCell, expects a [char], [NcStyleMask] and [NcChannelPair].

View File

@ -15,6 +15,343 @@ use crate::{
NCRESULT_ERR, NCRESULT_OK, NCSTYLE_MASK,
};
// Alpha -----------------------------------------------------------------------
/// 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)
}
/// 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);
}
// Channels --------------------------------------------------------------------
/// Gets the foreground [NcChannel] from an [NcCell].
#[inline]
pub fn cell_fchannel(cell: &NcCell) -> NcChannel {
channels_fchannel(cell.channels)
}
/// Gets the background [NcChannel] from an [NcCell].
#[inline]
pub fn cell_bchannel(cell: &NcCell) -> NcChannel {
channels_bchannel(cell.channels)
}
/// Sets the foreground [NcChannel] of an [NcCell] and returns the new
/// [NcChannelPair].
#[inline]
pub fn cell_set_fchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair {
channels_set_fchannel(&mut cell.channels, channel)
}
/// Sets the background [NcChannel] of an [NcCell] and returns the new
/// [NcChannelPair].
#[inline]
pub fn cell_set_bchannel(cell: &mut NcCell, channel: NcChannel) -> NcChannelPair {
channels_set_bchannel(&mut cell.channels, channel)
}
// NcColor ---------------------------------------------------------------------
/// Gets the foreground [NcColor] RGB components of an [NcCell],
/// and returns the [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)
}
/// Gets the background [NcColor] RGB components of an [NcCell],
/// and returns the [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 foreground [NcColor] 8-bit RGB components of of the [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 background [NcColor] 8-bit RGB components of 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);
}
// NcRgb -----------------------------------------------------------------------
/// Gets the foreground [NcRgb] from an [NcCell] (shifted to LSBs).
#[inline]
pub fn cell_fg_rgb(cell: &NcCell) -> NcRgb {
channels_fg_rgb(cell.channels)
}
/// Gets the background [NcRgb] from an [NcCell] (shifted to LSBs).
#[inline]
pub fn cell_bg_rgb(cell: &NcCell) -> NcRgb {
channels_bg_rgb(cell.channels)
}
/// Sets the foreground [NcRgb] 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 the background [NcRgb] of an [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);
}
// Default ---------------------------------------------------------------------
/// 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);
}
/// 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 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)
}
// Palette ---------------------------------------------------------------------
/// 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 an
/// [NcPaletteIndex] [indexed][NcPaletteIndex] [NcPalette][crate::NcPalette] color?
#[inline]
pub fn cell_bg_palindex_p(cell: &NcCell) -> bool {
channels_bg_palindex_p(cell.channels)
}
/// Gets 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
}
/// Gets the [NcPaletteIndex] of the background [NcChannel] of the [NcCell].
#[inline]
pub fn cell_bg_palindex(cell: &NcCell) -> NcPaletteIndex {
(cell.channels & 0xff) as NcPaletteIndex
}
/// 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;
}
/// 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;
}
// Styles ----------------------------------------------------------------------
/// 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);
}
/// 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;
}
// Chars -----------------------------------------------------------------------
/// 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
}
/// 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;
}
/// 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)
// }
}
// Misc. -----------------------------------------------------------------------
/// Saves the [NcStyleMask] and the [NcChannelPair],
/// and returns the [NcEgc], 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
}
}
/// Initializes (zeroes out) an [NcCell].
#[inline]
pub fn cell_init(cell: &mut NcCell) {
*cell = unsafe { core::mem::zeroed() }
}
/// 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'.
@ -106,329 +443,3 @@ pub unsafe fn cells_load_box(
}
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)
}

View File

@ -6,54 +6,9 @@ use crate::{
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
}
// Alpha -----------------------------------------------------------------------
/// 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].
/// Gets the [NcAlphaBits] 2-bit component from a 32-bit [NcChannel].
#[inline]
pub fn channel_alpha(channel: NcChannel) -> NcAlphaBits {
channel & NCCHANNEL_ALPHA_MASK
@ -71,25 +26,41 @@ pub fn channel_set_alpha(channel: &mut NcChannel, alpha: NcAlphaBits) {
}
}
/// Is this [NcChannel] using the "default color" rather than RGB/palette-indexed?
/// Gets the foreground [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
#[inline]
pub fn channel_default_p(channel: NcChannel) -> bool {
(channel & NCCELL_BGDEFAULT_MASK) == 0
pub fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits {
channel_alpha(channels_fchannel(channels))
}
/// Is this [NcChannel] using palette-indexed color rather than RGB?
/// Gets the background [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
#[inline]
pub fn channel_palindex_p(channel: NcChannel) -> bool {
!(channel_default_p(channel) && (channel & NCCELL_BG_PALETTE) == 0)
pub fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits {
channel_alpha(channels_bchannel(channels))
}
/// Marks an [NcChannel] as using its "default color", which also marks it opaque.
/// Sets the [NcAlphaBits] of the foreground [NcChannel] of an [NcChannelPair].
#[inline]
pub fn channel_set_default(channel: &mut NcChannel) -> NcChannel {
*channel &= !(NCCELL_BGDEFAULT_MASK | NCCELL_ALPHA_HIGHCONTRAST);
*channel
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);
}
// Channels --------------------------------------------------------------------
/// Extracts the 32-bit background [NcChannel] from a [NcChannelPair].
#[inline]
pub fn channels_bchannel(channels: NcChannelPair) -> NcChannel {
@ -125,33 +96,49 @@ pub fn channels_combine(fchannel: NcChannel, bchannel: NcChannel) -> NcChannelPa
channels
}
/// Extracts the foreground [NcRgb] 24-bit value from an [NcChannelPair],
/// shifted to LSBs.
// NcColor ---------------------------------------------------------------------
/// Gets the red [NcColor] 8-bit component from a 32-bit [NcChannel].
#[inline]
pub fn channels_fg_rgb(channels: NcChannelPair) -> NcChannel {
channels_fchannel(channels) & NCCELL_BG_RGB_MASK
pub const fn channel_r(channel: NcChannel) -> NcColor {
((channel & 0xff0000) >> 16) as NcColor
}
/// Extracts the background [NcRgb] 24-bit value from an [NcChannelPair],
/// shifted to LSBs.
/// Gets the [NcColor] 8-bit component from a 32-bit [NcChannel].
#[inline]
pub fn channels_bg_rgb(channels: NcChannelPair) -> NcChannel {
channels_bchannel(channels) & NCCELL_BG_RGB_MASK
pub const fn channel_b(channel: NcChannel) -> NcColor {
(channel & 0x0000ff) as NcColor
}
/// Extracts the foreground [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
/// Gets the green [NcColor] 8-bit component from a 32-bit [NcChannel].
#[inline]
pub fn channels_fg_alpha(channels: NcChannelPair) -> NcAlphaBits {
channel_alpha(channels_fchannel(channels))
pub const fn channel_g(channel: NcChannel) -> NcColor {
((channel & 0x00ff00) >> 8) as NcColor
}
/// Extracts the background [NcAlphabits] from an [NcChannelPair], shifted to LSBs.
/// Gets the three [NcColor] 8-bit RGB components from a 32-bit [NcChannel].
#[inline]
pub fn channels_bg_alpha(channels: NcChannelPair) -> NcAlphaBits {
channel_alpha(channels_bchannel(channels))
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
}
/// Extracts the foreground [NcRgb] 24-bit value from an [NcChannelPair], and
/// 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;
}
/// Gets 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]
@ -164,7 +151,7 @@ pub fn channels_fg_rgb8(
channel_rgb8(channels_fchannel(channels), r, g, b)
}
/// Extracts the background [NcRgb] 24-bit value from an [NcChannelPair], and
/// Gets 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]
@ -186,15 +173,6 @@ pub fn channels_set_fg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor
*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]
@ -204,8 +182,40 @@ pub fn channels_set_bg_rgb8(channels: &mut NcChannelPair, r: NcColor, g: NcColor
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".
// NcRgb -----------------------------------------------------------------------
/// Gets 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
}
/// Gets 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
}
/// 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);
}
/// Sets the foreground [NcRgb] 24-bit value of an [NcChannelPair],
/// 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 background [NcRgb] 24-bit value of an [NcChannelPair],
/// , 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);
@ -213,25 +223,19 @@ pub fn channels_set_bg_rgb(channels: &mut NcChannelPair, rgb: NcRgb) {
channels_set_bchannel(channels, channel);
}
/// Sets the [NcAlphaBits] of the foreground [NcChannel] of an [NcChannelPair].
// Default ---------------------------------------------------------------------
/// Is this [NcChannel] using the "default color" rather than RGB/palette-indexed?
#[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;
pub fn channel_default_p(channel: NcChannel) -> bool {
(channel & NCCELL_BGDEFAULT_MASK) == 0
}
/// Sets the [NcAlphaBits] of the background [NcChannel] of an [NcChannelPair].
/// Marks an [NcChannel] as using its "default color", which also marks it opaque.
#[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);
pub fn channel_set_default(channel: &mut NcChannel) -> NcChannel {
*channel &= !(NCCELL_BGDEFAULT_MASK | NCCELL_ALPHA_HIGHCONTRAST);
*channel
}
/// Is the foreground of an [NcChannelPair] using the "default foreground color"?
@ -240,13 +244,6 @@ 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.
@ -255,39 +252,6 @@ 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]
@ -307,3 +271,51 @@ pub fn channels_set_bg_default(channels: &mut NcChannelPair) -> NcChannelPair {
channels_set_bchannel(channels, channel);
*channels
}
// Palette ---------------------------------------------------------------------
/// 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)
}
/// 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 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 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;
}
/// 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;
}

View File

@ -2,7 +2,7 @@
// General Utility Macros ------------------------------------------------------
/// Sleeps for $ms milliseconds
/// Sleeps for $ms milliseconds.
#[macro_export]
macro_rules! sleep {
($ms:expr) => {
@ -10,7 +10,7 @@ macro_rules! sleep {
};
}
/// Converts an `&str` to `*mut CString`, for when `*const c_char` is needed.
/// Converts `&str` to `*mut CString`, for when `*const c_char` is needed.
#[macro_export]
macro_rules! cstring {
($s:expr) => {

View File

@ -1,14 +1,5 @@
//! `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::{

View File

@ -21,7 +21,7 @@
// + palette256_set
// + palette256_set_rgb
pub mod reimplemented;
mod reimplemented;
pub use reimplemented::*;
/// NcPalette structure consisting of an array of 256 [`NcChannel`]s.

View File

@ -15,18 +15,170 @@ use crate::{
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)
// Alpha -----------------------------------------------------------------------
/// Gets the foreground [NcAlphaBits] from the [NcPlane], shifted to LSBs.
#[inline]
pub fn ncplane_align(plane: &NcPlane, align: NcAlign, cols: i32) -> i32 {
notcurses_align(ncplane_dim_x(plane), align, cols)
pub fn ncplane_fg_alpha(plane: &NcPlane) -> NcAlphaBits {
channels_fg_alpha(unsafe { ncplane_channels(plane) })
}
/// Retrieve the current contents of the cell under the cursor into 'cell'.
/// This cell is invalidated if the associated plane is destroyed.
/// Gets the background [NcAlphaBits] from the [NcPlane], shifted to LSBs.
#[inline]
pub fn ncplane_bg_alpha(plane: &NcPlane) -> NcAlphaBits {
channels_bg_alpha(unsafe { ncplane_channels(plane) })
}
// NcChannel -------------------------------------------------------------------
/// Gets the foreground [NcChannel] from an [NcPlane].
#[inline]
pub fn ncplane_fchannel(plane: &NcPlane) -> NcChannel {
channels_fchannel(unsafe { ncplane_channels(plane) })
}
/// Gets the background [NcChannel] from an [NcPlane].
#[inline]
pub fn ncplane_bchannel(plane: &NcPlane) -> NcChannel {
channels_bchannel(unsafe { ncplane_channels(plane) })
}
// NcColor ---------------------------------------------------------------------
/// Gets the foreground [NcColor] RGB components from an [NcPlane].
#[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)
}
/// Gets the background [NcColor] RGB components from an [NcPlane].
#[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)
}
// NcRgb -----------------------------------------------------------------------
/// Gets the foreground [NcRgb] from an [NcPlane], shifted to LSBs.
#[inline]
pub fn ncplane_fg_rgb(plane: &NcPlane) -> NcChannel {
channels_fg_rgb(unsafe { ncplane_channels(plane) })
}
/// Gets the background [NcRgb] from an [NcPlane], shifted to LSBs.
#[inline]
pub fn ncplane_bg_rgb(plane: &NcPlane) -> NcChannel {
channels_bg_rgb(unsafe { ncplane_channels(plane) })
}
// Default ---------------------------------------------------------------------
/// 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) })
}
// put & print -----------------------------------------------------------------
/// Calls 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) }
}
/// Calls 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)
}
/// Replaces the [NcEgc] underneath us, but retain the styling.
/// The current styling of the plane will not be changed.
///
/// Replace the [NcCell] at the specified coordinates with the provided 7-bit char.
///
/// 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)
}
}
/// Calls `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(),
)
}
}
/// The [NcPlane] equivalent of `vprintf(3)`.
#[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,
)
}
}
// NcCell ----------------------------------------------------------------------
/// Retrieves the current contents of the [NcCell] under the cursor.
///
/// This NcCell is invalidated if the associated NcPlane 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) };
@ -42,7 +194,7 @@ pub fn ncplane_at_cursor_cell(plane: &mut NcPlane, cell: &mut NcCell) -> NcResul
result
}
/// Retrieve the current contents of the specified cell into 'cell'.
/// Retrieves 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 {
@ -59,41 +211,9 @@ pub fn ncplane_at_yx_cell(plane: &mut NcPlane, y: i32, x: i32, cell: &mut NcCell
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,
)
}
}
// size & alignment ------------------------------------------------------------
///
/// Gets the columns of the [NcPlane].
#[inline]
pub fn ncplane_dim_x(plane: &NcPlane) -> i32 {
unsafe {
@ -103,7 +223,8 @@ pub fn ncplane_dim_x(plane: &NcPlane) -> i32 {
}
}
///
/// Gets the rows of the [NcPlane].
#[inline]
#[inline]
pub fn ncplane_dim_y(plane: &NcPlane) -> i32 {
unsafe {
@ -113,82 +234,59 @@ pub fn ncplane_dim_y(plane: &NcPlane) -> i32 {
}
}
///
/// Resizes 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_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();
pub fn ncplane_resize_simple(plane: &mut NcPlane, ylen: i32, xlen: i32) -> NcResult {
let (mut oldy, mut oldx) = (0, 0);
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);
ncplane_dim_yx(plane, &mut oldy, &mut oldx);
}
let keepleny = {
if oldy > ylen {
ylen
} else {
oldy
}
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
};
let keeplenx = {
if oldx > xlen {
xlen
} else {
oldx
}
};
unsafe { ncplane_resize(plane, 0, 0, keepleny, keeplenx, 0, 0, ylen, xlen) }
}
///
/// Returns 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. See:
// - > https://github.com/dankamongmen/notcurses/issues/920
// - https://github.com/dankamongmen/notcurses/issues/904
#[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,
)
pub fn ncplane_align(plane: &NcPlane, align: NcAlign, cols: i32) -> i32 {
notcurses_align(ncplane_dim_x(plane), align, cols)
}
// line ------------------------------------------------------------------------
/// 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) }
}
///
/// 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) }
}
// perimeter -------------------------------------------------------------------
///
#[inline]
pub fn ncplane_perimeter(
@ -307,218 +405,110 @@ pub fn ncplane_perimeter_rounded(
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) }
}
// box -------------------------------------------------------------------------
/// Call ncplane_putchar_yx() at the current cursor location.
/// 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_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(
pub fn ncplane_box_sized(
plane: &mut NcPlane,
egc: &[u8],
stylemask: NcStyleMask,
ul: u64,
ur: u64,
ll: u64,
lr: u64,
ul: &NcCell,
ur: &NcCell,
ll: &NcCell,
lr: &NcCell,
hline: &NcCell,
vline: &NcCell,
ylen: i32,
xlen: i32,
ctlword: u32,
) -> 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(
ncplane_box(
plane,
CString::new(egc).expect("Bad EGC").as_ptr(),
stylemask as u32,
ul,
ur,
ll,
lr,
hline,
vline,
y + ylen - 1,
x + xlen - 1,
ctlword,
)
}
}
/// Extract the 32-bit working foreground channel from an ncplane.
///
#[inline]
pub fn ncplane_fchannel(plane: &NcPlane) -> NcChannel {
channels_fchannel(unsafe { ncplane_channels(plane) })
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
}
/// 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)
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,
)
}
///
@ -590,55 +580,42 @@ pub fn ncplane_rounded_box_sized(
)
}
// static inline int
// ncplane_printf(struct ncplane* n, const char* format, ...)
// __attribute__ ((format (printf, 2, 3)));
// gradient --------------------------------------------------------------------
// 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;
// }
/// 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? See:
// - https://github.com/dankamongmen/notcurses/issues/920
// - https://github.com/dankamongmen/notcurses/issues/904
#[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,
)
}
}

View File

@ -7,6 +7,7 @@ use crate::{
NcPlane,
};
/// # `NcMenu` Constructors
impl NcMenu {
/// `NcMenu` simple constructor
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
@ -19,6 +20,7 @@ impl NcMenu {
}
}
/// # `NcMenuOptions` Constructors
impl NcMenuOptions {
/// `NcMenuOptions` simple constructor
pub fn new() -> Self {
@ -52,6 +54,7 @@ impl NcMenuOptions {
}
}
/// # `NcMenuItem` Constructors
impl NcMenuItem {
/// `NcMenuItem` simple constructor
pub fn new(mut desc: i8, shortcut: NcInput) -> Self {
@ -65,6 +68,7 @@ impl NcMenuItem {
}
}
/// # `NcMenuSection` Constructors
impl NcMenuSection {
/// `NcMenuSection` simple constructor
pub fn new(name: &str, itemcount: i32, items: &mut [NcMenuItem], shortcut: NcInput) -> Self {

View File

@ -2,6 +2,7 @@
use crate::{ncreader_create, NcPlane, NcReader, NcReaderOptions};
/// # `NcReader` Constructors
impl NcReader {
/// `NcReader` simple constructor
pub unsafe fn new<'a>(plane: &mut NcPlane) -> &'a mut Self {
@ -14,6 +15,7 @@ impl NcReader {
}
}
/// # `NcReaderOptions` Constructors
impl NcReaderOptions {
/// `NcReaderOptions` simple constructor
pub fn new() -> Self {