Skip to content

Commit

Permalink
Implement dynamic font support /font/<name>/<start>-<end>
Browse files Browse the repository at this point in the history
This will NOT compile until stadiamaps/sdf_font_tools#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
  • Loading branch information
nyurik committed Jul 9, 2023
1 parent ed7d33a commit 35830cb
Show file tree
Hide file tree
Showing 11 changed files with 680 additions and 4 deletions.
178 changes: 178 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,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"] }
Expand All @@ -31,6 +32,7 @@ martin-mbtiles = { path = "./martin-mbtiles", version = "0.4.0", default-feature
martin-tile-utils = { path = "./martin-tile-utils", version = "0.1.0" }
num_cpus = "1"
openssl = "0.10"
pbf_font_tools = { version = "2.4.0", features = ["freetype"], path = "../sdf_font_tools/pbf_font_tools" }
pmtiles = { version = "0.2.2", features = ["mmap-async-tokio", "tilejson"] }
postgis = "0.9"
postgres = { version = "0.19", features = ["with-time-0_3", "with-uuid-1", "with-serde_json-1"] }
Expand Down
3 changes: 2 additions & 1 deletion martin-mbtiles/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::path::PathBuf;

use crate::mbtiles::MbtType;
use martin_tile_utils::TileInfo;

use crate::mbtiles::MbtType;

#[derive(thiserror::Error, Debug)]
pub enum MbtError {
#[error("SQL Error {0}")]
Expand Down
2 changes: 2 additions & 0 deletions martin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ actix-rt.workspace = true
actix-web.workspace = true
actix.workspace = true
async-trait.workspace = true
bit-set.workspace = true
brotli.workspace = true
clap.workspace = true
deadpool-postgres.workspace = true
Expand All @@ -45,6 +46,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
Expand Down
9 changes: 8 additions & 1 deletion martin/src/args/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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<PathBuf>,
/// Export a directory with font files as a font source. Can be specified multiple times.
#[arg(short, long)]
pub font: Vec<PathBuf>,
}

impl Args {
Expand Down Expand Up @@ -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()
}
}
Expand Down
63 changes: 63 additions & 0 deletions martin/src/bin/tmp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::path::PathBuf;

use log::error;
use pbf_font_tools::freetype::Library;

fn main() {
let _ = env_logger::builder().is_test(true).try_init();
error!("abc {}", foo());
let lib = Library::init().expect("Unable to initialize FreeType");
visit_dirs(&lib, PathBuf::from("/usr/share/fonts/opentype/noto"));
visit_dirs(&lib, PathBuf::from("/usr/share/fonts"));
}

fn foo() -> &'static str {
println!("foo");
"bar"
}

fn visit_dirs(lib: &Library, path: PathBuf) {
for dir_entry in path
.read_dir()
.expect("Unable to open font directory")
.flatten()
{
let path = dir_entry.path();
if path.is_dir() {
visit_dirs(lib, path);
continue;
}

if !matches!(path.extension(), Some(e) if (["otf", "ttf", "ttc"].contains(&e.to_str().unwrap())))
{
continue;
}

let mut face = lib.new_face(&path, 0).expect("Unable to load face");
let num_faces = face.num_faces() as usize;
print!("{}: {} faces: ", path.display(), num_faces);
for i in 0..num_faces {
if i > 0 {
face = lib
.new_face(&path, i as isize)
.expect("Unable to load face");
}
// print!("\n #{}: {:?} ", i, face.raw());
print!(
" #{}={}-{} face_index={}, num_glyphs={}",
i,
face.family_name()
.as_deref()
// .map(|v| v.as_str())
.unwrap_or("<family>"),
face.style_name()
.as_deref()
// .map(|v| v.as_str())
.unwrap_or("<style>"),
face.raw().face_index,
face.num_glyphs(),
);
}
println!();
}
}
Loading

0 comments on commit 35830cb

Please sign in to comment.