skia_safe/utils/
parse_path.rs1use std::ffi::CString;
2
3use crate::{interop, prelude::*, Path};
4
5use skia_bindings as sb;
6
7pub fn from_svg(svg: impl AsRef<str>) -> Option<Path> {
8 let str = CString::new(svg.as_ref()).unwrap();
9 Path::try_construct(|p| unsafe { sb::C_SkParsePath_FromSVGString(str.as_ptr(), p) })
10}
11
12pub use skia_bindings::SkParsePath_PathEncoding as PathEncoding;
13variant_name!(PathEncoding::Absolute);
14
15impl Path {
16 pub fn from_svg(svg: impl AsRef<str>) -> Option<Path> {
17 from_svg(svg)
18 }
19
20 pub fn to_svg(&self) -> String {
21 to_svg(self)
22 }
23
24 pub fn to_svg_with_encoding(&self, encoding: PathEncoding) -> String {
25 to_svg_with_encoding(self, encoding)
26 }
27}
28
29pub fn to_svg(path: &Path) -> String {
30 to_svg_with_encoding(path, PathEncoding::Absolute)
31}
32
33pub fn to_svg_with_encoding(path: &Path, encoding: PathEncoding) -> String {
34 interop::String::construct(|svg| {
35 unsafe { sb::C_SkParsePath_ToSVGString(path.native(), svg, encoding) };
36 })
37 .as_str()
38 .into()
39}
40
41#[cfg(test)]
42mod tests {
43 use super::Path;
44
45 #[test]
46 fn simple_path_to_svg_and_back() {
47 let mut path = Path::default();
48 path.move_to((0, 0));
49 path.line_to((100, 100));
50 path.line_to((0, 100));
51 path.close();
52
53 let svg = Path::to_svg(&path);
54 assert_eq!(svg, "M0 0L100 100L0 100L0 0Z");
55 let _recreated = Path::from_svg(svg).expect("Failed to parse SVG path");
57 }
58}