Skip to main content

Create Outlines

Create Outlines converts a text node into the vector paths of its laid-out glyphs — the operation a designer reaches for to bake type into art (to nudge a single letterform, or to hand off print-safe geometry that needs no font). It is the text twin of the single-node flatten (flatten_to_vector): per node, in place, identity preserved. It is not flatten (which unions a selection into one vector), and not outline mode (the wireframe view).

Why it is its own command

Text-to-outline is distinct from flatten on three axes, and conflating them is a known wart — the web editor folds text into its flatten set but leaves a standing TODO to split it into a separate api (vector.textToVectorNetwork()):

  • Different subsystem. Flatten bakes geometry from a shape builder. Outlining text requires font shaping — laying the string out into glyph runs, then taking each glyph's outline path. A pure-geometry path cannot do it.
  • Different semantics. Flatten unions the selection into one vector. Create Outlines converts each text node independently, keeping it a separate object at its own position — you outline type to then manipulate its letterforms, not to merge it with neighbors.
  • Different intent. "Create outlines" is a named act designers invoke deliberately on type; "flatten my text" is not how anyone thinks about it.

The operation

For each text node in the selection, independently:

  • Shape and outline. The node's paragraph is laid out exactly as it renders — the same shaping, wrapping, alignment, and fonts — and each glyph's outline becomes vector geometry. The result paints identically to the text it replaces.
  • Replace in place. The text node is swapped for a vector node at the same identity — id, name, tree position, and transform preserved. The paragraph's fills carry to the vector, so the color does not jump.
  • Non-text members are left unchanged, and stay selected. Create Outlines never touches shapes; it is text-only.

The whole command is one history entry; undo restores the text (still editable). Because each node is replaced at its own id and transform, no re-anchoring or union math is involved — the vector lands exactly where the text was.

The font dependency

Shaping needs the runtime's fonts. A text node whose fonts are unavailable is left unchanged (the command declines for it), never approximated — the same honest degradation flatten makes for its backend-gated kinds (flatten.md FLAT-2). This is why the capability is offered only where a font backend is present; a headless caller with no fonts outlines nothing.

Relation to flatten

Flatten composes this: when a flatten selection includes a text member, flatten delegates that member to the same text→vector conversion (so "flatten everything" on mixed type + shapes bakes the text into the union too). Create Outlines is the dedicated, per-node command; the shared primitive is the one font-backed conversion both call.

Contracts

  • OUTL-1 Per-node, in place: each selected text node is replaced by a vector node carrying its laid-out glyph outlines, at the same id, name, tree position, and transform; the paragraph's fills carry to the vector. Non-text members are left unchanged.
  • OUTL-2 Render fidelity: the outline is the paragraph as laid out (shaping, wrapping, alignment, fonts as rendered), so the vector paints where and how the text did.
  • OUTL-3 Font dependency: a text node whose shaping backend/fonts are unavailable is left unchanged (declines), never approximated; with no font backend at all, the command outlines nothing and declines.
  • OUTL-4 Per-node independence: every text node in the selection is converted independently — never unioned — so N text nodes yield N vectors, each at its own place.
  • OUTL-5 One entry: the whole conversion is a single history entry; undo restores the editable text.

Deferred, named: preserving rich per-run styling as multiple filled regions (the first pass carries the node-level fill); stroked-text outline (expand the glyph strokes) — the stroke-outline sibling, not this fill-outline command.