The Lookups Panel

The Lookups panel lets you inspect, edit, and debug the OpenType layout in a font. Choose a script and language, select a feature, then follow its lookups down to individual substitution or positioning rules. You can compare a rule’s input and output visually and trace what actually happens when a shaping engine applies the lookups to text.

Open Window > Panels > Lookups. The panel has two working modes: the visual rule editor and Debugger. The menu and debugger button are beside the script and language selectors.

Opening and Browsing Layout

On first opening, the panel initializes from the font’s stored binary OpenType layout tables when they are available. This lets you inspect an imported font without first compiling the reconstructed code in the Features panel. That code may be incomplete even when the original binary tables work.

The panel keeps its own editable Lookups document. The code in the Features panel is a separate document. Selecting a script, reopening the panel, or compiling Features does not replace an existing Lookups document. Import explicitly when you want Features-panel code to replace visual data.

Work through the panel in this order:

  1. Choose Script and Language to select the language system you want to inspect.
  2. Select a feature in the feature list. All features shows the available feature scope together. In debugger mode, selecting a row filters the browser; checking a feature enables it for the trace.
  3. Select a lookup to see its rules. Substitution, positioning, and context icons distinguish the kinds of operations. A contextual lookup calls other lookups when its pattern matches.
  4. Select a rule to inspect its glyphs and edit its operands or values in the preview area below the rules.

The substitution and positioning filter buttons narrow the kinds of features and lookups shown. The glyph-name search finds lookups involving the named glyphs and accepts wildcard patterns such as A.sc*. Clear it to restore the list. The separate search beside the rule buttons filters the selected lookup’s rules by partial text in their summaries and glyph names, without case sensitivity. These searches filter the browser; they do not insert or remove text in the debugger.

A feature’s list includes the lookups called by its contextual rules, including children that are not directly assigned to the feature. Those referenced children have muted names. They remain available because a caller needs them. In the debugger, a gray execution row has a different meaning: that invocation made no change.

Imported fonts often lack the author’s original lookup names. FontLab generates names where necessary. Suffixes such as mark_3.1 and mark_3.2 identify editable parts of one imported lookup, not successive versions of a rule.

Editing Rules and Reading the Preview

Use + and − beside the relevant list to add or remove features, lookups, or rules. When adding a lookup, choose its operation type and give it a useful name. A new lookup already contains its first empty rule. Use the rule list’s ordering buttons when you need to move a rule within that lookup.

Feature membership and lookup definitions are distinct. Removing a lookup’s assignment from one feature does not necessarily remove its shared definition: another feature or contextual caller may still use it. In particular, a lookup intended to run only through context should not also be assigned directly to an active feature, where it could run outside that context.

The Shapes column shows glyph samples, while the adjoining text describes the rule. For a substitution, choose the input and replacement glyphs using the glyph/class picker, or double-click the substitution text to edit it. For example, f i -> f_i describes a ligature rule; all three named glyphs must already exist. A complete exercise is in Substitution Lookups.

In the rule preview, the left canvas is the input and the right canvas is the result. Both use the same scale. Glyph names beneath the canvases identify the displayed samples. The background fill shows glyph bounds; faint dashed metric lines and the baseline help you compare placement. The arrowed width measurement shows advance width, which can differ from the width of the drawn outline. Drag the separator above the preview to adjust its height.

Blue glyphs are samples from classes. Click a blue glyph on either side to choose another member for the preview. This changes the sample, not the class membership. Use the Classes panel to edit the class itself; see Glyph Classes.

For single or pair positioning, the X and Y fields change placement and the width field changes advance. Placement moves the glyph relative to its origin; advance moves the origin used for the following glyph. Attachment rules instead identify the anchors involved. For mark-to-ligature attachment, use Component to inspect the receiving component. A missing-anchor diagnostic identifies data to inspect, not a successful attachment.

Where device corrections are available, choose the ppem size, glyph, and positioning field, then set or remove the pixel correction for that size. Stored OpenType lookup flags are retained; the preview’s direction follows the script and glyphs.

Visual positioning values are not automatically separate per-master values. For positioning that must interpolate across a designspace, use the appropriate kerning or anchor workflow described in Kerning Visually and Attaching Marks.

Context and Referenced Lookups

A summary such as @mark — apply mark_4 means: match a glyph belonging to @mark, then apply the lookup named mark_4. The name after apply identifies another lookup, not an output glyph. Its operation supplies the actual substitution or positioning.

Each action specifies an input position, counted from 1, and the lookup to apply there. The position counts the matched input, excluding surrounding context. Click the lookup name to open the searchable chooser; it narrows candidates to compatible lookups in the feature where possible. The compact + beside the controls adds another action at the selected input position. The other controls open the called lookup, move an action up, or remove it.

Open takes you to the referenced definition. Back to calling lookup returns with the previous script, language, feature, and filters. If the reference covers several imported parts, choose the part to inspect.

Expand Context to specify the surrounding pattern. Before and After refer to logical text order, including for right-to-left scripts. Spaces separate pattern positions; @name selects a class, and {A V} matches either glyph at one position. An empty field, shown as Any, leaves that side unconstrained. Use the eye button beside a context field to preview its class members and choose a representative sample.

