diff --git a/rust/src/cells/methods.rs b/rust/src/cells/methods.rs index b58e223f3..69b33d6da 100644 --- a/rust/src/cells/methods.rs +++ b/rust/src/cells/methods.rs @@ -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( diff --git a/rust/src/cells/mod.rs b/rust/src/cells/mod.rs index 0ab6c631c..faa4851b2 100644 --- a/rust/src/cells/mod.rs +++ b/rust/src/cells/mod.rs @@ -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 diff --git a/rust/src/cells/reimplemented.rs b/rust/src/cells/reimplemented.rs index 2b54681df..00bb3c6c4 100644 --- a/rust/src/cells/reimplemented.rs +++ b/rust/src/cells/reimplemented.rs @@ -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]; diff --git a/rust/src/direct/methods.rs b/rust/src/direct/methods.rs index 99534f847..108e62a69 100644 --- a/rust/src/direct/methods.rs +++ b/rust/src/direct/methods.rs @@ -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) }] } } diff --git a/rust/src/notcurses/methods.rs b/rust/src/notcurses/methods.rs index 658d211b2..bfff128ae 100644 --- a/rust/src/notcurses/methods.rs +++ b/rust/src/notcurses/methods.rs @@ -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 { + ) -> Option { 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 { @@ -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 { @@ -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 { diff --git a/rust/src/plane/methods.rs b/rust/src/plane/methods.rs index c49d7bf16..da9a41a39 100644 --- a/rust/src/plane/methods.rs +++ b/rust/src/plane/methods.rs @@ -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 { + ) -> NcResult { 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 { + ) -> NcResult { 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 { // 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 { - // 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, diff --git a/rust/src/plane/mod.rs b/rust/src/plane/mod.rs index 8fb95f355..512ea8410 100644 --- a/rust/src/plane/mod.rs +++ b/rust/src/plane/mod.rs @@ -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) diff --git a/rust/src/plane/reimplemented.rs b/rust/src/plane/reimplemented.rs index 7239f1766..a987e8bb5 100644 --- a/rust/src/plane/reimplemented.rs +++ b/rust/src/plane/reimplemented.rs @@ -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,