Klyff MSDF generation
klyff_msdf is a MSDF generation library. It supports klyff, a text rendering library designed for games with high customization needs.
MSDF (Multi-channel Signed Distance Field) is a technique for text rendering, originally made by Chlumsky at msdfgen. It supports infinite scaling while still retaining sharp corners (as opposed to SDF).
MSDF generation is reimplemented in 100% pure Rust, instead of binding to the original msdfgen C++ library.
See also: klyff, a text rendering library based on this crate.
Features
- GPU generation - Glyphs can be generated on the gpu using wgpu, gated behind [
wgpu] feature flag. - Trait for other font reader - Outline providers are abstracted behind a trait, allowing you to use your own font reader or any other file format. Interops with skrifa by default.
- Pure rust - No C/C++ dependencies.
Please note that GPU generation is currently recommended, as the CPU path is quite slow (O(n) lookup of nearest segment per pixel).
Quick Start
CPU generation:
//! use klyff_msdf::{AtlasRegionSize, MsdfGenerator, MsdfPixelFormat, SkrifaOutlineProvider};
//! use klyff_msdf::skrifa::{FontRef, GlyphId};
//!
//! let mut generator = MsdfGenerator::new();
//! let mut outline = generator
//! .read_glyph(&SkrifaOutlineProvider::new(font, glyph_id))
//! .expect("glyph is msdf-compatible");
//!
//! let size = AtlasRegionSize {
//! inner_width: 32,
//! inner_height: 32,
//! padding_x: 4,
//! padding_y: 4,
//! };
//!
//! // RGB MSDF, packed bytes suitable for writing to an image.
//! let _msdf: &[u8] = outline.generate_msdf(size, MsdfPixelFormat::PackedRgb8);
//! // Or the full MTSDF (RGBA), e.g. for uploading to a GPU texture.
//! let _mtsdf: &[u8] = outline.generate_mtsdf(size);
GPU generation:
//! use klyff_msdf::{GpuAtlasRegion, MsdfGenerator, MtsdfGpuWriter, SkrifaOutlineProvider};
//! use klyff_msdf::skrifa::{FontRef, GlyphId};
//!
//! fn gen_gpu(
//! device: &wgpu::Device,
//! queue: &wgpu::Queue,
//! atlas: &wgpu::Texture,
//! writer: &mut MtsdfGpuWriter,
//! generator: &mut MsdfGenerator,
//! font: FontRef<'_>,
//! glyph_ids: &[GlyphId],
//! ) {
//! // Queue multiple glyphs
//! for glyph_id in glyph_ids {
//! let outline = generator
//! .read_glyph(&SkrifaOutlineProvider::new(font.clone(), *glyph_id))
//! .expect("glyph is msdf-compatible");
//!
//! let region = GpuAtlasRegion {
//! layer: 0,
//! min_x: 0,
//! min_y: 0,
//! width: 40,
//! height: 40,
//! padding_x: 4,
//! padding_y: 4,
//! };
//! writer.add_glyph(outline, region);
//! }
//!
//! // Then flush them all in a single set of render passes:
//! let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
//! writer.write_glyphs(device, queue, &mut encoder, atlas);
//! queue.submit(std::iter::once(encoder.finish()));
//! }
License
All source code is licensed under the MIT License.