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}