CP437 conversion functions
This commit is contained in:
		
							parent
							
								
									ce946c2fb8
								
							
						
					
					
						commit
						e1ca802268
					
				
					 2 changed files with 65 additions and 14 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue