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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions