Pretext 0.1.0

dotnet add package Pretext --version 0.1.0
                    
NuGet\Install-Package Pretext -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Pretext" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Pretext" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Pretext" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Pretext --version 0.1.0
                    
#r "nuget: Pretext, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Pretext@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Pretext&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Pretext&version=0.1.0
                    
Install as a Cake Tool

Pretext

CI NuGet NuGet Downloads Docs Targets SkiaSharp 3.119.1 License: MIT

Universal text preparation and line layout with grapheme-aware wrapping, locale-aware segmentation, bidi support, and pluggable text-measurement backends.

The core Pretext package targets netstandard2.0, net461, net6.0, net8.0, and net10.0. The Pretext.Uno companion package targets net10.0-desktop, and the native macOS sample host targets net10.0-macos.

PretextSharp is a .NET/C# port of the original pretext project by Cheng Lou.

Documentation site: wieslawsoltes.github.io/PretextSharp

Key documentation:

NuGet Packages

Package Name NuGet Downloads Description
Pretext NuGet NuGet Downloads Backend-agnostic text preparation and line layout engine.
Pretext.Contracts NuGet NuGet Downloads Contracts for implementing custom text-measurement backends.
Pretext.Layout NuGet NuGet Downloads Platform-neutral wrap and obstacle-layout helpers built on top of Pretext.
Pretext.DirectWrite NuGet NuGet Downloads First-party DirectWrite backend for Windows hosts.
Pretext.FreeType NuGet NuGet Downloads First-party FreeType + Fontconfig backend for Linux hosts.
Pretext.CoreText NuGet NuGet Downloads First-party CoreText backend for macOS hosts.
Pretext.SkiaSharp NuGet NuGet Downloads First-party SkiaSharp backend for Pretext.
Pretext.Uno NuGet NuGet Downloads Uno-specific controls and render scheduling helpers built on top of Pretext.

Features

  • Prepare text once and reuse the result across repeated layout passes with Prepare and PrepareWithSegments.
  • Compute fast aggregate metrics with Layout, or materialize full line data with LayoutWithLines.
  • Stream line geometry incrementally with LayoutNextLine, LayoutNextLineRange, and WalkLineRanges for custom layout engines.
  • Re-materialize text lazily with MaterializeLineRange after cheap geometry-only probing.
  • Measure widest-line geometry without allocating text via MeasureLineStats and MeasureNaturalWidth.
  • Handle ordinary spaces, preserved spaces, tabs, hard breaks, non-breaking spaces, zero-width breaks, and soft hyphens.
  • Support WordBreakMode.KeepAll for CJK-focused no-space wrapping behavior.
  • Build rich inline flows with PrepareRichInline, WalkRichInlineLineRanges, and MaterializeRichInlineLineRange.
  • Support multilingual text with locale-aware segmentation on desktop targets and bidi-aware segment levels.
  • Keep the core library graphics-backend agnostic through Pretext.Contracts.
  • Ship first-party native backends for Windows (Pretext.DirectWrite), Linux (Pretext.FreeType), and macOS (Pretext.CoreText), plus the portable Pretext.SkiaSharp fallback backend.
  • Ship with a published Pretext.Layout helper library for platform-neutral wrap and obstacle-layout workflows.
  • Ship with a published Pretext.Uno companion library for reusable Uno host controls and render scheduling helpers.
  • Ship with deterministic parity tests plus shared, Uno, and native macOS sample hosts that demonstrate bubbles, masonry, editorial, justification, rich-inline, and virtualized markdown chat layouts.

Core API

API Purpose
Prepare Prepare text for repeated layout when you only need aggregate metrics.
PrepareWithSegments Prepare text and expose segments, widths, break metadata, and segment levels.
Layout Return line count and total height for a given width and line height.
LayoutWithLines Return materialized line text and line widths.
LayoutNextLine Stream the next line from a given cursor for custom layout flows.
LayoutNextLineRange Stream geometry-only line ranges without materializing text.
MaterializeLineRange Turn a LayoutLineRange back into a materialized LayoutLine.
WalkLineRanges Iterate line geometry without allocating full line text.
MeasureLineStats Return line count plus widest line width for a prepared block.
MeasureNaturalWidth Return the widest unwrapped line width for prepared text.
PrepareRichInline Prepare multi-item inline flow with collapsed boundary whitespace and atomic items.
WalkRichInlineLineRanges Stream rich-inline line ranges without materializing fragment text.
MaterializeRichInlineLineRange Materialize one streamed rich-inline line when you actually need fragment text.
MeasureRichInlineStats Measure rich-inline line count and max line width.
ProfilePrepare Measure preparation cost for profiling and diagnostics.
SetLocale Override locale-sensitive segmentation behavior when needed.
ClearCache Reset cached font state and prepared segment text caches.

