Skip to main content

Crate klyff_msdf

Crate klyff_msdf 

Source
Expand description

§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.

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].

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).

Re-exports§

pub use skrifa;

Structs§

Aabb
A bounding box.
AtlasRegionSize
Region of a texture atlas.
GlyphOutline
Parsed outline of a glyph.
MsdfGenerator
MSDF/MTSDF generator.
SegmentCollector
State for processing glyph’s outline segment.
SkrifaOutlineProvider

Enums§

MsdfPixelFormat
ReadGlyphOutlineError

Traits§

OutlineProvider
Represents font data sources.

Functions§

median
Returns the most common value out of the three. In a MSDF, the median of the 3 channels at each pixel yields the pseudo distance field.