COOLJAPAN
← All posts

OxiText 0.2.0 — The Pure-Rust Text Pipeline: shape, bidi, line-break, layout, rasterize

OxiText is the COOLJAPAN Pure-Rust text pipeline — shaping, UAX #9 bidi reordering, UAX #14 line-breaking, layout, and glyph rasterization. A NoFFI replacement for the HarfBuzz + FriBidi + ICU + FreeType C/C++ stack, pairing with OxiFont. Part of the sovereign Rust stack.

release oxitext pure-rust cooljapan noffi text typography shaping bidi layout

Drawing text is the last thing every Rust app reaches for C for — and it shouldn’t be.

Today we’re releasing OxiText 0.2.0 — the COOLJAPAN Pure-Rust text pipeline that takes a Unicode string all the way to pixels: shape → bidi-reorder → line-break → layout → rasterize.

No HarfBuzz. No FriBidi. No ICU C library. No FreeType. No FFI, no -sys crates, not even an opt-in native escape hatch. OxiText is composed entirely from mature Pure-Rust crates, so it builds as a single static binary, needs no system libraries and no C toolchain at build time, and stays headless-testable and WASM-friendly by design.

Why OxiText

Text rendering is deceptively hard, and for decades that difficulty has been outsourced to a stack of C/C++ libraries that every GUI, document, and graphics project ends up linking:

Each of those is a separate -sys crate, a separate build-time dependency, a separate surface for memory-safety bugs, and a separate reason your binary won’t cross-compile cleanly or run in the browser. OxiText replaces the whole chain. It’s the typography backbone for the COOLJAPAN ecosystem — and because it’s 100% Pure Rust, the same code path renders text on Linux, macOS, Windows, and WASM with no native libraries underneath.

What we built

OxiText is a 3-stage pipelineshape → layout → raster — split into focused workspace crates so you only pull in what you draw with:

1. Shape (oxitext-shape) Converts Unicode text into a ShapedRun of glyphs with advances, clusters, and GSUB/GPOS applied. The primary backend is swash; rustybuzz is opt-in for HarfBuzz test-suite parity. Shaping covers Arabic, Devanagari, Thai, CJK, and Latin, with script detection helpers (requires_arabic_shaping, requires_indic_shaping, requires_mark_positioning) driving automatic, script-based font fallback chains. It also supports OpenType variable-font axes and keeps a per-Pipeline LRU shape cache keyed on the font pointer plus the text.

2. Layout (oxitext-layout) Reorders bidirectional text per UAX #9 (full right-to-left and mixed-direction support), breaks runs into lines per UAX #14 (word-aware greedy wrapping with mandatory breaks and hyphenation), aligns them (Left, Right, Center, Justify), and computes PositionedGlyph screen coordinates. Vertical text follows UAX #50 — upright/rotated classification and tate-chu-yoko. When you want CLDR-accurate break opportunities, oxitext-icu plugs in as an opt-in source.

3. Raster (oxitext-raster) Renders each positioned glyph to a coverage bitmap via fontdue (primary), with ab_glyph and swash (TrueType hinting) as opt-in alternates. It does subpixel rendering (quarter-pixel positioning plus LCD 3-tap / 5-tap FIR filtering) and color glyphs: COLRv0, COLRv1 gradients, CBDT/CBLC bitmaps, and SVG via resvg.

Two more crates round out the pipeline:

Everything sits behind a thin facade crate, oxitext, whose Pipeline ties the layers together: measure, shape_and_layout, render_to_image, and composite_to_rgba.

Getting Started

Add the facade crate:

cargo add oxitext

Or in Cargo.toml:

[dependencies]
oxitext = "0.2.0"

Then measure a string and rasterize it to pixels:

use oxitext::{Pipeline, prelude::*};

let font_data = std::fs::read("my-font.ttf")?;
let pipeline = Pipeline::from_bytes(&font_data)?;

// Measure a string
let metrics = pipeline.measure("Hello, world!", &TextStyle::default())?;
println!("width={:.1} height={:.1}", metrics.width, metrics.height);

// Shape, lay out, and rasterize to RGBA pixels
let result = pipeline.render_to_image("Hello, OxiText!", &TextStyle::default())?;
println!("{} lines, {}x{} pixels", result.lines.len(), result.width, result.height);

That single Pipeline runs the whole shape → layout → raster chain for you — no HarfBuzz handle, no FreeType face, no ICU break iterator to wire up by hand.

Highlights

Tips

Part of the COOLJAPAN ecosystem

OxiText is part of NoFFI — the COOLJAPAN initiative to replace every C/C++/Fortran/-sys FFI dependency in the Rust ecosystem with a clean, memory-safe, 100% Pure-Rust implementation. Where the native world reaches for HarfBuzz, FriBidi, ICU, and FreeType, OxiText offers one sovereign, FFI-free pipeline.

It pairs closely with OxiFont, which handles font parsing, OpenType-table access, glyph outlines, and font discovery that feeds OxiText’s fallback chain. And it’s consumed across the ecosystem: oximedia (subtitles and captions), oxigdal-symbology (map labels), oxiphoton (text on images), oxigaf (PDF/EPUB reflow), OxiUI (every widget, via the oxitext-sdf GPU glyph atlas), and oxirag (document rendering).

Repository: https://github.com/cool-japan/oxitext

Star the repo if you want a world where rendering a line of text no longer means linking four C libraries. ✨

Pure Rust typography — sovereign, safe, and FFI-free.

KitaSan at COOLJAPAN OÜ June 23, 2026

↑ Back to all posts