1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
diff --git a/src/lib.rs b/src/lib.rs
index 99e14d9..a745b10 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -37,6 +37,8 @@ use sixel_tokenizer::{ColorCoordinateSystem, Parser};
pub struct SixelImage {
color_registers: BTreeMap<u16, SixelColor>,
pixels: Vec<Vec<Pixel>>,
+ pan: Option<usize>,
+ pad: Option<usize>,
}
impl SixelImage {
@@ -62,14 +64,14 @@ impl SixelImage {
}
/// Serializes the whole image, returning a stringified sixel representation of it
pub fn serialize(&self) -> String {
- let sixel_serializer = SixelSerializer::new(&self.color_registers, &self.pixels);
+ let sixel_serializer = SixelSerializer::new(&self.color_registers, &self.pixels, self.pan, self.pad);
let serialized_image = sixel_serializer.serialize();
serialized_image
}
/// Serializes a specific rectangle of this image without manipulating the image itself, x/y
/// coordinates as well as width height are in pixels
pub fn serialize_range(&self, start_x_index: usize, start_y_index: usize, width: usize, height: usize) -> String {
- let sixel_serializer = SixelSerializer::new(&self.color_registers, &self.pixels);
+ let sixel_serializer = SixelSerializer::new(&self.color_registers, &self.pixels, self.pan, self.pad);
let serialized_image = sixel_serializer.serialize_range(start_x_index, start_y_index, width, height);
serialized_image
}
diff --git a/src/sixel_deserializer.rs b/src/sixel_deserializer.rs
index 92ba43f..ae32a64 100644
--- a/src/sixel_deserializer.rs
+++ b/src/sixel_deserializer.rs
@@ -15,6 +15,8 @@ pub struct SixelDeserializer {
stop_parsing: bool,
got_dcs: bool,
transparent_background: bool,
+ pan: Option<usize>,
+ pad: Option<usize>,
}
impl SixelDeserializer {
@@ -29,6 +31,8 @@ impl SixelDeserializer {
stop_parsing: false,
got_dcs: false,
transparent_background: false,
+ pan: None,
+ pad: None,
}
}
/// Provide a `max_height` value in pixels, all pixels beyond this max height will not be
@@ -47,6 +51,8 @@ impl SixelDeserializer {
Ok(SixelImage {
pixels,
color_registers,
+ pan: self.pan,
+ pad: self.pad
})
}
/// Handle a [`SixelEvent`], changing the internal state to match
@@ -71,8 +77,9 @@ impl SixelDeserializer {
}
}
}
- SixelEvent::RasterAttribute { pan: _, pad: _, ph, pv } => {
- // we ignore pan/pad because (reportedly) no-one uses them
+ SixelEvent::RasterAttribute { pan, pad, ph, pv } => {
+ self.pan = Some(pan);
+ self.pad = Some(pad);
if !self.transparent_background {
if let Some(pv) = pv {
self.pad_lines_vertically(pv);
diff --git a/src/sixel_serializer.rs b/src/sixel_serializer.rs
index 72e3d7b..7d20487 100644
--- a/src/sixel_serializer.rs
+++ b/src/sixel_serializer.rs
@@ -5,18 +5,22 @@ use crate::{SixelColor, Pixel};
pub struct SixelSerializer <'a>{
color_registers: &'a BTreeMap<u16, SixelColor>,
pixels: &'a Vec<Vec<Pixel>>,
+ pan: Option<usize>,
+ pad: Option<usize>,
}
impl <'a>SixelSerializer <'a>{
- pub fn new(color_registers: &'a BTreeMap<u16, SixelColor>, pixels: &'a Vec<Vec<Pixel>>) -> Self {
+ pub fn new(color_registers: &'a BTreeMap<u16, SixelColor>, pixels: &'a Vec<Vec<Pixel>>, pan: Option<usize>, pad: Option<usize>) -> Self {
SixelSerializer {
color_registers,
- pixels
+ pixels,
+ pan,
+ pad
}
}
pub fn serialize(&self) -> String {
let serialized_image = String::new();
- let serialized_image = self.serialize_empty_dcs(serialized_image);
+ let serialized_image = self.serialize_dcs(serialized_image, None, None);
let serialized_image = self.serialize_color_registers(serialized_image);
let serialized_image = self.serialize_pixels(serialized_image, None, None, None, None);
let serialized_image = self.serialize_end_event(serialized_image);
@@ -24,14 +28,17 @@ impl <'a>SixelSerializer <'a>{
}
pub fn serialize_range(&self, start_x_index: usize, start_y_index: usize, width: usize, height: usize) -> String {
let serialized_image = String::new();
- let serialized_image = self.serialize_empty_dcs(serialized_image);
+ let serialized_image = self.serialize_dcs(serialized_image, Some(width), Some(height));
let serialized_image = self.serialize_color_registers(serialized_image);
let serialized_image = self.serialize_pixels(serialized_image, Some(start_x_index), Some(start_y_index), Some(width), Some(height));
let serialized_image = self.serialize_end_event(serialized_image);
serialized_image
}
- fn serialize_empty_dcs(&self, mut append_to: String) -> String {
- append_to.push_str("\u{1b}Pq");
+ fn serialize_dcs(&self, mut append_to: String, width: Option<usize>, height: Option<usize>) -> String {
+ append_to.push_str("\u{1b}P0;1;0q");
+ let width = width.unwrap_or_else(|| self.pixels.first().map(|first_line| first_line.len()).unwrap_or(0));
+ let height = height.unwrap_or_else(|| self.pixels.len());
+ append_to.push_str(&format!("\"{};{};{};{}", self.pan.unwrap_or(1), self.pad.unwrap_or(1), width, height));
append_to
}
fn serialize_color_registers(&self, mut append_to: String) -> String {
|