Introduce ASCII art representations of the Asterinas logo

This commit is contained in:
Tate, Hongliang Tian 2025-09-09 09:41:40 +08:00 committed by Tate, Hongliang Tian
parent f6a55e0af3
commit 8d2fec7873
11 changed files with 237 additions and 14 deletions

14
Cargo.lock generated
View File

@ -232,6 +232,7 @@ dependencies = [
"lending-iterator",
"libflate",
"log",
"logo-ascii-art",
"loongArch64",
"lru",
"osdk-frame-allocator",
@ -1104,6 +1105,13 @@ version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "logo-ascii-art"
version = "0.1.0"
dependencies = [
"owo-colors 4.2.2",
]
[[package]]
name = "loongArch64"
version = "0.2.5"
@ -1270,7 +1278,7 @@ name = "osdk-test-kernel"
version = "0.16.0"
dependencies = [
"ostd",
"owo-colors 4.2.0",
"owo-colors 4.2.2",
]
[[package]]
@ -1351,9 +1359,9 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "owo-colors"
version = "4.2.0"
version = "4.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564"
checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e"
[[package]]
name = "paste"

View File

@ -34,6 +34,7 @@ members = [
"kernel/libs/aster-bigtcp",
"kernel/libs/jhash",
"kernel/libs/keyable-arc",
"kernel/libs/logo-ascii-art",
"kernel/libs/typeflags",
"kernel/libs/typeflags-util",
"kernel/libs/atomic-integer-wrapper",

View File

@ -183,7 +183,8 @@ NON_OSDK_CRATES := \
kernel/libs/keyable-arc \
kernel/libs/typeflags \
kernel/libs/typeflags-util \
kernel/libs/atomic-integer-wrapper
kernel/libs/atomic-integer-wrapper \
kernel/libs/logo-ascii-art
# In contrast, OSDK crates depend on OSTD (or being `ostd` itself)
# and need to be built or tested with OSDK.

View File

@ -22,6 +22,7 @@ aster-systree = { path = "comps/systree" }
aster-keyboard = { path = "comps/keyboard" }
component = { path = "libs/comp-sys/component" }
controlled = { path = "libs/comp-sys/controlled" }
logo-ascii-art = { path = "libs/logo-ascii-art" }
osdk-frame-allocator = { path = "../osdk/deps/frame-allocator" }
osdk-heap-allocator = { path = "../osdk/deps/heap-allocator" }
ostd = { path = "../ostd" }

View File

@ -0,0 +1,20 @@
[package]
name = "logo-ascii-art"
version = "0.1.0"
edition = "2024"
[dependencies]
# This crate is only needed by `main.rs`, not `lib.rs`
owo-colors = { version = "4.2.2", optional = true }
[features]
default = []
color = ["owo-colors"]
[[bin]]
name = "logo-ascii-art"
path = "src/main.rs"
required-features = ["color"]
[lints]
workspace = true

View File

@ -0,0 +1,7 @@
# logo-ascii-art
This crate provides ASCII art representations of the Asterinas logo.
The ASCII art are offered as two static string slices containing the logo:
* A classic black-and-white version; and
* A vibrant, gradient-colored one, suitable for splash screens or command-line tool branding.

View File

@ -0,0 +1,46 @@
// SPDX-License-Identifier: MPL-2.0
//! Provides ASCII art representations of the Asterinas logo.
//!
//! This crate offers two static string slices containing the logo:
//! a classic black-and-white version and
//! a vibrant, gradient-colored one,
//! suitable for splash screens or command-line tool branding.
#![no_std]
/// Returns the ASCII art of the Asterinas logo in black and white.
///
/// ## Generation
///
/// The ASCII art was generated using the online tool at
/// [asciiart.eu](https://www.asciiart.eu/image-to-ascii).
pub fn get_black_white_version() -> &'static str {
// The ASCII art is generated using an online tool:
// https://www.asciiart.eu/image-to-ascii
static LOGO_ASCII_ART: &str = include_str!("logo_ascii_art.txt");
LOGO_ASCII_ART
}
/// Returns the ASCII art of the Asterinas logo with gradient colors.
///
/// The colors are represented using ANSI escape codes,
/// so this version must be viewed in a terminal.
///
/// ## Generation
///
/// This version is generated by the CLI version of this crate.
/// To regenerate it, run the following command:
///
/// ```sh
/// cd logo-ascii-art/
/// cargo run --features=color > src/logo_ascii_art_gradient.txt
/// ```
pub fn get_gradient_color_version() -> &'static str {
// The gradient color version is generated by running:
// ```
// cd logo_ascii_art && cargo run > src/logo_ascii_art_gradient.txt
// ```
static LOGO_ASCII_ART: &str = include_str!("logo_ascii_art_gradient.txt");
LOGO_ASCII_ART
}

View File

