libsixel_rs/device_control_string/raster.rs
1use crate::std::fmt;
2
3/// Raster attributes
4///
5/// The `" (2/2)` character is the set raster attributes command.
6///
7/// This command selects the raster attributes for the sixel data string that follows it.
8///
9/// You must use the command before any sixel data string.
10///
11/// The `"` command overrides any raster attributes set by the macro parameter described above.
12///
13/// You use the following format for the `"` command:
14///
15/// | " | Pan | ; | Pad; | Ph; | Pv |
16/// |-----|------|------|------|------|------|
17/// | 2/2 | `**` | 3/11 | `**` | `**` | `**` |
18///
19/// where:
20///
21/// **Pan** and **Pad** define the pixel aspect ratio for the following sixel data string. Pan is the numerator, and Pad is the denominator.
22///
23/// ```no_build, no_run
24/// Pan
25/// --- = pixel aspect ratio
26/// Pad
27/// ```
28///
29/// The pixel aspect ratio defines the shape of the pixels the terminal uses to draw the sixel image.
30///
31/// Pan defines the vertical shape of the pixel. Pad defines the horizontal shape of the pixel. For example, to define a pixel that is twice as high as it is wide, you use a value of 2 for Pan and 1 for Pad.
32///
33/// If you use the set raster attributes command (") in a sixel data string, you must specify a pixel aspect ratio. You can only use integer values for Pan and Pad. The VT300 rounds the pixel aspect ratio to the nearest integer.
34///
35/// **Ph** and **Pv** define the horizontal and vertical size of the image (in pixels), respectively.
36///
37/// `Ph` and `Pv` do not limit the size of the image defined by the sixel data. However, `Ph` and `Pv` let you omit background sixel data from the image definition and still have a color background. They also provide a concise way for the application or terminal to encode the size of an image.
38///
39/// ___NOTE: The VT300 uses Ph and Pv to erase the background when P2 is set to 0 or 2.___
40#[repr(C)]
41#[derive(Clone, Copy, Debug, Default, PartialEq)]
42pub struct Raster {
43 pan: usize,
44 pad: usize,
45 h: usize,
46 v: usize,
47}
48
49impl Raster {
50 /// Creates a new [Raster].
51 pub const fn new() -> Self {
52 Self {
53 pan: 0,
54 pad: 0,
55 h: 0,
56 v: 0,
57 }
58 }
59
60 /// Creates a new [Raster] with the provided parameters.
61 pub const fn create(pan: usize, pad: usize, h: usize, v: usize) -> Self {
62 Self { pan, pad, h, v }
63 }
64
65 /// Gets the `pan` numerator for the pixel aspect ratio.
66 pub const fn pan(&self) -> usize {
67 self.pan
68 }
69
70 /// Sets the `pan` numerator for the pixel aspect ratio.
71 pub fn set_pan(&mut self, val: usize) {
72 self.pan = val;
73 }
74
75 /// Builder function that sets the `pan` numerator for the pixel aspect ratio.
76 pub fn with_pan(mut self, val: usize) -> Self {
77 self.set_pan(val);
78 self
79 }
80
81 /// Gets the `pad` denominator for the pixel aspect ratio.
82 pub const fn pad(&self) -> usize {
83 self.pad
84 }
85
86 /// Sets the `pad` denominator for the pixel aspect ratio.
87 pub fn set_pad(&mut self, val: usize) {
88 self.pad = val;
89 }
90
91 /// Builder function that sets the `pad` denominator for the pixel aspect ratio.
92 pub fn with_pad(mut self, val: usize) -> Self {
93 self.set_pad(val);
94 self
95 }
96
97 /// Gets the horizontal size of the image.
98 pub const fn h(&self) -> usize {
99 self.h
100 }
101
102 /// Sets the horizontal size of the image.
103 pub fn set_h(&mut self, val: usize) {
104 self.h = val;
105 }
106
107 /// Builder function that sets the horizontal size of the image.
108 pub fn with_h(mut self, val: usize) -> Self {
109 self.set_h(val);
110 self
111 }
112
113 /// Gets the vertical size of the image.
114 pub const fn v(&self) -> usize {
115 self.v
116 }
117
118 /// Sets the vertical size of the image.
119 pub fn set_v(&mut self, val: usize) {
120 self.v = val;
121 }
122
123 /// Builder function that sets the vertical size of the image.
124 pub fn with_v(mut self, val: usize) -> Self {
125 self.set_v(val);
126 self
127 }
128}
129
130impl fmt::Display for Raster {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 write!(f, r#""{};{};{};{}"#, self.pan, self.pad, self.h, self.v)
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139
140 #[test]
141 fn test_display() {
142 let raster = Raster::create(2, 1, 600, 480);
143 let exp_raster = r#""2;1;600;480"#;
144
145 assert_eq!(format!("{raster}").as_str(), exp_raster);
146 }
147}