61 lines
2.8 KiB
Rust
61 lines
2.8 KiB
Rust
|
|
//! Mac OS Roman: the high half of the table and revision handling.
|
|||
|
|
//!
|
|||
|
|
//! The lower 128 byte values are identical to ASCII; only `0x80..=0xFF` carry
|
|||
|
|
//! Mac-specific glyphs. The table below is the **post-Mac OS 8.5** revision
|
|||
|
|
//! (byte `0xDB` is the Euro sign); [`MacRomanRevision::Classic`] swaps that one
|
|||
|
|
//! slot back to the pre-8.5 currency sign. See `docs` in the consuming projects
|
|||
|
|
//! for why revision pinning is per-encoding.
|
|||
|
|
//!
|
|||
|
|
//! Source: the Unicode Consortium `VENDORS/APPLE/ROMAN.TXT` mapping.
|
|||
|
|
|
|||
|
|
/// Unicode scalars for Mac OS Roman bytes `0x80..=0xFF` (post-8.5 revision).
|
|||
|
|
///
|
|||
|
|
/// Index `i` corresponds to byte value `0x80 + i` — e.g. index 0 is `0x80` → 'Ä'.
|
|||
|
|
pub(crate) const MAC_ROMAN_HIGH: [char; 128] = [
|
|||
|
|
'Ä', 'Å', 'Ç', 'É', 'Ñ', 'Ö', 'Ü', 'á', // 0x80-0x87
|
|||
|
|
'à', 'â', 'ä', 'ã', 'å', 'ç', 'é', 'è', // 0x88-0x8F
|
|||
|
|
'ê', 'ë', 'í', 'ì', 'î', 'ï', 'ñ', 'ó', // 0x90-0x97
|
|||
|
|
'ò', 'ô', 'ö', 'õ', 'ú', 'ù', 'û', 'ü', // 0x98-0x9F
|
|||
|
|
'†', '°', '¢', '£', '§', '•', '¶', 'ß', // 0xA0-0xA7
|
|||
|
|
'®', '©', '™', '´', '¨', '≠', 'Æ', 'Ø', // 0xA8-0xAF
|
|||
|
|
'∞', '±', '≤', '≥', '¥', 'µ', '∂', '∑', // 0xB0-0xB7
|
|||
|
|
'∏', 'π', '∫', 'ª', 'º', 'Ω', 'æ', 'ø', // 0xB8-0xBF
|
|||
|
|
'¿', '¡', '¬', '√', 'ƒ', '≈', '∆', '«', // 0xC0-0xC7
|
|||
|
|
'»', '…', '\u{00A0}', 'À', 'Ã', 'Õ', 'Œ', 'œ', // 0xC8-0xCF
|
|||
|
|
'–', '—', '\u{201C}', '\u{201D}', '\u{2018}', '\u{2019}', '÷', '◊', // 0xD0-0xD7
|
|||
|
|
'ÿ', 'Ÿ', '⁄', '€', '‹', '›', '\u{FB01}', '\u{FB02}', // 0xD8-0xDF (0xDB € post-8.5)
|
|||
|
|
'‡', '·', '‚', '„', '‰', 'Â', 'Ê', 'Á', // 0xE0-0xE7
|
|||
|
|
'Ë', 'È', 'Í', 'Î', 'Ï', 'Ì', 'Ó', 'Ô', // 0xE8-0xEF
|
|||
|
|
'\u{F8FF}', 'Ò', 'Ú', 'Û', 'Ù', 'ı', 'ˆ', '˜', // 0xF0-0xF7 (0xF0 = Apple logo, PUA)
|
|||
|
|
'¯', '˘', '˙', '˚', '¸', '˝', '˛', 'ˇ', // 0xF8-0xFF
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
/// Index of byte `0xDB`, the only slot that differs across the 8.5 revision.
|
|||
|
|
const EURO_SLOT: usize = (0xDB - 0x80) as usize;
|
|||
|
|
|
|||
|
|
/// The pre-8.5 glyph at `0xDB`: CURRENCY SIGN.
|
|||
|
|
const CLASSIC_CURRENCY: char = '\u{00A4}';
|
|||
|
|
|
|||
|
|
/// Which revision of Mac OS Roman to use.
|
|||
|
|
///
|
|||
|
|
/// The Mac OS 8.5 Euro update changed exactly one byte (`0xDB`). Defaults to
|
|||
|
|
/// [`Modern`](MacRomanRevision::Modern); choose [`Classic`](MacRomanRevision::Classic)
|
|||
|
|
/// for pre-8.5 / emulator fidelity.
|
|||
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|||
|
|
pub enum MacRomanRevision {
|
|||
|
|
/// Mac OS 8.5 and later: `0xDB` is EURO SIGN (`U+20AC`).
|
|||
|
|
#[default]
|
|||
|
|
Modern,
|
|||
|
|
/// Before Mac OS 8.5: `0xDB` is CURRENCY SIGN (`U+00A4`).
|
|||
|
|
Classic,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// The effective high-half table for `revision` (a cheap 512-byte stack copy).
|
|||
|
|
pub(crate) fn high_table(revision: MacRomanRevision) -> [char; 128] {
|
|||
|
|
let mut table = MAC_ROMAN_HIGH;
|
|||
|
|
if revision == MacRomanRevision::Classic {
|
|||
|
|
table[EURO_SLOT] = CLASSIC_CURRENCY;
|
|||
|
|
}
|
|||
|
|
table
|
|||
|
|
}
|