From ebfdb1dafa430786db10dad2ef7d5467c1bdbed1 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 2 Jul 2023 19:59:52 +0200 Subject: Move everything into `crates/` directory --- cli/src/fonts.rs | 183 ------------------------------------------------------- 1 file changed, 183 deletions(-) delete mode 100644 cli/src/fonts.rs (limited to 'cli/src/fonts.rs') diff --git a/cli/src/fonts.rs b/cli/src/fonts.rs deleted file mode 100644 index 75835741..00000000 --- a/cli/src/fonts.rs +++ /dev/null @@ -1,183 +0,0 @@ -use std::cell::OnceCell; -use std::env; -use std::fs::{self, File}; -use std::path::{Path, PathBuf}; - -use memmap2::Mmap; -use typst::diag::StrResult; -use typst::font::{Font, FontBook, FontInfo, FontVariant}; -use typst::util::Bytes; -use walkdir::WalkDir; - -use crate::args::FontsCommand; - -/// Execute a font listing command. -pub fn fonts(command: FontsCommand) -> StrResult<()> { - let mut searcher = FontSearcher::new(); - searcher.search(&command.font_paths); - - for (name, infos) in searcher.book.families() { - println!("{name}"); - if command.variants { - for info in infos { - let FontVariant { style, weight, stretch } = info.variant; - println!("- Style: {style:?}, Weight: {weight:?}, Stretch: {stretch:?}"); - } - } - } - - Ok(()) -} - -/// Searches for fonts. -pub struct FontSearcher { - /// Metadata about all discovered fonts. - pub book: FontBook, - /// Slots that the fonts are loaded into. - pub fonts: Vec, -} - -/// Holds details about the location of a font and lazily the font itself. -pub struct FontSlot { - /// The path at which the font can be found on the system. - path: PathBuf, - /// The index of the font in its collection. Zero if the path does not point - /// to a collection. - index: u32, - /// The lazily loaded font. - font: OnceCell>, -} - -impl FontSlot { - /// Get the font for this slot. - pub fn get(&self) -> Option { - self.font - .get_or_init(|| { - let data = fs::read(&self.path).ok()?.into(); - Font::new(data, self.index) - }) - .clone() - } -} - -impl FontSearcher { - /// Create a new, empty system searcher. - pub fn new() -> Self { - Self { book: FontBook::new(), fonts: vec![] } - } - - /// Search everything that is available. - pub fn search(&mut self, font_paths: &[PathBuf]) { - self.search_system(); - - #[cfg(feature = "embed-fonts")] - self.add_embedded(); - - for path in font_paths { - self.search_dir(path) - } - } - - /// Add fonts that are embedded in the binary. - #[cfg(feature = "embed-fonts")] - fn add_embedded(&mut self) { - let mut process = |bytes: &'static [u8]| { - let buffer = Bytes::from_static(bytes); - for (i, font) in Font::iter(buffer).enumerate() { - self.book.push(font.info().clone()); - self.fonts.push(FontSlot { - path: PathBuf::new(), - index: i as u32, - font: OnceCell::from(Some(font)), - }); - } - }; - - macro_rules! add { - ($filename:literal) => { - process(include_bytes!(concat!("../../assets/fonts/", $filename,))); - }; - } - - // Embed default fonts. - add!("LinLibertine_R.ttf"); - add!("LinLibertine_RB.ttf"); - add!("LinLibertine_RBI.ttf"); - add!("LinLibertine_RI.ttf"); - add!("NewCMMath-Book.otf"); - add!("NewCMMath-Regular.otf"); - add!("NewCM10-Regular.otf"); - add!("NewCM10-Bold.otf"); - add!("NewCM10-Italic.otf"); - add!("NewCM10-BoldItalic.otf"); - add!("DejaVuSansMono.ttf"); - add!("DejaVuSansMono-Bold.ttf"); - add!("DejaVuSansMono-Oblique.ttf"); - add!("DejaVuSansMono-BoldOblique.ttf"); - } - - /// Search for fonts in the linux system font directories. - fn search_system(&mut self) { - if cfg!(target_os = "macos") { - self.search_dir("/Library/Fonts"); - self.search_dir("/Network/Library/Fonts"); - self.search_dir("/System/Library/Fonts"); - } else if cfg!(unix) { - self.search_dir("/usr/share/fonts"); - self.search_dir("/usr/local/share/fonts"); - } else if cfg!(windows) { - self.search_dir( - env::var_os("WINDIR") - .map(PathBuf::from) - .unwrap_or_else(|| "C:\\Windows".into()) - .join("Fonts"), - ); - - if let Some(roaming) = dirs::config_dir() { - self.search_dir(roaming.join("Microsoft\\Windows\\Fonts")); - } - - if let Some(local) = dirs::cache_dir() { - self.search_dir(local.join("Microsoft\\Windows\\Fonts")); - } - } - - if let Some(dir) = dirs::font_dir() { - self.search_dir(dir); - } - } - - /// Search for all fonts in a directory recursively. - fn search_dir(&mut self, path: impl AsRef) { - for entry in WalkDir::new(path) - .follow_links(true) - .sort_by(|a, b| a.file_name().cmp(b.file_name())) - .into_iter() - .filter_map(|e| e.ok()) - { - let path = entry.path(); - if matches!( - path.extension().and_then(|s| s.to_str()), - Some("ttf" | "otf" | "TTF" | "OTF" | "ttc" | "otc" | "TTC" | "OTC"), - ) { - self.search_file(path); - } - } - } - - /// Index the fonts in the file at the given path. - fn search_file(&mut self, path: &Path) { - if let Ok(file) = File::open(path) { - if let Ok(mmap) = unsafe { Mmap::map(&file) } { - for (i, info) in FontInfo::iter(&mmap).enumerate() { - self.book.push(info); - self.fonts.push(FontSlot { - path: path.into(), - index: i as u32, - font: OnceCell::new(), - }); - } - } - } - } -} -- cgit v1.2.3