API Selection

Need Start with
Line count and total height only Prepare + Layout
Actual line text and widths PrepareWithSegments + LayoutWithLines
One line at a time in a custom loop PrepareWithSegments + LayoutNextLine
Geometry only, fewer allocations PrepareWithSegments + WalkLineRanges
Rich inline fragments with atomic chips or badges PrepareRichInline + WalkRichInlineLineRanges
Preparation cost diagnostics ProfilePrepare

Quick Start

Install the engine plus one or more backends:

dotnet add package Pretext
dotnet add package Pretext.SkiaSharp

Optional host-native backends:

dotnet add package Pretext.DirectWrite   # Windows
dotnet add package Pretext.FreeType      # Linux
dotnet add package Pretext.CoreText      # macOS

Supported target frameworks for the core package:

  • netstandard2.0
  • net461
  • net6.0
  • net8.0
  • net10.0

Then prepare and lay out text:

using Pretext;

const string text = "Hello soft\u00ADwrapped world";
const string font = "16px Inter";
const double lineHeight = 20;

var prepared = PretextLayout.PrepareWithSegments(text, font);
var metrics = PretextLayout.Layout(prepared, maxWidth: 160, lineHeight);
var lines = PretextLayout.LayoutWithLines(prepared, maxWidth: 160, lineHeight);

Console.WriteLine(metrics.LineCount);
Console.WriteLine(metrics.Height);

foreach (var line in lines.Lines)
{
    Console.WriteLine($"{line.Text} ({line.Width})");
}

If the prepared text is empty after normalization, Layout returns new LayoutResult(0, 0). If a container in your UI must still reserve one visual row, clamp with Math.Max(1, metrics.LineCount) in the caller instead of expecting Pretext to synthesize a blank line.

The core package exposes the Pretext namespace and is not tied to Uno. Add one or more backend packages in non-Uno hosts so measurement can be provided automatically. When multiple first-party backends are referenced, Pretext prefers the host-native backend on its matching OS and falls back to Pretext.SkiaSharp otherwise.

The font argument is a CSS-like subset such as 16px Inter, italic 16px Georgia, or 700 18px "IBM Plex Sans". Line height is supplied separately to layout calls.

Use WhiteSpaceMode.PreWrap when your layout needs preserved spaces, tabs, or hard breaks:

var prepared = PretextLayout.PrepareWithSegments(
    "foo\tbar\nbaz",
    "16px Inter",
    new PrepareOptions(WhiteSpaceMode.PreWrap));

Use WordBreakMode.KeepAll when CJK-heavy text should avoid ordinary intra-run breaks:

var prepared = PretextLayout.PrepareWithSegments(
    "日本語foo-bar",
    "16px Inter",
    new PrepareOptions(WordBreak: WordBreakMode.KeepAll));

Use the rich-inline helper when paragraph text and atomic inline boxes must share one flow:

var flow = PretextLayout.PrepareRichInline(
[
    new RichInlineItem("Ship ", "16px Inter"),
    new RichInlineItem("@maya", "700 12px Inter", RichInlineBreakMode.Never, extraWidth: 18),
    new RichInlineItem("'s note wraps cleanly.", "16px Inter"),
]);

PretextLayout.WalkRichInlineLineRanges(flow, 180, line =>
{
    var materialized = PretextLayout.MaterializeRichInlineLineRange(flow, line);
    Console.WriteLine(string.Join("", materialized.Fragments.Select(f => f.Text)));
});

Companion Packages

Install the platform-neutral layout-helper package when you want reusable wrap-metric and obstacle-flow helpers outside Uno as well:

dotnet add package Pretext.Layout

