Skip to content

QCurve is silently rewritten to OnCurve across the wire — quiet quad corruption on edit #125

Description

@kostyafarber

From the 2026-07 re-review (worse than originally reported).

shift-wire/src/lib.rs:317 maps PointType::QCurve → OnCurve going out, and the reverse mapping (lib.rs:323-328) has no QCurve arm — so any glyph structure that round-trips through the wire silently rewrites quadratic points as on-curves. Binary import no longer produces QCurve (quads are lifted to cubics as of #120), but the UFO reader (ufo/reader.rs:58) and .glyphs reader (glyphs/reader.rs:37-38) still do.

Consequences for a font with quadratic outlines imported from .glyphs or a quad-UFO:

  • The renderer mis-displays quads (treats controls as cubic-shaped data).
  • Editing a quad glyph corrupts it: the edited structure comes back through the wire with QCurve erased, and subsequent saves write cubic-shaped geometry that no longer matches the source curves.

Options:

  1. Plumb QCurve through the wire and renderer — honest support; touches NapiPointType, packages/types, glyph-state segmentation, rendering, and editing behaviors. The real fix if quad editing is ever in scope.
  2. Extend fix: lift TrueType quadratics to cubics on binary import #120's policy to all importers: lift quads to cubics in the UFO and .glyphs readers too, making the IR cubic-only by construction (document as import behavior; disclosure report should mention it). Cheap, consistent, loses quad-native round-tripping for .glyphs/quad-UFO sources.
  3. Interim guard: refuse to edit (read-only open) glyphs containing QCurve until 1 or 2 lands, so nothing corrupts silently.

Given .glyphs is import-only and TT-outline editing is not a v1.0 goal, option 2 is probably right for now, with 1 as the post-1.0 path if quad-native editing becomes a goal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions