aboutsummaryrefslogtreecommitdiff
path: root/src/ascii_art.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ascii_art.rs')
-rw-r--r--src/ascii_art.rs186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/ascii_art.rs b/src/ascii_art.rs
new file mode 100644
index 0000000..b9a9fad
--- /dev/null
+++ b/src/ascii_art.rs
@@ -0,0 +1,186 @@
+// This file is part of elem <https://github.com/Fuwn/elem>.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 3.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright (C) 2022-2022 Fuwn <[email protected]>
+// SPDX-License-Identifier: GPL-3.0-only
+
+/// ASCII lettering from <http://www.patorjk.com/software/taag/#p=display&f=ANSI%20Regular&t=Type%20Something%20>
+
+pub const HEIGHT: usize = 5;
+const ONE: &str = r#" ██
+███
+ ██
+ ██
+ ██ "#;
+const TWO: &str = r#"██████
+ ██
+ █████
+██
+███████ "#;
+const THREE: &str = r#"██████
+ ██
+ █████
+ ██
+██████ "#;
+const FOUR: &str = r#"██ ██
+██ ██
+███████
+ ██
+ ██ "#;
+const FIVE: &str = r#"███████
+██
+███████
+ ██
+███████ "#;
+const SIX: &str = r#" ██████
+██
+███████
+██ ██
+ ██████ "#;
+const SEVEN: &str = r#"███████
+ ██
+ ██
+ ██
+ ██ "#;
+const EIGHT: &str = r#" █████
+██ ██
+ █████
+██ ██
+ █████ "#;
+const NINE: &str = r#" █████
+██ ██
+ ██████
+ ██
+ █████ "#;
+const ZERO: &str = r#" ██████
+██ ████
+██ ██ ██
+████ ██
+ ██████ "#;
+const QUESTION_MARK: &str = r#"██████
+ ██
+ ▄███
+ ▀▀
+ ██ "#;
+const ELLIPSIS: &str = r#"
+
+
+
+██ ██ ██ "#;
+const SMILEY_FACE: &str = r#" ██
+██ ██
+ ██
+██ ██
+ ██ "#;
+
+/// Convert a number to ASCII art
+fn number_to_art(number: u64) -> String {
+ // Used for when an error occurs
+ if number == 1337 {
+ return QUESTION_MARK.to_string();
+ } else if number == 80085 {
+ // Used for when a background process is running
+ return ELLIPSIS.to_string();
+ } else if number == 43770 {
+ // The battery level display for the dummy process
+ return SMILEY_FACE.to_string();
+ }
+
+ let to_art_digit = |number: u64| match number {
+ 0 => ZERO,
+ 1 => ONE,
+ 2 => TWO,
+ 3 => THREE,
+ 4 => FOUR,
+ 5 => FIVE,
+ 6 => SIX,
+ 7 => SEVEN,
+ 8 => EIGHT,
+ 9 => NINE,
+ _ => unreachable!(),
+ };
+ let mut art = String::new();
+
+ // Splitting the number into its individual digits, then convert each digit to
+ // it's ASCII art representation
+ for i in 0..HEIGHT {
+ for digit in number
+ .to_string()
+ .chars()
+ .map(|c| {
+ u64::from(c.to_digit(10).expect(
+ "couldn't convert character to digit, this should never happen",
+ ))
+ })
+ .collect::<Vec<_>>()
+ {
+ art.push_str(
+ to_art_digit(digit)
+ .lines()
+ .nth(i)
+ .expect("invalid line from digit art, this should never happen"),
+ );
+ }
+
+ art.push('\n');
+ }
+
+ // Removing the last newline to get rid of the last empty line
+ art.pop();
+
+ art
+}
+
+pub fn number_to_image(number: u64) -> Vec<u8> {
+ let art = number_to_art(number);
+ let mut image = vec![];
+
+ // Iterating over each character in the ASCII art, and converting it into a
+ // transparent or filled pixel
+ for pixel in art
+ // Replacing these characters with different characters isn't at all needed
+ // (except for the newline character), but it makes the following
+ // process a little more readable.
+ .replace(' ', "a")
+ .replace('█', "b")
+ .replace('\n', "")
+ .as_bytes()
+ {
+ if pixel == &97 {
+ // A transparent pixel
+ image.push(0);
+ image.push(0);
+ image.push(0);
+ image.push(0);
+ } else if pixel == &98 {
+ // A solid white pixel
+ image.push(255u8);
+ image.push(255u8);
+ image.push(255u8);
+ image.push(255u8);
+ } else {
+ unreachable!();
+ }
+ }
+
+ // Create an image from the pixel data
+ lodepng::encode_memory(
+ &image,
+ art.lines().next().unwrap().chars().count(),
+ HEIGHT,
+ lodepng::ColorType::RGBA,
+ 8,
+ )
+ .unwrap_or_else(|_| panic!("unable to encode digit {number}"))
+}