Skip to content

[skera] Partially instance coupled avar2 mappings - #2253

Closed
behdad wants to merge 7 commits into
skera-cff2-downgradefrom
skera-cff2-avar2-instance
Closed

behdad wants to merge 7 commits into
skera-cff2-downgradefrom
skera-cff2-avar2-instance

Conversation

@behdad

@behdad behdad commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Partial instancing now accepts coupled avar version 2 maps. It rebases the avar2 store in intermediate-coordinate space and adds offset compensation to preserve the original final coordinates. Pinned axes remain hidden with a degenerate user range, and a subsequent full instance resolves them automatically. Each output axis gets a separate delta row so shared input indices cannot leak compensation between axes.

Validation:

  • Full skera suite: 170 unit tests, seven CFF semantic tests, and 92 existing integration tests passed.
  • Rust 1.89 Clippy passed.
  • Tests cover pins, ranges, changed defaults, shared delta indices, implicit maps, OS/2 style metadata, and exact outlines/metrics for partial-then-full composition. Original font mappings are the oracle for range compensation; F2Dot14 quantization can introduce small differences.
  • Six generated avar2 partial instances passed OTS. A 33 by 33 user-coordinate grid per request stayed within two F2Dot14 units of the original mapping. HarfBuzz 14.5.1 output was also inspected; its range compensation differs at some locations, so those outputs are not used as exact goldens.

Readers use read-fonts directly. write-fonts handles font assembly and owned table rebuilding; Skera retains its direct serializers and repacker. There is no separate generated Skera table tree.

Retain the old final-coordinate space in outline, metric, layout, and color tables. Rebase avar2 inputs and compensate output coordinates, keeping pinned axes hidden until full instancing. Privatize axis delta rows before adding compensation.
Apply requested weight and width defaults to OS/2 while retaining metric variation stores in their original coordinate space. Cover both style classes and composition with a full instance.
@behdad
behdad force-pushed the skera-cff2-avar2-instance branch from 6095b25 to f61addb Compare October 14, 2026 23:11
@behdad

behdad commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Self-review of 896c1427, the coupled avar2 instancing slice.

The central design decision is sound: a pinned user axis need not have a constant final coordinate when other axes affect it through avar2. Keeping that axis hidden, preserving the original final-coordinate consumers, and rebuilding the input mapping avoids incorrectly baking a varying coordinate. A subsequent full instance can resolve and remove those hidden axes. The existing composition test checks this separately from ordinary independent-axis instancing.

I compared 18 coupled restrictions against HarfBuzz 14.6.0 (8ad7bfe80): three explicit/shared/implicit index-map variants, six pin/range/default requests, and a 13 × 13 coordinate grid per output. The largest source-to-output difference was 2 raw F2Dot14 units for both libraries. Their outputs agree exactly on the grid in 17 cases, and differ by at most one raw unit in the remaining shared-row case.

This compensation is quantized, so exact source equivalence is not its contract. The existing broader unit-test allowance of eight raw units is conservative; the measured matrix above does not establish a universal two-unit bound. The README/API warning about mapping-rounding differences should remain explicit. Hidden-axis retention is an implementation tradeoff with the same rationale as HarfBuzz, rather than a substitute for full instancing.

No additional coupling-specific correctness failure emerged from these checks. I will integrate the reviewed #2252 parent, keep its source-range validation and untouched-axis precision corrections, and rerun the coupled mapping/composition tests and full Skera checks. The newly introduced handler also removes the earlier partial-avar2 restriction at this boundary.

Preserve both hidden-axis handling and untouched fixed-point axis records
when merging the reviewed parent. Keep float outline normalization and
the separate metric coordinate path. Update the stack-boundary support
description now that partial coupled avar2 has its handler.

All 433 Skera tests, the reader scalar regression, Clippy 1.89, Rust 1.85
all-target/all-feature checks, formatting, and spelling checks pass.
Eighteen coupled restrictions match HarfBuzz axis records. On a 13 by 13
coordinate grid they differ by at most one raw F2Dot14 unit from HarfBuzz
and two units from the source, with the same source error in HarfBuzz.
@behdad

behdad commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Pushed the reviewed parent integration as cd5fada6, retaining hidden coupled axes, source-range validation, untouched-axis record precision, float outline normalization, and the separate metric coordinate path. Updated the stack-boundary support description to include partial coupled avar2.

All 433 Skera tests passed, including coupled mapping and partial-then-full composition; the reader regression, Clippy 1.89, Rust 1.85 checks, formatting, and spelling checks also passed. The 18 coupled restrictions × 169 locations retain identical axis records to HarfBuzz. Coordinate outputs agree exactly in 17 cases and differ by at most one raw F2Dot14 unit in the remaining case; both libraries' maximum source error is two raw units.

No additional coupling-specific algorithm change was needed. Continuing to #2254, whose recorder transaction changes are now implemented earlier in #2248; its remaining contribution is regression coverage.

Merge the repaired #2249 ancestry after the #2248 squash merge.
The tree is identical to the previously validated PR head.

Assisted-by: OpenAI Codex
@behdad

behdad commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by the rebuilt, consolidated instancing stack in #2416–#2423. MATH and name-table overrides remain separately covered by #2415 and #2411.

@behdad behdad closed this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant