From 79813a25499070a55bf1b7fa8d4c01ee03c0e964 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 16 Aug 2023 12:43:55 -0700 Subject: [PATCH] Import from KLE --- .gitignore | 3 +- Cargo.lock | 114 +++++++++++++++++++++++++++++ dyesub-tool/Cargo.toml | 2 + dyesub-tool/src/key/mod.rs | 70 ------------------ dyesub-tool/src/key/oyayubi.rs | 35 --------- dyesub-tool/src/main.rs | 74 +++++-------------- dyesub-tool/src/svg/measure.rs | 2 +- dyesub-tool/templates/document.xml | 81 ++++++++++++++------ flake.nix | 2 +- 9 files changed, 194 insertions(+), 189 deletions(-) delete mode 100644 dyesub-tool/src/key/mod.rs delete mode 100644 dyesub-tool/src/key/oyayubi.rs diff --git a/.gitignore b/.gitignore index b6b9fae..8a48101 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target .direnv -output.svg \ No newline at end of file +output.svg +layout.json \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 3d7b096..ff239f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "csscolorparser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf" +dependencies = [ + "phf", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -86,8 +95,10 @@ version = "0.1.0" dependencies = [ "askama", "derive_more", + "kle-serial", "lazy_static", "regex", + "serde_json", "strum", "strum_macros", ] @@ -107,6 +118,23 @@ dependencies = [ "libm", ] +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "kle-serial" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbb2235a7a2c256a7d0e6393a2f29b27995dc098b797c0fd02f418166709eae" +dependencies = [ + "csscolorparser", + "rgb", + "serde", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -172,6 +200,48 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "proc-macro2" version = "1.0.66" @@ -190,6 +260,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + [[package]] name = "regex" version = "1.9.3" @@ -219,6 +304,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +[[package]] +name = "rgb" +version = "0.8.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ec2d3e3fc7a92ced357df9cebd5a10b6fb2aa1ee797bf7e9ce2f17dffc8f59" + [[package]] name = "rustc_version" version = "0.4.0" @@ -234,6 +325,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + [[package]] name = "semver" version = "1.0.18" @@ -260,6 +357,23 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + [[package]] name = "strum" version = "0.25.0" diff --git a/dyesub-tool/Cargo.toml b/dyesub-tool/Cargo.toml index a99af79..4bf83bb 100644 --- a/dyesub-tool/Cargo.toml +++ b/dyesub-tool/Cargo.toml @@ -6,7 +6,9 @@ edition = "2021" [dependencies] askama = "0.12.0" derive_more = "0.99.17" +kle-serial = "0.2.2" lazy_static = "1.4.0" regex = "1.9.3" +serde_json = "1.0.105" strum = "0.25.0" strum_macros = "0.25.2" diff --git a/dyesub-tool/src/key/mod.rs b/dyesub-tool/src/key/mod.rs deleted file mode 100644 index 28e3553..0000000 --- a/dyesub-tool/src/key/mod.rs +++ /dev/null @@ -1,70 +0,0 @@ -mod oyayubi; -pub use oyayubi::OYAYUBI; - -use std::fmt::{Display, self}; - -#[derive(Clone, Copy)] -pub enum Key<'a> { - Oyayubi { - latin: char, - normal: char, - shift: char, - alt_shift: Option, - }, - Single { - text: &'a str, - u: f64, - }, - Icon { - icon_path: &'a str, - u: f64, - }, - Break, -} - -pub const fn oyayubi<'a>(latin: char, normal: char, shift: char, alt_shift: Option) -> Key<'a> { - Key::Oyayubi { - latin, - normal, - shift, - alt_shift, - } -} - -pub const fn single<'a>(text: &'a str, u: f64) -> Key<'a> { - Key::Single { - text, - u, - } -} - -pub const fn icon<'a>(icon_path: &'a str, u: f64) -> Key<'a> { - Key::Icon { - icon_path, - u, - } -} - -impl<'a> Key<'a> { - pub fn width_mod(&self) -> f64 { - use Key::*; - match self { - Oyayubi { .. } => 1.0, - Single { u, .. } => *u, - Icon { u, .. } => *u, - Break => 0.0, - } - } -} - -impl<'a> Display for Key<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Key::*; - write!(f, "{}", match self { - Oyayubi { latin, .. } => latin.to_string(), - Single { text, .. } => text.to_string(), - Icon { icon_path, .. } => icon_path.to_string(), - Break => "".to_string(), - }) - } -} \ No newline at end of file diff --git a/dyesub-tool/src/key/oyayubi.rs b/dyesub-tool/src/key/oyayubi.rs deleted file mode 100644 index ffffea5..0000000 --- a/dyesub-tool/src/key/oyayubi.rs +++ /dev/null @@ -1,35 +0,0 @@ -use super::Key; -use super::oyayubi as k; - -pub const OYAYUBI: [Key; 30] = [ - k('Q', '。', 'ぁ', None), - k('W', 'か', 'え', None), - k('E', 'た', 'り', None), - k('R', 'こ', 'ゃ', None), - k('T', 'さ', 'れ', None), - k('Y', 'ら', 'よ', Some('ぱ')), - k('U', 'ち', 'に', None), - k('I', 'く', 'る', None), - k('O', 'つ', 'ま', None), - k('P', ',', 'ぇ', Some('ぴ')), - k('A', 'う', 'を', None), - k('S', 'し', 'あ', None), - k('D', 'て', 'な', None), - k('F', 'け', 'ゅ', None), - k('G', 'せ', 'も', None), - k('H', 'は', 'み', None), - k('J', 'と', 'お', None), - k('K', 'き', 'の', None), - k('L', 'い', 'ょ', Some('ぽ')), - k(';', 'ん', 'っ', None), // Missing + - k('Z', '.', 'ぅ', None), - k('X', 'ひ', 'ー', None), - k('C', 'す', 'ろ', None), - k('V', 'ふ', 'や', None), - k('B', 'へ', 'ぃ', None), - k('N', 'め', 'ぬ', Some('ぷ')), - k('M', 'そ', 'ゆ', None), - k(',', 'ね', 'む', Some('ぺ')), // Missing < - k('.', 'ほ', 'わ', None), // Missing > - k('?', '・', 'ぉ', Some('ゎ')) // Missing / -]; \ No newline at end of file diff --git a/dyesub-tool/src/main.rs b/dyesub-tool/src/main.rs index 0c0d63f..325c2b7 100644 --- a/dyesub-tool/src/main.rs +++ b/dyesub-tool/src/main.rs @@ -1,9 +1,6 @@ pub mod svg; use svg::*; -pub mod key; -use key::*; - use askama::Template; use derive_more::From; use std::{fs::OpenOptions, io::Write}; @@ -13,46 +10,32 @@ use lazy_static::lazy_static; #[template(path = "document.xml")] struct DocumentTemplate<'a> { dimensions: &'a DocumentDimensions, - box_size: SVGMeasure, - positions: Vec<(&'a Key<'a>, (SVGMeasure, SVGMeasure))>, + keyboard: kle_serial::Keyboard, } struct DocumentDimensions { width: SVGMeasure, height: SVGMeasure, + margin: SVGMeasure, +} + +fn kle_font_units(kle_font_units: &usize) -> SVGMeasure { + return SVGMeasure::new((6 + kle_font_units * 2) as f64, SVGUnit::Pixel); +} + +lazy_static! { + static ref LETTER_LANDSCAPE: DocumentDimensions = DocumentDimensions { + width: SVGMeasure::new(11.0, SVGUnit::Inch), + height: SVGMeasure::new(8.5, SVGUnit::Inch), + margin: SVGMeasure::new(0.25, SVGUnit::Inch), + }; } #[derive(From, Debug)] enum Error { Io(std::io::Error), Template(askama::Error), -} - -fn positions<'a>( - keys: &'a Vec, - size: SVGMeasure, - margin: SVGMeasure, - padding: SVGMeasure, - dimensions: &DocumentDimensions, -) -> Vec<(&'a Key<'a>, (SVGMeasure, SVGMeasure))> { - let grid = size + padding; - let mut x = margin; - let mut y = margin; - let mut positions = Vec::with_capacity(keys.len()); - for key in keys { - if let Key::Break = key { - x = margin; - y = y + grid; - continue; - } - if x + grid > dimensions.width - margin { - x = margin; - y = y + grid; - } - positions.push((key, (x, y))); - x = x + size * key.width_mod() + padding; - } - positions + LayoutParse(serde_json::Error), } fn main() -> Result<(), Error> { @@ -61,33 +44,10 @@ fn main() -> Result<(), Error> { .truncate(true) .create(true) .open("output.svg")?; - let dimensions = DocumentDimensions { - width: SVGMeasure::new(8.5, SVGUnit::Inch), - height: SVGMeasure::new(11.0, SVGUnit::Inch), - }; - let box_size = SVGMeasure::new(14.0, SVGUnit::Millimeter); - let padding = SVGMeasure::new(2.5, SVGUnit::Millimeter); - let margin = SVGMeasure::new(0.25, SVGUnit::Inch); let document = DocumentTemplate { - positions: positions(&KEYS, box_size, margin, padding, &dimensions), - dimensions: &dimensions, - box_size, + dimensions: &LETTER_LANDSCAPE, + keyboard: serde_json::from_str(&std::fs::read_to_string("layout.json")?)?, }; write!(file, "{}", document.render()?)?; Ok(()) -} - -lazy_static! { - static ref KEYS: Vec> = { - let mut keys = OYAYUBI.to_vec(); - keys.push(Key::Break); - keys.push(single("親指左", 3.0)); - keys.push(single("親指右", 3.0)); - keys.push(Key::Break); - keys.push(icon("assets/nixos.svg", 1.0)); - keys.push(icon("assets/playpause.svg", 1.0)); - keys.push(icon("assets/previous.svg", 1.0)); - keys.push(icon("assets/next.svg", 1.0)); - keys - }; } \ No newline at end of file diff --git a/dyesub-tool/src/svg/measure.rs b/dyesub-tool/src/svg/measure.rs index 092c2a6..e9c3afa 100644 --- a/dyesub-tool/src/svg/measure.rs +++ b/dyesub-tool/src/svg/measure.rs @@ -19,7 +19,7 @@ pub struct SVGMeasure { } impl SVGMeasure { - pub fn new(measure: f64, unit: SVGUnit) -> Self { + pub const fn new(measure: f64, unit: SVGUnit) -> Self { Self { measure, unit } } diff --git a/dyesub-tool/templates/document.xml b/dyesub-tool/templates/document.xml index 49a9758..be9847b 100644 --- a/dyesub-tool/templates/document.xml +++ b/dyesub-tool/templates/document.xml @@ -4,30 +4,63 @@ - {% for (key, (x, y)) in positions %} - {% let width = box_size * key.width_mod() %} - - - {% let dy = "0.125em" %} - {% match key %} - {% when crate::key::Key::Oyayubi with { latin, normal, shift, alt_shift } %} - {% let font_size = "0.45cm" %} - {% let latin_font_size = "0.4cm" %} - {% let alt_shift_font_size = "0.325cm" %} - {{ latin }} - {{ shift }} - {{ normal }} - {% if let Some(alt_shift) = alt_shift %} - {{ alt_shift }} - {% endif %} - {% when crate::key::Key::Single with { text, u } %} - {% let font_size = "0.5cm" %} - {{ text }} - {% when crate::key::Key::Icon with { icon_path, u } %} - {% let icon_width_mm = 7.5 %} - - {% when crate::key::Key::Break %} - {% endmatch %} + {% let u = crate::svg::SVGMeasure::new(14.0, crate::svg::SVGUnit::Millimeter) %} + {% let padding = crate::svg::SVGMeasure::new(2.5, crate::svg::SVGUnit::Millimeter) %} + {% let dy = "0.125em" %} + {% for key in keyboard.keys %} + {% let x = u * key.x + padding * key.x + dimensions.margin %} + {% let y = u * key.y + padding * key.y + dimensions.margin %} + {% let width = u * key.width %} + {% let height = u * key.height %} + + + + {# top-left #} + {% if let Some(legend) = key.legends[0] %} + {{ legend.text }} + {% endif %} + + {# top-center #} + {% if let Some(legend) = key.legends[1] %} + {{ legend.text }} + {% endif %} + + {# top-right #} + {% if let Some(legend) = key.legends[2] %} + {{ legend.text }} + {% endif %} + + {# middle-left #} + {% if let Some(legend) = key.legends[3] %} + {{ legend.text }} + {% endif %} + + {# middle-center #} + {% if let Some(legend) = key.legends[4] %} + {{ legend.text }} + {% endif %} + + {# middle-right #} + {% if let Some(legend) = key.legends[5] %} + {{ legend.text }} + {% endif %} + + {# bottom-left #} + {% if let Some(legend) = key.legends[6] %} + {{ legend.text }} + {% endif %} + + {# bottom-center #} + {% if let Some(legend) = key.legends[7] %} + {{ legend.text }} + {% endif %} + + {# bottom-right #} + {% if let Some(legend) = key.legends[8] %} + {{ legend.text }} + {% endif %} + + {# TODO 9-11 are side #} {% endfor %} diff --git a/flake.nix b/flake.nix index 7abf022..dc99fc7 100644 --- a/flake.nix +++ b/flake.nix @@ -51,7 +51,7 @@ Updating `cargoHash`: pname = "dyesub-tool"; version = "0.1.0"; buildAndTestSubdir = "dyesub-tool"; - cargoHash = "sha256-QlLyKDZZ+/bB4xBv0j9GoL6Ur3Okdskkazi4WlHhx6Y="; + cargoHash = "sha256-kZUTrejN4KVZ91CkpweLivwm9KaMT+fT6Ljq5Vy0Jik="; meta = meta // { description = "A tool for generating dye sublimation transfer sheet SVGs for Japanese thumb shift 拇指シフト keycaps."; };