The context rule preview shows the input on the left and the effects of the referenced lookups on the right. Gray glyphs are the surrounding context. Use Use in debugger to insert the sampled context and input into the debugger and immediately shape it. Then alter the input to test a case that should not match. The worked contextual editing procedure is in Contextual Substitution.

Importing, Copying, and Compiling

The panel menu separates transferring editable data from making that data supply normal font previews and export.

Command What it does
Import All Features from Features Panel Compiles the current Features-panel code for conversion and replaces the whole Lookups document.
Import Selected Features from Features Panel Imports the feature rows selected in the Features panel, replacing those feature assignments while preserving unrelated features and shared lookup definitions.
Copy feature / Copy features Places FEA text for the selected feature scope on the clipboard. All features copies the current scope’s feature set.
Copy lookup / Copy lookups Places the selected lookup definitions and their referenced dependencies on the clipboard as FEA.
Compile Builds the Lookups document and makes it supply the Glyph window, Preview panel, and font export.

Import includes pending edits in Features. It is undoable, and a failed conversion leaves the visual document intact. Import All replaces visual work, so retain anything you need before using it. Importing does not publish a new font build.

To take a visual edit back to feature code, copy the feature or lookups and paste into the Features panel or another editor. Standalone lookup definitions can go in PREFIX, with a feature referencing them. Check for duplicate names or declarations before pasting. Copy produces FEA from the selected data; it does not recover the original author’s comments or update Features automatically. Detailed transfer steps are in The Features Panel.

The last successful compilation in Lookups or Features selects which document supplies ordinary previews and export. Compile here chooses the Lookups document; Compile features in Features chooses that code. A failed compilation retains the preceding successful tables. The debugger makes a private build for its own trace and does not change this choice.

Some imported constructions can be inspected in retained binary form but cannot be edited and rebuilt visually without loss. Read any reported limitation before replacing working layout. The fact that an imported font can be debugged does not guarantee a lossless conversion to either editable representation.

Tracing a Lookup Run

Use the debugger to find the operation that changes a glyph, fails to match, or reverses an earlier change. It runs the Lookups document through HarfBuzz. An unchanged imported document can use its retained binary tables; edited rules need a private build. Running a trace does not publish that build to the Glyph window or replace Features-panel code.

  1. Open Debugger beside the Script and Language selectors.
  2. Check the features to test in the feature list. Selecting a feature row filters the browser; its checkbox controls the debugger selection.
  3. Enter ordinary text, such as fi, and press Enter or click the return-arrow button. For exact glyph input, use adjacent names such as /f/i or /a.alt, without adding separator spaces. Use /space when the glyph-name sequence needs an explicit space glyph.
  4. Select a lookup row to inspect its output. Use the forward, back, and play controls to follow changes. Double-click a row, or use Edit lookup in its context menu, to open the definition.
  5. Click Result to see the completed shaping result, then test the same feature with different input and surrounding text.

Leave Script shaping on when judging normal text. HarfBuzz applies its processing for the selected script, including default or required features, together with the checked features. Turn it off to isolate the checked features without script-specific joining and reordering. This diagnostic mode can produce text that would be unsuitable for ordinary use; restore Script shaping when checking the complete behavior.

The trace records executions, so a lookup can appear more than once. Context, substitution, and positioning icons identify the kind of operation. Gray rows made no change: forward, back, and play skip them, but you can click them to inspect their output. The context menu can reveal unchanged automatic lookups or restrict the list to changed steps. A contextual caller may remain visible to explain a changed child even when the caller has no net effect.

The debugger has one output preview. It shows the state after the selected invocation; Result includes final positioning and shaping work outside the individual lookup rows. Right-to-left output is aligned to the right. In this preview, blue highlights glyphs affected by the selected step; it does not indicate class membership as it does in the rule preview.

Read the metrics

Expand Metrics when the outlines alone do not explain the result. Values are in font units.

Field What to inspect
Glyph / ID The glyph name and its identifier in the compiled font.
Input # The original input position, counted from zero. Each /glyphName token counts as one input symbol.
Spacing X / Y The advance that moves the origin for the next glyph.
Shift X / Y The placement offset of the current glyph.

A dash means positioning has not yet supplied a value at that stage. For attached marks, inspect Result as well as the lookup step: the completed shaping pass can resolve attachment relationships after an individual lookup returns.

Features-panel text enters this debugger only through import into the Lookups document. To make the tested visual document supply normal previews and font export, choose Compile in Lookups. The last successful compilation in Lookups or Features selects which document supplies those builds; see The Features Panel.

A contextual trace includes the caller and any child lookups it actually invokes. Selecting a child shows that invocation’s output; the caller’s output includes its children’s completed work. An uncalled child has no execution to show. The same lookup can therefore appear several times with different inputs during a run.

For a substitution that appears to undo itself, follow the ChangeA/RestoreA example in Substitution Lookups. For marks whose offsets become meaningful only after attachment is resolved, inspect Result and consult Mark Features and Export.