klyff_msdf 0.1.1

MSDF generation library with optional GPU acceleration.
Documentation
klyff_msdf-0.1.1 has been yanked.

klyff_msdf

This is a reimplementation of msdfgen by Chlumsky in pure rust.

By default generation is done on CPU, but for wgpu user it's recommended that you use the gpu generator (gated behind feature flag wgpu) for much faster generation and avoiding texture upload.

Create a [MsdfGenerator] and store it throughout your application's lifetime. Use it to process glyph and obtain a [GlyphOutline]. For incompatible glyphs (colored / bitmap), an [ReadGlyphOutlineError::ShouldRasterize] is returned, so you can handle separately in your application.

To generate MSDF / MTSDF on the CPU, use [GlyphOutline::generate_msdf] or [GlyphOutline::generate_mtsdf].

# #[cfg(feature = "skrifa")]
# {
use klyff_msdf::{AtlasRegionSize, MsdfGenerator, MsdfPixelFormat, SkrifaOutlineProvider};
use klyff_msdf::skrifa::{FontRef, GlyphId};

fn gen_cpu(font: FontRef<'_>, glyph_id: 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 is done through [MtsdfGpuWriter].

# #[cfg(all(feature = "skrifa", feature = "wgpu"))]
# {
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()));
}
# }

Non-skrifa font reader

This crate provides interop with [skrifa] by default (feature flag skrifa). You can implement the [OutlineProvider] trait yourself to use other font reader (or even work with other formats like svg).