Attaching Marks
Build attachment around clear anchor names, then compare the source preview with compiled text behavior. A base-and-mark pair, a stack of marks, and a marked ligature share the attachment principle but require different receiving structures.
The Mark-Positioning Environment
Use the ordinary Glyph window with anchors visible. Enable Show mark attachment to preview the current anchor relationships on a base-and-mark sequence. There is no separate mark-positioning editing mode.
With feature processing off, this anchor preview does not itself normalize a combining sequence into a precomposed glyph. Enter the intended base and combining mark explicitly when you need to inspect their attachment.
View > Anchors & Elements > Anchor Cloud overlays matching marks for the selected receiving anchor. It lets you inspect several potential attachments at once. Check that the cloud is using the anchor and master you intend; an especially tall or wide mark may reveal a problem hidden by the ordinary acute accent.
Clouds use ordinary root-name matching: top, top_1, and _top share the root top, so a matching mark can appear at each numbered receiving position of a ligature. They do not preview every possible explicit bracket mapping. Turn off the anchor's cloud button, Use in glyph construction, to hide its cloud; turn off Show in cloud in a mark glyph's class menu in the Glyph panel to exclude that glyph from clouds. Caret anchors do not participate.
The Preview panel's mark-attachment content provides a broader comparison surface. Use it alongside the current Glyph window and variation controls, while keeping source-anchor preview distinct from compiled OpenType feature proofing.
Mark-to-Base Attachment
A mark-to-base relationship attaches a mark to an ordinary base glyph. For a top accent:
- In the base glyph, add or select
topand place it where the mark should attach. - In the combining mark, add or select
_topat the mark's attachment location. - Check the mark's GDEF role and its metrics.
- Preview a base-plus-mark sequence with Show mark attachment enabled.
- Compare several marks against the base and the mark against several bases.
- Repeat the inspection in other masters and intermediate designs.
Zero advance is normally appropriate for a combining mark, but the anchor and GDEF role remain separate data. A zero-width ordinary glyph does not automatically become a correctly classified mark.
What the anchors build
A simplified FEA equivalent can look like this:
markClass acutecomb <anchor 100 0> @TopMarks;
feature mark {
pos base a <anchor 250 500> mark @TopMarks;
} mark;
The example requires a and acutecomb. It aligns the mark's attachment point with the base's point. Different marks in the same mark class can have different attaching coordinates; each declaration records the coordinates for its own glyphs.
FontLab groups eligible marks into mark classes according to the attachment-anchor name and connects them to the corresponding receiving anchors. A base's top and the marks' _top anchors define one attachment family. Moving that base anchor changes the intended position for every paired mark, so one design adjustment replaces many separately maintained placements. Regenerate the lookups for export after changing source anchors.
This is a class-based relationship rather than a list of unrelated base/mark pairs. Inspect representative narrow and wide marks against the same base, and the same mark against different bases, to judge whether the shared attachment convention works. A mark with a different intended attachment belongs to the appropriate separate family; a similar name is not a reason to force it into the wrong one.
Within a single lookup, a mark belongs to only one mark class: the classes must be disjoint. If a mark participates in more than one attachment family, the generated lookup organization must accommodate that rather than assigning overlapping classes carelessly within one lookup.
An FEA class on the base side is only a compact way to repeat a coordinate for several bases. It does not give each base a different coordinate automatically. Source anchors are usually clearer when those receiving positions differ glyph by glyph.
Mark-to-Mark Attachment
A mark-to-mark relationship uses another mark as the receiver. Give the lower mark its attaching _top anchor and an outgoing top anchor for the next mark. The upper mark's _top can then meet that outgoing location.
For example, a circumflex can attach above a base and receive an acute accent above itself. The second attachment must be judged against the placed lower mark, not independently against the base's original top anchor.
Common stacks can instead be precombined into one mark, an alternative to runtime mark-on-mark stacking. A precombined mark can itself be built by recipe. For example, with the matching incoming and outgoing top anchors, =fathatan-ar+shadda-ar@top retains the lower mark’s _top for attaching the completed stack to a base. The shadda’s propagated top remains available for another mark. Inspect both the incoming and outgoing anchors before using the result.
A simplified compiled relationship is:
markClass acutecomb <anchor 100 0> @TopMarks;
feature mkmk {
pos mark circumflexcomb <anchor 200 180> mark @TopMarks;
} mkmk;
This example describes only the upper attachment; the lower mark still needs its base-attachment path. Test the complete stack with both mark and mkmk behavior available. Building those features from anchors is taught in Mark Features and Export.
Inspect different stack heights, widths, and intended mark orders. Naming anchors consistently supplies the relationship, but the design still needs enough separation and the text must reach the appropriate marks in the correct shaping context.
Mark-to-Ligature Attachment
A ligature can represent several input components, each needing its own mark position. Use numbered anchor families such as top_1, top_2, or bottom_2 to identify the intended ligature component.
These are text-layout components of the ligature, not necessarily the same objects as its FontLab outline components. A ligature drawn as one continuous contour can still need several attachment positions.
For a three-component ligature with top attachment on the first component and bottom attachment on the second, the conceptual FEA is:
markClass acutecomb <anchor 100 0> @TopMarks;
markClass dotbelowcomb <anchor 100 0> @BottomMarks;
feature mark {
pos ligature f_i_l
<anchor 150 500> mark @TopMarks
ligComponent
<anchor 400 -50> mark @BottomMarks
ligComponent
<anchor NULL>;
} mark;
ligComponent preserves the component sequence. A component with no receiving anchors is represented by NULL, not by an invented anchor at the origin. A genuine (0, 0) anchor is a real position and must remain distinguishable from a missing one.
Keep the ligature component count and numbered anchors consistent. Leading, interior, and trailing gaps can be meaningful; do not renumber later anchors simply to remove a gap. A NULL slot preserves the later components’ positions rather than shifting their attachment data onto the wrong component. Check the logical ligature component receiving each mark, particularly in RTL text, rather than numbering solely from its left-to-right appearance.
In the Anchors & Pins panel, group the receiving anchors by ligature component in reading order: all anchors for component 1, then component 2, and so on. Drag entries to reorder them and edit their names to correct indices. Modern & recipes create numbered anchors; inspect reading-order assignment, especially for RTL constructions, as explained in Anchors for Positioning. Both a finished-letter ligature and a separately drawn skeleton with attached dots need this organization; the drawing method does not remove the layout requirement.
Test marks on each component using text that actually forms the ligature. Directly displaying the ligature and a mark may not provide the same component association as shaping its original input sequence.