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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/// A separator type for a list of values.
///
/// <https://www.w3.org/TR/SVG11/types.html#DataTypeList>
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ListSeparator {
/// `10,20`
Comma,
/// `10 20`
Space,
/// `10, 20`
CommaSpace,
}
/// Options for SVG types writing.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct WriteOptions {
/// Use #RGB color notation when possible.
///
/// By default all colors written using #RRGGBB notation.
///
/// # Examples
///
/// `#ff0000` -> `#f00`, `#000000` -> `#000`, `#00aa00` -> `#0a0`
///
/// Default: disabled
pub trim_hex_colors: bool,
/// Remove leading zero from numbers.
///
/// # Examples
///
/// - `0.1` -> `.1`
/// - `-0.1` -> `-.1`
///
/// Default: disabled
pub remove_leading_zero: bool,
/// Use compact path notation.
///
/// SVG allow us to remove some symbols from path notation without breaking parsing.
///
/// # Examples
///
/// `M 10 -20 A 5.5 0.3 -4 1 1 0 -0.1` -> `M10-20A5.5.3-4 1 1 0-.1`
///
/// Default: disabled
pub use_compact_path_notation: bool,
/// Join ArcTo flags.
///
/// Elliptical arc curve segment has flags parameters, which can have values of `0` or `1`.
/// Since we have fixed-width values, we can skip spaces between them.
///
/// **Note:** Sadly, but most of the viewers doesn't support such notation,
/// even though it's valid according to the SVG spec.
///
/// # Examples
///
/// `A 5 5 30 1 1 10 10` -> `A 5 5 30 1110 10`
///
/// Default: disabled
pub join_arc_to_flags: bool,
/// Remove duplicated commands.
///
/// If a segment has the same type as a previous then we can skip command specifier.
///
/// # Examples
///
/// `M 10 10 L 20 20 L 30 30 L 40 40` -> `M 10 10 L 20 20 30 30 40 40`
///
/// Default: disabled
pub remove_duplicated_path_commands: bool,
/// Use implicit LineTo commands.
///
/// 'If a MoveTo is followed by multiple pairs of coordinates,
/// the subsequent pairs are treated as implicit LineTo commands.'
///
/// # Examples
///
/// `M 10 10 L 20 20 L 30 30` -> `M 10 10 20 20 30 30`
///
/// Default: disabled
pub use_implicit_lineto_commands: bool,
/// Simplify transform matrices into short equivalent when possible.
///
/// If not set - all transform will be saved as 'matrix'.
///
/// # Examples
///
/// ```text
/// matrix(1 0 0 1 10 20) -> translate(10 20)
/// matrix(1 0 0 1 10 0) -> translate(10)
/// matrix(2 0 0 3 0 0) -> scale(2 3)
/// matrix(2 0 0 2 0 0) -> scale(2)
/// matrix(0 1 -1 0 0 0) -> rotate(-90)
/// ```
///
/// Default: disabled
pub simplify_transform_matrices: bool,
/// Set the separator type for list types.
///
/// Affects `Points`, `LengthList`, `NumberList` and `Transform`.
///
/// Default: `ListSeparator::Space`
pub list_separator: ListSeparator,
}
impl Default for WriteOptions {
#[inline]
fn default() -> WriteOptions {
WriteOptions {
trim_hex_colors: false,
remove_leading_zero: false,
use_compact_path_notation: false,
join_arc_to_flags: false,
remove_duplicated_path_commands: false,
use_implicit_lineto_commands: false,
simplify_transform_matrices: false,
list_separator: ListSeparator::Space,
}
}
}
impl WriteOptions {
/// Writes a selected separator to the output buffer.
///
/// Uses `WriteOptions::list_separator` option.
#[inline]
pub fn write_separator(&self, out: &mut Vec<u8>) {
match self.list_separator {
ListSeparator::Space => out.push(b' '),
ListSeparator::Comma => out.push(b','),
ListSeparator::CommaSpace => out.extend_from_slice(b", "),
}
}
}