Skip to content

Cactusinhand/pretext-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Pretext

Pretext measures and lays out text by separating the process into two phases. First, it uses Canvas to measure text dimensions (prepare). Then, it computes the final positions using pure arithmetic (layout). Since the layout phase doesn't interact with the DOM, it avoids reflows entirely and typically takes about 0.0002ms to run.

You can use it to predict heights for virtualized lists, shrinkwrap chat bubbles, or route text around obstacles before rendering anything to the screen.

Installation

npm install @chenglou/pretext

Quick Start

If you only need to know the height or line count (e.g., for virtualized lists), use the basic prepare and layout functions.

import { prepare, layout } from '@chenglou/pretext';

// Measure once after fonts are ready
await document.fonts.ready;
const prepared = prepare("Hello World, Pretext is fast!", "16px Inter");

// Calculate layout on resize (no DOM interaction)
const { height, lineCount } = layout(prepared, 300, 24); 
// width: 300px, lineHeight: 24px

console.log(`Height: ${height}px, Lines: ${lineCount}`);

Layout Patterns

Depending on your target output, use different API paths:

Scenario API Path
Virtual scroll or height prediction prepare() + layout()
Canvas or SVG rendering prepareWithSegments() + layoutWithLines()
Finding the tightest width prepareWithSegments() + walkLineRanges()
Flowing text across columns prepareWithSegments() + layoutNextLine()

Multi-column Flow

You can flow text across multiple regions using cursor handoff.

import { prepareWithSegments, layoutNextLine } from '@chenglou/pretext';

const prepared = prepareWithSegments(longText, "18px Georgia");
let cursor = { segmentIndex: 0, graphemeIndex: 0 };

// First column
const column1 = layoutNextLine(prepared, cursor, 300);
cursor = column1.end;

// Second column
const column2 = layoutNextLine(prepared, cursor, 300);

Rules

Pretext relies on a few constraints to work correctly:

  1. prepare() must run after document.fonts.ready. If fonts aren't loaded, the segment metrics will be inaccurate and the resulting heights will be wrong.
  2. The layout() function is strictly stateless. Do not read the DOM or call Canvas APIs inside your resize handler before calling layout().
  3. Pass lineHeight as a raw number (like 24), not a CSS string.
  4. Avoid using system-ui. Provide explicit font names so sizes are consistent.

Development

bun start              # Dev server
bun run check          # Typecheck & lint
bun test               # Invariant tests
bun run accuracy-check # Browser accuracy sweep

License

MIT © Chenglou

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages