From cfddfbcc55f462f4501d29eb039070f455399263 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 20 Jun 2023 17:49:40 -0400 Subject: [PATCH 01/10] Implement dynamic font support `/font//-` This will NOT compile until https://github.com/stadiamaps/sdf_font_tools/pull/13 is merged and published This implements dynamic font protobuf generation, allowing users to request font ranges on the fly, and combining them in any order, e.g. `Font1,Font2,Font3`, same as with sprites and tiles This is a first iteration, without any multithreading support. In theory, this could be done far faster by generating SDFs with multiple threads. Current steps: * during init, figure out all glyphs available in each font, and store them as a bitset * during request: * combine requested bitsets to figure out which glyph should come from which font file * load those glyphs from files (using a single instance of the freetype lib) * convert them to SDFs and package them into a protobuf --- Cargo.lock | 173 +++++++++++++++++ Cargo.toml | 2 + martin-mbtiles/src/errors.rs | 2 + martin/Cargo.toml | 2 + martin/src/args/root.rs | 9 +- martin/src/config.rs | 12 +- martin/src/fonts/mod.rs | 359 +++++++++++++++++++++++++++++++++++ martin/src/lib.rs | 1 + martin/src/srv/server.rs | 47 ++++- martin/src/utils/error.rs | 4 + 10 files changed, 608 insertions(+), 3 deletions(-) create mode 100644 martin/src/fonts/mod.rs diff --git a/Cargo.lock b/Cargo.lock index f868394d6..caac12b5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -407,6 +407,21 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -1139,6 +1154,27 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "freetype-rs" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59c337e64822dd56a3a83ed75a662a470736bdb3a9fabfb588dff276b94a4e0" +dependencies = [ + "bitflags 1.3.2", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643148ca6cbad6bec384b52fbe1968547d578c4efe83109e035c43a71734ff88" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fs4" version = "0.6.6" @@ -1701,6 +1737,7 @@ dependencies = [ "actix-rt", "actix-web", "async-trait", + "bit-set", "brotli", "cargo-husky", "clap", @@ -1718,6 +1755,7 @@ dependencies = [ "martin-mbtiles", "martin-tile-utils", "num_cpus", + "pbf_font_tools", "pmtiles", "postgis", "postgres", @@ -2036,6 +2074,20 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pbf_font_tools" +version = "2.4.0" +dependencies = [ + "futures", + "glob", + "protobuf", + "protobuf-codegen", + "protoc-bin-vendored", + "sdf_glyph_renderer", + "thiserror", + "tokio", +] + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -2264,6 +2316,107 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "protobuf" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65f4a8ec18723a734e5dc09c173e0abf9690432da5340285d536edcb4dac190" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-codegen" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e85514a216b1c73111d9032e26cc7a5ecb1bb3d4d9539e91fb72a4395060f78" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror", +] + +[[package]] +name = "protobuf-parse" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d6fbd6697c9e531873e81cec565a85e226b99a0f10e1acc079be057fe2fcba" +dependencies = [ + "anyhow", + "indexmap 1.9.3", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6872f4d4f4b98303239a2b5838f5bbbb77b01ffc892d627957f37a22d7cfe69c" +dependencies = [ + "thiserror", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005ca8623e5633e298ad1f917d8be0a44bcf406bf3cde3b80e63003e49a3f27d" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb9fc9cce84c8694b6ea01cc6296617b288b703719b725b8c9c65f7c5874435" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d2a07dcf7173a04d49974930ccbfb7fd4d74df30ecfc8762cf2f895a094516" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54fef0b04fcacba64d1d80eed74a20356d96847da8497a59b0a0a436c9165b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8782f2ce7d43a9a5c74ea4936f001e9e8442205c244f7a3d4286bd4c37bc924" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5de656c7ee83f08e0ae5b81792ccfdc1d04e7876b1d9a38e6876a9e09e02537" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9653c3ed92974e34c5a6e0a510864dab979760481714c172e0a34e437cb98804" + [[package]] name = "quote" version = "1.0.33" @@ -2654,6 +2807,14 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "sdf_glyph_renderer" +version = "0.6.0" +dependencies = [ + "freetype-rs", + "thiserror", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -3812,6 +3973,18 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "whoami" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index a7ce09837..41063c4d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ actix-rt = "2" actix-web = "4" anyhow = "1.0" async-trait = "0.1" +bit-set = "0.5.3" brotli = "3" cargo-husky = { version = "1", features = ["user-hooks"], default-features = false } clap = { version = "4", features = ["derive"] } @@ -35,6 +36,7 @@ log = "0.4" martin-mbtiles = { path = "./martin-mbtiles", version = "0.6.0", default-features = false } martin-tile-utils = { path = "./martin-tile-utils", version = "0.1.0" } num_cpus = "1" +pbf_font_tools = { version = "2.4.0", features = ["freetype"], path = "../sdf_font_tools/pbf_font_tools" } pmtiles = { version = "0.3", features = ["mmap-async-tokio", "tilejson"] } postgis = "0.9" postgres = { version = "0.19", features = ["with-time-0_3", "with-uuid-1", "with-serde_json-1"] } diff --git a/martin-mbtiles/src/errors.rs b/martin-mbtiles/src/errors.rs index cb732b66e..be9336df0 100644 --- a/martin-mbtiles/src/errors.rs +++ b/martin-mbtiles/src/errors.rs @@ -5,6 +5,8 @@ use sqlite_hashes::rusqlite; use crate::MbtType; +use crate::mbtiles::MbtType; + #[derive(thiserror::Error, Debug)] pub enum MbtError { #[error("The source and destination MBTiles files are the same: {}", .0.display())] diff --git a/martin/Cargo.toml b/martin/Cargo.toml index 41dce6fcd..08e7d06c2 100644 --- a/martin/Cargo.toml +++ b/martin/Cargo.toml @@ -56,6 +56,7 @@ actix-http.workspace = true actix-rt.workspace = true actix-web.workspace = true async-trait.workspace = true +bit-set.workspace = true brotli.workspace = true clap.workspace = true deadpool-postgres.workspace = true @@ -68,6 +69,7 @@ log.workspace = true martin-mbtiles.workspace = true martin-tile-utils.workspace = true num_cpus.workspace = true +pbf_font_tools.workspace = true pmtiles.workspace = true postgis.workspace = true postgres-protocol.workspace = true diff --git a/martin/src/args/root.rs b/martin/src/args/root.rs index 98c82560b..8e2a1fba5 100644 --- a/martin/src/args/root.rs +++ b/martin/src/args/root.rs @@ -10,7 +10,7 @@ use crate::args::srv::SrvArgs; use crate::args::State::{Ignore, Share, Take}; use crate::config::Config; use crate::file_config::FileConfigEnum; -use crate::{Error, Result}; +use crate::{Error, OneOrMany, Result}; #[derive(Parser, Debug, PartialEq, Default)] #[command(about, version)] @@ -44,6 +44,9 @@ pub struct MetaArgs { /// Export a directory with SVG files as a sprite source. Can be specified multiple times. #[arg(short, long)] pub sprite: Vec, + /// Export a directory with font files as a font source. Can be specified multiple times. + #[arg(short, long)] + pub font: Vec, } impl Args { @@ -81,6 +84,10 @@ impl Args { config.sprites = FileConfigEnum::new(self.meta.sprite); } + if !self.meta.font.is_empty() { + config.fonts = OneOrMany::new_opt(self.meta.font); + } + cli_strings.check() } } diff --git a/martin/src/config.rs b/martin/src/config.rs index 90005d033..9ed340bb5 100644 --- a/martin/src/config.rs +++ b/martin/src/config.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::fs::File; use std::future::Future; use std::io::prelude::*; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::pin::Pin; use futures::future::try_join_all; @@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize}; use subst::VariableMap; use crate::file_config::{resolve_files, FileConfigEnum}; +use crate::fonts::{resolve_fonts, FontSources}; use crate::mbtiles::MbtSource; use crate::pg::PgConfig; use crate::pmtiles::PmtSource; @@ -24,6 +25,7 @@ pub type UnrecognizedValues = HashMap; pub struct ServerState { pub tiles: TileSources, pub sprites: SpriteSources, + pub fonts: FontSources, } #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] @@ -43,6 +45,9 @@ pub struct Config { #[serde(default, skip_serializing_if = "FileConfigEnum::is_none")] pub sprites: FileConfigEnum, + #[serde(skip_serializing_if = "Option::is_none")] + pub fonts: OptOneMany, + #[serde(flatten)] pub unrecognized: UnrecognizedValues, } @@ -61,10 +66,14 @@ impl Config { res.extend(self.mbtiles.finalize("mbtiles.")?); res.extend(self.sprites.finalize("sprites.")?); + // TODO: support for unrecognized fonts? + // res.extend(self.fonts.finalize("fonts.")?); + if self.postgres.is_empty() && self.pmtiles.is_empty() && self.mbtiles.is_empty() && self.sprites.is_empty() + && self.fonts.is_empty() { Err(NoSources) } else { @@ -76,6 +85,7 @@ impl Config { Ok(ServerState { tiles: self.resolve_tile_sources(idr).await?, sprites: SpriteSources::resolve(&mut self.sprites)?, + fonts: resolve_fonts(&mut self.fonts)?, }) } diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs new file mode 100644 index 000000000..dc079112b --- /dev/null +++ b/martin/src/fonts/mod.rs @@ -0,0 +1,359 @@ +use std::collections::hash_map::Entry; +use std::collections::HashMap; +use std::ffi::OsStr; +use std::fmt::Debug; +use std::path::{Path, PathBuf}; + +use bit_set::BitSet; +use log::{debug, info, warn}; +use pbf_font_tools::freetype::{Face, Library}; +use pbf_font_tools::protobuf::Message; +use pbf_font_tools::{render_sdf_glyph, Fontstack, Glyphs, PbfFontError}; +use serde::{Deserialize, Serialize}; + +use crate::fonts::FontError::IoError; +use crate::OneOrMany; + +const MAX_UNICODE_CP: usize = 0xFFFF; +const CP_RANGE_SIZE: usize = 256; +const FONT_SIZE: usize = 24; +#[allow(clippy::cast_possible_wrap)] +const CHAR_HEIGHT: isize = (FONT_SIZE as isize) << 6; +const BUFFER_SIZE: usize = 3; +const RADIUS: usize = 8; +const CUTOFF: f64 = 0.25_f64; + +/// Each range is 256 codepoints long, so the highest range ID is 0xFFFF / 256 = 255. +const MAX_UNICODE_CP_RANGE_ID: usize = MAX_UNICODE_CP / CP_RANGE_SIZE; + +#[derive(thiserror::Error, Debug)] +pub enum FontError { + #[error("Font {0} not found")] + FontNotFound(String), + + #[error("Font range start ({0}) must be <= end ({1})")] + InvalidFontRangeStartEnd(u32, u32), + + #[error("Font range start ({0}) must be multiple of {CP_RANGE_SIZE} (e.g. 0, 256, 512, ...)")] + InvalidFontRangeStart(u32), + + #[error( + "Font range end ({0}) must be multiple of {CP_RANGE_SIZE} - 1 (e.g. 255, 511, 767, ...)" + )] + InvalidFontRangeEnd(u32), + + #[error("Given font range {0}-{1} is invalid. It must be {CP_RANGE_SIZE} characters long (e.g. 0-255, 256-511, ...)")] + InvalidFontRange(u32, u32), + + #[error("FreeType font error: {0}")] + FreeType(#[from] pbf_font_tools::freetype::Error), + + #[error("IO error accessing {}: {0}", .1.display())] + IoError(std::io::Error, PathBuf), + + #[error("Font {0} uses bad file {}", .1.display())] + InvalidFontFilePath(String, PathBuf), + + #[error("No font files found in {}", .0.display())] + NoFontFilesFound(PathBuf), + + #[error("Font {} could not be loaded", .0.display())] + UnableToReadFont(PathBuf), + + #[error("{0} in file {}", .1.display())] + FontProcessingError(spreet::error::Error, PathBuf), + + #[error("Font {0} is missing a family name")] + MissingFamilyName(PathBuf), + + #[error("PBF Font error: {0}")] + PbfFontError(#[from] PbfFontError), + + #[error("Error serializing protobuf: {0}")] + ErrorSerializingProtobuf(#[from] pbf_font_tools::protobuf::Error), +} + +fn recurse_dirs( + lib: &Library, + path: &Path, + fonts: &mut HashMap, + catalog: &mut HashMap, +) -> Result<(), FontError> { + for dir_entry in path + .read_dir() + .map_err(|e| IoError(e, path.to_path_buf()))? + .flatten() + { + let path = dir_entry.path(); + + if path.is_dir() { + recurse_dirs(lib, &path, fonts, catalog)?; + continue; + } + + if !path + .extension() + .and_then(OsStr::to_str) + .is_some_and(|e| ["otf", "ttf", "ttc"].contains(&e)) + { + continue; + } + + let mut face = lib.new_face(&path, 0)?; + let num_faces = face.num_faces() as isize; + for i in 0..num_faces { + if i > 0 { + face = lib.new_face(&path, i)?; + } + let Some(family) = face.family_name() else { + return Err(FontError::MissingFamilyName(path.clone())); + }; + let mut name = family.clone(); + let style = face.style_name(); + if let Some(style) = &style { + name.push(' '); + name.push_str(style); + } + // Make sure font name has no slashes or commas, replacing them with spaces and de-duplicating spaces + name = name + .replace(['/', ','], " ") + .replace(" ", " ") + .replace(" ", " "); + + match fonts.entry(name) { + Entry::Occupied(v) => { + warn!("Ignoring duplicate font source {} from {} because it was already configured for {}", + v.key(), path.display(), v.get().path.display()); + } + Entry::Vacant(v) => { + let key = v.key(); + let Some((codepoints, count, ranges )) = get_available_codepoints(&mut face) else { + warn!("Ignoring font source {key} from {} because it has no available glyphs", path.display()); + continue + }; + + let start = ranges.first().map(|(s, _)| *s).unwrap(); + let end = ranges.last().map(|(_, e)| *e).unwrap(); + info!( + "Configured font source {key} with {count} glyphs ({start:04X}-{end:04X}) from {}", + path.display() + ); + debug!( + "Available font ranges: {}", + ranges + .iter() + .map(|(s, e)| if s == e { + format!("{s:02X}") + } else { + format!("{s:02X}-{e:02X}") + }) + .collect::>() + .join(", "), + ); + + catalog.insert( + v.key().clone(), + FontEntry { + family, + style, + total_glyphs: count, + start, + end, + }, + ); + + v.insert(FontSource { + path: path.clone(), + face_index: i, + codepoints, + }); + } + } + } + } + + Ok(()) +} + +type GetGlyphInfo = (BitSet, usize, Vec<(usize, usize)>); + +fn get_available_codepoints(face: &mut Face) -> Option { + let mut codepoints = BitSet::with_capacity(MAX_UNICODE_CP); + let mut spans = Vec::new(); + let mut first: Option = None; + let mut count = 0; + + for cp in 0..=MAX_UNICODE_CP { + if face.get_char_index(cp) != 0 { + codepoints.insert(cp); + count += 1; + if first.is_none() { + first = Some(cp); + } + } else if let Some(start) = first { + spans.push((start, cp - 1)); + first = None; + } + } + + if count == 0 { + None + } else { + Some((codepoints, count, spans)) + } +} + +pub fn resolve_fonts(config: &mut Option>) -> Result { + let Some(cfg) = config else { + return Ok(FontSources::default()); + }; + + let mut fonts = HashMap::new(); + let mut catalog = HashMap::new(); + let lib = Library::init()?; + + for path in cfg.iter() { + let disp_path = path.display(); + if path.exists() { + recurse_dirs(&lib, path, &mut fonts, &mut catalog)?; + } else { + warn!("Ignoring non-existent font source {disp_path}"); + }; + } + + let mut masks = Vec::with_capacity(MAX_UNICODE_CP_RANGE_ID + 1); + + let mut bs = BitSet::with_capacity(CP_RANGE_SIZE); + for v in 0..=MAX_UNICODE_CP { + bs.insert(v); + if v % CP_RANGE_SIZE == (CP_RANGE_SIZE - 1) { + masks.push(bs); + bs = BitSet::with_capacity(CP_RANGE_SIZE); + } + } + + Ok(FontSources { + fonts, + masks, + catalog: FontCatalog { fonts: catalog }, + }) +} + +#[derive(Debug, Clone, Default)] +pub struct FontSources { + fonts: HashMap, + masks: Vec, + catalog: FontCatalog, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] +pub struct FontCatalog { + // TODO: Use pre-sorted BTreeMap instead + fonts: HashMap, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] +pub struct FontEntry { + pub family: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub style: Option, + pub total_glyphs: usize, + pub start: usize, + pub end: usize, +} + +impl FontSources { + #[must_use] + pub fn get_catalog(&self) -> &FontCatalog { + &self.catalog + } + + /// Given a list of IDs in a format "id1,id2,id3", return a combined font. + #[allow(clippy::cast_possible_truncation)] + pub fn get_font_range(&self, ids: &str, start: u32, end: u32) -> Result, FontError> { + if start > end { + return Err(FontError::InvalidFontRangeStartEnd(start, end)); + } + if start % (CP_RANGE_SIZE as u32) != 0 { + return Err(FontError::InvalidFontRangeStart(start)); + } + if end % (CP_RANGE_SIZE as u32) != (CP_RANGE_SIZE as u32 - 1) { + return Err(FontError::InvalidFontRangeEnd(end)); + } + if (end - start) != (CP_RANGE_SIZE as u32 - 1) { + return Err(FontError::InvalidFontRange(start, end)); + } + + let mut needed = self.masks[(start as usize) / CP_RANGE_SIZE].clone(); + let fonts = ids + .split(',') + .filter_map(|id| match self.fonts.get(id) { + None => Some(Err(FontError::FontNotFound(id.to_string()))), + Some(v) => { + let mut ds = needed.clone(); + ds.intersect_with(&v.codepoints); + if ds.is_empty() { + None + } else { + needed.difference_with(&v.codepoints); + Some(Ok((id, v, ds))) + } + } + }) + .collect::, FontError>>()?; + + if fonts.is_empty() { + return Ok(Vec::new()); + } + + let lib = Library::init()?; + let mut stack = Fontstack::new(); + + for (id, font, ds) in fonts { + if stack.has_name() { + let name = stack.mut_name(); + name.push_str(", "); + name.push_str(id); + } else { + stack.set_name(id.to_string()); + } + + let face = lib.new_face(&font.path, font.face_index)?; + + // FreeType conventions: char width or height of zero means "use the same value" + // and setting both resolution values to zero results in the default value + // of 72 dpi. + // + // See https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_set_char_size + // and https://www.freetype.org/freetype2/docs/tutorial/step1.html for details. + face.set_char_size(0, CHAR_HEIGHT, 0, 0)?; + + for cp in ds.iter() { + let glyph = render_sdf_glyph(&face, cp as u32, BUFFER_SIZE, RADIUS, CUTOFF)?; + stack.glyphs.push(glyph); + } + } + + stack.set_range(format!("{start}-{end}")); + + let mut glyphs = Glyphs::new(); + glyphs.stacks.push(stack); + let mut result = Vec::new(); + glyphs.write_to_vec(&mut result)?; + Ok(result) + } +} + +#[derive(Clone, Debug)] +pub struct FontSource { + path: PathBuf, + face_index: isize, + codepoints: BitSet, +} + +// #[cfg(test)] +// mod tests { +// use std::path::PathBuf; +// +// use super::*; +// } diff --git a/martin/src/lib.rs b/martin/src/lib.rs index 8903799d0..827fa036a 100644 --- a/martin/src/lib.rs +++ b/martin/src/lib.rs @@ -11,6 +11,7 @@ pub mod args; mod config; pub mod file_config; +pub mod fonts; pub mod mbtiles; pub mod pg; pub mod pmtiles; diff --git a/martin/src/srv/server.rs b/martin/src/srv/server.rs index e6c740d85..c8670c4ab 100755 --- a/martin/src/srv/server.rs +++ b/martin/src/srv/server.rs @@ -24,6 +24,7 @@ use serde::{Deserialize, Serialize}; use tilejson::{tilejson, TileJSON}; use crate::config::ServerState; +use crate::fonts::{FontError, FontSources}; use crate::source::{Source, TileCatalog, TileSources, UrlQuery}; use crate::sprites::{SpriteCatalog, SpriteError, SpriteSources}; use crate::srv::config::{SrvConfig, KEEP_ALIVE_DEFAULT, LISTEN_ADDRESSES_DEFAULT}; @@ -86,6 +87,19 @@ pub fn map_sprite_error(e: SpriteError) -> actix_web::Error { } } +pub fn map_font_error(e: FontError) -> actix_web::Error { + #[allow(clippy::enum_glob_use)] + use FontError::*; + match e { + FontNotFound(_) => error::ErrorNotFound(e.to_string()), + InvalidFontRangeStartEnd(_, _) + | InvalidFontRangeStart(_) + | InvalidFontRangeEnd(_) + | InvalidFontRange(_, _) => ErrorBadRequest(e.to_string()), + _ => map_internal_error(e), + } +} + /// Root path will eventually have a web front. For now, just a stub. #[route("/", method = "GET", method = "HEAD")] #[allow(clippy::unused_async)] @@ -147,6 +161,34 @@ async fn get_sprite_json( Ok(HttpResponse::Ok().json(sheet.get_index())) } +#[derive(Deserialize, Debug)] +struct FontRequest { + fontstack: String, + start: u32, + end: u32, +} + +#[route( + "/font/{fontstack}/{start}-{end}", + method = "GET", + wrap = "middleware::Compress::default()" +)] +#[allow(clippy::unused_async)] +async fn get_font(path: Path, fonts: Data) -> Result { + let data = fonts + .get_font_range(&path.fontstack, path.start, path.end) + .map_err(map_font_error)?; + Ok(HttpResponse::Ok() + .content_type("application/x-protobuf") + .body(data)) +} + +#[route("/font", method = "GET", wrap = "middleware::Compress::default()")] +#[allow(clippy::unused_async)] +async fn get_font_catalog(fonts: Data) -> HttpResponse { + HttpResponse::Ok().json(fonts.get_catalog()) +} + #[route( "/{source_ids}", method = "GET", @@ -424,10 +466,12 @@ pub fn router(cfg: &mut web::ServiceConfig) { cfg.service(get_health) .service(get_index) .service(get_catalog) + .service(get_font_catalog) .service(git_source_info) .service(get_tile) .service(get_sprite_json) - .service(get_sprite_png); + .service(get_sprite_png) + .service(get_font); } /// Create a new initialized Actix `App` instance together with the listening address. @@ -447,6 +491,7 @@ pub fn new_server(config: SrvConfig, state: ServerState) -> crate::Result<(Serve App::new() .app_data(Data::new(state.tiles.clone())) .app_data(Data::new(state.sprites.clone())) + .app_data(Data::new(state.fonts.clone())) .app_data(Data::new(catalog.clone())) .wrap(cors_middleware) .wrap(middleware::NormalizePath::new(TrailingSlash::MergeOnly)) diff --git a/martin/src/utils/error.rs b/martin/src/utils/error.rs index a06ddaf6a..bc28e4efc 100644 --- a/martin/src/utils/error.rs +++ b/martin/src/utils/error.rs @@ -3,6 +3,7 @@ use std::io; use std::path::PathBuf; use crate::file_config::FileError; +use crate::fonts::FontError; use crate::pg::PgError; use crate::sprites::SpriteError; @@ -59,4 +60,7 @@ pub enum Error { #[error("{0}")] SpriteError(#[from] SpriteError), + + #[error("{0}")] + FontError(#[from] FontError), } From 276bae2c2c18996e046936b4cfd4b1dc3ddeb68f Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sun, 16 Jul 2023 22:18:56 -0400 Subject: [PATCH 02/10] cleaner regex gen --- Cargo.lock | 8 ++++++-- Cargo.toml | 2 +- martin-mbtiles/src/errors.rs | 2 -- martin/src/fonts/mod.rs | 25 +++++++++++++++++-------- martin/src/srv/server.rs | 2 +- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index caac12b5f..22b36fc1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2076,7 +2076,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbf_font_tools" -version = "2.4.0" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67768bb2719d708e2de28cec7271dae35c717122c0fa4d9f8558ef5e7fa83db7" dependencies = [ "futures", "glob", @@ -2809,7 +2811,9 @@ dependencies = [ [[package]] name = "sdf_glyph_renderer" -version = "0.6.0" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b05c114d181e20b509e03b05856cc5823bc6189d581c276fe37c5ebc5e3b3b9" dependencies = [ "freetype-rs", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 41063c4d1..4c5718548 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ log = "0.4" martin-mbtiles = { path = "./martin-mbtiles", version = "0.6.0", default-features = false } martin-tile-utils = { path = "./martin-tile-utils", version = "0.1.0" } num_cpus = "1" -pbf_font_tools = { version = "2.4.0", features = ["freetype"], path = "../sdf_font_tools/pbf_font_tools" } +pbf_font_tools = { version = "2.5.0", features = ["freetype"] } pmtiles = { version = "0.3", features = ["mmap-async-tokio", "tilejson"] } postgis = "0.9" postgres = { version = "0.19", features = ["with-time-0_3", "with-uuid-1", "with-serde_json-1"] } diff --git a/martin-mbtiles/src/errors.rs b/martin-mbtiles/src/errors.rs index be9336df0..cb732b66e 100644 --- a/martin-mbtiles/src/errors.rs +++ b/martin-mbtiles/src/errors.rs @@ -5,8 +5,6 @@ use sqlite_hashes::rusqlite; use crate::MbtType; -use crate::mbtiles::MbtType; - #[derive(thiserror::Error, Debug)] pub enum MbtError { #[error("The source and destination MBTiles files are the same: {}", .0.display())] diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs index dc079112b..a7019ad64 100644 --- a/martin/src/fonts/mod.rs +++ b/martin/src/fonts/mod.rs @@ -3,12 +3,14 @@ use std::collections::HashMap; use std::ffi::OsStr; use std::fmt::Debug; use std::path::{Path, PathBuf}; +use std::sync::OnceLock; use bit_set::BitSet; use log::{debug, info, warn}; use pbf_font_tools::freetype::{Face, Library}; use pbf_font_tools::protobuf::Message; use pbf_font_tools::{render_sdf_glyph, Fontstack, Glyphs, PbfFontError}; +use regex::Regex; use serde::{Deserialize, Serialize}; use crate::fonts::FontError::IoError; @@ -79,6 +81,8 @@ fn recurse_dirs( fonts: &mut HashMap, catalog: &mut HashMap, ) -> Result<(), FontError> { + static RE_SPACES: OnceLock = OnceLock::new(); + for dir_entry in path .read_dir() .map_err(|e| IoError(e, path.to_path_buf()))? @@ -115,10 +119,11 @@ fn recurse_dirs( name.push_str(style); } // Make sure font name has no slashes or commas, replacing them with spaces and de-duplicating spaces - name = name - .replace(['/', ','], " ") - .replace(" ", " ") - .replace(" ", " "); + name = name.replace(['/', ','], " "); + name = RE_SPACES + .get_or_init(|| Regex::new(r"\s+").unwrap()) + .replace_all(name.as_str(), " ") + .to_string(); match fonts.entry(name) { Entry::Occupied(v) => { @@ -127,9 +132,13 @@ fn recurse_dirs( } Entry::Vacant(v) => { let key = v.key(); - let Some((codepoints, count, ranges )) = get_available_codepoints(&mut face) else { - warn!("Ignoring font source {key} from {} because it has no available glyphs", path.display()); - continue + let Some((codepoints, count, ranges)) = get_available_codepoints(&mut face) + else { + warn!( + "Ignoring font source {key} from {} because it has no available glyphs", + path.display() + ); + continue; }; let start = ranges.first().map(|(s, _)| *s).unwrap(); @@ -328,7 +337,7 @@ impl FontSources { // and https://www.freetype.org/freetype2/docs/tutorial/step1.html for details. face.set_char_size(0, CHAR_HEIGHT, 0, 0)?; - for cp in ds.iter() { + for cp in &ds { let glyph = render_sdf_glyph(&face, cp as u32, BUFFER_SIZE, RADIUS, CUTOFF)?; stack.glyphs.push(glyph); } diff --git a/martin/src/srv/server.rs b/martin/src/srv/server.rs index c8670c4ab..b5cd05386 100755 --- a/martin/src/srv/server.rs +++ b/martin/src/srv/server.rs @@ -91,7 +91,7 @@ pub fn map_font_error(e: FontError) -> actix_web::Error { #[allow(clippy::enum_glob_use)] use FontError::*; match e { - FontNotFound(_) => error::ErrorNotFound(e.to_string()), + FontNotFound(_) => ErrorNotFound(e.to_string()), InvalidFontRangeStartEnd(_, _) | InvalidFontRangeStart(_) | InvalidFontRangeEnd(_) From 80998d29826fa924d3377000a0d9b85f5be5877d Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Fri, 20 Oct 2023 00:48:52 -0400 Subject: [PATCH 03/10] Update catalog handling --- martin/src/fonts/mod.rs | 61 +++++++++++++++++----------------------- martin/src/srv/server.rs | 11 ++------ 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs index a7019ad64..955ce89b7 100644 --- a/martin/src/fonts/mod.rs +++ b/martin/src/fonts/mod.rs @@ -1,11 +1,12 @@ use std::collections::hash_map::Entry; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::ffi::OsStr; use std::fmt::Debug; use std::path::{Path, PathBuf}; use std::sync::OnceLock; use bit_set::BitSet; +use itertools::Itertools; use log::{debug, info, warn}; use pbf_font_tools::freetype::{Face, Library}; use pbf_font_tools::protobuf::Message; @@ -79,7 +80,6 @@ fn recurse_dirs( lib: &Library, path: &Path, fonts: &mut HashMap, - catalog: &mut HashMap, ) -> Result<(), FontError> { static RE_SPACES: OnceLock = OnceLock::new(); @@ -91,7 +91,7 @@ fn recurse_dirs( let path = dir_entry.path(); if path.is_dir() { - recurse_dirs(lib, &path, fonts, catalog)?; + recurse_dirs(lib, &path, fonts)?; continue; } @@ -105,9 +105,9 @@ fn recurse_dirs( let mut face = lib.new_face(&path, 0)?; let num_faces = face.num_faces() as isize; - for i in 0..num_faces { - if i > 0 { - face = lib.new_face(&path, i)?; + for face_index in 0..num_faces { + if face_index > 0 { + face = lib.new_face(&path, face_index)?; } let Some(family) = face.family_name() else { return Err(FontError::MissingFamilyName(path.clone())); @@ -132,7 +132,7 @@ fn recurse_dirs( } Entry::Vacant(v) => { let key = v.key(); - let Some((codepoints, count, ranges)) = get_available_codepoints(&mut face) + let Some((codepoints, glyphs, ranges)) = get_available_codepoints(&mut face) else { warn!( "Ignoring font source {key} from {} because it has no available glyphs", @@ -144,7 +144,7 @@ fn recurse_dirs( let start = ranges.first().map(|(s, _)| *s).unwrap(); let end = ranges.last().map(|(_, e)| *e).unwrap(); info!( - "Configured font source {key} with {count} glyphs ({start:04X}-{end:04X}) from {}", + "Configured font source {key} with {glyphs} glyphs ({start:04X}-{end:04X}) from {}", path.display() ); debug!( @@ -160,21 +160,17 @@ fn recurse_dirs( .join(", "), ); - catalog.insert( - v.key().clone(), - FontEntry { + v.insert(FontSource { + path: path.clone(), + face_index, + codepoints, + catalog_entry: CatalogFontEntry { family, style, - total_glyphs: count, + glyphs, start, end, }, - ); - - v.insert(FontSource { - path: path.clone(), - face_index: i, - codepoints, }); } } @@ -218,13 +214,12 @@ pub fn resolve_fonts(config: &mut Option>) -> Result>) -> Result, masks: Vec, - catalog: FontCatalog, } -#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] -pub struct FontCatalog { - // TODO: Use pre-sorted BTreeMap instead - fonts: HashMap, -} +pub type FontCatalog = BTreeMap; #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)] -pub struct FontEntry { +pub struct CatalogFontEntry { pub family: String, #[serde(skip_serializing_if = "Option::is_none")] pub style: Option, - pub total_glyphs: usize, + pub glyphs: usize, pub start: usize, pub end: usize, } impl FontSources { #[must_use] - pub fn get_catalog(&self) -> &FontCatalog { - &self.catalog + pub fn get_catalog(&self) -> FontCatalog { + self.fonts + .iter() + .map(|(k, v)| (k.clone(), v.catalog_entry.clone())) + .sorted_by(|(a, _), (b, _)| a.cmp(b)) + .collect() } /// Given a list of IDs in a format "id1,id2,id3", return a combined font. @@ -358,6 +348,7 @@ pub struct FontSource { path: PathBuf, face_index: isize, codepoints: BitSet, + catalog_entry: CatalogFontEntry, } // #[cfg(test)] diff --git a/martin/src/srv/server.rs b/martin/src/srv/server.rs index b5cd05386..df755853e 100755 --- a/martin/src/srv/server.rs +++ b/martin/src/srv/server.rs @@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize}; use tilejson::{tilejson, TileJSON}; use crate::config::ServerState; -use crate::fonts::{FontError, FontSources}; +use crate::fonts::{FontCatalog, FontError, FontSources}; use crate::source::{Source, TileCatalog, TileSources, UrlQuery}; use crate::sprites::{SpriteCatalog, SpriteError, SpriteSources}; use crate::srv::config::{SrvConfig, KEEP_ALIVE_DEFAULT, LISTEN_ADDRESSES_DEFAULT}; @@ -50,6 +50,7 @@ static SUPPORTED_ENCODINGS: &[HeaderEnc] = &[ pub struct Catalog { pub tiles: TileCatalog, pub sprites: SpriteCatalog, + pub fonts: FontCatalog, } impl Catalog { @@ -57,6 +58,7 @@ impl Catalog { Ok(Self { tiles: state.tiles.get_catalog(), sprites: state.sprites.get_catalog()?, + fonts: state.fonts.get_catalog(), }) } } @@ -183,12 +185,6 @@ async fn get_font(path: Path, fonts: Data) -> Result) -> HttpResponse { - HttpResponse::Ok().json(fonts.get_catalog()) -} - #[route( "/{source_ids}", method = "GET", @@ -466,7 +462,6 @@ pub fn router(cfg: &mut web::ServiceConfig) { cfg.service(get_health) .service(get_index) .service(get_catalog) - .service(get_font_catalog) .service(git_source_info) .service(get_tile) .service(get_sprite_json) From d25db188fc59cb3c9a08b800a4bb5be342e7e175 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Fri, 20 Oct 2023 14:27:21 -0400 Subject: [PATCH 04/10] updates --- martin/src/args/root.rs | 4 +- martin/src/config.rs | 6 +- martin/src/fonts/mod.rs | 64 +++++++++++----------- martin/tests/mb_server_test.rs | 2 + martin/tests/pg_server_test.rs | 1 + martin/tests/pmt_server_test.rs | 2 + tests/expected/auto/catalog_auto.json | 3 +- tests/expected/configured/catalog_cfg.json | 3 +- 8 files changed, 46 insertions(+), 39 deletions(-) diff --git a/martin/src/args/root.rs b/martin/src/args/root.rs index 8e2a1fba5..90a6b0cf9 100644 --- a/martin/src/args/root.rs +++ b/martin/src/args/root.rs @@ -10,7 +10,7 @@ use crate::args::srv::SrvArgs; use crate::args::State::{Ignore, Share, Take}; use crate::config::Config; use crate::file_config::FileConfigEnum; -use crate::{Error, OneOrMany, Result}; +use crate::{Error, OptOneMany, Result}; #[derive(Parser, Debug, PartialEq, Default)] #[command(about, version)] @@ -85,7 +85,7 @@ impl Args { } if !self.meta.font.is_empty() { - config.fonts = OneOrMany::new_opt(self.meta.font); + config.fonts = OptOneMany::new(self.meta.font); } cli_strings.check() diff --git a/martin/src/config.rs b/martin/src/config.rs index 9ed340bb5..625485e01 100644 --- a/martin/src/config.rs +++ b/martin/src/config.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use subst::VariableMap; use crate::file_config::{resolve_files, FileConfigEnum}; -use crate::fonts::{resolve_fonts, FontSources}; +use crate::fonts::FontSources; use crate::mbtiles::MbtSource; use crate::pg::PgConfig; use crate::pmtiles::PmtSource; @@ -45,7 +45,7 @@ pub struct Config { #[serde(default, skip_serializing_if = "FileConfigEnum::is_none")] pub sprites: FileConfigEnum, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "OptOneMany::is_none")] pub fonts: OptOneMany, #[serde(flatten)] @@ -85,7 +85,7 @@ impl Config { Ok(ServerState { tiles: self.resolve_tile_sources(idr).await?, sprites: SpriteSources::resolve(&mut self.sprites)?, - fonts: resolve_fonts(&mut self.fonts)?, + fonts: FontSources::resolve(&mut self.fonts)?, }) } diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs index 955ce89b7..1d0e8a59f 100644 --- a/martin/src/fonts/mod.rs +++ b/martin/src/fonts/mod.rs @@ -15,7 +15,7 @@ use regex::Regex; use serde::{Deserialize, Serialize}; use crate::fonts::FontError::IoError; -use crate::OneOrMany; +use crate::OptOneMany; const MAX_UNICODE_CP: usize = 0xFFFF; const CP_RANGE_SIZE: usize = 256; @@ -208,37 +208,6 @@ fn get_available_codepoints(face: &mut Face) -> Option { } } -pub fn resolve_fonts(config: &mut Option>) -> Result { - let Some(cfg) = config else { - return Ok(FontSources::default()); - }; - - let mut fonts = HashMap::new(); - let lib = Library::init()?; - - for path in cfg.iter() { - let disp_path = path.display(); - if path.exists() { - recurse_dirs(&lib, path, &mut fonts)?; - } else { - warn!("Ignoring non-existent font source {disp_path}"); - }; - } - - let mut masks = Vec::with_capacity(MAX_UNICODE_CP_RANGE_ID + 1); - - let mut bs = BitSet::with_capacity(CP_RANGE_SIZE); - for v in 0..=MAX_UNICODE_CP { - bs.insert(v); - if v % CP_RANGE_SIZE == (CP_RANGE_SIZE - 1) { - masks.push(bs); - bs = BitSet::with_capacity(CP_RANGE_SIZE); - } - } - - Ok(FontSources { fonts, masks }) -} - #[derive(Debug, Clone, Default)] pub struct FontSources { fonts: HashMap, @@ -258,6 +227,37 @@ pub struct CatalogFontEntry { } impl FontSources { + pub fn resolve(config: &mut OptOneMany) -> Result { + if config.is_empty() { + return Ok(Self::default()); + } + + let mut fonts = HashMap::new(); + let lib = Library::init()?; + + for path in config.iter() { + let disp_path = path.display(); + if path.exists() { + recurse_dirs(&lib, path, &mut fonts)?; + } else { + warn!("Ignoring non-existent font source {disp_path}"); + }; + } + + let mut masks = Vec::with_capacity(MAX_UNICODE_CP_RANGE_ID + 1); + + let mut bs = BitSet::with_capacity(CP_RANGE_SIZE); + for v in 0..=MAX_UNICODE_CP { + bs.insert(v); + if v % CP_RANGE_SIZE == (CP_RANGE_SIZE - 1) { + masks.push(bs); + bs = BitSet::with_capacity(CP_RANGE_SIZE); + } + } + + Ok(Self { fonts, masks }) + } + #[must_use] pub fn get_catalog(&self) -> FontCatalog { self.fonts diff --git a/martin/tests/mb_server_test.rs b/martin/tests/mb_server_test.rs index 31f3177ef..046920f24 100644 --- a/martin/tests/mb_server_test.rs +++ b/martin/tests/mb_server_test.rs @@ -69,6 +69,7 @@ async fn mbt_get_catalog() { content_type: image/webp name: ne2sr sprites: {} + fonts: {} "###); } @@ -100,6 +101,7 @@ async fn mbt_get_catalog_gzip() { content_type: image/webp name: ne2sr sprites: {} + fonts: {} "###); } diff --git a/martin/tests/pg_server_test.rs b/martin/tests/pg_server_test.rs index 341e9aabc..3a48728a3 100644 --- a/martin/tests/pg_server_test.rs +++ b/martin/tests/pg_server_test.rs @@ -115,6 +115,7 @@ postgres: content_type: application/x-protobuf description: public.table_source_multiple_geom.geom2 sprites: {} + fonts: {} "###); } diff --git a/martin/tests/pmt_server_test.rs b/martin/tests/pmt_server_test.rs index 3ed778313..b9f89628d 100644 --- a/martin/tests/pmt_server_test.rs +++ b/martin/tests/pmt_server_test.rs @@ -54,6 +54,7 @@ async fn pmt_get_catalog() { stamen_toner__raster_CC-BY-ODbL_z3: content_type: image/png sprites: {} + fonts: {} "###); } @@ -72,6 +73,7 @@ async fn pmt_get_catalog_gzip() { p_png: content_type: image/png sprites: {} + fonts: {} "###); } diff --git a/tests/expected/auto/catalog_auto.json b/tests/expected/auto/catalog_auto.json index 3ce4162f5..59082de5e 100644 --- a/tests/expected/auto/catalog_auto.json +++ b/tests/expected/auto/catalog_auto.json @@ -163,5 +163,6 @@ "description": "Major cities from Natural Earth data" } }, - "sprites": {} + "sprites": {}, + "fonts": {} } diff --git a/tests/expected/configured/catalog_cfg.json b/tests/expected/configured/catalog_cfg.json index 2fb48ab5d..b6cee7284 100644 --- a/tests/expected/configured/catalog_cfg.json +++ b/tests/expected/configured/catalog_cfg.json @@ -53,5 +53,6 @@ "sub/circle" ] } - } + }, + "fonts": {} } From 9c51d468580408a0260da079a077103cc8a3863c Mon Sep 17 00:00:00 2001 From: Lucas Date: Sat, 28 Oct 2023 10:33:39 +0800 Subject: [PATCH 05/10] add doc about font (#3) --- docs/src/21-run-with-cli.md | 3 ++ docs/src/30-config-file.md | 5 +++ docs/src/37-sources-fonts.md | 60 ++++++++++++++++++++++++++++++++++++ docs/src/SUMMARY.md | 1 + 4 files changed, 69 insertions(+) create mode 100644 docs/src/37-sources-fonts.md diff --git a/docs/src/21-run-with-cli.md b/docs/src/21-run-with-cli.md index 3354d91d0..40309e004 100644 --- a/docs/src/21-run-with-cli.md +++ b/docs/src/21-run-with-cli.md @@ -19,6 +19,9 @@ Options: -s, --sprite Export a directory with SVG files as a sprite source. Can be specified multiple times + -f, --font + Export a directory with font files as a font source. Can be specified multiple times + -k, --keep-alive Connection keep alive timeout. [DEFAULT: 75] diff --git a/docs/src/30-config-file.md b/docs/src/30-config-file.md index deaeba64d..b941e9254 100644 --- a/docs/src/30-config-file.md +++ b/docs/src/30-config-file.md @@ -183,4 +183,9 @@ sprites: sources: # SVG images in this directory will be published as a "my_sprites" sprite source my_sprites: /path/to/some_dir +# Font configuration +fonts: + # otf, ttf, ttc files will be find recursively + - /path/to/font_dir1 + - /path/to/font_dir2 ``` diff --git a/docs/src/37-sources-fonts.md b/docs/src/37-sources-fonts.md new file mode 100644 index 000000000..7a2168775 --- /dev/null +++ b/docs/src/37-sources-fonts.md @@ -0,0 +1,60 @@ +## Font Sources + +Martin can serve font assests(`otf`, `ttf`, `ttc`) for map rendering, and there is no need to supply a large number of small pre-generated font protobuf files. Martin can generate them dynamically on the fly based on your request. + +## API +You can request font protobuf of single or combination of fonts. + +||API|Demo| +|----|----|----| +|Single|/font/{fontstack}/{start}-{end}|http://127.0.0.1:3000/font/Overpass Mono Bold/0-255| +|Combination|/font/{fontstack1},{fontstack2},{fontstack_n}/{start}-{end}|http://127.0.0.1:3000/font/Overpass Mono Bold,Overpass Mono Light/0-255| + +Martin will list all the font resources in the `/catalog` endpoint, you could call it to check all your font resources before an accurate request. + +```shell +curl http://127.0.0.1:3000/catalog +{ + "fonts": { + "Overpass Mono Bold": { + "family": "Overpass Mono", + "style": "Bold", + "glyphs": 931, + "start": 0, + "end": 64258 + }, + "Overpass Mono Light": { + "family": "Overpass Mono", + "style": "Light", + "glyphs": 931, + "start": 0, + "end": 64258 + }, + "Overpass Mono SemiBold": { + "family": "Overpass Mono", + "style": "SemiBold", + "glyphs": 931, + "start": 0, + "end": 64258 + } + } +} +``` + +## Configuring from CLI +A font directory can be configured from the [CLI](run-with-cli.md) with the `--font` flag. The flag can be used multiple times to configure multiple font directories. + +```shell +martin --font /path/to/font_dir1 --font /path/to/font_dir2 +``` + +## Configuring from Config File + +A font directory can be configured from the config file with the `fonts` key. + +```yaml +# Fonts configuration +fonts: + - /path/to/fonts_dir1 + - /path/to/fonts_dir2 +``` \ No newline at end of file diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index b63349be0..018f59937 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -14,6 +14,7 @@ - [MBTiles and PMTiles File Sources](34-sources-files.md) - [Composite Sources](35-sources-composite.md) - [Sprite Sources](36-sources-sprites.md) + - [Font Sources](37-sources-fonts.md) - [Usage and Endpoint API](40-using-endpoints.md) - [Using with MapLibre](41-using-with-maplibre.md) - [Using with Leaflet](42-using-with-leaflet.md) From 328d98a8f2d3aa269bf9045645c8999ff937b394 Mon Sep 17 00:00:00 2001 From: Lucas Date: Sat, 28 Oct 2023 10:37:27 +0800 Subject: [PATCH 06/10] add font test (#4) --- tests/config.yaml | 2 ++ tests/expected/configured/catalog_cfg.json | 17 ++++++++++++++++- tests/expected/configured/font_1.pbf | Bin 0 -> 78006 bytes tests/expected/configured/font_2.pbf | Bin 0 -> 79714 bytes tests/expected/configured/font_3.pbf | Bin 0 -> 79714 bytes tests/expected/given_config.yaml | 2 ++ tests/fixtures/fonts/overpass-mono-regular.ttf | Bin 0 -> 132620 bytes .../fonts/sub_dir/overpass-mono-light.otf | Bin 0 -> 93752 bytes tests/test.sh | 12 ++++++++++++ 9 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tests/expected/configured/font_1.pbf create mode 100644 tests/expected/configured/font_2.pbf create mode 100644 tests/expected/configured/font_3.pbf create mode 100755 tests/fixtures/fonts/overpass-mono-regular.ttf create mode 100755 tests/fixtures/fonts/sub_dir/overpass-mono-light.otf diff --git a/tests/config.yaml b/tests/config.yaml index 471f31428..8d35213e0 100644 --- a/tests/config.yaml +++ b/tests/config.yaml @@ -168,3 +168,5 @@ sprites: paths: tests/fixtures/sprites/src1 sources: mysrc: tests/fixtures/sprites/src2 +fonts: + - tests/fixtures/fonts \ No newline at end of file diff --git a/tests/expected/configured/catalog_cfg.json b/tests/expected/configured/catalog_cfg.json index b6cee7284..810687e76 100644 --- a/tests/expected/configured/catalog_cfg.json +++ b/tests/expected/configured/catalog_cfg.json @@ -54,5 +54,20 @@ ] } }, - "fonts": {} + "fonts": { + "Overpass Mono Light": { + "family": "Overpass Mono", + "style": "Light", + "glyphs": 931, + "start": 0, + "end": 64258 + }, + "Overpass Mono Regular": { + "family": "Overpass Mono", + "style": "Regular", + "glyphs": 931, + "start": 0, + "end": 64258 + } + } } diff --git a/tests/expected/configured/font_1.pbf b/tests/expected/configured/font_1.pbf new file mode 100644 index 0000000000000000000000000000000000000000..bb3447323326210290a8245565925ffa8be32993 GIT binary patch literal 78006 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 JXH9s3e*?wj6U+br literal 0 HcmV?d00001 diff --git a/tests/expected/configured/font_2.pbf b/tests/expected/configured/font_2.pbf new file mode 100644 index 0000000000000000000000000000000000000000..f57bcc48cbad0691b4f71030c97dc7ddb0614d40 GIT binary patch literal 79714 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 #a3c4B=UT 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 MUy7XgcEAOH2mHh-asU7T literal 0 HcmV?d00001 diff --git a/tests/expected/configured/font_3.pbf b/tests/expected/configured/font_3.pbf new file mode 100644 index 0000000000000000000000000000000000000000..f57bcc48cbad0691b4f71030c97dc7ddb0614d40 GIT binary patch literal 79714 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 #a3c4B=UT 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 MUy7XgcEAOH2mHh-asU7T literal 0 HcmV?d00001 diff --git a/tests/expected/given_config.yaml b/tests/expected/given_config.yaml index 6ba51282e..5dba15acb 100644 --- a/tests/expected/given_config.yaml +++ b/tests/expected/given_config.yaml @@ -164,3 +164,5 @@ sprites: paths: tests/fixtures/sprites/src1 sources: mysrc: tests/fixtures/sprites/src2 +fonts: +- tests/fixtures/fonts diff --git a/tests/fixtures/fonts/overpass-mono-regular.ttf b/tests/fixtures/fonts/overpass-mono-regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..107fe320d187c03de47e42121885946d04b3c2a0 GIT binary patch literal 132620 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
}JmjU@4etf$G4vbI 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 z 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 literal 0 HcmV?d00001 diff --git a/tests/test.sh b/tests/test.sh index 2ff631790..a1f9b837b 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -97,6 +97,14 @@ test_png() fi } +test_font(){ + FILENAME="$TEST_OUT_DIR/$1.pbf" + URL="$MARTIN_URL/$2" + + echo "Testing $(basename "$FILENAME") from $URL" + $CURL "$URL" > "$FILENAME" +} + # Delete a line from a file $1 that matches parameter $2 remove_line() { @@ -268,6 +276,10 @@ test_png spr_cmp sprite/src1,mysrc.png test_jsn spr_cmp_2x sprite/src1,mysrc@2x.json test_png spr_cmp_2x sprite/src1,mysrc@2x.png +test_font font_1 font/Overpass%20Mono%20Light/0-255 +test_font font_2 font/Overpass%20Mono%20Regular/0-255 +test_font font_3 font/Overpass%20Mono%20Regular%2COverpass%20Mono%20Light/0-255 + kill_process $PROCESS_ID validate_log "${TMP_DIR}/test_log_2.txt" From f34b5428889f09ad53f6070ee5e81e59e1590368 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Fri, 27 Oct 2023 23:39:57 -0400 Subject: [PATCH 07/10] cleanup --- debian/config.yaml | 4 + docs/src/21-run-with-cli.md | 4 +- docs/src/30-config-file.md | 7 +- docs/src/36-sources-sprites.md | 2 +- docs/src/37-sources-fonts.md | 26 ++-- martin/src/args/root.rs | 2 +- martin/src/fonts/mod.rs | 176 +++++++++++++------------- tests/config.yaml | 4 +- tests/expected/auto/catalog_auto.json | 17 ++- tests/expected/generated_config.yaml | 3 + tests/expected/given_config.yaml | 1 + tests/test.sh | 3 +- 12 files changed, 142 insertions(+), 107 deletions(-) diff --git a/debian/config.yaml b/debian/config.yaml index d9289352a..f59118cbf 100644 --- a/debian/config.yaml +++ b/debian/config.yaml @@ -29,3 +29,7 @@ worker_processes: 8 # - /path/to/mbtiles.mbtiles # sources: # mb-src1: /path/to/mbtiles1.mbtiles + +# fonts: +# - /path/to/font/file.ttf +# - /path/to/font_dir diff --git a/docs/src/21-run-with-cli.md b/docs/src/21-run-with-cli.md index 40309e004..c7c48487a 100644 --- a/docs/src/21-run-with-cli.md +++ b/docs/src/21-run-with-cli.md @@ -20,7 +20,7 @@ Options: Export a directory with SVG files as a sprite source. Can be specified multiple times -f, --font - Export a directory with font files as a font source. Can be specified multiple times + Export a font file or a directory with font files as a font source (recursive). Can be specified multiple times -k, --keep-alive Connection keep alive timeout. [DEFAULT: 75] @@ -31,7 +31,7 @@ Options: -W, --workers Number of web server workers - -b, --auto-bounds + -b, --auto-bounds Specify how bounds should be computed for the spatial PG tables. [DEFAULT: quick] Possible values: diff --git a/docs/src/30-config-file.md b/docs/src/30-config-file.md index b941e9254..a4df42845 100644 --- a/docs/src/30-config-file.md +++ b/docs/src/30-config-file.md @@ -183,9 +183,10 @@ sprites: sources: # SVG images in this directory will be published as a "my_sprites" sprite source my_sprites: /path/to/some_dir + # Font configuration fonts: - # otf, ttf, ttc files will be find recursively - - /path/to/font_dir1 - - /path/to/font_dir2 + # A list of *.otf, *.ttf, and *.ttc font files and dirs to search recursively. + - /path/to/font/file.ttf + - /path/to/font_dir ``` diff --git a/docs/src/36-sources-sprites.md b/docs/src/36-sources-sprites.md index 76b742028..4cd713996 100644 --- a/docs/src/36-sources-sprites.md +++ b/docs/src/36-sources-sprites.md @@ -1,6 +1,6 @@ ## Sprite Sources -Given a directory with SVG images, Martin will generate a sprite -- a JSON index and a PNG image, for both low and high resolution displays. The SVG filenames without extension will be used as the sprite image IDs. The images are searched recursively in the given directory, so subdirectory names will be used as prefixes for the image IDs, e.g. `icons/bicycle.svg` will be available as `icons/bicycle` sprite image. +Given a directory with SVG images, Martin will generate a sprite -- a JSON index and a PNG image, for both low and high resolution displays. The SVG filenames without extension will be used as the sprite image IDs. The images are searched recursively in the given directory, so subdirectory names will be used as prefixes for the image IDs, e.g. `icons/bicycle.svg` will be available as `icons/bicycle` sprite image. The sprite generation is not yet cached, and may require external reverse proxy or CDN for faster operation. ### API Martin uses [MapLibre sprites API](https://maplibre.org/maplibre-style-spec/sprite/) specification to serve sprites via several endpoints. The sprite image and index are generated on the fly, so if the sprite directory is updated, the changes will be reflected immediately. diff --git a/docs/src/37-sources-fonts.md b/docs/src/37-sources-fonts.md index 7a2168775..d531e95d8 100644 --- a/docs/src/37-sources-fonts.md +++ b/docs/src/37-sources-fonts.md @@ -1,14 +1,15 @@ ## Font Sources -Martin can serve font assests(`otf`, `ttf`, `ttc`) for map rendering, and there is no need to supply a large number of small pre-generated font protobuf files. Martin can generate them dynamically on the fly based on your request. +Martin can serve glyph ranges from `otf`, `ttf`, and `ttc` fonts as needed by MapLibre text rendering. Martin will generate them dynamically on the fly. +The glyph range generation is not yet cached, and may require external reverse proxy or CDN for faster operation. ## API -You can request font protobuf of single or combination of fonts. +Fonts ranges are available either for a single font, or a combination of multiple fonts. The font names are case-sensitive and should match the font name in the font file as published in the catalog. When combining multiple fonts, the glyph range will contain glyphs from the first listed font if available, and fallback to the next font if the glyph is not available in the first font, etc. The glyph range will be empty if none of the fonts contain the glyph. -||API|Demo| -|----|----|----| -|Single|/font/{fontstack}/{start}-{end}|http://127.0.0.1:3000/font/Overpass Mono Bold/0-255| -|Combination|/font/{fontstack1},{fontstack2},{fontstack_n}/{start}-{end}|http://127.0.0.1:3000/font/Overpass Mono Bold,Overpass Mono Light/0-255| +| Type | API | Example | +|----------|------------------------------------------------|-----------------------------------------------------------------------| +| Single | `/font/{name}/{start}-{end}` | `/font/Overpass Mono Bold/0-255` | +| Combined | `/font/{name1},{name2},{name_n}/{start}-{end}` | `/font/Overpass Mono Bold,Overpass Mono Light/0-255` | Martin will list all the font resources in the `/catalog` endpoint, you could call it to check all your font resources before an accurate request. @@ -41,11 +42,11 @@ curl http://127.0.0.1:3000/catalog } ``` -## Configuring from CLI -A font directory can be configured from the [CLI](run-with-cli.md) with the `--font` flag. The flag can be used multiple times to configure multiple font directories. +## Using from CLI +A font file or directory can be configured from the [CLI](21-run-with-cli.md) with the `--font` flag. The flag can be used multiple times. ```shell -martin --font /path/to/font_dir1 --font /path/to/font_dir2 +martin --font /path/to/font/file.ttf --font /path/to/font_dir ``` ## Configuring from Config File @@ -55,6 +56,7 @@ A font directory can be configured from the config file with the `fonts` key. ```yaml # Fonts configuration fonts: - - /path/to/fonts_dir1 - - /path/to/fonts_dir2 -``` \ No newline at end of file + # A list of *.otf, *.ttf, and *.ttc font files and dirs to search recursively. + - /path/to/font/file.ttf + - /path/to/font_dir +``` diff --git a/martin/src/args/root.rs b/martin/src/args/root.rs index 90a6b0cf9..fe15d2494 100644 --- a/martin/src/args/root.rs +++ b/martin/src/args/root.rs @@ -44,7 +44,7 @@ pub struct MetaArgs { /// Export a directory with SVG files as a sprite source. Can be specified multiple times. #[arg(short, long)] pub sprite: Vec, - /// Export a directory with font files as a font source. Can be specified multiple times. + /// Export a font file or a directory with font files as a font source (recursive). Can be specified multiple times. #[arg(short, long)] pub font: Vec, } diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs index 1d0e8a59f..78b8bd209 100644 --- a/martin/src/fonts/mod.rs +++ b/martin/src/fonts/mod.rs @@ -81,98 +81,104 @@ fn recurse_dirs( path: &Path, fonts: &mut HashMap, ) -> Result<(), FontError> { - static RE_SPACES: OnceLock = OnceLock::new(); - - for dir_entry in path - .read_dir() - .map_err(|e| IoError(e, path.to_path_buf()))? - .flatten() + if path.is_dir() { + for dir_entry in path + .read_dir() + .map_err(|e| IoError(e, path.to_path_buf()))? + .flatten() + { + recurse_dirs(lib, &dir_entry.path(), fonts)?; + } + } else if path + .extension() + .and_then(OsStr::to_str) + .is_some_and(|e| ["otf", "ttf", "ttc"].contains(&e)) { - let path = dir_entry.path(); + parse_font(lib, fonts, path)?; + } - if path.is_dir() { - recurse_dirs(lib, &path, fonts)?; - continue; - } + Ok(()) +} - if !path - .extension() - .and_then(OsStr::to_str) - .is_some_and(|e| ["otf", "ttf", "ttc"].contains(&e)) - { - continue; - } +fn parse_font( + lib: &Library, + fonts: &mut HashMap, + path: &Path, +) -> Result<(), FontError> { + static RE_SPACES: OnceLock = OnceLock::new(); - let mut face = lib.new_face(&path, 0)?; - let num_faces = face.num_faces() as isize; - for face_index in 0..num_faces { - if face_index > 0 { - face = lib.new_face(&path, face_index)?; - } - let Some(family) = face.family_name() else { - return Err(FontError::MissingFamilyName(path.clone())); - }; - let mut name = family.clone(); - let style = face.style_name(); - if let Some(style) = &style { - name.push(' '); - name.push_str(style); + let mut face = lib.new_face(path, 0)?; + let num_faces = face.num_faces() as isize; + for face_index in 0..num_faces { + if face_index > 0 { + face = lib.new_face(path, face_index)?; + } + let Some(family) = face.family_name() else { + return Err(FontError::MissingFamilyName(path.to_path_buf())); + }; + let mut name = family.clone(); + let style = face.style_name(); + if let Some(style) = &style { + name.push(' '); + name.push_str(style); + } + // Make sure font name has no slashes or commas, replacing them with spaces and de-duplicating spaces + name = name.replace(['/', ','], " "); + name = RE_SPACES + .get_or_init(|| Regex::new(r"\s+").unwrap()) + .replace_all(name.as_str(), " ") + .to_string(); + + match fonts.entry(name) { + Entry::Occupied(v) => { + warn!( + "Ignoring duplicate font {} from {} because it was already configured from {}", + v.key(), + path.display(), + v.get().path.display() + ); } - // Make sure font name has no slashes or commas, replacing them with spaces and de-duplicating spaces - name = name.replace(['/', ','], " "); - name = RE_SPACES - .get_or_init(|| Regex::new(r"\s+").unwrap()) - .replace_all(name.as_str(), " ") - .to_string(); - - match fonts.entry(name) { - Entry::Occupied(v) => { - warn!("Ignoring duplicate font source {} from {} because it was already configured for {}", - v.key(), path.display(), v.get().path.display()); - } - Entry::Vacant(v) => { - let key = v.key(); - let Some((codepoints, glyphs, ranges)) = get_available_codepoints(&mut face) - else { - warn!( - "Ignoring font source {key} from {} because it has no available glyphs", - path.display() - ); - continue; - }; - - let start = ranges.first().map(|(s, _)| *s).unwrap(); - let end = ranges.last().map(|(_, e)| *e).unwrap(); - info!( - "Configured font source {key} with {glyphs} glyphs ({start:04X}-{end:04X}) from {}", + Entry::Vacant(v) => { + let key = v.key(); + let Some((codepoints, glyphs, ranges)) = get_available_codepoints(&mut face) else { + warn!( + "Ignoring font {key} from {} because it has no available glyphs", path.display() ); - debug!( - "Available font ranges: {}", - ranges - .iter() - .map(|(s, e)| if s == e { - format!("{s:02X}") - } else { - format!("{s:02X}-{e:02X}") - }) - .collect::>() - .join(", "), - ); - - v.insert(FontSource { - path: path.clone(), - face_index, - codepoints, - catalog_entry: CatalogFontEntry { - family, - style, - glyphs, - start, - end, - }, - }); - } + continue; + }; + + let start = ranges.first().map(|(s, _)| *s).unwrap(); + let end = ranges.last().map(|(_, e)| *e).unwrap(); + info!( + "Configured font {key} with {glyphs} glyphs ({start:04X}-{end:04X}) from {}", + path.display() + ); + debug!( + "Available font ranges: {}", + ranges + .iter() + .map(|(s, e)| if s == e { + format!("{s:02X}") + } else { + format!("{s:02X}-{e:02X}") + }) + .collect::>() + .join(", "), + ); + + v.insert(FontSource { + path: path.to_path_buf(), + face_index, + codepoints, + catalog_entry: CatalogFontEntry { + family, + style, + glyphs, + start, + end, + }, + }); } } } diff --git a/tests/config.yaml b/tests/config.yaml index 8d35213e0..cecc48aa7 100644 --- a/tests/config.yaml +++ b/tests/config.yaml @@ -168,5 +168,7 @@ sprites: paths: tests/fixtures/sprites/src1 sources: mysrc: tests/fixtures/sprites/src2 + fonts: - - tests/fixtures/fonts \ No newline at end of file + - tests/fixtures/fonts/overpass-mono-regular.ttf + - tests/fixtures/fonts diff --git a/tests/expected/auto/catalog_auto.json b/tests/expected/auto/catalog_auto.json index 59082de5e..3c8b6cb0a 100644 --- a/tests/expected/auto/catalog_auto.json +++ b/tests/expected/auto/catalog_auto.json @@ -164,5 +164,20 @@ } }, "sprites": {}, - "fonts": {} + "fonts": { + "Overpass Mono Light": { + "family": "Overpass Mono", + "style": "Light", + "glyphs": 931, + "start": 0, + "end": 64258 + }, + "Overpass Mono Regular": { + "family": "Overpass Mono", + "style": "Regular", + "glyphs": 931, + "start": 0, + "end": 64258 + } + } } diff --git a/tests/expected/generated_config.yaml b/tests/expected/generated_config.yaml index 50bf43f96..224057bea 100644 --- a/tests/expected/generated_config.yaml +++ b/tests/expected/generated_config.yaml @@ -212,3 +212,6 @@ mbtiles: world_cities_diff: tests/fixtures/mbtiles/world_cities_diff.mbtiles world_cities_modified: tests/fixtures/mbtiles/world_cities_modified.mbtiles zoomed_world_cities: tests/fixtures/mbtiles/zoomed_world_cities.mbtiles +fonts: +- tests/fixtures/fonts/overpass-mono-regular.ttf +- tests/fixtures/fonts diff --git a/tests/expected/given_config.yaml b/tests/expected/given_config.yaml index 5dba15acb..64291515e 100644 --- a/tests/expected/given_config.yaml +++ b/tests/expected/given_config.yaml @@ -165,4 +165,5 @@ sprites: sources: mysrc: tests/fixtures/sprites/src2 fonts: +- tests/fixtures/fonts/overpass-mono-regular.ttf - tests/fixtures/fonts diff --git a/tests/test.sh b/tests/test.sh index a1f9b837b..8fdfd1360 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -135,6 +135,7 @@ validate_log() # Make sure the log has just the expected warnings, remove them, and test that there are no other ones test_log_has_str "$LOG_FILE" 'WARN martin::pg::table_source] Table public.table_source has no spatial index on column geom' + test_log_has_str "$LOG_FILE" 'WARN martin::fonts] Ignoring duplicate font Overpass Mono Regular from tests/fixtures/fonts/overpass-mono-regular.ttf because it was already configured from tests/fixtures/fonts/overpass-mono-regular.ttf' echo "Checking for no other warnings or errors in the log" if grep -e ' ERROR ' -e ' WARN ' "$LOG_FILE"; then @@ -161,7 +162,7 @@ echo "Test auto configured Martin" TEST_OUT_DIR="$(dirname "$0")/output/auto" mkdir -p "$TEST_OUT_DIR" -ARG=(--default-srid 900913 --auto-bounds calc --save-config "$(dirname "$0")/output/generated_config.yaml" tests/fixtures/mbtiles tests/fixtures/pmtiles) +ARG=(--default-srid 900913 --auto-bounds calc --save-config "$(dirname "$0")/output/generated_config.yaml" tests/fixtures/mbtiles tests/fixtures/pmtiles --font tests/fixtures/fonts/overpass-mono-regular.ttf --font tests/fixtures/fonts) set -x $MARTIN_BIN "${ARG[@]}" 2>&1 | tee "${TMP_DIR}/test_log_1.txt" & PROCESS_ID=`jobs -p` From 8384586eeb0c0f3d16908205c5a99b22bc8fda99 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sat, 28 Oct 2023 00:22:56 -0400 Subject: [PATCH 08/10] better errors --- docs/src/37-sources-fonts.md | 17 ++- martin/src/fonts/mod.rs | 248 +++++++++++++++++------------------ 2 files changed, 133 insertions(+), 132 deletions(-) diff --git a/docs/src/37-sources-fonts.md b/docs/src/37-sources-fonts.md index d531e95d8..797d0b8c2 100644 --- a/docs/src/37-sources-fonts.md +++ b/docs/src/37-sources-fonts.md @@ -4,14 +4,16 @@ Martin can serve glyph ranges from `otf`, `ttf`, and `ttc` fonts as needed by Ma The glyph range generation is not yet cached, and may require external reverse proxy or CDN for faster operation. ## API -Fonts ranges are available either for a single font, or a combination of multiple fonts. The font names are case-sensitive and should match the font name in the font file as published in the catalog. When combining multiple fonts, the glyph range will contain glyphs from the first listed font if available, and fallback to the next font if the glyph is not available in the first font, etc. The glyph range will be empty if none of the fonts contain the glyph. +Fonts ranges are available either for a single font, or a combination of multiple fonts. The font names are case-sensitive and should match the font name in the font file as published in the catalog. Make sure to URL-escape font names as they usually contain spaces. -| Type | API | Example | -|----------|------------------------------------------------|-----------------------------------------------------------------------| -| Single | `/font/{name}/{start}-{end}` | `/font/Overpass Mono Bold/0-255` | -| Combined | `/font/{name1},{name2},{name_n}/{start}-{end}` | `/font/Overpass Mono Bold,Overpass Mono Light/0-255` | +When combining multiple fonts, the glyph range will contain glyphs from the first listed font if available, and fallback to the next font if the glyph is not available in the first font, etc. The glyph range will be empty if none of the fonts contain the glyph. -Martin will list all the font resources in the `/catalog` endpoint, you could call it to check all your font resources before an accurate request. +| Type | API | Example | +|----------|------------------------------------------------|--------------------------------------------------------------| +| Single | `/font/{name}/{start}-{end}` | `/font/Overpass%20Mono%20Bold/0-255` | +| Combined | `/font/{name1},{name2},{name_n}/{start}-{end}` | `/font/Overpass%20Mono%20Bold,Overpass%20Mono%20Light/0-255` | + +Martin will show all available fonts at the `/catalog` endpoint. ```shell curl http://127.0.0.1:3000/catalog @@ -43,7 +45,8 @@ curl http://127.0.0.1:3000/catalog ``` ## Using from CLI -A font file or directory can be configured from the [CLI](21-run-with-cli.md) with the `--font` flag. The flag can be used multiple times. + +A font file or directory can be configured from the [CLI](21-run-with-cli.md) with one or more `--font` parameters. ```shell martin --font /path/to/font/file.ttf --font /path/to/font_dir diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs index 78b8bd209..0eeb38731 100644 --- a/martin/src/fonts/mod.rs +++ b/martin/src/fonts/mod.rs @@ -2,7 +2,7 @@ use std::collections::hash_map::Entry; use std::collections::{BTreeMap, HashMap}; use std::ffi::OsStr; use std::fmt::Debug; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::OnceLock; use bit_set::BitSet; @@ -54,8 +54,8 @@ pub enum FontError { #[error("IO error accessing {}: {0}", .1.display())] IoError(std::io::Error, PathBuf), - #[error("Font {0} uses bad file {}", .1.display())] - InvalidFontFilePath(String, PathBuf), + #[error("Invalid font file {}", .0.display())] + InvalidFontFilePath(PathBuf), #[error("No font files found in {}", .0.display())] NoFontFilesFound(PathBuf), @@ -76,116 +76,6 @@ pub enum FontError { ErrorSerializingProtobuf(#[from] pbf_font_tools::protobuf::Error), } -fn recurse_dirs( - lib: &Library, - path: &Path, - fonts: &mut HashMap, -) -> Result<(), FontError> { - if path.is_dir() { - for dir_entry in path - .read_dir() - .map_err(|e| IoError(e, path.to_path_buf()))? - .flatten() - { - recurse_dirs(lib, &dir_entry.path(), fonts)?; - } - } else if path - .extension() - .and_then(OsStr::to_str) - .is_some_and(|e| ["otf", "ttf", "ttc"].contains(&e)) - { - parse_font(lib, fonts, path)?; - } - - Ok(()) -} - -fn parse_font( - lib: &Library, - fonts: &mut HashMap, - path: &Path, -) -> Result<(), FontError> { - static RE_SPACES: OnceLock = OnceLock::new(); - - let mut face = lib.new_face(path, 0)?; - let num_faces = face.num_faces() as isize; - for face_index in 0..num_faces { - if face_index > 0 { - face = lib.new_face(path, face_index)?; - } - let Some(family) = face.family_name() else { - return Err(FontError::MissingFamilyName(path.to_path_buf())); - }; - let mut name = family.clone(); - let style = face.style_name(); - if let Some(style) = &style { - name.push(' '); - name.push_str(style); - } - // Make sure font name has no slashes or commas, replacing them with spaces and de-duplicating spaces - name = name.replace(['/', ','], " "); - name = RE_SPACES - .get_or_init(|| Regex::new(r"\s+").unwrap()) - .replace_all(name.as_str(), " ") - .to_string(); - - match fonts.entry(name) { - Entry::Occupied(v) => { - warn!( - "Ignoring duplicate font {} from {} because it was already configured from {}", - v.key(), - path.display(), - v.get().path.display() - ); - } - Entry::Vacant(v) => { - let key = v.key(); - let Some((codepoints, glyphs, ranges)) = get_available_codepoints(&mut face) else { - warn!( - "Ignoring font {key} from {} because it has no available glyphs", - path.display() - ); - continue; - }; - - let start = ranges.first().map(|(s, _)| *s).unwrap(); - let end = ranges.last().map(|(_, e)| *e).unwrap(); - info!( - "Configured font {key} with {glyphs} glyphs ({start:04X}-{end:04X}) from {}", - path.display() - ); - debug!( - "Available font ranges: {}", - ranges - .iter() - .map(|(s, e)| if s == e { - format!("{s:02X}") - } else { - format!("{s:02X}-{e:02X}") - }) - .collect::>() - .join(", "), - ); - - v.insert(FontSource { - path: path.to_path_buf(), - face_index, - codepoints, - catalog_entry: CatalogFontEntry { - family, - style, - glyphs, - start, - end, - }, - }); - } - } - } - - Ok(()) -} - type GetGlyphInfo = (BitSet, usize, Vec<(usize, usize)>); fn get_available_codepoints(face: &mut Face) -> Option { @@ -242,12 +132,7 @@ impl FontSources { let lib = Library::init()?; for path in config.iter() { - let disp_path = path.display(); - if path.exists() { - recurse_dirs(&lib, path, &mut fonts)?; - } else { - warn!("Ignoring non-existent font source {disp_path}"); - }; + recurse_dirs(&lib, path.clone(), &mut fonts, true)?; } let mut masks = Vec::with_capacity(MAX_UNICODE_CP_RANGE_ID + 1); @@ -357,9 +242,122 @@ pub struct FontSource { catalog_entry: CatalogFontEntry, } -// #[cfg(test)] -// mod tests { -// use std::path::PathBuf; -// -// use super::*; -// } +fn recurse_dirs( + lib: &Library, + path: PathBuf, + fonts: &mut HashMap, + is_top_level: bool, +) -> Result<(), FontError> { + let start_count = fonts.len(); + if path.is_dir() { + for dir_entry in path + .read_dir() + .map_err(|e| IoError(e, path.clone()))? + .flatten() + { + recurse_dirs(lib, dir_entry.path(), fonts, false)?; + } + if is_top_level && fonts.len() == start_count { + return Err(FontError::NoFontFilesFound(path)); + } + } else { + if path + .extension() + .and_then(OsStr::to_str) + .is_some_and(|e| ["otf", "ttf", "ttc"].contains(&e)) + { + parse_font(lib, fonts, path.clone())?; + } + if is_top_level && fonts.len() == start_count { + return Err(FontError::InvalidFontFilePath(path)); + } + } + + Ok(()) +} + +fn parse_font( + lib: &Library, + fonts: &mut HashMap, + path: PathBuf, +) -> Result<(), FontError> { + static RE_SPACES: OnceLock = OnceLock::new(); + + let mut face = lib.new_face(&path, 0)?; + let num_faces = face.num_faces() as isize; + for face_index in 0..num_faces { + if face_index > 0 { + face = lib.new_face(&path, face_index)?; + } + let Some(family) = face.family_name() else { + return Err(FontError::MissingFamilyName(path)); + }; + let mut name = family.clone(); + let style = face.style_name(); + if let Some(style) = &style { + name.push(' '); + name.push_str(style); + } + // Make sure font name has no slashes or commas, replacing them with spaces and de-duplicating spaces + name = name.replace(['/', ','], " "); + name = RE_SPACES + .get_or_init(|| Regex::new(r"\s+").unwrap()) + .replace_all(name.as_str(), " ") + .to_string(); + + match fonts.entry(name) { + Entry::Occupied(v) => { + warn!( + "Ignoring duplicate font {} from {} because it was already configured from {}", + v.key(), + path.display(), + v.get().path.display() + ); + } + Entry::Vacant(v) => { + let key = v.key(); + let Some((codepoints, glyphs, ranges)) = get_available_codepoints(&mut face) else { + warn!( + "Ignoring font {key} from {} because it has no available glyphs", + path.display() + ); + continue; + }; + + let start = ranges.first().map(|(s, _)| *s).unwrap(); + let end = ranges.last().map(|(_, e)| *e).unwrap(); + info!( + "Configured font {key} with {glyphs} glyphs ({start:04X}-{end:04X}) from {}", + path.display() + ); + debug!( + "Available font ranges: {}", + ranges + .iter() + .map(|(s, e)| if s == e { + format!("{s:02X}") + } else { + format!("{s:02X}-{e:02X}") + }) + .collect::>() + .join(", "), + ); + + v.insert(FontSource { + path: path.clone(), + face_index, + codepoints, + catalog_entry: CatalogFontEntry { + family, + style, + glyphs, + start, + end, + }, + }); + } + } + } + + Ok(()) +} From 51c858c4c7dd57eda810cbc9deedbd1a8e8a4ca3 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sat, 28 Oct 2023 00:38:29 -0400 Subject: [PATCH 09/10] remove unwrap --- martin/src/fonts/mod.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/martin/src/fonts/mod.rs b/martin/src/fonts/mod.rs index 0eeb38731..f81540dcb 100644 --- a/martin/src/fonts/mod.rs +++ b/martin/src/fonts/mod.rs @@ -76,7 +76,7 @@ pub enum FontError { ErrorSerializingProtobuf(#[from] pbf_font_tools::protobuf::Error), } -type GetGlyphInfo = (BitSet, usize, Vec<(usize, usize)>); +type GetGlyphInfo = (BitSet, usize, Vec<(usize, usize)>, usize, usize); fn get_available_codepoints(face: &mut Face) -> Option { let mut codepoints = BitSet::with_capacity(MAX_UNICODE_CP); @@ -100,7 +100,9 @@ fn get_available_codepoints(face: &mut Face) -> Option { if count == 0 { None } else { - Some((codepoints, count, spans)) + let start = spans[0].0; + let end = spans[spans.len() - 1].1; + Some((codepoints, count, spans, start, end)) } } @@ -316,7 +318,9 @@ fn parse_font( } Entry::Vacant(v) => { let key = v.key(); - let Some((codepoints, glyphs, ranges)) = get_available_codepoints(&mut face) else { + let Some((codepoints, glyphs, ranges, start, end)) = + get_available_codepoints(&mut face) + else { warn!( "Ignoring font {key} from {} because it has no available glyphs", path.display() @@ -324,8 +328,6 @@ fn parse_font( continue; }; - let start = ranges.first().map(|(s, _)| *s).unwrap(); - let end = ranges.last().map(|(_, e)| *e).unwrap(); info!( "Configured font {key} with {glyphs} glyphs ({start:04X}-{end:04X}) from {}", path.display() From d79ee81f06dddf79c02ea0e69fa09f30c58962e7 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sat, 28 Oct 2023 00:48:43 -0400 Subject: [PATCH 10/10] test sprites --- tests/expected/auto/catalog_auto.json | 10 +++++++++- tests/expected/generated_config.yaml | 1 + tests/test.sh | 7 ++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/expected/auto/catalog_auto.json b/tests/expected/auto/catalog_auto.json index 3c8b6cb0a..fd502f77f 100644 --- a/tests/expected/auto/catalog_auto.json +++ b/tests/expected/auto/catalog_auto.json @@ -163,7 +163,15 @@ "description": "Major cities from Natural Earth data" } }, - "sprites": {}, + "sprites": { + "src1": { + "images": [ + "another_bicycle", + "bear", + "sub/circle" + ] + } + }, "fonts": { "Overpass Mono Light": { "family": "Overpass Mono", diff --git a/tests/expected/generated_config.yaml b/tests/expected/generated_config.yaml index 224057bea..435d52f41 100644 --- a/tests/expected/generated_config.yaml +++ b/tests/expected/generated_config.yaml @@ -212,6 +212,7 @@ mbtiles: world_cities_diff: tests/fixtures/mbtiles/world_cities_diff.mbtiles world_cities_modified: tests/fixtures/mbtiles/world_cities_modified.mbtiles zoomed_world_cities: tests/fixtures/mbtiles/zoomed_world_cities.mbtiles +sprites: tests/fixtures/sprites/src1 fonts: - tests/fixtures/fonts/overpass-mono-regular.ttf - tests/fixtures/fonts diff --git a/tests/test.sh b/tests/test.sh index 8fdfd1360..e620e19ee 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -97,7 +97,8 @@ test_png() fi } -test_font(){ +test_font() +{ FILENAME="$TEST_OUT_DIR/$1.pbf" URL="$MARTIN_URL/$2" @@ -162,7 +163,7 @@ echo "Test auto configured Martin" TEST_OUT_DIR="$(dirname "$0")/output/auto" mkdir -p "$TEST_OUT_DIR" -ARG=(--default-srid 900913 --auto-bounds calc --save-config "$(dirname "$0")/output/generated_config.yaml" tests/fixtures/mbtiles tests/fixtures/pmtiles --font tests/fixtures/fonts/overpass-mono-regular.ttf --font tests/fixtures/fonts) +ARG=(--default-srid 900913 --auto-bounds calc --save-config "$(dirname "$0")/output/generated_config.yaml" tests/fixtures/mbtiles tests/fixtures/pmtiles --sprite tests/fixtures/sprites/src1 --font tests/fixtures/fonts/overpass-mono-regular.ttf --font tests/fixtures/fonts) set -x $MARTIN_BIN "${ARG[@]}" 2>&1 | tee "${TMP_DIR}/test_log_1.txt" & PROCESS_ID=`jobs -p` @@ -279,7 +280,7 @@ test_png spr_cmp_2x sprite/src1,mysrc@2x.png test_font font_1 font/Overpass%20Mono%20Light/0-255 test_font font_2 font/Overpass%20Mono%20Regular/0-255 -test_font font_3 font/Overpass%20Mono%20Regular%2COverpass%20Mono%20Light/0-255 +test_font font_3 font/Overpass%20Mono%20Regular,Overpass%20Mono%20Light/0-255 kill_process $PROCESS_ID validate_log "${TMP_DIR}/test_log_2.txt"