@ -0,0 +1,24 @@
......
.-++++=:
.=+++++=:
:+++++++=:
.-++++++++=.
.=**++==+++=.
:****+-.=+++=.
.=****+: .++++=.
.+****=. .++++-
.-*****=. :++++-
.::-=============+*****+-----=++++=-:::::::.
..:-*#########*********+++++++=======:.
.:+*#####****+++++++++++=====-..
..-+#******=.. -++++.
-+=...:*******=..=++++.
.+*+++=. ..=*****+-=++++.
.:***+=.. .-+**++++++=.
.-***+: .-+++++++=
.*#*=. .=+++++=
.-*#+.. .:=+++-
.=#=. .=++-
:*=. ...
.:-. Presented by the Asterinas developers
.. Released under Mozilla Public License v2.0

View File

@ -0,0 +1,24 @@
......
.-++++=:
.=+++++=:
:+++++++=:
.-++++++++=.
.=**++==+++=.
:****+-.=+++=.
.=****+: .++++=.
.+****=. .++++-
.-*****=. :++++-
.::-=============+*****+-----=++++=-:::::::.
..:-*#########*********+++++++=======:.
.:+*#####****+++++++++++=====-..
..-+#******=.. -++++.
-+=...:*******=..=++++.
.+*+++=. ..=*****+-=++++.
.:***+=.. .-+**++++++=.
.-***+: .-+++++++=
.*#*=. .=+++++=
.-*#+.. .:=+++-
.=#=. .=++-
:*=. ...
.:-. Presented by the Asterinas developers
.. Released under Mozilla Public License v2.0

View File

@ -0,0 +1,99 @@
// SPDX-License-Identifier: MPL-2.0
use logo_ascii_art::get_black_white_version;
/// Generates the ASCII art of the Asterinas logo in gradient colors.
///
/// The gradient-color version is generated
/// by applying a horizontal gradient color transformation
/// on the black-and-white version.
fn gen_gradient_color_version() -> String {
use owo_colors::{Rgb, *};
let start_gradient_color = Rgb(33, 54, 245);
let end_gradient_color = Rgb(113, 240, 252);
let colored_logo = apply_gradient(
get_black_white_version(),
start_gradient_color,
end_gradient_color,
);
return colored_logo;
/// Applies a horizontal gradient color transformation to ASCII art.
///
/// This function takes a string of ASCII art and
/// two `Rgb` color values representing the start and end colors of the gradient.
/// The function returns a new string of the ASCII art with the gradient colors applied.
///
/// The gradient is applied horizontally.
/// The leftmost, non-whitespace character will be colored with `start_color`,
/// and the rightmost, non-whitespace character will be colored with `end_color`.
/// All non-whitespace characters between the leftmost and the rightmost ones
/// will be colored based on its column position,
/// interpolating between the `start_color` and `end_color` linearly.
fn apply_gradient(ascii_art: &str, start_color: Rgb, end_color: Rgb) -> String {
let lines: Vec<&str> = ascii_art.lines().collect();
if lines.is_empty() {
return String::new();
}
let interpolate = |col| -> Rgb {
let min_col = lines
.iter()
.flat_map(|line| line.char_indices())
.filter(|(_, c)| !c.is_whitespace())
.map(|(idx, _)| idx)
.min()
.unwrap_or(0);
let max_col = lines
.iter()
.flat_map(|line| line.char_indices())
.filter(|(_, c)| !c.is_whitespace())
.map(|(idx, _)| idx)
.max()
.unwrap_or(0);
// Unexpected logo ASCII art!
assert!(min_col != max_col);
if col < min_col {
return start_color;
}
if col > max_col {
return end_color;
}
let r = start_color.0 as f32
+ (end_color.0 as f32 - start_color.0 as f32) * (col - min_col) as f32
/ (max_col - min_col) as f32;
let g = start_color.1 as f32
+ (end_color.1 as f32 - start_color.1 as f32) * (col - min_col) as f32
/ (max_col - min_col) as f32;
let b = start_color.2 as f32
+ (end_color.2 as f32 - start_color.2 as f32) * (col - min_col) as f32
/ (max_col - min_col) as f32;
Rgb(r as u8, g as u8, b as u8)
};
let mut result = String::new();
for line in &lines {
for (col, ch) in line.chars().enumerate() {
if ch.is_whitespace() {
result.push(ch);
} else {
let color = interpolate(col);
result.push_str(&ch.color(color).to_string());
}
}
result.push('\n');
}
result
}
}
fn main() {
print!("{}", gen_gradient_color_version());
}

View File

@ -186,14 +186,6 @@ fn first_kthread() {
}
fn print_banner() {
println!("\x1B[36m");
println!(
r"
_ ___ _____ ___ ___ ___ _ _ _ ___
/_\ / __|_ _| __| _ \_ _| \| | /_\ / __|
/ _ \\__ \ | | | _|| /| || .` |/ _ \\__ \
/_/ \_\___/ |_| |___|_|_\___|_|\_/_/ \_\___/
"
);
println!("\x1B[0m");
println!("");
println!("{}", logo_ascii_art::get_gradient_color_version());
}