~vpzom/savg

561051b74b71381a6dd01d0f720f82b8039edf68 — Colin Reeder 5 years ago fa9ae5a
Initial work on saving
4 files changed, 235 insertions(+), 1 deletions(-)

M Cargo.lock
M Cargo.toml
M src/main.rs
A src/save.rs
M Cargo.lock => Cargo.lock +146 -0
@@ 10,6 10,27 @@ dependencies = [
]

[[package]]
name = "backtrace"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "backtrace-sys"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 45,6 66,39 @@ version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "cfg-if"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "encoding_rs"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "failure"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
 "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "failure_derive"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
 "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
 "syn 0.15.15 (registry+https://github.com/rust-lang/crates.io-index)",
 "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "fragile"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 221,6 275,24 @@ version = "0.2.43"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "log"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "memchr"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "pango"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 251,6 323,38 @@ version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "proc-macro2"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "quick-xml"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "encoding_rs 0.8.10 (registry+https://github.com/rust-lang/crates.io-index)",
 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "quote"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "rustc-demangle"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "savg"
version = "0.1.0"
dependencies = [


@@ 259,9 363,36 @@ dependencies = [
 "gdk 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "glib 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "gtk 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "quick-xml 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "syn"
version = "0.15.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
 "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "synstructure"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
 "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
 "syn 0.15.15 (registry+https://github.com/rust-lang/crates.io-index)",
 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 287,10 418,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

[metadata]
"checksum atk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7017e53393e713212aed7aea336b6553be4927f58c37070a56c2fe3d107e489"
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd940f0d609699e343ef71c4af5f66423afbf30d666f796dabd8fd15229cf5b6"
"checksum cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d25596627380be4381247dba06c69ad05ca21b3b065bd9827e416882ac41dcd2"
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum encoding_rs 0.8.10 (registry+https://github.com/rust-lang/crates.io-index)" = "065f4d0c826fdaef059ac45487169d918558e3cf86c9d89f6e81cf52369126e5"
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
"checksum fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
"checksum gdk 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc52c7244046df9d959df87289f1fc5cca23f9f850bab0c967963e2ecb83a96"
"checksum gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc3aa730cb4df3de5d9fed59f43afdf9e5fb2d3d10bfcbd04cec031435ce87f5"


@@ 305,9 442,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum gtk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d487d333a4b87072e6bf9f2e55befa0ebef01b9496c2e263c0f4a1ff3d6c04b1"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16"
"checksum pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c2cb169402a3eb1ba034a7cc7d95b8b1c106e9be5ba4be79a5a93dc1a2795f4"
"checksum pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6eb49268e69dd0c1da5d3001a61aac08e2e9d2bfbe4ae4b19b9963c998f6453"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
"checksum quick-xml 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b62a38216952bff95085ad664b772492288a96a25544f48d25e7200de1d7db7"
"checksum quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5829244f52738cfee93b3a165c1911388675be000c888d2fae620dee8fa5b"
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
"checksum syn 0.15.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0a9c2bf1e53c21704a7cce1b2a42768f1ae32a6777108a0d7f1faa4bfe7f7c04"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

M Cargo.toml => Cargo.toml +1 -0
@@ 9,3 9,4 @@ cairo-rs = "0.5.0"
gdk = "0.9.0"
glib = "0.6.0"
fragile = "0.3.0"
quick-xml = "0.13.1"

M src/main.rs => src/main.rs +26 -1
@@ 2,8 2,10 @@ extern crate cairo;
extern crate fragile;
extern crate gdk;
extern crate gtk;
extern crate quick_xml;

mod document;
mod save;
mod types;

use document::*;


@@ 25,8 27,23 @@ fn main() {
            gdk::EventMask::BUTTON_PRESS_MASK
            ).bits() as i32);

    let save_item = gtk::MenuItem::new_with_label("Save");

    let file_menu = gtk::Menu::new();
    file_menu.append(&save_item);

    let file_item = gtk::MenuItem::new_with_label("File");
    file_item.set_submenu(&file_menu);

    let menu_bar = gtk::MenuBar::new();
    menu_bar.append(&file_item);

    let main_box = gtk::Box::new(gtk::Orientation::Vertical, 2);
    main_box.pack_start(&menu_bar, false, false, 0);
    main_box.pack_end(&area, true, true, 0);

    let window = gtk::Window::new(gtk::WindowType::Toplevel);
    window.add(&area);
    window.add(&main_box);
    window.set_title("Savg");
    window.show_all();



@@ 81,6 98,14 @@ fn main() {
        });
    }

    {
        let instance = instance.clone();
        save_item.connect_activate(move |_| {
            let document = instance.document.read().unwrap();
            save::save_svg(&document, std::fs::File::create("/tmp/savg.svg").expect("jhdsjkghsdfkj"));
        });
    }

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(true)

A src/save.rs => src/save.rs +62 -0
@@ 0,0 1,62 @@
use quick_xml;
use std;

use document;

pub enum Error {
    XML(quick_xml::Error),
    IO(std::io::Error),
}

impl From<quick_xml::Error> for Error {
    fn from(e: quick_xml::Error) -> Error {
        Error::XML(e)
    }
}

pub fn save_svg(doc: &document::Document, dest: impl std::io::Write) -> Result<(), Error> {
    let mut writer = quick_xml::Writer::new(dest);

    let width_str = doc.size.width.to_string();
    let height_str = doc.size.height.to_string();

    let root_attrs: Vec<quick_xml::events::attributes::Attribute> = vec![
        (&b"version"[..], &b"1.1"[..]).into(),
        (&b"xmlns"[..], &b"http://www.w3.org/2000/svg"[..]).into(),
        ("width", &width_str[..]).into(),
        ("height", &height_str[..]).into(),
    ];

    writer.write_event(quick_xml::events::Event::Decl(quick_xml::events::BytesDecl::new(b"1.0", None, None)))?;
    writer.write_event(quick_xml::events::Event::Start(quick_xml::events::BytesStart::borrowed_name(b"svg")
                                                       .with_attributes(root_attrs.into_iter())))?;

    for elem in &doc.content {
        write_element_svg(&elem, &mut writer)?;
    }

    writer.write_event(quick_xml::events::Event::End(quick_xml::events::BytesEnd::borrowed(b"svg")))?;

    Ok(())
}

fn write_element_svg(elem: &document::Element, writer: &mut quick_xml::Writer<impl std::io::Write>) -> Result<(), Error> {
    match elem {
        document::Element::Rect(rect) => {
            let x_str = rect.position.x.to_string();
            let y_str = rect.position.y.to_string();
            let width_str = rect.size.width.to_string();
            let height_str = rect.size.height.to_string();
            let attrs = vec![
                ("x", &x_str[..]),
                ("y", &y_str[..]),
                ("width", &width_str[..]),
                ("height", &height_str[..]),
            ];
            writer.write_event(quick_xml::events::Event::Start(quick_xml::events::BytesStart::borrowed_name(b"rect")
                                                               .with_attributes(attrs.into_iter())))?;
            writer.write_event(quick_xml::events::Event::End(quick_xml::events::BytesEnd::borrowed(b"rect")))?;
            Ok(())
        }
    }
}