suzuri

Crates.iosuzuri
lib.rssuzuri
version0.2.1
created_at2025-12-11 05:17:38.911743+00
updated_at2025-12-31 22:32:56.769896+00
descriptionText rendering library
homepage
repositoryhttps://github.com/helgev-traP/Suzuri
max_upload_size
id1979187
size258,869
Helgev (helgev-traP)

documentation

https://docs.rs/Suzuri

README

Suzuri

Suzuri is a text rendering library written in Rust. Use this crate to layout and render text with consistent results.

This crate prioritizes consistency and reproducibility within a two-pass layout data flow. It ensures that layout results remain stable even when constraints change, provided there is enough whitespace (e.g., preventing unstable line breaks when layout width is reduced).

Features

  • Flexible Backend: Supports both CPU-based rendering and GPU acceleration (via wgpu).
  • Robust Layout: Handles text wrapping, alignment, and multi-font shaping with predictable results.
  • Font Management: Easy loading of system fonts and custom font files via fontdb.
  • Thread Safety: Designed with internal locking for safe concurrent use.

Overview

The library is composed of the following main functionalities:

  • [font_storage::FontStorage]: Manages font loading and caching. It handles system fonts and custom font data.
  • Text Representation: Defined by [text::TextData] and [text::TextElement]. These structures hold the content and styling information (font, size, color, etc.) for text.
  • [text::TextLayout]: The engine that calculates glyph positions, handling wrapping, alignment, and other layout properties based on the configuration.
  • Renderers:
    • [renderer::CpuRenderer]: Renders text into a pixel buffer on the CPU.
    • [renderer::GpuRenderer]: A graphics-API-independent text renderer. It manages texture atlases and glyph quads, allowing implementation on any graphics backend (e.g., OpenGL, Vulkan, DirectX).
    • [renderer::WgpuRenderer]: A concrete implementation built on top of GpuRenderer using the wgpu graphics API.

The [FontSystem] acts as the central hub, coordinating these components to provide a unified API.

How to Read the Documentation

To get started with Suzuri, we recommend reading the documentation in the following order:

  1. [FontSystem]: The entry point of the library. Learn how to initialize the system.
  2. [fontdb]: Understanding fontdb is essential for querying fonts (by family, weight, style) to obtain the Font ID needed for text elements.
  3. [text::TextData] & [text::TextElement]: Learn how to create text content with styles and custom data.
  4. [text::TextLayout]: Understand how the text is measured and arranged.
  5. Renderers: Finally, explore the specific renderer you intend to use (e.g., in [renderer] module) for integration details.

Installation

Add the following to your Cargo.toml:

[dependencies]
suzuri = "0.2.0"

To use wgpu features, enable the wgpu feature:

[dependencies]
suzuri = { version = "0.2.0", features = ["wgpu"] }

Usage

1. Initialize FontSystem

[FontSystem] is the entry point for Suzuri. It handles font loading, layout, and renderer management.

use suzuri::{FontSystem, fontdb::{self, Family, Query}};

let font_system = FontSystem::new();
font_system.load_system_fonts();

// Query a font
let font_id = font_system
    .query(&Query {
        families: &[Family::Name("Arial"), Family::SansSerif],
        weight: fontdb::Weight::NORMAL,
        stretch: fontdb::Stretch::Normal,
        style: fontdb::Style::Normal,
    })
    .map(|(id, _)| id);
    // .expect("Font not found"); // Handle error appropriately

2. Prepare Text Data

Define the content and style of the text you want to render.

# use suzuri::{FontSystem, fontdb};
# use suzuri::text::{TextData, TextElement};
# let font_system = FontSystem::new();
# let font_id = None; 
#
// Color type is user-definable
#[derive(Clone, Copy, Debug)]
struct MyColor { r: f32, g: f32, b: f32, a: f32 }

// For wgpu rendering, convert to [f32; 4] (Premultiplied Alpha)
impl From<MyColor> for [f32; 4] {
    fn from(c: MyColor) -> Self {
        [c.r * c.a, c.g * c.a, c.b * c.a, c.a]
    }
}

let mut data = TextData::new();
if let Some(id) = font_id {
    data.append(TextElement {
        content: "Hello, Suzuri!".to_string(),
        font_id: id,
        font_size: 32.0,
        user_data: MyColor { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
    });
}

3. Layout the Text

Configure layout settings with [text::TextLayoutConfig] and calculate the placement.

# use suzuri::{FontSystem, text::TextData};
use suzuri::text::{TextLayoutConfig, HorizontalAlign, VerticalAlign, WrapStyle};
# let font_system = FontSystem::new();
# let data = TextData::<u8>::new();

let config = TextLayoutConfig {
    max_width: Some(800.0),
    max_height: None,
    horizontal_align: HorizontalAlign::Left,
    vertical_align: VerticalAlign::Top,
    line_height_scale: 1.2,
    wrap_style: WrapStyle::WordWrap,
    ..Default::default()
};

let layout = font_system.layout_text(&data, &config);

4. Rendering

CPU Rendering

For detailed usage, please refer to the [renderer::CpuRenderer] documentation.

GPU Rendering (wgpu)

To render using wgpu, initialize the renderer with the device and queue, then draw within a render pass.

For detailed usage, please refer to the [renderer::WgpuRenderer] documentation.

License

MIT OR Apache-2.0

Commit count: 0

cargo fmt