[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.
pull/1838/head
joseLuís 3 years ago
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…
Cancel
Save