The specimen is yours | pattern

Your Font Does Not Agree With Itself

A font file can store three answers to a short question: how far apart should two baselines be? The fixture below gives 1.2 em, 1.1 em, and 1.45 em. They are not three platform predictions. They are three documented interpretations, one of which is primarily a clipping envelope. Bring a raw TrueType font and the same parser will read every relevant byte, then decode every default-instance outline point to find whether the metadata disagreement occupies real space.

Drop one raw .ttf here

Your bytes stay in this tab. The CC0 fixture is already running.

Preparing the shipped fixture...

Published anchor first

OpenType's bit-7 selection rule, reproduced from bytes

The instrument reads the head, hhea, and OS/2 tables independently. For the shipped fixture, OS/2 version 4 makes fsSelection bit 7 meaningful. Because that bit is set, OpenType 1.9.1 strongly recommends the sTypo total for default spacing. It does not require every layout engine to obey.

File
unitsPerEm, head +18
OS/2 version, +0
fsSelection, OS/2 +62
numGlyphs, maxp +4
Selected Unicode cmap

The same line, ruled three ways

Each card sets the same supported text twice. The gold lines are baselines. The faint band is that metric set's ascender-to-descender envelope. The baseline gap is computed from the file in design units, divided by unitsPerEm, then multiplied by the selected pixel size.

What the columns are

hhea interpretation is the older Apple-specific metric set. sTypo interpretation is the portable typographic set, selected by USE_TYPO_METRICS when the version gate permits it. legacy usWin interpretation treats the Windows clipping extents as a baseline distance, as older software sometimes did.

What the columns are not

They are not macOS, Windows, and browser screenshots. Current software can choose different logic, and a browser can produce different results depending on its engine, shaping path, font structure, and CSS. A clean platform label here would be convenient and false.

Second layer

Are the disputed heights occupied?

Metadata can be stale. The parser therefore opens every glyph through loca, expands simple point flags and deltas, follows transformed composite components, and then solves each quadratic segment for its own extremum. A glyph above hhea or sTypo escapes a layout envelope. That does not prove an application will clip it. The usWin pair has the documented clipping role, so crossing it is the sharper warning, and even there the specification only recommends covering head.yMax when clipping is unacceptable.

Two vertical quantities live here and they are not the same. The control-point box is the hull of every stored on-curve and off-curve point, which is exactly what OpenType defines the glyf and head boxes to be, so stored boxes are validated against it. The outline extent solves each quadratic for the point the curve actually reaches. The specification is explicit that the first contains the second but need not touch it, so only the outline extent is allowed to support the sentence that a glyph occupies the disputed space. On this fixture the two agree, because every fixture point is on-curve. On a real font they do not: one accented glyph in DejaVu Sans has a control hull 20.72 units deeper than its own curve.

Every decoded vertical span

Per glyph, a dim stroke for the control-point hull and a pale stroke for the outline extent inside it. Dashed pairs are stored envelope boundaries. This is a geometric census, not a rasterized image.

hhea is gold, sTypo is mint, usWin is violet. Horizontal position is glyph ID order, not character order.

Two claims, not one

The title fuses two failures that come apart. A file whose three stored pairs are identical copies can still have outlines outside them, and a file whose three pairs differ can hold every outline comfortably inside all three. They are separate results and this page reports them separately for the loaded file.

Does the file disagree with itself?

Do the outlines escape?

