---
title: "onefont"
url: https://recursiveai.org/onefont/
description: "A font and text-shaping library for .NET, with no dependency beyond .NET itself. TrueType and OpenType fonts, OpenType shaping for complex scripts, Unicode bidi, line breaking and graphemes, and font fallback. MIT or Apache-2.0."
---

# onefont

Fonts and text shaping for .NET, in C# with no dependency beyond .NET itself. Load a font, shape a run of text, and get glyphs, advances, offsets and clusters back.

```sh
dotnet add package RecursiveAI.OneFont
```

- [Getting started](https://recursiveai.org/onefont/docs/getting-started/)
- [Docs](https://recursiveai.org/onefont/docs/)
- [Cookbook](https://recursiveai.org/onefont/cookbook/)
- [Articles](https://recursiveai.org/onefont/articles/)
- [GitHub](https://github.com/recursive-ai-oss/onefont-csharp)
- [NuGet](https://www.nuget.org/packages/RecursiveAI.OneFont)

## A quick look

Shape Arabic, Indic or Latin text with the font’s own OpenType tables. A fallback chain shapes each cluster with the first face that has its character.

[The shaping rules](https://recursiveai.org/onefont/docs/shaping/)

*Program.cs · C#*

```
using OneFont;
 
byte[] font = File.ReadAllBytes("arabic.ttf");
FontFace face = FontFace.Load(font);
 
// Glyphs, advances and offsets, by cluster.
foreach (ShapedCluster c in TextShaping.ShapeRun(text, face, rightToLeft: true))
    foreach (ShapedGlyph g in c.Glyphs)
        GlyphOutline o = face.GetOutline(g.GlyphId);
 
// Where a line may end.
var breaks = TextSegmentation.GetLineBreakOpportunities(text);
```

### Fonts

TrueType, OpenType with CFF outlines and TrueType Collections. Every read is bounds-checked, and glyph outlines come out as move, line, quadratic and cubic segments.

### Shaping

OpenType GSUB and GPOS with every lookup type and flag, and shapers for Arabic, the Indic scripts, Khmer, Myanmar, Tibetan and the other Universal Shaping Engine scripts, and Thai and Lao.

### Unicode

Bidi levels and visual order (UAX #9), line break opportunities (UAX #14) and grapheme boundaries (UAX #29), on Unicode 17.

### Safe on fonts you didn’t make

Safe code only. Work, depth and growth budgets keep hostile fonts cheap, and a fuzz target runs them through the whole public surface.

## The package

- **Package**: `RecursiveAI.OneFont`, version 1.3.0. No runtime dependencies.
- **Checked**: Compared with SixLabors.Fonts on 1,042 cases in Latin, Greek, Cyrillic, Arabic, Hebrew and 17 complex scripts, with every difference listed with its reason. Unicode 17’s official line break, grapheme and bidi test files pass in full.
- **Its job**: onefont shapes; laying out lines and painting glyphs is up to you. No WOFF, color glyphs, hinting or vertical layout.
- **Used by**: [onepdf](https://recursiveai.org/onepdf/)’s layout package shapes its text with onefont.
- **.NET**: .NET 10. NativeAOT and trimming are supported. MIT or Apache-2.0.
- **How it was made**: AI agents designed, wrote and tested it on [Alera](https://recursiveai.org/alera/); Kurtis decided what to build.

## Go further

- [GitHub](https://github.com/recursive-ai-oss/onefont-csharp)
- [NuGet](https://www.nuget.org/packages/RecursiveAI.OneFont)
- [Getting started](https://recursiveai.org/onefont/docs/getting-started/)
- [Cookbook](https://recursiveai.org/onefont/cookbook/)
- [Shaping rules and limits](https://recursiveai.org/onefont/docs/shaping/)
- [Changelog](https://recursiveai.org/onefont/docs/changelog/)
