diff --git a/index.html b/index.html
index 4a1e2c4..0eef48f 100644
--- a/index.html
+++ b/index.html
@@ -44,7 +44,8 @@
+
+
diff --git a/src/bin/svg-wasm.rs b/src/bin/svg-wasm.rs
index e6feb39..675baa5 100644
--- a/src/bin/svg-wasm.rs
+++ b/src/bin/svg-wasm.rs
@@ -77,6 +77,7 @@ fn span(text: &str) -> HtmlElement {
pub fn run() {
let document = web!(document);
+ let print_labels = get_labels();
let mode = get_mode();
let var_count = get_var_number();
let vars = (0..var_count).map(|x| 2usize.pow(x as u32)).collect::>();
@@ -100,7 +101,7 @@ pub fn run() {
macro_rules! render_svg {
($sol:expr, $mask:expr) => {
- let svg = svg::get_svg(if var_count < 5 { 64 } else { 80 }, &function, &vars, $mask);
+ let svg = svg::get_svg(if var_count < 5 { 64 } else { 80 }, print_labels, &function, &vars, $mask);
let svg_container = document.create_element("div").unwrap();
svg_container.set_class_name("solution");
svg_container.set_inner_html(&svg);
@@ -175,6 +176,14 @@ fn get_var_number() -> usize {
get_var_number_el().value().parse().unwrap()
}
+fn get_labels_el() -> HtmlInputElement {
+ web!(document).get_element_by_id("labels").unwrap().unchecked_into()
+}
+
+fn get_labels() -> bool {
+ get_labels_el().checked()
+}
+
fn get_mode_el() -> HtmlSelectElement {
web!(document).get_element_by_id("mode-select").unwrap().unchecked_into()
}
diff --git a/src/bin/svg.rs b/src/bin/svg.rs
index c894876..5a4d3f0 100644
--- a/src/bin/svg.rs
+++ b/src/bin/svg.rs
@@ -45,5 +45,5 @@ fn main() {
.collect()
};
- println!("{}", svg::get_svg(SIZE_FACTOR, &function, &vars, &block_masks));
+ println!("{}", svg::get_svg(SIZE_FACTOR, false, &function, &vars, &block_masks));
}
diff --git a/src/ui/svg.rs b/src/ui/svg.rs
index a53b900..9b2e854 100644
--- a/src/ui/svg.rs
+++ b/src/ui/svg.rs
@@ -15,9 +15,12 @@ const COLORS: &'static [Color] = &[
rgb(128, 0, 128), // dark red
];
-pub fn get_svg(size_factor: usize, function: &FunctionSpec, vars: &[Variable], block_masks: &[(usize, usize)]) -> String {
+pub fn get_svg(size_factor: usize, print_labels: bool,
+ function: &FunctionSpec, vars: &[Variable], block_masks: &[(usize, usize)]) -> String {
+ let size2 = (size_factor / 2) as f32;
let size4 = size_factor / 4;
let size8 = size_factor / 8;
+ let size16 = (size_factor / 16) as f32;
let delta = size_factor as f32 / 32.0;
let mut svg = String::new();
@@ -32,7 +35,118 @@ pub fn get_svg(size_factor: usize, function: &FunctionSpec, vars: &[Variable], b
}
}
- svg += &BeginSvg { w: w * size_factor + 3, h: h * size_factor + 3 }.to_string();
+ let (start_x, start_y, w_add, h_add) = if print_labels {
+ let mut a = 0.0;
+ let mut b = 0.0;
+ let mut c = 0.0;
+ let mut d = 0.0;
+ for i in 0..vars.len() {
+ match i % 4 {
+ 0 => {
+ b -= size2;
+ d += size2;
+ },
+ 1 => {
+ a -= size2;
+ c += size2;
+ },
+ 2 => {
+ d += size2;
+ },
+ 3 => {
+ c += size2;
+ },
+ _ => unreachable!()
+ }
+ }
+ (a, b, c, d)
+ } else {
+ (0.0, 0.0, 0.0, 0.0)
+ };
+
+ let w_base = (w * size_factor + 3) as f32;
+ let h_base = (h * size_factor + 3) as f32;
+ svg += &BeginSvg {
+ w: w_base + w_add, h: h_base + h_add,
+ x: start_x, y: start_y
+ }.to_string();
+
+ if print_labels {
+ for i in 0..vars.len() {
+ let offset = (i / 4) as f32 * size2 + size16;
+ let initial_window = 2usize.pow(((i + 2) / 4) as u32);
+ let mut start = vec![false; initial_window];
+ start.extend(vec![true; initial_window]);
+ let desired_len = if i % 2 == 0 { w } else { h };
+ while start.len() < desired_len {
+ let j = start.len();
+ for k in 0..j {
+ start.push(start[j-k-1]);
+ }
+ }
+ let mut segments = vec![];
+ let mut j = 0;
+ while j < desired_len {
+ if let Some((idx, _)) = start[j..].iter().find_position(|x| **x) {
+ j += idx;
+ let j2 = start[j..].iter().find_position(|x| !**x).map(|x| x.0).unwrap_or(desired_len-j);
+ segments.push((j, j+j2-1));
+ j += j2;
+ } else {
+ break;
+ }
+ }
+ let var_name = print_var(vars[i]);
+ match i % 4 {
+ 0 => {
+ for (x1, x2) in segments {
+ svg += &line_segment(x1 * size_factor, -offset, (x2 + 1) * size_factor, -offset)
+ .width(2.0)
+ .to_string();
+ svg += &text((x1 + x2 + 1) * size_factor / 2, -offset - size16, var_name)
+ .align(Align::Center)
+ .size(SIZE_FONT)
+ .to_string();
+ }
+ },
+ 1 => {
+ for (y1, y2) in segments {
+ svg += &line_segment(-offset, y1 * size_factor, -offset, (y2 + 1) * size_factor)
+ .width(2.0)
+ .to_string();
+ svg += &text(-offset - size8 as f32, (y1 + y2 + 1) * size_factor / 2, var_name)
+ .align(Align::Center)
+ .size(SIZE_FONT)
+ .to_string();
+ }
+ },
+ 2 => {
+ for (x1, x2) in segments {
+ svg += &line_segment(x1 * size_factor, h_base + offset, (x2 + 1) * size_factor, h_base + offset)
+ .width(2.0)
+ .to_string();
+ svg += &text((x1 + x2 + 1) * size_factor / 2, h_base + offset + size4 as f32, var_name)
+ .align(Align::Center)
+ .size(SIZE_FONT)
+ .to_string();
+ }
+ },
+ 3 => {
+ for (y1, y2) in segments {
+ svg += &line_segment(w_base + offset, y1 * size_factor, w_base + offset, (y2 + 1) * size_factor)
+ .width(2.0)
+ .to_string();
+ svg += &text(w_base + offset + size8 as f32, (y1 + y2 + 1) * size_factor / 2, var_name)
+ .align(Align::Center)
+ .size(SIZE_FONT)
+ .to_string();
+ }
+ },
+ _ => unreachable!()
+ }
+ }
+ }
+
for (i, &(x, y)) in grid.iter().enumerate() {
svg += &rectangle(1 + x * size_factor, 1 + y * size_factor, size_factor, size_factor)
.fill(white())