libnotcurses_sys/visual/options/
mod.rs

1//!
2
3use crate::{c_api::ffi, NcBlitter, NcPlane, NcRgba, NcScale};
4use core::ptr::null_mut;
5
6mod builder;
7pub use builder::NcVisualOptionsBuilder;
8
9/// Options struct for [`NcVisual`][crate::NcVisual].
10///
11/// It is recommended to construct it via [`NcVisualOptionsBuilder`]
12/// by calling [`NcVisualOptions::builder()`].
13///
14/// # Usage
15///
16/// If a plane is not provided, one will be created, having the exact size
17/// necessary to display the visual (this might be smaller or larger than
18/// the rendering area). if [`ChildPlane`] is provided, this will be
19/// interpreted as the parent.
20///
21/// A subregion of the visual can be rendered using `beg_y`, `beg_x`, `len_y`,
22/// and `len_x`.
23///
24/// # Fields
25///
26/// - [`n`]: an optional mutable pointer to an [`NcPlane`].
27///
28/// - [`scaling`]: an [`NcScale`] indicating how the source will be
29///   stretched/scaled relative to the `NcPlane`.
30///
31/// - [`y`]: if an `NcPlane` is provided in `n` then this specifies where the
32///   `NcVisual` will be on that plane.
33///
34///   Otherwise it specifies where the created `NcPlane` will be placed relative
35///   to the standard plane's origin.
36///
37///   If [`VerAligned`] is set, this will be interpreted as an [`NcAlign`] value.
38///
39/// - [`x`]: if an `NcPlane` is provided in `n` then this specifies where the
40///   `NcVisual` will be on that plane.
41///
42///   Otherwise it specifies where the created `NcPlane` will be placed relative
43///   to the standard plane's origin.
44///
45///   If [`HorAligned`] is set, this will be interpreted as an [`NcAlign`] value.
46///
47/// - [`begy`]: origin of rendered section in the *y* axis.
48/// - [`begx`]: origin of rendered section in the *x* axis.
49/// - [`leny`]: length of rendered section in the *y* axis.
50/// - [`lenx`]: length of rendered section in the *x* axis.
51///
52/// - [`blitter`]: [`NcBlitter`] glyph set to use for blitting.
53///
54/// - [`flags`]: [`NcVisualFlag`].
55///
56/// - [`transcolor`]: treats this color as transparent when the [`AddAlpha`]
57///   flag is active.
58///
59/// - [`pxoffy`]: pixel offset within the cell in the *y* axis.
60///
61///   If [`NcBlitter::Pixel`] is used the bitmap will be drawn offset from the
62///   upper-left cell’s origin by these amounts, otherwise this will be ignored.
63///
64///   It is an error if either number exceeds the cell-pixel geometry in any
65///   dimension (see [`NcPixelGeometry.cell_y`], [`NcVisualGeometry.cdim_yx`]).
66///
67/// - [`pxoffx`]: pixel offset within the cell in the *x* axis.
68///
69///   If [`NcBlitter::Pixel`] is used, the bitmap will be drawn offset from the
70///   upper-left cell’s origin by these amounts, otherwise this will be ignored.
71///
72///   It is an error if either number exceeds the cell-pixel geometry in any
73///   dimension (see [`NcPixelGeometry.cell_x`], [`NcVisualGeometry.cdim_yx`]).
74///
75/// [`NcVisualOptions::builder()`]: NcVisualOptions#method.builder
76/// [`NcAlign`]: crate::NcAlign
77/// [`NcPixelGeometry.cell_y`]: crate::NcPixelGeometry#structfield.cell_y
78/// [`NcPixelGeometry.cell_x`]: crate::NcPixelGeometry#structfield.cell_x
79/// [`NcVisualGeometry.cdim_yx`]: crate::NcVisualGeometry#structfield.cdim_yx
80/// [`n`]: crate::c_api::ffi::ncvisual_options#structfield.n
81/// [`scaling`]: crate::c_api::ffi::ncvisual_options#structfield.scaling
82/// [`y`]: crate::c_api::ffi::ncvisual_options#structfield.y
83/// [`x`]: crate::c_api::ffi::ncvisual_options#structfield.x
84/// [`begy`]: crate::c_api::ffi::ncvisual_options#structfield.begy
85/// [`begx`]: crate::c_api::ffi::ncvisual_options#structfield.begx
86/// [`leny`]: crate::c_api::ffi::ncvisual_options#structfield.leny
87/// [`lenx`]: crate::c_api::ffi::ncvisual_options#structfield.lenx
88/// [`blitter`]: crate::c_api::ffi::ncvisual_options#structfield.blitter
89/// [`flags`]: crate::c_api::ffi::ncvisual_options#structfield.flags
90/// [`transcolor`]: crate::c_api::ffi::ncvisual_options#structfield.transcolor
91/// [`pxoffy`]: crate::c_api::ffi::ncvisual_options#structfield.pxoffy
92/// [`pxoffx`]: crate::c_api::ffi::ncvisual_options#structfield.pxoffx
93/// [`AddAlpha`]: NcVisualFlag#associatedconstant.AddAlpha
94/// [`Childplane`]: NcVisualFlag#associatedconstant.Childplane
95/// [`VerAligned`]:NcVisualFlag#associatedconstant.VerAligned
96/// [`HorAligned`]: NcVisualFlag#associatedconstant.HorAligned
97pub type NcVisualOptions = crate::c_api::ffi::ncvisual_options;
98
99/// # Constructors
100impl<'ncplane> NcVisualOptions {
101    /// Returns a builder object for `NcVisualOptions`.
102    pub fn builder() -> NcVisualOptionsBuilder<'ncplane> {
103        NcVisualOptionsBuilder::default()
104    }
105
106    /// New `NcVisualOptions`.
107    ///
108    /// # Arguments
109    ///
110    /// * `plane` - an optional mutable pointer to an [`NcPlane`].
111    ///
112    /// * `scale` - An [`NcScale`] indicating how the source will be
113    ///   stretched/scaled relative to the `NcPlane`.
114    ///
115    /// * `y` - if an `NcPlane` is provided in `plane` then this specifies where
116    ///   the `NcVisual` will be on that plane in the *y* axis.
117    ///
118    ///   Otherwise it specifies where the created `NcPlane` will be placed
119    ///   in the *y* axis, relative to the standard plane's origin.
120    ///
121    ///   If [`VerAligned`] is set, this will be interpreted as an [`NcAlign`]
122    ///   value.
123    ///
124    /// * `x` - if an `NcPlane` is provided in `plane` then this specifies where
125    ///   the `NcVisual` will be on that plane, in the *x* axis.
126    ///
127    ///   Otherwise it specifies where the created `NcPlane` will be placed,
128    ///   in the *y* axis, relative to the standard plane's origin.
129    ///
130    ///   If [`HorAligned`] is set, this will be interpreted as an [`NcAlign`]
131    ///   value.
132    ///
133    /// * `section_yx_lenyx` - The size of the rendered section.
134    ///
135    ///   `None` renders the entire visual, otherwise the provided tuple
136    ///   (`y`, `x`, `len_y`, `len_x`) sets `[yx]` as the origin of the section
137    ///   and `len_[yx]` as the its length on each respective dimension.
138    ///
139    /// * `cell_offset_yx` - Pixel offsets within the cell.
140    ///
141    ///   If [`NcBlitter::Pixel`] is used the bitmap will be drawn offset from
142    ///   the upper-left cell’s origin by these amounts, otherwise this will be
143    ///   ignored.
144    ///
145    ///   It is an error if either number exceeds the cell-pixel geometry in any
146    ///   dimension (see [`NcVisualGeometry.cdim_yx`]).
147    ///
148    /// * `blitter` - [`NcBlitter`] glyph set to use for blitting.
149    ///
150    /// * `flags` - [`NcVisualFlag`].
151    ///
152    /// * `transcolor` - treats this color as transparent when the [`AddAlpha`]
153    ///   flag is active
154    ///
155    /// # Notes
156    ///
157    /// If the [`Childplane`] flag is used then the `plane` is interpreted as
158    /// the parent `NcPlane` of the new plane created for this
159    /// [`NcVisual`][crate::NcVisual].
160    ///
161    /// [`NcAlign`]: crate::NcAlign
162    /// [`NcPixelGeometry.cell_y`]: crate::NcPixelGeometry#structfield.cell_y
163    /// [`NcPixelGeometry.cell_x`]: crate::NcPixelGeometry#structfield.cell_x
164    /// [`NcVisualGeometry.cdim_yx`]: crate::NcVisualGeometry#structfield.cdim_yx
165    /// [`AddAlpha`]: NcVisualFlag#associatedconstant.AddAlpha
166    /// [`Childplane`]: NcVisualFlag#associatedconstant.Childplane
167    /// [`VerAligned`]:NcVisualFlag#associatedconstant.VerALigned
168    /// [`HorAligned`]: NcVisualFlag#associatedconstant.HorALigned
169    pub fn new(
170        plane: Option<&mut NcPlane>,
171        scale: impl Into<NcScale>,
172        y: i32,
173        x: i32,
174        section_yx_lenyx: Option<(u32, u32, u32, u32)>,
175        cell_offset_yx: Option<(u32, u32)>,
176        blitter: impl Into<NcBlitter>,
177        flags: impl Into<NcVisualFlag>,
178        transcolor: impl Into<NcRgba>,
179    ) -> Self {
180        let plane_ptr = if let Some(p) = plane { p } else { null_mut() };
181        let (begy, begx, leny, lenx) =
182            if let Some(s) = section_yx_lenyx { (s.0, s.1, s.2, s.3) } else { (0, 0, 0, 0) };
183        let (pxoffy, pxoffx) = if let Some(o) = cell_offset_yx { (o.0, o.1) } else { (0, 0) };
184
185        Self {
186            n: plane_ptr,
187            scaling: scale.into().into(),
188
189            y,
190            x,
191
192            begy,
193            begx,
194            leny,
195            lenx,
196
197            blitter: blitter.into().into(),
198
199            flags: flags.into().into(),
200
201            transcolor: transcolor.into().into(),
202
203            pxoffy,
204            pxoffx,
205        }
206    }
207}
208
209/// # Methods
210impl NcVisualOptions {
211    /// Returns `true` if it does have an associated [`NcPlane`].
212    pub fn does_plane(&self) -> bool {
213        !self.n.is_null()
214    }
215
216    /// Returns `true` if it has the [`ChildPlane`] flag set.
217    ///
218    /// [`ChildPlane`]: NcVisualFlag#associatedconstant.ChildPlane
219    pub fn does_child_plane(&self) -> bool {
220        self.flags & NcVisualFlag::ChildPlane != NcVisualFlag::None
221    }
222
223    /// Returns `true` if it has the [`AddAlpha`] flag set.
224    ///
225    /// [`AddAlpha`]: NcVisualFlag#associatedconstant.AddAlpha
226    pub fn does_alpha(&self) -> bool {
227        self.flags & NcVisualFlag::AddAlpha != NcVisualFlag::None
228    }
229
230    /// Returns `true` if it has the [`Blend`] flag set.
231    ///
232    /// [`Blend`]: NcVisualFlag#associatedconstant.Blend
233    pub fn does_blend(&self) -> bool {
234        self.flags & NcVisualFlag::Blend != NcVisualFlag::None
235    }
236
237    /// Returns `false` if it has the [`NoDegrade`] flag set.
238    ///
239    /// [`NoDegrade`]: NcVisualFlag#associatedconstant.NoDegrade
240    pub fn does_degrade(&self) -> bool {
241        self.flags & NcVisualFlag::NoDegrade == NcVisualFlag::None
242    }
243
244    /// Returns `false` if it has the [`NoInterpolate`] flag set.
245    ///
246    /// [`NoInterpolate`]: NcVisualFlag#associatedconstant.NoInterpolate
247    pub fn does_interpolate(&self) -> bool {
248        self.flags & NcVisualFlag::NoInterpolate == NcVisualFlag::None
249    }
250
251    /// Returns `true` if it has the [`VerAligned`] flag set.
252    ///
253    /// [`VerAligned`]: NcVisualFlag#associatedconstant.VerAligned
254    pub fn is_veraligned(&self) -> bool {
255        self.flags & NcVisualFlag::VerAligned != NcVisualFlag::None
256    }
257
258    /// Returns `true` if it has the [`HorAligned`] flag set.
259    ///
260    /// [`HorAligned`]: NcVisualFlag#associatedconstant.HorAligned
261    pub fn is_horaligned(&self) -> bool {
262        self.flags & NcVisualFlag::HorAligned != NcVisualFlag::None
263    }
264}
265
266/// A bitmask of flags for [`NcVisualOptions`].
267///
268/// # Flag
269/// - [`None`][NcVisualFlag::None]
270/// - [`AddAlpha`][NcVisualFlag::AddAlpha]
271/// - [`Blend`][NcVisualFlag::Blend]
272/// - [`ChildPlane`][NcVisualFlag::ChildPlane]
273/// - [`NoDegrade`][NcVisualFlag::NoDegrade]
274/// - [`HorAligned`][NcVisualFlag::HorAligned]
275/// - [`VerAligned`][NcVisualFlag::VerAligned]
276/// - [`NoInterpolate`][NcVisualFlag::NoInterpolate]
277///
278/// # Default
279/// *[`NcVisualFlag::None`]
280#[derive(Copy, Clone, Debug, PartialEq, Eq)]
281pub struct NcVisualFlag(pub c_api::NcVisualFlag_u64);
282
283impl NcVisualFlag {
284    /// No flags.
285    pub const None: Self = Self(0);
286
287    /// Treats as transparent the color specified in the `transcolor` field.
288    pub const AddAlpha: Self = Self(c_api::NCVISUAL_OPTION_ADDALPHA);
289
290    /// Uses [`NcAlpha::Blend`] with the `NcVisual`.
291    ///
292    /// [`NcAlpha::Blend`]: crate::NcAlpha#associatedconstant.Blend
293    pub const Blend: Self = Self(c_api::NCVISUAL_OPTION_BLEND);
294
295    /// allows you to indicate that the n field of ncvisual_options refers not to
296    /// the plane onto which you'd like to blit, but the parent of a new plane.
297    ///
298    /// A plane will be created using the other parameters in the ncvisual_options,
299    /// as a child of this parent. This means things like, say, vertically centering
300    /// a sprixel relative to the standard plane can be done in one step.
301    pub const ChildPlane: Self = Self(c_api::NCVISUAL_OPTION_CHILDPLANE);
302
303    /// Fails rather than gracefully degrade. See [`NcBlitter`][crate::NcBlitter].
304    pub const NoDegrade: Self = Self(c_api::NCVISUAL_OPTION_NODEGRADE);
305
306    /// Y is an alignment, not absolute.
307    pub const VerAligned: Self = Self(c_api::NCVISUAL_OPTION_VERALIGNED);
308
309    /// X is an alignment, not absolute.
310    pub const HorAligned: Self = Self(c_api::NCVISUAL_OPTION_HORALIGNED);
311
312    /// Uses non-interpolative scaling.
313    pub const NoInterpolate: Self = Self(c_api::NCVISUAL_OPTION_NOINTERPOLATE);
314}
315
316mod core_impls {
317    use super::{c_api::NcVisualFlag_u64, NcVisualFlag};
318
319    impl Default for NcVisualFlag {
320        fn default() -> Self {
321            Self::None
322        }
323    }
324
325    crate::from_primitive![NcVisualFlag, NcVisualFlag_u64];
326    crate::unit_impl_from![NcVisualFlag, NcVisualFlag_u64];
327    crate::unit_impl_ops![bitwise; NcVisualFlag, NcVisualFlag_u64];
328    crate::unit_impl_fmt![bases+display; NcVisualFlag];
329}
330
331pub(crate) mod c_api {
332    use super::ffi;
333
334    pub type NcVisualFlag_u64 = u64;
335
336    /// [`NcVisualFlag_u64`] flag to treat as transparent the color specified
337    /// in the `transcolor` field.
338    pub const NCVISUAL_OPTION_ADDALPHA: NcVisualFlag_u64 =
339        ffi::NCVISUAL_OPTION_ADDALPHA as NcVisualFlag_u64;
340
341    /// [`NcVisualFlag_u64`] flag uses [`NcAlpha::Blend`] with the `NcVisual`.
342    ///
343    /// [`NcAlpha::Blend`]: crate::NcAlpha#associatedconstant.Blend
344    pub const NCVISUAL_OPTION_BLEND: NcVisualFlag_u64 =
345        ffi::NCVISUAL_OPTION_BLEND as NcVisualFlag_u64;
346
347    /// [`NcVisualFlag_u64`] flag to indicate that the `n` field of
348    /// `ncvisual_options` refers not to the plane onto which you'd like to blit,
349    /// but the parent of a new plane.
350    ///
351    /// A plane will be created using the other parameters in the ncvisual_options,
352    /// as a child of this parent. This means things like, say, vertically centering
353    /// a sprixel relative to the standard plane can be done in one step.
354    pub const NCVISUAL_OPTION_CHILDPLANE: NcVisualFlag_u64 =
355        ffi::NCVISUAL_OPTION_CHILDPLANE as NcVisualFlag_u64;
356
357    /// [`NcVisualFlag_u64`] flag to fail rather than gracefully degrade.
358    ///
359    /// See [`NcBlitter`][crate::NcBlitter].
360    pub const NCVISUAL_OPTION_NODEGRADE: NcVisualFlag_u64 =
361        ffi::NCVISUAL_OPTION_NODEGRADE as NcVisualFlag_u64;
362
363    /// [`NcVisualFlag_u64`] flag to indicate Y is an alignment, not absolute.
364    pub const NCVISUAL_OPTION_VERALIGNED: NcVisualFlag_u64 =
365        ffi::NCVISUAL_OPTION_VERALIGNED as NcVisualFlag_u64;
366
367    /// [`NcVisualFlag_u64`] flag to indicate X is an alignment, not absolute.
368    pub const NCVISUAL_OPTION_HORALIGNED: NcVisualFlag_u64 =
369        ffi::NCVISUAL_OPTION_HORALIGNED as NcVisualFlag_u64;
370
371    /// [`NcVisualFlag_u64`] flag to use non-interpolative scaling.
372    pub const NCVISUAL_OPTION_NOINTERPOLATE: NcVisualFlag_u64 =
373        ffi::NCVISUAL_OPTION_NOINTERPOLATE as NcVisualFlag_u64;
374}