What the specification suggests, measured on this file

    There is a fourth stored vertical pair, head.yMin and head.yMax, and it is deliberately not plotted as an envelope. OpenType defines it as the aggregate of the glyph boxes, so comparing decoded control points against it is very nearly comparing a quantity with itself, and it would be the one boundary that could not surprise anyone. It appears above only as a validation check on the decoding, where a mismatch is a fact about the file rather than about typography.

    A file can disagree without being broken

    Vertical metrics arrived through different histories and backward-compatibility constraints. OpenType now gives the sTypo fields an explicit selection bit, while usWinAscent and usWinDescent describe a clipping region. A conforming file can store distinct values because they do distinct jobs. The interesting defect is often not difference itself, but a clipping envelope smaller than the outlines it is meant to contain, or stored glyph boxes that the points do not support.

    Apple's own reference manual states both halves of this in one page: the field table calls hhea.ascent the distance from the baseline of the highest ascender, and the note below it says those values "represent the design intentions of the font's creator rather than any computed value, and individual glyphs may well exceed the limits they represent". A page that quotes only the field table would be asserting something the same document withdraws.

    The fixture is deliberately argumentative, and it is an outlier on purpose: most shipping fonts store the same numbers in all three slots, so the three-way disagreement is a property of the format that a given file may or may not exercise. Its hhea total is computed as 800 - (-200) + 200 = 1200. Its sTypo total is 750 - (-250) + 100 = 1100. Its usWin envelope is 1100 + 350 = 1450. The tallest decoded point is 1050 and the deepest is -300, every fixture point is on-curve so the outline reaches both, and the usWin clipping envelope contains every one of them while the other two envelopes are crossed. Those claims are recalculated below and offline, not trusted from this paragraph.

    running checks

    The check

    Every green row has a falsifiable opposite, and a row that measured nothing is marked N/A rather than counted as a pass. The refusal rows mutate the known-good fixture ten different ways and each one has to name the offending byte. The geometry rows flip a single flag bit so one glyph's apex becomes an off-curve control point: the stored hull still reads 1050 and the curve only reaches 525, and the crossing count has to fall accordingly. If the reader's file is refused, those rows stay visible and its own precise error is added here.

    Nothing left the device

    Local file name
    Local byte length
    Local SHA-256
    Requests after load
    Active connection policyContent Security Policy: connect-src 'none'
    StorageNo cookie, localStorage, sessionStorage, cache, or IndexedDB write

    The request count comes from the Resource Timing API and counts resources whose start time is after the page load boundary. It is a visible check, not a claim that this API can observe every browser subsystem. Open developer tools, choose Network, clear it, then drop a font: there should be no request carrying the file. This page uses no fetch, XMLHttpRequest, WebSocket, EventSource, sendBeacon, analytics, remote font, or third-party script.

    Free choices and uncertainties

    Parser warnings for this specimen

    What this does not prove

    It does not predict exact line boxes, first baselines, clipping, or document reflow in a named application, browser, operating system, pixel size, variation instance, or shaped string. It does not prove the font is well designed, conformant in every table, safe to install, or licensed for any use. It audits documented fields and unhinted default-instance TrueType outline points in one local file.

    Fixture provenance and licence

    Metric Rift Fixture 1.0.ttf was generated from first principles for this page. Its seven glyph IDs use only simple geometric polygons. It contains no inherited font data. The generator source and binary are shipped beside this page and dedicated to the public domain under CC0-1.0. The fixture has unitsPerEm 1000; hhea 800, -200, 200; sTypo 750, -250, 100; usWin 1100, 350; OS/2 version 4; fsSelection bit 7 set; and decoded y extrema 1050 and -300. The verifier rebuilds the binary and demands byte-for-byte identity.

    Primary sources and exact uses
    1. OpenType 1.9.1: OS/2 and Windows Metrics Table, Microsoft Corporation, 2024. Field offsets and signedness, OS/2 versions, USE_TYPO_METRICS bit 7, the sTypo spacing formula, and usWin clipping semantics.
    2. OpenType 1.9.1: Horizontal Header Table. hhea field order, signed lineGap, and the historical platform note.
    3. OpenType 1.9.1: Recommendations for OpenType Fonts. Historical baseline-distance interpretations and current consistency guidance.
    4. OpenType Font File, plus the head, maxp, loca, glyf, and cmap sections. Binary layout, bounds, point decoding, composites, global boxes, and Unicode mapping.
    5. Apple: TrueType Reference Manual, hhea. Apple's field names and the note that these values are design intentions rather than computed values, which individual glyphs may exceed.
    6. Google Fonts Guide: Vertical metrics. Independent operational context for why distinct vertical-metric sets remain a font-production concern.
    7. Glyphs Learn: Vertical metrics. Independent account of the historical three-set problem and why platform names need caveats.