mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 18:10:14 +01:00
CP437 conversion functions
This commit is contained in:
parent
ce946c2fb8
commit
e1ca802268
|
@ -46,7 +46,7 @@ impl Cp437Grid {
|
||||||
|
|
||||||
for (index, char) in value.chars().enumerate() {
|
for (index, char) in value.chars().enumerate() {
|
||||||
if !char.is_ascii() {
|
if !char.is_ascii() {
|
||||||
return Err(InvalidChar { index, char });
|
return Err(Cp437LoadError::InvalidChar { index, char });
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_lf = char == '\n';
|
let is_lf = char == '\n';
|
||||||
|
@ -95,21 +95,15 @@ mod feature_cp437 {
|
||||||
|
|
||||||
/// An array of 256 elements, mapping most of the CP437 values to UTF-8 characters
|
/// An array of 256 elements, mapping most of the CP437 values to UTF-8 characters
|
||||||
///
|
///
|
||||||
/// Mostly follows CP437, except for:
|
/// Mostly follows CP437, except 0x0A, which is kept for use as line ending.
|
||||||
/// * 0x0A & 0x0D are kept for use as line endings.
|
|
||||||
/// * 0x1A is used for SAUCE.
|
|
||||||
/// * 0x1B is used for ANSI escape sequences.
|
|
||||||
///
|
|
||||||
/// These exclusions should be fine since most programs can't even use them
|
|
||||||
/// without issues. And this makes rendering simpler too.
|
|
||||||
///
|
///
|
||||||
/// See <https://en.wikipedia.org/wiki/Code_page_437#Character_set>
|
/// See <https://en.wikipedia.org/wiki/Code_page_437#Character_set>
|
||||||
///
|
///
|
||||||
/// Copied from https://github.com/kip93/cp437-tools. License: GPL-3.0
|
/// Mostly copied from https://github.com/kip93/cp437-tools. License: GPL-3.0
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const CP437_TO_UTF8: [char; 256] = [
|
pub const CP437_TO_UTF8: [char; 256] = [
|
||||||
/* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '\r', '♫', '☼',
|
/* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '♪', '♫', '☼',
|
||||||
/* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '', '', '∟', '↔', '▲', '▼',
|
/* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '→', '←', '∟', '↔', '▲', '▼',
|
||||||
/* 2X */ ' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/',
|
/* 2X */ ' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
/* 3X */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
|
/* 3X */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
/* 4X */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
/* 4X */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
@ -187,6 +181,28 @@ mod feature_cp437 {
|
||||||
grid
|
grid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert the provided bytes to UTF-8.
|
||||||
|
pub fn cp437_to_str(cp437: &[u8]) -> String {
|
||||||
|
cp437.iter().map(move |char| cp437_to_char(*char)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a single CP-437 character to UTF-8.
|
||||||
|
pub fn cp437_to_char(cp437: u8) -> char {
|
||||||
|
CP437_TO_UTF8[cp437 as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert the provided text to CP-437 bytes.
|
||||||
|
///
|
||||||
|
/// Characters that are not available are mapped to '?'.
|
||||||
|
pub fn str_to_cp437(utf8: &str) -> Vec<u8> {
|
||||||
|
utf8.chars().map(char_to_cp437).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a single UTF-8 character to CP-437.
|
||||||
|
pub fn char_to_cp437(utf8: char) -> u8 {
|
||||||
|
*UTF8_TO_CP437.get(&utf8).unwrap_or(&MISSING_CHAR_CP437)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -219,7 +235,7 @@ mod tests {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(feature = "cp437")]
|
#[cfg(feature = "cp437")]
|
||||||
mod tests_feature_cp437 {
|
mod tests_feature_cp437 {
|
||||||
use crate::{CharGrid, Cp437Grid};
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn round_trip_cp437() {
|
fn round_trip_cp437() {
|
||||||
|
@ -228,4 +244,39 @@ mod tests_feature_cp437 {
|
||||||
let actual = CharGrid::from(&cp437);
|
let actual = CharGrid::from(&cp437);
|
||||||
assert_eq!(actual, utf8);
|
assert_eq!(actual, utf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_str() {
|
||||||
|
// test text from https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios
|
||||||
|
let utf8 = r#"A quick brown fox jumps over the lazy dog.
|
||||||
|
0123456789 ¿?¡!`'"., <>()[]{} &@%*^#$\/
|
||||||
|
|
||||||
|
* Wieniläinen sioux'ta puhuva ökyzombie diggaa Åsan roquefort-tacoja.
|
||||||
|
* Ça me fait peur de fêter noël là, sur cette île bizarroïde où une mère et sa môme essaient de me tuer avec un gâteau à la cigüe brûlé.
|
||||||
|
* Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich.
|
||||||
|
* El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.
|
||||||
|
|
||||||
|
┌─┬─┐ ╔═╦═╗ ╒═╤═╕ ╓─╥─╖
|
||||||
|
│ │ │ ║ ║ ║ │ │ │ ║ ║ ║
|
||||||
|
├─┼─┤ ╠═╬═╣ ╞═╪═╡ ╟─╫─╢
|
||||||
|
└─┴─┘ ╚═╩═╝ ╘═╧═╛ ╙─╨─╜
|
||||||
|
|
||||||
|
░░░░░ ▐▀█▀▌ .·∙•○°○•∙·.
|
||||||
|
▒▒▒▒▒ ▐ █ ▌ ☺☻ ♥♦♣♠ ♪♫☼
|
||||||
|
▓▓▓▓▓ ▐▀█▀▌ $ ¢ £ ¥ ₧
|
||||||
|
█████ ▐▄█▄▌ ◄►▲▼ ←→↑↓↕↨
|
||||||
|
|
||||||
|
⌠
|
||||||
|
│dx ≡ Σ √x²ⁿ·δx
|
||||||
|
⌡"#;
|
||||||
|
|
||||||
|
let cp437 = str_to_cp437(utf8);
|
||||||
|
let actual = cp437_to_str(&*cp437);
|
||||||
|
assert_eq!(utf8, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_invalid() {
|
||||||
|
assert_eq!(cp437_to_char(char_to_cp437('😜')), '?');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ mod command_code;
|
||||||
mod compression;
|
mod compression;
|
||||||
mod compression_code;
|
mod compression_code;
|
||||||
mod connection;
|
mod connection;
|
||||||
mod cp437;
|
pub mod cp437;
|
||||||
mod data_ref;
|
mod data_ref;
|
||||||
mod grid;
|
mod grid;
|
||||||
mod origin;
|
mod origin;
|
||||||
|
|
Loading…
Reference in a new issue