9 releases (breaking)
new 0.7.0 | Mar 11, 2025 |
---|---|
0.6.0 | Mar 9, 2025 |
0.5.0 | Mar 8, 2025 |
0.4.0 | Mar 4, 2025 |
0.1.1 | Feb 27, 2025 |
#83 in Graphics APIs
736 downloads per month
185KB
3.5K
SLoC
VersaTiles Glyphs
VersaTiles Glyphs is a Rust tool and library for generating signed distance field (SDF) glyphs from TrueType fonts. It aims for high-precision rendering by working directly with font vector outlines—no additional C++ libraries or wrappers required.
See the results for Noto Sans (in several languages) here:
versatiles.org/versatiles-glyphs-rs
Why Another Glyph Tool?
There are numerous glyph rendering projects — e.g., font-maker, fontnik, node-fontnik, sdf_font_tools, sdf-glyph-foundry, and TinySDF. However, many have tradeoffs such as low rendering precision, unmaintained code, or "unfavourable architecture".
VersaTiles Glyphs tries to:
- Render SDF with maximum accuracy.
- Render directly from the raw vector data - without intermediate rasterisation like TinySDF.
- Render Bezier curves with more than enough line segments.
- Compensates for rounding errors by shifting the glyphs by sub-pixel distances in the right direction, since the PBF values for
left
,top
andadvance
must be integers. - Have no wrappers of external, unmaintained code.
- Have simple and straightforward build steps.
- Be actively maintained, any contributions are welcome.
Installation
1. Via Installation Script
Use a single shell command to download and install the latest precompiled binary:
curl -Ls "https://github.com/versatiles-org/versatiles-glyphs-rs/raw/refs/heads/main/scripts/install.sh" | sh
2. Via Cargo
Install from crates.io using the Rust package manager:
cargo install versatiles_glyphs
3. From Source
To build the latest (potentially prereleased) version:
git clone https://github.com/versatiles-org/versatiles-glyphs-rs.git
cd versatiles-glyphs-rs
cargo build --release
The compiled binary will be located at target/release/versatiles_glyphs
.
Usage
versatiles_glyphs
provides three main subcommands: recurse
, merge
, debug
.
Subcommand: recurse
Recursively scans fonts from one or more directories or files, converting them into glyph sets:
versatiles_glyphs recurse ./font/
If a directory contains a fonts.json
(like this example), it uses the files from that JSON instead of a raw file scan.
Output follows the VersaTiles frontend specification:
📂 glyphs/ ├── 📂 {font_id}/ │ └── 📄 {start}-{end}.pbf ├── 📄 font_families.json └── 📄 index.json
Specify an output directory with -o
or --output-directory
:
versatiles_glyphs recurse ./font/ -o ../web/glyphs
Generate a TAR archive instead of directories, with -t
or --tar
:
versatiles_glyphs recurse ./font/ --tar | gzip -9 > glyphs.tar.gz
Subcommand: merge
Merges one or more font files into a single directory of glyphs:
versatiles_glyphs merge ./font/
It supports the same --output-directory
and --tar
options.
Subcommand: debug
Loads an existing directory of *.pbf
files and returns an overview of all glyphs as CSV or TSV:
versatiles_glyphs debug glyphs/noto_sans_regular
The returned columns are:
codepoint,width,height,left,top,advance,bitmap_size
Development Notes
Documentation
You can find the latest documentation at docs.rs/versatiles_glyphs.
Quick Overview
- Font files are added to a
FontManager
, which scans their metadata and parses the font name to guess the font family, style, weight, width … - Font files of the same font (e.g. when a font is split into multiple files, each for a different language) are combined in a
FontWrapper
. - The
FontManager
can render all glyphs and write them to one of twoWriter
s:FileWriter
orTarWriter
- Glyphs are rendered serially per
GlyphBlock
. Each block contains a maximum of 256 glyphs. The blocks are rendered in parallel. - A single glyph is rendered with
render_glyph
fromRenderer::new_precise()
.
Font Metrics & Precision
Since no official SDF-glyph spec for all metrics could be found, most references come from:
Testing Online
Every new release is showcased at versatiles.org/versatiles-glyphs-rs. If you’d like to expand or alter characters tested, edit these lines.
Local Web Testing
- Run the build script:
./pages/build.sh
- Serve the
./pages/web/
directory (e.g., usingnpx http-server -sc0
,python3 -m http.server
orcargo install basic-http-server
) - Visit it in your browser to check changes.
Contributing
Issues and pull requests are always welcome. Join the community by reporting bugs, improving documentation, or adding new features!
License
This project is distributed under the Unlicense. Essentially, you can do whatever you want with the code—no attribution required.
Dependencies
~7–14MB
~173K SLoC