vectorizer/
svg.rs

1//!
2//! List demo in Embroidery API (command part).
3//!
4
5mod private
6{
7  use std::fmt;
8
9  /// Wrapper around attributes needed to construct an SVG file.
10  ///
11  /// This struct represents an SVG file and contains attributes such as paths, width, height,
12  /// and the number of decimal places to use in the path string.
13  ///
14  /// # Fields
15  /// * `paths` - A vector of `SvgPath` representing the paths in the SVG file.
16  /// * `width` - The width of the SVG file.
17  /// * `height` - The height of the SVG file.
18  /// * `path_precision` - The number of decimal places to use in the path string.
19  #[ derive( Debug, Clone ) ]
20  pub struct SvgFile 
21  {
22    /// <path> attributes in svg file
23    pub paths : Vec< SvgPath >,
24    /// Width of svg file in pixels
25    pub width : usize,
26    /// Height of svg file in pixels
27    pub height : usize,
28    /// Number of decimal places to use in path string
29    pub path_precision : Option< u32 >,
30  }
31
32  /// Represents a <path> attribute in an SVG file.
33  ///
34  /// This struct contains a collection of `Path` and `Spline` that represents a shape with holes,
35  /// and the color to fill the path.
36  ///
37  /// # Fields
38  /// * `path` - A collection of `Path` and `Spline` that represents a shape with holes.
39  /// * `color` - The color to fill the path.
40  #[ derive( Debug, Clone ) ]
41  pub struct SvgPath
42  {
43    /// A collection of `Path` and `Spline` that represents a shape with holes
44    pub path : visioncortex::CompoundPath,
45    /// Color to fill the path
46    pub color : visioncortex::Color,
47  }
48
49  impl SvgFile 
50  {
51    /// Constructs a new instance of `SvgFile`
52    pub fn new( width : usize, height : usize, path_precision : Option< u32 > ) -> Self 
53    {
54      SvgFile 
55      {
56        paths: vec![],
57        width,
58        height,
59        path_precision,
60      }
61    }
62
63    /// Add a path to the file
64    pub fn add_path( &mut self, path : visioncortex::CompoundPath, color : visioncortex::Color ) 
65    {
66      self.paths.push( SvgPath { path, color } )
67    }
68  }
69
70  impl fmt::Display for SvgFile 
71  {
72    /// Displays `SvgFile` in proper xml representation
73    fn fmt( &self, f : &mut fmt::Formatter::< '_ > ) -> fmt::Result 
74    {
75      writeln!( f, r#"<?xml version="1.0" encoding="UTF-8"?>"# )?;
76      writeln!
77      (
78        f,
79        r#"<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="{}" height="{}">"#,
80        self.width, 
81        self.height
82      )?;
83
84      for path in &self.paths 
85      {
86        path.fmt_with_precision( f, self.path_precision )?;
87      }
88
89      writeln!( f, "</svg>" )
90    }
91  }
92
93  impl fmt::Display for SvgPath 
94  {
95    fn fmt( &self, f : &mut fmt::Formatter::< '_ > ) -> fmt::Result 
96    {
97      self.fmt_with_precision( f, None )
98    }
99  }
100
101  impl SvgPath 
102  {
103    /// Convert `SvgPath` to a <path> string
104    fn fmt_with_precision( &self, f : &mut fmt::Formatter::< '_ >, precision : Option< u32 > ) -> fmt::Result 
105    {
106      let ( string, offset ) = self.path.to_svg_string( true, visioncortex::PointF64::default(), precision );
107      writeln!
108      (
109        f,
110        "<path d=\"{}\" fill=\"{}\" transform=\"translate({},{})\"/>",
111        string,
112        self.color.to_hex_string(),
113        offset.x,
114        offset.y
115      )
116    }
117  }
118}
119
120crate::mod_interface!
121{
122  own use 
123  {
124    SvgFile,
125    SvgPath
126  };
127}