diff --git a/dyesub-tool/assets/next.svg b/dyesub-tool/assets/next.svg
new file mode 100644
index 0000000..b805ced
--- /dev/null
+++ b/dyesub-tool/assets/next.svg
@@ -0,0 +1,3 @@
+
diff --git a/dyesub-tool/assets/nixos.svg b/dyesub-tool/assets/nixos.svg
new file mode 100644
index 0000000..8041d98
--- /dev/null
+++ b/dyesub-tool/assets/nixos.svg
@@ -0,0 +1,124 @@
+
+
+
+
diff --git a/dyesub-tool/assets/playpause.svg b/dyesub-tool/assets/playpause.svg
new file mode 100644
index 0000000..3a02310
--- /dev/null
+++ b/dyesub-tool/assets/playpause.svg
@@ -0,0 +1,3 @@
+
diff --git a/dyesub-tool/assets/previous.svg b/dyesub-tool/assets/previous.svg
new file mode 100644
index 0000000..b55a8f9
--- /dev/null
+++ b/dyesub-tool/assets/previous.svg
@@ -0,0 +1,3 @@
+
diff --git a/dyesub-tool/src/key/mod.rs b/dyesub-tool/src/key/mod.rs
new file mode 100644
index 0000000..28e3553
--- /dev/null
+++ b/dyesub-tool/src/key/mod.rs
@@ -0,0 +1,70 @@
+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
new file mode 100644
index 0000000..ffffea5
--- /dev/null
+++ b/dyesub-tool/src/key/oyayubi.rs
@@ -0,0 +1,35 @@
+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 ba9def8..0c0d63f 100644
--- a/dyesub-tool/src/main.rs
+++ b/dyesub-tool/src/main.rs
@@ -1,16 +1,20 @@
pub mod svg;
use svg::*;
+pub mod key;
+use key::*;
+
use askama::Template;
use derive_more::From;
use std::{fs::OpenOptions, io::Write};
+use lazy_static::lazy_static;
#[derive(Template)]
#[template(path = "document.xml")]
-struct DocumentTemplate {
- dimensions: DocumentDimensions,
+struct DocumentTemplate<'a> {
+ dimensions: &'a DocumentDimensions,
box_size: SVGMeasure,
- positions: Vec<(SVGMeasure, SVGMeasure)>,
+ positions: Vec<(&'a Key<'a>, (SVGMeasure, SVGMeasure))>,
}
struct DocumentDimensions {
@@ -24,22 +28,31 @@ enum Error {
Template(askama::Error),
}
-fn positions(
+fn positions<'a>(
+ keys: &'a Vec,
size: SVGMeasure,
+ margin: SVGMeasure,
padding: SVGMeasure,
dimensions: &DocumentDimensions,
- count: u32,
-) -> Vec<(SVGMeasure, SVGMeasure)> {
+) -> Vec<(&'a Key<'a>, (SVGMeasure, SVGMeasure))> {
let grid = size + padding;
- let row_count = ((dimensions.width - padding * 2.0) / grid) as u32;
- (0..count)
- .map(|i| {
- (
- grid * (i % row_count).into() + padding,
- grid * (i / row_count).into() + padding,
- )
- })
- .collect()
+ 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
}
fn main() -> Result<(), Error> {
@@ -53,13 +66,28 @@ fn main() -> Result<(), Error> {
height: SVGMeasure::new(11.0, SVGUnit::Inch),
};
let box_size = SVGMeasure::new(14.0, SVGUnit::Millimeter);
- let boxes = 54;
let padding = SVGMeasure::new(2.5, SVGUnit::Millimeter);
+ let margin = SVGMeasure::new(0.25, SVGUnit::Inch);
let document = DocumentTemplate {
- positions: positions(box_size, padding, &dimensions, boxes),
- dimensions,
+ positions: positions(&KEYS, box_size, margin, padding, &dimensions),
+ dimensions: &dimensions,
box_size,
};
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 fd59c9f..092c2a6 100644
--- a/dyesub-tool/src/svg/measure.rs
+++ b/dyesub-tool/src/svg/measure.rs
@@ -23,11 +23,11 @@ impl SVGMeasure {
Self { measure, unit }
}
- fn to_user_units(self) -> f64 {
+ pub fn to_user_units(self) -> f64 {
self.measure * self.unit.to_user_units()
}
- fn to_unit(self, unit: SVGUnit) -> Self {
+ pub fn to_unit(self, unit: SVGUnit) -> Self {
SVGMeasure {
measure: self.to_user_units() / unit.to_user_units(),
unit,
diff --git a/dyesub-tool/templates/document.xml b/dyesub-tool/templates/document.xml
index 7804fe5..49a9758 100644
--- a/dyesub-tool/templates/document.xml
+++ b/dyesub-tool/templates/document.xml
@@ -1,7 +1,33 @@