diff --git a/Cargo.lock b/Cargo.lock index 821c6da..0565004 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -846,6 +846,7 @@ version = "0.1.0" dependencies = [ "calloop", "chrono", + "rctree", "resvg", "serde", "smithay-client-toolkit", diff --git a/Cargo.toml b/Cargo.toml index 8919b3e..cad8dd2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,5 @@ toml = "0.5" serde = { version = "1.0", features = ["derive"] } xdg = "2.4" calloop = "0.9" -xmlwriter = "0.1" \ No newline at end of file +xmlwriter = "0.1" +rctree = "0.4" diff --git a/src/main.rs b/src/main.rs index 3342ca6..6e981f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,7 +70,7 @@ fn time_to_degrees(timestamp: i32, // should be time/timestamp fn hour_marker( hour: i32, - hour_name_path_data: &PathData, + hour_name_path_data: &(PathData, PathData), is_current_hour: bool, ) -> Group { let season = match hour { @@ -93,8 +93,6 @@ fn hour_marker( let x1 = IMAGE_WIDTH as f32 / 2.0 - delta_x; let y1 = (IMAGE_WIDTH as f32 / 2.0 - OUTER_R) + delta_y; - let utc_hour_y = IMAGE_WIDTH as f32 / 2.0 - OUTER_R + RING_WIDTH + UTC_HOUR_FONT_SIZE; - let path_data = PathData::new() .move_to((x1, y1)) .elliptical_arc_by((OUTER_R, OUTER_R, 15, 0, 1, 2.0 * delta_x, 0)) @@ -112,20 +110,10 @@ fn hour_marker( let path = Path::new().set("class", "hour-outline").set("d", path_data); let hour_name_path = Path::new() .set("class", "hour-name") - .set("d", hour_name_path_data.clone()); - - let utc_hour_text = Text::new() + .set("d", hour_name_path_data.0.clone()); + let utc_hour_path = Path::new() .set("class", "utc") - .set( - "transform", - format!("rotate(-7.5, {}, {})", IMAGE_WIDTH / 2, IMAGE_WIDTH / 2), - ) - .set("x", IMAGE_WIDTH / 2) - .set("y", utc_hour_y) - .set("text-anchor", "middle") - .set("dominant-baseline", "mathematical") - .set("font-size", UTC_HOUR_FONT_SIZE) - .add(TextNode::new(format!("U {:02}", hour))); + .set("d", hour_name_path_data.1.clone()); Group::new() .set( @@ -146,7 +134,7 @@ fn hour_marker( ) .add(path) .add(hour_name_path) - .add(utc_hour_text) + .add(utc_hour_path) } fn get_range_path(radius: f32, range_name: &str, start_time: i32, end_time: i32) -> Path { @@ -219,7 +207,7 @@ fn get_moon_path(radius: f32, moon_phase: f64) -> Path { Path::new().set("class", "moon").set("d", path_data) } -fn gen_svg(config: &Option, hour_name_path_cache: &[PathData; 24]) -> Document { +fn gen_svg(config: &Option, hour_name_path_cache: &[(PathData, PathData); 24]) -> Document { let local_timestamp = Local::now(); let utc_hour = local_timestamp.with_timezone(&Utc).time().hour(); let local_hour = local_timestamp.time().hour(); @@ -251,7 +239,7 @@ fn gen_svg(config: &Option, hour_name_path_cache: &[PathData; 24]) -> Do #border {stroke: none; fill: rgb(19, 17, 30); } .hour path.hour-outline {stroke: rgb(0, 0, 0); stroke-width: 2px;} .hour path.hour-name {stroke: none; fill: rgb(238, 187, 85);} - .hour text.utc {stroke: none; fill: rgb(91, 68, 38);} + .hour path.utc {stroke: none; fill: rgb(91, 68, 38);} .winter path {fill: rgb(70, 62, 108);} .active.winter path.hour-outline {fill: rgb(100, 92, 138);} .spring path {fill: rgb(55, 87, 55);} @@ -715,7 +703,7 @@ fn redraw( surface: &wl_surface::WlSurface, (buf_x, buf_y): (u32, u32), config: &Option, - hour_name_path_cache: &[PathData; 24], + hour_name_path_cache: &[(PathData, PathData); 24], ) -> Result<(), ::std::io::Error> { let document = gen_svg(config, hour_name_path_cache); let svg_tree = svg_to_usvg(document); diff --git a/src/svg_clock.rs b/src/svg_clock.rs index 1bc1a42..a470143 100644 --- a/src/svg_clock.rs +++ b/src/svg_clock.rs @@ -1,3 +1,4 @@ +use rctree::Node; use svg::{ node::{ element::{path::Data as PathData, Definitions, Path, Text, TextPath}, @@ -48,19 +49,32 @@ fn hour_name_path() -> Path { Path::new().set("id", "hour-name-path").set("d", path_data) } -fn create_temp_document(hour_name: &str) -> Document { +fn create_temp_document(hour: usize) -> Document { let definitions = Definitions::new().add(hour_name_path()); + let utc_hour_y = IMAGE_WIDTH as f32 / 2.0 - OUTER_R + RING_WIDTH + UTC_HOUR_FONT_SIZE; let hour_name_text_path = TextPath::new() .set("xlink:href", "#hour-name-path") .set("startOffset", "50%") - .add(TextNode::new(hour_name)); + .add(TextNode::new(HOUR_NAMES[hour])); let hour_name_text = Text::new() .set("id", "hour-name") .set("text-anchor", "middle") .set("dominant-baseline", "mathematical") .set("font-size", HOUR_NAME_FONT_SIZE) .add(hour_name_text_path); + let utc_hour_text = Text::new() + .set("id", "utc-hour") + .set( + "transform", + format!("rotate(-7.5, {}, {})", IMAGE_WIDTH / 2, IMAGE_WIDTH / 2), + ) + .set("x", IMAGE_WIDTH / 2) + .set("y", utc_hour_y) + .set("text-anchor", "middle") + .set("dominant-baseline", "mathematical") + .set("font-size", UTC_HOUR_FONT_SIZE) + .add(TextNode::new(format!("U {:02}", hour))); Document::new() .set("viewBox", (0i32, 0i32, 700i32, 700i32)) @@ -69,13 +83,13 @@ fn create_temp_document(hour_name: &str) -> Document { .set("xmlns:xlink", "http://www.w3.org/1999/xlink") .add(definitions) .add(hour_name_text) + .add(utc_hour_text) } -fn cache_hour_name_path(hour_name: &str) -> PathData { - let tree = svg_to_usvg(create_temp_document(hour_name)); - let mut svg_path_data: PathData = PathData::new(); - let text_node = tree.node_by_id("hour-name").unwrap(); - match *text_node.borrow() { +fn node_to_path(node: Node) -> PathData { + let mut svg_path_data = PathData::new(); + + match *node.borrow() { usvg::NodeKind::Path(ref path) => { let path_data = &path.data; for segment in path_data.0.iter() { @@ -110,31 +124,38 @@ fn cache_hour_name_path(hour_name: &str) -> PathData { svg_path_data } -pub fn cache_hour_name_paths() -> [PathData; 24] { +fn cache_hour_name_path(hour: usize) -> (PathData, PathData) { + let tree = svg_to_usvg(create_temp_document(hour)); + let text_node = tree.node_by_id("hour-name").unwrap(); + let utc_text_node = tree.node_by_id("utc-hour").unwrap(); + (node_to_path(text_node), node_to_path(utc_text_node)) +} + +pub fn cache_hour_name_paths() -> [(PathData, PathData); 24] { [ - cache_hour_name_path(HOUR_NAMES[0]), - cache_hour_name_path(HOUR_NAMES[1]), - cache_hour_name_path(HOUR_NAMES[2]), - cache_hour_name_path(HOUR_NAMES[3]), - cache_hour_name_path(HOUR_NAMES[4]), - cache_hour_name_path(HOUR_NAMES[5]), - cache_hour_name_path(HOUR_NAMES[6]), - cache_hour_name_path(HOUR_NAMES[7]), - cache_hour_name_path(HOUR_NAMES[8]), - cache_hour_name_path(HOUR_NAMES[9]), - cache_hour_name_path(HOUR_NAMES[10]), - cache_hour_name_path(HOUR_NAMES[11]), - cache_hour_name_path(HOUR_NAMES[12]), - cache_hour_name_path(HOUR_NAMES[13]), - cache_hour_name_path(HOUR_NAMES[14]), - cache_hour_name_path(HOUR_NAMES[15]), - cache_hour_name_path(HOUR_NAMES[16]), - cache_hour_name_path(HOUR_NAMES[17]), - cache_hour_name_path(HOUR_NAMES[18]), - cache_hour_name_path(HOUR_NAMES[19]), - cache_hour_name_path(HOUR_NAMES[20]), - cache_hour_name_path(HOUR_NAMES[21]), - cache_hour_name_path(HOUR_NAMES[22]), - cache_hour_name_path(HOUR_NAMES[23]), + cache_hour_name_path(0), + cache_hour_name_path(1), + cache_hour_name_path(2), + cache_hour_name_path(3), + cache_hour_name_path(4), + cache_hour_name_path(5), + cache_hour_name_path(6), + cache_hour_name_path(7), + cache_hour_name_path(8), + cache_hour_name_path(9), + cache_hour_name_path(10), + cache_hour_name_path(11), + cache_hour_name_path(12), + cache_hour_name_path(13), + cache_hour_name_path(14), + cache_hour_name_path(15), + cache_hour_name_path(16), + cache_hour_name_path(17), + cache_hour_name_path(18), + cache_hour_name_path(19), + cache_hour_name_path(20), + cache_hour_name_path(21), + cache_hour_name_path(22), + cache_hour_name_path(23), ] }