It exposes:

  • Pretext.Layout.PreparedTextMetrics
  • Pretext.Layout.ColumnFlowLayout
  • Pretext.Layout.ObstacleLayoutHelper
  • Pretext.Layout.WrapMetrics
  • Pretext.Layout.PositionedLine

Uno Companion

Install the Uno companion package when you want the reusable Uno-specific helpers on top of the core engine:

dotnet add package Pretext.Uno

It brings Pretext, Pretext.Layout, Pretext.Contracts, Pretext.SkiaSharp, Pretext.DirectWrite, Pretext.FreeType, and Pretext.CoreText transitively, then lets backend discovery choose the best supported backend for the current OS. It exposes:

  • Pretext.PretextLayout
  • Pretext.Layout.PreparedTextMetrics
  • Pretext.Layout.ColumnFlowLayout
  • Pretext.Layout.ObstacleLayoutHelper
  • Pretext.Uno.Controls.StretchScrollHost
  • Pretext.Uno.Controls.UiRenderScheduler

Sample Apps

The sample hosts share reusable data, prepared-model logic, and sample assets through samples/PretextSamples.Shared.

  • samples/PretextSamples.Uno uses Uno Platform and Pretext.Uno

  • samples/PretextSamples.MacOS uses native AppKit on net10.0-macos and binds Pretext explicitly to Pretext.CoreText

  • Overview

  • Accordion

  • Bubbles

  • Masonry

  • Rich Text

  • Markdown Chat

  • Dynamic Layout

  • Editorial Engine

  • Justification Comparison

  • Variable ASCII

Run the Uno host with:

dotnet run --project samples/PretextSamples.Uno/PretextSamples.Uno.csproj -f net10.0-desktop

Run the native macOS host with:

dotnet run --project samples/PretextSamples.MacOS/PretextSamples.MacOS.csproj -f net10.0-macos

For the current documentation map covering package selection, backend discovery, custom backends, and sample hosts, start in:

Building

Prerequisites

  • .NET 10 SDK for building this repository
  • Uno.Sdk 6.5.x for the Uno sample host only

Build, test, and pack

dotnet build PretextSamples.slnx
dotnet build samples/PretextSamples.MacOS/PretextSamples.MacOS.csproj
dotnet test tests/Pretext.Uno.Tests/Pretext.Uno.Tests.csproj
bash ./pack-packages.sh

Docs and CI

The repository includes:

  • ci.yml for multi-platform build, test, docs validation, and preview package generation
  • docs.yml for GitHub Pages deployment
  • pack-packages.sh for the shared package restore/pack list used by CI and releases
  • release.yml for tag-driven packing, optional NuGet publication, and GitHub release creation
  • a Lunet docs site in site/

The docs cover:

  • installation and namespace/package selection
  • font strings, measurement, and prepared-text lifecycle
  • whitespace and break behavior, locale-aware segmentation, and bidi
  • practical Uno, native host, and generic SkiaSharp integration patterns
  • full reference coverage for the public core API and companion helper packages

Project Structure

src/
  Pretext.Contracts/
  Pretext/
  Pretext.Layout/
  Pretext.DirectWrite/
  Pretext.FreeType/
  Pretext.CoreText/
  Pretext.SkiaSharp/
  Pretext.Uno/
tests/
  Pretext.Uno.Tests/
samples/
  PretextSamples.Uno/
  PretextSamples.Shared/
  PretextSamples.MacOS/
site/

Attribution

The core Pretext implementation in this repository is ported from the original pretext project by Cheng Lou. This repository adapts that work to .NET, native and SkiaSharp backends, packaging, tests, samples, and companion Uno helpers.

License

MIT. See LICENSE.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Pretext:

Package Downloads
Pretext.Uno

Uno-specific controls and render scheduling helpers for Pretext text rendering scenarios.

Pretext.Layout

Platform-neutral wrap and obstacle-layout helpers built on top of Pretext.

ProText

High-performance Avalonia 12 text controls powered by PretextSharp.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 379 5/1/2026
0.1.0-preview.5 170 4/28/2026
0.1.0-preview.4 49 4/20/2026
0.1.0-preview.3 58 4/15/2026
0.1.0-preview.2 53 4/14/2026
0.1.0-preview.1 59 4/12/2026

Split text measurement behind backend contracts and added pluggable graphics integrations.