diff --git a/cli/src/args.rs b/cli/src/args.rs index 7d666fd8..bc4d9d18 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -1,6 +1,10 @@ use clap::{ArgAction, Parser, Subcommand}; use std::path::PathBuf; +/// The character typically used to separate path components +/// in environment variables. +const ENV_PATH_SEP: char = if cfg!(windows) { ';' } else { ':' }; + #[derive(Debug, Parser)] #[clap(about, version)] pub struct CliArguments { @@ -26,6 +30,10 @@ pub struct CliArguments { /// How much raster images of rasterized effects should be scaled up. #[clap(long, default_value = "1.5")] pub raster_scale: f32, + + /// Common font arguments. + #[command(flatten)] + pub font: FontsArgs, } // What to do. @@ -42,4 +50,24 @@ pub struct FontsCommand { /// Also lists style variants of each font family #[arg(long)] pub all: bool, + + /// Common font arguments. + #[command(flatten)] + pub font: FontsArgs, +} + +/// Common arguments to customize available fonts. +#[derive(Debug, Clone, Parser)] +pub struct FontsArgs { + /// Adds additional directories to search for fonts. + /// + /// If multiple paths are specified, they are separated by the system's path + /// separator (`:` on Unix-like systems and `;` on Windows). + #[arg(long = "font-path", value_name = "DIR", value_delimiter = ENV_PATH_SEP)] + pub font_paths: Vec, + + /// Ensures system fonts won't be used, unless explicitly included via + /// `--font-path`. + #[arg(long)] + pub ignore_system_fonts: bool, } diff --git a/cli/src/convert.rs b/cli/src/convert.rs index ce6d2b32..51b77a18 100644 --- a/cli/src/convert.rs +++ b/cli/src/convert.rs @@ -3,18 +3,28 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use svg2pdf::{ConversionOptions, PageOptions}; +use crate::args::FontsArgs; + pub fn convert_( input: &PathBuf, output: Option, conversion_options: ConversionOptions, page_options: PageOptions, + font_options: FontsArgs, ) -> Result<(), String> { if let Ok(()) = log::set_logger(&LOGGER) { log::set_max_level(log::LevelFilter::Warn); } let mut fontdb = fontdb::Database::new(); - fontdb.load_system_fonts(); + + if !font_options.ignore_system_fonts { + fontdb.load_system_fonts(); + } + + for font_path in &font_options.font_paths { + fontdb.load_fonts_dir(font_path); + } fontdb.set_serif_family("Times New Roman"); fontdb.set_sans_serif_family("Arial"); diff --git a/cli/src/fonts.rs b/cli/src/fonts.rs index a51da44f..571616e4 100644 --- a/cli/src/fonts.rs +++ b/cli/src/fonts.rs @@ -5,7 +5,14 @@ use std::collections::BTreeMap; pub fn fonts(command: &FontsCommand) -> Result<(), String> { // Prepare the font database. let mut fontdb = fontdb::Database::new(); - fontdb.load_system_fonts(); + + if !command.font.ignore_system_fonts { + fontdb.load_system_fonts(); + } + + for font_path in &command.font.font_paths { + fontdb.load_fonts_dir(font_path); + } // Collect the font famillies. let mut font_families: BTreeMap> = BTreeMap::new(); diff --git a/cli/src/main.rs b/cli/src/main.rs index cbb0fed5..66da8872 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -32,7 +32,13 @@ fn run() -> Result<(), String> { let page_options = PageOptions { dpi: args.dpi }; - return convert::convert_(&input, args.output, conversion_options, page_options); + return convert::convert_( + &input, + args.output, + conversion_options, + page_options, + args.font, + ); }; // Otherwise execute the command provided if any.