Atelier

AtelierText

Unicode to positioned glyphs, vector outlines, and SVG.

composer require atelier/text

Text placed in an SVG depends on the fonts of whoever opens it. This package removes that dependency: it reads a font file, looks each codepoint up in its cmap, positions the glyphs, and returns their outlines as path data. What ships is geometry, and geometry renders the same everywhere.

560.09
Outlines read from a font file and set on a baseline. Each tick is where one more glyph ends, and the number is the width of the run. No font is installed where this renders.

Features

  • Outlines, not text elements
    Path data from the font's own contours, so nothing depends on what is installed where the drawing is opened.
  • One group per glyph
    Each carries a data-char attribute, and idPrefix makes the ids deterministic, which is what a stylesheet or an animation needs to address a single letter.
  • Placement is arguments
    x, baselineY, letterSpacing and wordSpacing are parameters of the call, not post-processing. baselineY is the line the glyphs sit on, not the top of the text.
  • A file or a query
    fromFile() takes a path; fromFinder() takes a FontQuery of family, weight and style against a directory of fonts.
  • A seam for real shaping
    The built-in mapper is one cmap lookup per codepoint. TextShaperInterface is where a shaping engine plugs in, and everything downstream consumes its GlyphRun.
  • A missing glyph throws
    MissingGlyphException rather than a blank where a letter should be. A size that is not finite and positive throws too.

Draw a word as path data

use Atelier\Text\SvgText;

$path = SvgText::fromFile('Inter-Regular.woff2')
    ->path('Atelier', size: 64, baselineY: 72);

echo $path->d();

d() is the combined outline of the whole run, ready to drop into a drawing you are already building.

Get a whole document

$svg = SvgText::fromFile('Inter-Regular.woff2')
    ->svg('Atelier', size: 64, idPrefix: 'headline');

echo $svg->toPrettyString();

An atelier/svg document, one group per glyph. Passing idPrefix makes those ids deterministic, so headline-glyph-0 can be targeted from CSS or animated.

Choose a font by query

use Alto\Font\FontFinder;
use Alto\Font\FontQuery;

$finder = FontFinder::fromDirectories(__DIR__.'/fonts');

$font = SvgText::fromFinder($finder, FontQuery::family('Inter')->weight(700));
$path = $font->path('Atelier', size: 64);

What it does not do

One cmap lookup per codepoint, left to right. No font fallback, no bidirectional text, no ligatures, no kerning, no script shaping. That is a boundary, not a gap: everything downstream consumes a GlyphRun, so a real shaping engine replaces the mapper without touching the rest.

A codepoint the font has no glyph for throws MissingGlyphException rather than rendering a blank.

Install

The source is at github.com/ateliersvg/text. There is no release yet, and no Packagist entry, so composer require has nothing to fetch.

It will need PHP 8.4 and ext-mbstring, one version ahead of the rest of the range. WOFF2 files also need a Brotli decoder that alto/font supports: either ext-brotli or the brotli binary.