mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
[rust] fix the NcEgc
mess.
- An `EGC` is an UTF-8 string of length 1, not a unicode code point (char). - remove the `NcEgc` type and use `&str` and `String`, instead (for now). - update some docs. - rustfmt.
This commit is contained in:
parent
dc6f697995
commit
cadca69138
@ -1,8 +1,8 @@
|
||||
//! `NcCell` methods and associated functions.
|
||||
|
||||
use crate::{
|
||||
cstring, error, nccell_load, NcAlphaBits, NcCell, NcChannels, NcComponent, NcEgc,
|
||||
NcEgcBackstop, NcPaletteIndex, NcPlane, NcResult, NcRgb, NcStyle, NCRESULT_ERR,
|
||||
cstring, error, nccell_load, NcAlphaBits, NcCell, NcChannels, NcComponent, NcEgcBackstop,
|
||||
NcPaletteIndex, NcPlane, NcResult, NcRgb, NcStyle, NCRESULT_ERR,
|
||||
};
|
||||
|
||||
#[allow(unused_imports)] // for the doc comments
|
||||
@ -293,19 +293,19 @@ impl NcCell {
|
||||
|
||||
/// # `NcCell` methods: other components
|
||||
impl NcCell {
|
||||
/// Returns true if the two cells have distinct [`NcEgc`]s, attributes,
|
||||
/// Returns true if the two cells have distinct `EGC`s, attributes,
|
||||
/// or [`NcChannel`]s.
|
||||
///
|
||||
/// The actual egcpool index needn't be the same--indeed, the planes
|
||||
/// needn't even be the same. Only the expanded NcEgc must be bit-equal.
|
||||
/// needn't even be the same. Only the expanded `EGC` must be bit-equal.
|
||||
///
|
||||
/// *C style function: [nccellcmp()][crate::nccellcmp].*
|
||||
pub fn compare(plane1: &NcPlane, cell1: &NcCell, plane2: &NcPlane, cell2: &NcCell) -> bool {
|
||||
crate::nccellcmp(plane1, cell1, plane2, cell2)
|
||||
}
|
||||
|
||||
/// Saves the [`NcStyle`] and the [`NcChannels`], and returns the [`NcEgc`].
|
||||
/// (These are the three elements of an NcCell).
|
||||
/// Saves the [`NcStyle`] and the [`NcChannels`], and returns the `EGC`.
|
||||
/// (These are the three elements of an `NcCell`).
|
||||
///
|
||||
/// *C style function: [nccell_fg_alpha()][crate::nccell_fg_alpha].*
|
||||
pub fn extract(
|
||||
@ -313,16 +313,16 @@ impl NcCell {
|
||||
plane: &mut NcPlane,
|
||||
styles: &mut NcStyle,
|
||||
channels: &mut NcChannels,
|
||||
) -> NcEgc {
|
||||
) -> String {
|
||||
crate::nccell_extract(plane, self, styles, channels)
|
||||
}
|
||||
|
||||
/// Returns the [`NcEgc`] of the NcCell.
|
||||
/// Returns the `EGC` of the `NcCell`.
|
||||
///
|
||||
/// See also: [extended_gcluster][NcCell#method.extended_gcluster] method.
|
||||
///
|
||||
/// *(No equivalent C style function)*
|
||||
pub fn egc(&mut self, plane: &mut NcPlane) -> NcEgc {
|
||||
pub fn egc(&mut self, plane: &mut NcPlane) -> String {
|
||||
let (mut _styles, mut _channels) = (0, 0);
|
||||
crate::nccell_extract(plane, self, &mut _styles, &mut _channels)
|
||||
}
|
||||
@ -358,7 +358,7 @@ impl NcCell {
|
||||
|
||||
/// # `NcCell` methods: text
|
||||
impl NcCell {
|
||||
// /// Returns a pointer to the [`NcEgc`] of this NcCell in the [NcPlane] `plane`.
|
||||
// /// Returns a pointer to the `EGC` of this NcCell in the [NcPlane] `plane`.
|
||||
// ///
|
||||
// /// This pointer can be invalidated by any further operation on the referred
|
||||
// /// plane, so… watch out!
|
||||
@ -369,14 +369,14 @@ impl NcCell {
|
||||
// egcpointer
|
||||
// }
|
||||
|
||||
/// Copies the UTF8-encoded [`NcEgc`] out of this NcCell,
|
||||
/// Copies the UTF8-encoded `EGC` out of this NcCell,
|
||||
/// whether simple or complex.
|
||||
///
|
||||
/// The result is not tied to the [NcPlane],
|
||||
/// and persists across erases and destruction.
|
||||
///
|
||||
/// *C style function: [nccell_strdup()][crate::nccell_strdup].*
|
||||
pub fn strdup(&self, plane: &NcPlane) -> NcEgc {
|
||||
pub fn strdup(&self, plane: &NcPlane) -> String {
|
||||
crate::nccell_strdup(plane, self)
|
||||
}
|
||||
|
||||
@ -404,11 +404,11 @@ impl NcCell {
|
||||
|
||||
/// # `NcCell` methods: boxes
|
||||
impl NcCell {
|
||||
/// Loads up six cells with the [`NcEgc`]s necessary to draw a box.
|
||||
/// Loads up six cells with the `EGC`s necessary to draw a box.
|
||||
///
|
||||
/// On error, any [`NcCell`]s this function might have loaded before the error
|
||||
/// are [release][NcCell#method.release]d.
|
||||
/// There must be at least six [`NcEgc`]s in `gcluster`.
|
||||
/// There must be at least six `EGC`s in `gcluster`.
|
||||
///
|
||||
/// *C style function: [nccells_load_box()][crate::nccells_load_box].*
|
||||
pub fn load_box(
|
||||
|
@ -90,7 +90,7 @@ use crate::{NcChannel, NcPlane};
|
||||
/// # Description
|
||||
///
|
||||
/// An `NcCell` corresponds to a single character cell on some `NcPlane`,
|
||||
/// which can be occupied by a single [`NcEgc`] grapheme cluster (some root
|
||||
/// which can be occupied by a single `EGC` grapheme cluster (some root
|
||||
/// spacing glyph, along with possible combining characters, which might span
|
||||
/// multiple columns).
|
||||
///
|
||||
@ -114,14 +114,14 @@ use crate::{NcChannel, NcPlane};
|
||||
/// ```txt
|
||||
/// NcCell: 128 bits structure comprised of the following 5 elements:
|
||||
///
|
||||
/// GCLUSTER|GCLUSTER|GCLUSTER|GCLUSTER 1. NcEgc
|
||||
/// GCLUSTER|GCLUSTER|GCLUSTER|GCLUSTER 1. `EGC`
|
||||
/// 00000000║WWWWWWWW║11111111|11111111 2. NcEgcBackstop + 3. width + 4. NcStyle
|
||||
/// ~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB 5. NcChannels
|
||||
/// ~~AA~~~~|RRRRRRRR|GGGGGGGG|BBBBBBBB "
|
||||
///
|
||||
/// 1. (32b) Extended Grapheme Cluster, presented either as:
|
||||
///
|
||||
/// 1.1. An NcEgc of up to 4 bytes:
|
||||
/// 1.1. An EGC 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:
|
||||
@ -148,7 +148,7 @@ use crate::{NcChannel, NcPlane};
|
||||
///
|
||||
/// 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`]
|
||||
/// is not reliable. It's just quoting whether or not the `EGC`
|
||||
/// contains a "Wide Asian" double-width character.
|
||||
/// This is set for some things, like most emoji, and not set for
|
||||
/// other things, like cuneiform.
|
||||
@ -207,62 +207,63 @@ use crate::{NcChannel, NcPlane};
|
||||
///
|
||||
pub type NcCell = crate::bindings::ffi::cell;
|
||||
|
||||
// RETHINK:
|
||||
//
|
||||
// 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)
|
||||
///
|
||||
///
|
||||
// TODO: there should be two types at least:
|
||||
// - an utf-8 string len 1 of type &str.
|
||||
// - a unicode codepoint of type char.
|
||||
pub type NcEgc = char;
|
||||
// /// Extended Grapheme Cluster. A unicode string of length 1.
|
||||
// ///
|
||||
// /// 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)
|
||||
// ///
|
||||
// ///
|
||||
// FIXME: should be an utf-8 string len 1 of type &str.
|
||||
// pub type NcEgc = String;
|
||||
// pub type NcEgc<'a> = &'a str;
|
||||
|
||||
// NcEgcBackStop
|
||||
/// An `u8` always at zero, part of the [`NcCell`] struct
|
||||
|
@ -3,7 +3,7 @@
|
||||
use libc::strcmp;
|
||||
|
||||
use crate::{
|
||||
cstring, nccell_release, NcAlphaBits, NcCell, NcChannel, NcChannels, NcComponent, NcEgc,
|
||||
cstring, nccell_release, rstring, NcAlphaBits, NcCell, NcChannel, NcChannels, NcComponent,
|
||||
NcIntResult, NcPaletteIndex, NcPlane, NcRgb, NcStyle, NCALPHA_BGDEFAULT_MASK,
|
||||
NCALPHA_BG_PALETTE, NCALPHA_FGDEFAULT_MASK, NCALPHA_FG_PALETTE, NCALPHA_OPAQUE, NCRESULT_ERR,
|
||||
NCRESULT_OK, NCSTYLE_MASK,
|
||||
@ -313,13 +313,13 @@ pub const fn nccell_wide_left_p(cell: &NcCell) -> bool {
|
||||
nccell_double_wide_p(cell) && cell.gcluster != 0
|
||||
}
|
||||
|
||||
// /// Loads a 7-bit [`NcEgc`] character into the [`NcCell`].
|
||||
// /// Loads a 7-bit `EGC` character into the [`NcCell`].
|
||||
// ///
|
||||
// /// *Method: NcCell.[load_char()][NcCell#method.load_char].*
|
||||
// //
|
||||
// // TODO:CHECK is this necessary at all?
|
||||
// #[inline]
|
||||
// pub fn nccell_load_char(plane: &mut NcPlane, cell: &mut NcCell, ch: NcEgc) /* -> i32 */
|
||||
// pub fn nccell_load_char(plane: &mut NcPlane, cell: &mut NcCell, ch: char) /* -> i32 */
|
||||
// {
|
||||
// let _ = unsafe { crate::nccell_load(plane, cell, ch) };
|
||||
// }
|
||||
@ -354,29 +354,21 @@ pub const fn nccell_wide_left_p(cell: &NcCell) -> bool {
|
||||
// return nccell_load(n, c, gcluster);
|
||||
// }
|
||||
|
||||
/// Copies the UTF8-encoded [`NcEgc`] out of the [`NcCell`], whether simple or complex.
|
||||
/// Copies the UTF8-encoded `EGC` out of the [`NcCell`], whether simple or complex.
|
||||
///
|
||||
/// The result is not tied to the [NcPlane],
|
||||
/// and persists across erases and destruction.
|
||||
///
|
||||
/// *Method: NcCell.[strdup()][NcCell#method.strdup].*
|
||||
#[inline]
|
||||
pub fn nccell_strdup(plane: &NcPlane, cell: &NcCell) -> NcEgc {
|
||||
core::char::from_u32(
|
||||
unsafe { libc::strdup(crate::nccell_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(nccell_extended_gcluster(plane, cell)) as i32 as u32)
|
||||
// }
|
||||
pub fn nccell_strdup(plane: &NcPlane, cell: &NcCell) -> String {
|
||||
rstring![libc::strdup(crate::nccell_extended_gcluster(plane, cell))].into()
|
||||
}
|
||||
|
||||
// Misc. -----------------------------------------------------------------------
|
||||
|
||||
/// Saves the [`NcStyle`] and the [`NcChannels`],
|
||||
/// and returns the [`NcEgc`], of an [`NcCell`].
|
||||
/// and returns the `EGC`, of an [`NcCell`].
|
||||
///
|
||||
/// *Method: NcCell.[extract()][NcCell#method.extract].*
|
||||
#[inline]
|
||||
@ -385,7 +377,7 @@ pub fn nccell_extract(
|
||||
cell: &NcCell,
|
||||
stylemask: &mut NcStyle,
|
||||
channels: &mut NcChannels,
|
||||
) -> NcEgc {
|
||||
) -> String {
|
||||
if *stylemask != 0 {
|
||||
*stylemask = cell.stylemask;
|
||||
}
|
||||
@ -395,10 +387,10 @@ pub fn nccell_extract(
|
||||
nccell_strdup(plane, cell)
|
||||
}
|
||||
|
||||
/// Returns true if the two cells are distinct [`NcEgc`]s, attributes, or channels.
|
||||
/// Returns true if the two cells are distinct `EGC`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;
|
||||
/// be the same. Only the expanded EGC must be equal. The EGC must be bit-equal;
|
||||
///
|
||||
/// *Method: NcCell.[compare()][NcCell#method.compare].*
|
||||
//
|
||||
@ -448,12 +440,12 @@ pub fn nccell_prime(
|
||||
unsafe { crate::nccell_load(plane, cell, cstring![gcluster]) }
|
||||
}
|
||||
|
||||
/// Loads up six cells with the [`NcEgc`]s necessary to draw a box.
|
||||
/// Loads up six cells with the `EGC`s necessary to draw a box.
|
||||
///
|
||||
/// Returns [`NCRESULT_OK`] on success or [`NCRESULT_ERR`] on error.
|
||||
///
|
||||
/// On error, any [`NcCell`]s this function might have loaded before the error
|
||||
/// are [nccell_release]d. There must be at least six [`NcEgc`]s in `gcluster`.
|
||||
/// are [nccell_release]d. There must be at least six `EGC`s in `gcluster`.
|
||||
///
|
||||
/// *Method: NcCell.[load_box()][NcCell#method.load_box].*
|
||||
pub fn nccells_load_box(
|
||||
@ -468,6 +460,8 @@ pub fn nccells_load_box(
|
||||
vl: &mut NcCell,
|
||||
gcluster: &str,
|
||||
) -> NcIntResult {
|
||||
assert![gcluster.len() >= 6]; // DEBUG
|
||||
|
||||
// TODO: CHECK: mutable copy for pointer arithmetics:
|
||||
let mut gclu = cstring![gcluster];
|
||||
|
||||
|
@ -5,7 +5,7 @@ use core::ptr::{null, null_mut};
|
||||
use crate::ffi::sigset_t;
|
||||
use crate::{
|
||||
cstring, error, error_ref_mut, rstring, NcAlign, NcBlitter, NcCapabilities, NcChannels,
|
||||
NcComponent, NcDim, NcDirect, NcDirectFlags, NcEgc, NcError, NcInput, NcOffset, NcPaletteIndex,
|
||||
NcComponent, NcDim, NcDirect, NcDirectFlags, NcError, NcInput, NcOffset, NcPaletteIndex,
|
||||
NcPlane, NcResult, NcRgb, NcScale, NcStyle, NcTime, NCRESULT_ERR,
|
||||
};
|
||||
|
||||
@ -745,7 +745,7 @@ impl NcDirect {
|
||||
///
|
||||
/// All lines start at the current cursor position.
|
||||
///
|
||||
/// The [NcEgc] at `egc` may not use more than one column.
|
||||
/// The string at `egc` may not use more than one column.
|
||||
///
|
||||
/// For a horizontal line, `len` cannot exceed the screen width minus the
|
||||
/// cursor's offset.
|
||||
@ -754,18 +754,12 @@ impl NcDirect {
|
||||
#[inline]
|
||||
pub fn hline_interp(
|
||||
&mut self,
|
||||
egc: &NcEgc,
|
||||
egc: &str,
|
||||
len: NcDim,
|
||||
h1: NcChannels,
|
||||
h2: NcChannels,
|
||||
) -> NcResult<()> {
|
||||
// https://github.com/dankamongmen/notcurses/issues/1339
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "i686"))]
|
||||
let egc_ptr = &(*egc as i8);
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "i686")))]
|
||||
let egc_ptr = &(*egc as u8);
|
||||
|
||||
error![unsafe { crate::ncdirect_hline_interp(self, egc_ptr, len as i32, h1, h2) }]
|
||||
error![unsafe { crate::ncdirect_hline_interp(self, cstring![egc], len as i32, h1, h2) }]
|
||||
}
|
||||
|
||||
/// Draws horizontal lines using the specified [NcChannels]s, interpolating
|
||||
@ -773,7 +767,7 @@ impl NcDirect {
|
||||
///
|
||||
/// All lines start at the current cursor position.
|
||||
///
|
||||
/// The [NcEgc] at `egc` may not use more than one column.
|
||||
/// The string at `egc` may not use more than one column.
|
||||
///
|
||||
/// For a vertical line, `len` may be as long as you'd like; the screen
|
||||
/// will scroll as necessary.
|
||||
@ -782,17 +776,11 @@ impl NcDirect {
|
||||
#[inline]
|
||||
pub fn vline_interp(
|
||||
&mut self,
|
||||
egc: &NcEgc,
|
||||
egc: &str,
|
||||
len: NcDim,
|
||||
h1: NcChannels,
|
||||
h2: NcChannels,
|
||||
) -> NcResult<()> {
|
||||
// https://github.com/dankamongmen/notcurses/issues/1339
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "i686"))]
|
||||
let egc_ptr = &(*egc as i8);
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "i686")))]
|
||||
let egc_ptr = &(*egc as u8);
|
||||
|
||||
error![unsafe { crate::ncdirect_vline_interp(self, egc_ptr, len as i32, h1, h2) }]
|
||||
error![unsafe { crate::ncdirect_vline_interp(self, cstring![egc], len as i32, h1, h2) }]
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use core::ptr::{null, null_mut};
|
||||
|
||||
use crate::{
|
||||
cstring, error, error_ref_mut, notcurses_init, rstring, Nc, NcAlign, NcBlitter, NcChannels,
|
||||
NcDim, NcEgc, NcError, NcFile, NcInput, NcLogLevel, NcOptions, NcPlane, NcResult, NcScale,
|
||||
NcDim, NcError, NcFile, NcInput, NcLogLevel, NcOptions, NcPlane, NcResult, NcScale,
|
||||
NcSignalSet, NcStats, NcStyle, NcTime, NCOPTION_NO_ALTERNATE_SCREEN, NCOPTION_SUPPRESS_BANNERS,
|
||||
NCRESULT_ERR,
|
||||
};
|
||||
@ -130,10 +130,11 @@ impl Nc {
|
||||
}
|
||||
|
||||
/// Retrieves the current contents of the specified [NcCell][crate::NcCell]
|
||||
/// as last rendered, returning the [NcEgc] (or None on error) and writing
|
||||
/// out the [NcStyle] and the [NcChannels].
|
||||
/// as last rendered, returning the `EGC` (or None on error) and writing
|
||||
/// out the [`NcStyle`] and the [`NcChannels`].
|
||||
///
|
||||
/// This NcEgc must be freed by the caller.
|
||||
// possible BUG? CHECK:
|
||||
/// This `EGC` must be freed by the caller.
|
||||
///
|
||||
/// *C style function: [notcurses_at_yx()][crate::notcurses_at_yx].*
|
||||
pub fn at_yx(
|
||||
@ -142,16 +143,15 @@ impl Nc {
|
||||
x: NcDim,
|
||||
stylemask: &mut NcStyle,
|
||||
channels: &mut NcChannels,
|
||||
) -> Option<NcEgc> {
|
||||
) -> Option<String> {
|
||||
let egc = unsafe { crate::notcurses_at_yx(self, x as i32, y as i32, stylemask, channels) };
|
||||
if egc.is_null() {
|
||||
return None;
|
||||
}
|
||||
let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char");
|
||||
Some(egc)
|
||||
Some(rstring![egc].into())
|
||||
}
|
||||
|
||||
/// Returns the bottommost [NcPlane] on the standard pile,
|
||||
/// Returns the bottommost [`NcPlane`] on the standard pile,
|
||||
/// of which there is always at least one.
|
||||
///
|
||||
/// *C style function: [notcurses_bottom()][crate::notcurses_bottom].*
|
||||
@ -306,7 +306,7 @@ impl Nc {
|
||||
rstring![crate::notcurses_detected_terminal(self)].to_string()
|
||||
}
|
||||
|
||||
/// Destroys all [NcPlane]s other than the stdplane.
|
||||
/// Destroys all [`NcPlane`]s other than the stdplane.
|
||||
///
|
||||
/// *C style function: [notcurses_drop_planes()][crate::notcurses_drop_planes].*
|
||||
pub fn drop_planes(&mut self) {
|
||||
@ -409,7 +409,7 @@ impl Nc {
|
||||
error![unsafe { crate::notcurses_inputready_fd(self) }]
|
||||
}
|
||||
|
||||
/// Returns an [NcBlitter] from a string representation.
|
||||
/// Returns an [`NcBlitter`] from a string representation.
|
||||
///
|
||||
/// *C style function: [notcurses_lex_blitter()][crate::notcurses_lex_blitter].*
|
||||
pub fn lex_blitter(op: &str) -> NcResult<NcBlitter> {
|
||||
@ -430,7 +430,7 @@ impl Nc {
|
||||
error![unsafe { crate::notcurses_lex_margins(cstring![op], options) }]
|
||||
}
|
||||
|
||||
/// Returns an [NcScale] from a string representation.
|
||||
/// Returns an [`NcScale`] from a string representation.
|
||||
///
|
||||
/// *C style function: [notcurses_lex_scalemode()][crate::notcurses_lex_scalemode].*
|
||||
pub fn lex_scalemode(op: &str) -> NcResult<NcScale> {
|
||||
@ -496,7 +496,7 @@ impl Nc {
|
||||
|
||||
/// Refreshes the physical screen to match what was last rendered (i.e.,
|
||||
/// without reflecting any changes since the last call to
|
||||
/// [render][crate::Nc#method.render]).
|
||||
/// [`render`][crate::Nc#method.render]).
|
||||
///
|
||||
/// Returns the current screen geometry (`y`, `x`).
|
||||
///
|
||||
@ -523,12 +523,13 @@ impl Nc {
|
||||
}
|
||||
|
||||
/// Performs the rendering and rasterization portion of
|
||||
/// [render][Nc#method.render] but do not write the resulting buffer
|
||||
/// [`render`][Nc#method.render] but do not write the resulting buffer
|
||||
/// out to the terminal.
|
||||
///
|
||||
/// Using this function, the user can control the writeout process,
|
||||
/// and render a second frame while writing another.
|
||||
///
|
||||
// possible BUG? CHECK:
|
||||
/// The returned buffer must be freed by the caller.
|
||||
///
|
||||
/// *C style function: [notcurses_render_to_buffer()][crate::notcurses_render_to_buffer].*
|
||||
@ -549,7 +550,7 @@ impl Nc {
|
||||
|
||||
/// Writes the last rendered frame, in its entirety, to 'fp'.
|
||||
///
|
||||
/// If [render()][Nc#method.render] has not yet been called,
|
||||
/// If [`render`][Nc#method.render] has not yet been called,
|
||||
/// nothing will be written.
|
||||
///
|
||||
/// *C style function: [notcurses_render_to_file()][crate::notcurses_render_to_file].*
|
||||
@ -613,7 +614,7 @@ impl Nc {
|
||||
// crate::notcurses_stddim_yx_const(self, y, x)
|
||||
// }
|
||||
|
||||
/// Returns a mutable reference to the standard [NcPlane] for this terminal.
|
||||
/// 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.
|
||||
@ -623,7 +624,7 @@ impl Nc {
|
||||
unsafe { &mut *crate::notcurses_stdplane(self) }
|
||||
}
|
||||
|
||||
/// Returns a reference to the standard [NcPlane] for this terminal.
|
||||
/// 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.
|
||||
@ -640,21 +641,21 @@ impl Nc {
|
||||
error![unsafe { crate::notcurses_stop(self) }]
|
||||
}
|
||||
|
||||
/// Gets the name of an [NcBlitter] blitter.
|
||||
/// Gets the name of an [`NcBlitter`] blitter.
|
||||
///
|
||||
/// *C style function: [notcurses_str_blitter()][crate::notcurses_str_blitter].*
|
||||
pub fn str_blitter(blitter: NcBlitter) -> String {
|
||||
rstring![crate::notcurses_str_blitter(blitter)].to_string()
|
||||
}
|
||||
|
||||
/// Gets the name of an [NcScale] scaling mode.
|
||||
/// Gets the name of an [`NcScale`] scaling mode.
|
||||
///
|
||||
/// *C style function: [notcurses_str_scalemode()][crate::notcurses_str_scalemode].*
|
||||
pub fn str_scalemode(scalemode: NcScale) -> String {
|
||||
rstring![crate::notcurses_str_scalemode(scalemode)].to_string()
|
||||
}
|
||||
|
||||
/// Returns an [NcStyle] with the supported curses-style attributes.
|
||||
/// Returns an [`NcStyle`] with the supported curses-style attributes.
|
||||
///
|
||||
/// The attribute is only indicated as supported if the terminal can support
|
||||
/// it together with color.
|
||||
@ -673,7 +674,7 @@ impl Nc {
|
||||
crate::notcurses_term_dim_yx(self)
|
||||
}
|
||||
|
||||
/// Returns the topmost [NcPlane], of which there is always at least one.
|
||||
/// Returns the topmost [`NcPlane`], of which there is always at least one.
|
||||
///
|
||||
/// *C style function: [notcurses_top()][crate::notcurses_top].*
|
||||
pub fn top(&mut self) -> &mut NcPlane {
|
||||
|
@ -6,9 +6,9 @@ use core::{
|
||||
|
||||
use crate::{
|
||||
cstring, error, error_ref, error_ref_mut, rstring, Nc, NcAlign, NcAlphaBits, NcBlitter,
|
||||
NcBoxMask, NcCell, NcChannel, NcChannels, NcComponent, NcDim, NcEgc, NcError, NcFadeCb,
|
||||
NcOffset, NcPaletteIndex, NcPixelGeometry, NcPlane, NcPlaneOptions, NcResizeCb, NcResult,
|
||||
NcRgb, NcStyle, NcTime, NCRESULT_ERR,
|
||||
NcBoxMask, NcCell, NcChannel, NcChannels, NcComponent, NcDim, NcError, NcFadeCb, NcOffset,
|
||||
NcPaletteIndex, NcPixelGeometry, NcPlane, NcPlaneOptions, NcResizeCb, NcResult, NcRgb, NcStyle,
|
||||
NcTime, NCRESULT_ERR,
|
||||
};
|
||||
|
||||
/// # NcPlaneOptions Constructors
|
||||
@ -530,19 +530,19 @@ impl NcPlane {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/// ## NcPlane methods: `NcCell` & `NcEgc`
|
||||
/// ## NcPlane methods: `NcCell` & strings
|
||||
impl NcPlane {
|
||||
/// Retrieves the current contents of the [`NcCell`] under the cursor,
|
||||
/// returning the [`NcEgc`] and writing out the [`NcStyle`] and the [`NcChannels`].
|
||||
/// returning the `EGC` and writing out the [`NcStyle`] and the [`NcChannels`].
|
||||
///
|
||||
/// This NcEgc must be freed by the caller.
|
||||
/// This `EGC` must be freed by the caller.
|
||||
///
|
||||
/// *C style function: [ncplane_at_cursor()][crate::ncplane_at_cursor].*
|
||||
pub fn at_cursor(
|
||||
&mut self,
|
||||
stylemask: &mut NcStyle,
|
||||
channels: &mut NcChannels,
|
||||
) -> NcResult<NcEgc> {
|
||||
) -> NcResult<String> {
|
||||
let egc = unsafe { crate::ncplane_at_cursor(self, stylemask, channels) };
|
||||
if egc.is_null() {
|
||||
return Err(NcError::with_msg(
|
||||
@ -550,12 +550,11 @@ impl NcPlane {
|
||||
&format!("NcPlane.at_cursor({:0X}, {:0X})", stylemask, channels),
|
||||
));
|
||||
}
|
||||
let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char");
|
||||
Ok(egc)
|
||||
Ok(rstring![egc].into())
|
||||
}
|
||||
|
||||
/// Retrieves the current contents of the [`NcCell`] under the cursor
|
||||
/// into `cell`. Returns the number of bytes in the [`NcEgc`].
|
||||
/// into `cell`. Returns the number of bytes in the `EGC`.
|
||||
///
|
||||
/// This NcCell is invalidated if the associated NcPlane is destroyed.
|
||||
///
|
||||
@ -571,9 +570,9 @@ impl NcPlane {
|
||||
}
|
||||
|
||||
/// Retrieves the current contents of the specified [`NcCell`], returning the
|
||||
/// [`NcEgc`] and writing out the [`NcStyle`] and the [`NcChannels`].
|
||||
/// `EGC` and writing out the [`NcStyle`] and the [`NcChannels`].
|
||||
///
|
||||
/// This NcEgc must be freed by the caller.
|
||||
/// This `EGC` must be freed by the caller.
|
||||
///
|
||||
/// *C style function: [ncplane_at_yx()][crate::ncplane_at_yx].*
|
||||
pub fn at_yx(
|
||||
@ -582,7 +581,7 @@ impl NcPlane {
|
||||
x: NcDim,
|
||||
stylemask: &mut NcStyle,
|
||||
channels: &mut NcChannels,
|
||||
) -> NcResult<NcEgc> {
|
||||
) -> NcResult<String> {
|
||||
let egc = unsafe { crate::ncplane_at_yx(self, y as i32, x as i32, stylemask, channels) };
|
||||
if egc.is_null() {
|
||||
return Err(NcError::with_msg(
|
||||
@ -593,12 +592,11 @@ impl NcPlane {
|
||||
),
|
||||
));
|
||||
}
|
||||
let egc = core::char::from_u32(unsafe { *egc } as u32).expect("wrong char");
|
||||
Ok(egc)
|
||||
Ok(rstring![egc].into())
|
||||
}
|
||||
|
||||
/// Retrieves the current contents of the specified [`NcCell`] into `cell`.
|
||||
/// Returns the number of bytes in the [`NcEgc`].
|
||||
/// Returns the number of bytes in the `EGC`.
|
||||
///
|
||||
/// This NcCell is invalidated if the associated plane is destroyed.
|
||||
///
|
||||
@ -674,7 +672,7 @@ impl NcPlane {
|
||||
]
|
||||
}
|
||||
|
||||
/// Creates a flat string from the `NcEgc`'s of the selected region of the
|
||||
/// Creates a flat string from the `EGC`'s of the selected region of the
|
||||
/// `NcPlane`.
|
||||
///
|
||||
/// Starts at the plane's `beg_y` * `beg_x` coordinates (which must lie on
|
||||
@ -767,14 +765,15 @@ impl NcPlane {
|
||||
}
|
||||
|
||||
// TODO: call put_egc
|
||||
// /// Replaces the [`NcEgc`][crate::NcEgc] to the current location, but retain
|
||||
// /// Replaces the `EGC` to the current location, but retain
|
||||
// /// the styling. The current styling of the plane will not be changed.
|
||||
// pub fn putchar_stained(&mut self, y: NcDim, x: NcDim, ch: char) ->
|
||||
// NcResult<NcDim> {
|
||||
// error![crate::ncplane_putchar_stained(self, ch)]
|
||||
// }
|
||||
|
||||
/// Replaces the [`NcEgc`][crate::NcEgc], but retain the styling.
|
||||
/// Replaces the [NcCell] at the `y`,`x` coordinates with the provided
|
||||
/// 7-bit `char`, but retain the styling.
|
||||
/// The current styling of the plane will not be changed.
|
||||
///
|
||||
/// On success, returns the number of columns the cursor was advanced.
|
||||
@ -789,8 +788,7 @@ impl NcPlane {
|
||||
]
|
||||
}
|
||||
|
||||
/// Writes a series of [`NcEgc`][crate::NcEgc]s to the current location,
|
||||
/// using the current style.
|
||||
/// Writes a string to the current location, using the current style.
|
||||
///
|
||||
/// Advances the cursor by some positive number of columns
|
||||
/// (though not beyond the end of the plane),
|
||||
@ -836,8 +834,7 @@ impl NcPlane {
|
||||
]
|
||||
}
|
||||
|
||||
/// Writes a series of [`NcEgc`][crate::NcEgc]s to the current location, but
|
||||
/// retains the styling.
|
||||
/// Writes a string to the current location, but retains the styling.
|
||||
///
|
||||
/// The current styling of the plane will not be changed.
|
||||
///
|
||||
@ -857,8 +854,7 @@ impl NcPlane {
|
||||
]
|
||||
}
|
||||
|
||||
/// Write a string, which is a series of [`NcEgc`][crate::NcEgc]s, to the
|
||||
/// current location, using the current style.
|
||||
/// Write a string to the provided location, using the current style.
|
||||
///
|
||||
/// They will be interpreted as a series of columns.
|
||||
///
|
||||
@ -919,7 +915,7 @@ impl NcPlane {
|
||||
///
|
||||
/// *C style function: [ncplane_dup()][crate::ncplane_dup].*
|
||||
//
|
||||
// TODO: deal with the opaque field.
|
||||
// TODO: deal with the opaque field that is stored in NcPlaneOptions.userptr
|
||||
pub fn dup(&mut self) -> &mut NcPlane {
|
||||
unsafe { &mut *crate::ncplane_dup(self, null_mut()) }
|
||||
}
|
||||
@ -1931,7 +1927,7 @@ impl NcPlane {
|
||||
/// *C style function: [ncplane_gradient()][crate::ncplane_gradient].*
|
||||
pub fn gradient(
|
||||
&mut self,
|
||||
egc: &NcEgc,
|
||||
egc: &str,
|
||||
stylemask: NcStyle,
|
||||
ul: NcChannels,
|
||||
ur: NcChannels,
|
||||
@ -1940,16 +1936,10 @@ impl NcPlane {
|
||||
y_stop: NcDim,
|
||||
x_stop: NcDim,
|
||||
) -> NcResult<NcDim> {
|
||||
// https://github.com/dankamongmen/notcurses/issues/1339
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "i686"))]
|
||||
let egc_ptr = &(*egc as i8);
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "i686")))]
|
||||
let egc_ptr = &(*egc as u8);
|
||||
|
||||
let res = unsafe {
|
||||
crate::ncplane_gradient(
|
||||
self,
|
||||
egc_ptr,
|
||||
cstring![egc],
|
||||
stylemask as u32,
|
||||
ul,
|
||||
ur,
|
||||
@ -1971,7 +1961,7 @@ impl NcPlane {
|
||||
#[inline]
|
||||
pub fn gradient_sized(
|
||||
&mut self,
|
||||
egc: &NcEgc,
|
||||
egc: &str,
|
||||
stylemask: NcStyle,
|
||||
ul: NcChannel,
|
||||
ur: NcChannel,
|
||||
|
@ -235,9 +235,8 @@ pub use reimplemented::*;
|
||||
/// from the top to the bottom along a pile's z-axis. The result is a matrix of
|
||||
/// [`NcCell`][crate::NcCell]s. Rasterizing takes this matrix, together with the
|
||||
/// current state of the visual area, and produces a stream of optimized control
|
||||
/// sequences and [`NcEgc`][crate::NcEgc]s for the terminal. By writing this
|
||||
/// stream to the terminal, the physical display is synced to some pile's
|
||||
/// `NcPlane`s.
|
||||
/// sequences and `EGC`s for the terminal. By writing this stream to the
|
||||
/// terminal, the physical display is synced to some pile's `NcPlane`s.
|
||||
///
|
||||
/// [`NcPlane.render`][crate::NcPlane#method.render] performs the first of these
|
||||
/// tasks for the pile of which the plane is a part. The output is maintained
|
||||
@ -262,7 +261,7 @@ pub use reimplemented::*;
|
||||
/// - [`NcChannel` & `NcChannels`](#ncplane-methods-ncchannel)
|
||||
/// - [`NcComponent`, `NcRgb` & default color](#ncplane-methods-nccomponent-ncrgb--default-color)
|
||||
/// - [`NcStyle` & `NcPaletteIndex`](#ncplane-methods-ncstylemask--paletteindex)
|
||||
/// - [`NcCell` & `NcEgc`](#ncplane-methods-nccell--ncegc)
|
||||
/// - [`NcCell` & strings](#ncplane-methods-nccell--strings)
|
||||
/// - [cursor](#ncplane-methods-cursor)
|
||||
/// - [`NcPlane` & `Notcurses`](#ncplane-methods-ncplane--notcurses)
|
||||
/// - [boxes & perimeters](#ncplane-methods-boxes--perimeters)
|
||||
|
@ -4,7 +4,7 @@ use core::ptr::null_mut;
|
||||
|
||||
use crate::{
|
||||
cstring, nccell_release, NcAlign, NcAlphaBits, NcBoxMask, NcCell, NcChannel, NcChannels,
|
||||
NcComponent, NcDim, NcEgc, NcIntResult, NcPlane, NcRgb, NcStyle, NCRESULT_ERR, NCRESULT_OK,
|
||||
NcComponent, NcDim, NcIntResult, NcPlane, NcRgb, NcStyle, NCRESULT_ERR, NCRESULT_OK,
|
||||
};
|
||||
|
||||
// Alpha -----------------------------------------------------------------------
|
||||
@ -224,7 +224,7 @@ pub fn ncplane_putchar_yx(plane: &mut NcPlane, y: NcDim, x: NcDim, ch: char) ->
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a series of [NcEgc]s to the current location, using the current style.
|
||||
/// Writes a series of `EGC`s to the current location, using the current style.
|
||||
///
|
||||
/// Advances the cursor by some positive number of columns
|
||||
/// (though not beyond the end of the plane),
|
||||
@ -749,7 +749,7 @@ pub fn ncplane_rounded_box_sized(
|
||||
#[inline]
|
||||
pub fn ncplane_gradient_sized(
|
||||
plane: &mut NcPlane,
|
||||
egc: &NcEgc,
|
||||
egc: &str,
|
||||
stylemask: NcStyle,
|
||||
ul: NcChannel,
|
||||
ur: NcChannel,
|
||||
@ -761,18 +761,12 @@ pub fn ncplane_gradient_sized(
|
||||
if y_len < 1 || x_len < 1 {
|
||||
return NCRESULT_ERR;
|
||||
}
|
||||
// https://github.com/dankamongmen/notcurses/issues/1339
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "i686"))]
|
||||
let egc_ptr = &(*egc as i8);
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "i686")))]
|
||||
let egc_ptr = &(*egc as u8);
|
||||
|
||||
let (mut y, mut x) = (0, 0);
|
||||
unsafe {
|
||||
crate::ncplane_cursor_yx(plane, &mut y, &mut x);
|
||||
crate::ncplane_gradient(
|
||||
plane,
|
||||
egc_ptr,
|
||||
cstring![egc],
|
||||
stylemask as u32,
|
||||
ul as u64,
|
||||
ur as u64,
|
||||
|
Loading…
Reference in New Issue
Block a user