Stage B, PR 1: bmf sub-object and memoised flattenGlyph#65
Merged
Conversation
…, PR 1) Splits the conflated Glyph.xoffset/yoffset/xadvance into glyph.bmf (BMF char-line metadata) and flattenGlyph(glyph) (union-bbox origin), and adds a WeakMap-memoised flattenGlyph so callers can switch off the legacy top-level fields without per-call recomputation. Legacy fields stay populated by syncLegacyFields for one more PR (mirror writes, deprecate reads); PR 2 deletes them and runs the v6 DB migration. Behavioural fix surfaced during migration: moving a TTF-imported glyph no longer overwrites its source-font bearing — bmf.xoffset/yoffset are now independent of where ink sits in the layer buffer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First of three PRs finishing the Stage A → Stage B migration. Splits today's conflated
Glyph.xoffset/yoffset/xadvance(which is doing two jobs: editor union-bbox origin + BMF char-line metadata) into:glyph.bmf: { xoffset, yoffset, xadvance }— the BMF char-line nudge from source-font metrics (TTF bearings or parsed.fnt). Independent of where ink sits in the layer buffer.flattenGlyph(glyph).xoffset/yoffset— the union-bbox origin of inked layers. Pure derivation, now memoised viaWeakMap<Glyph, FlattenedGlyph>(Glyph mutations always produce a new object, so reference identity tracks invalidation).Every reader has been migrated to one or the other; every writer populates
bmfcorrectly. Legacy top-level fields (pixels/width/height/xoffset/yoffset/xadvance) stay populated bysyncLegacyFieldsfor this PR — they're marked@deprecatedand PR 2 deletes them along with a v6 DB migration. PR 3 then rolls PortableFont to v3 with full layer-stack round-trip.Behavioural fix surfaced during migration
Moving a TTF-imported glyph no longer overwrites its source-font bearing. Previously, the move tool updated the single
glyph.xoffset/yoffsetfield — which was the BMF metadata and the flatten origin — so dragging a glyph silently destroyed the TTF bearing recorded at import time. Nowbmf.xoffset/yoffsetare independent of layer offsets, so moves only affect the flatten origin.Side cleanup
DEFAULT_XADVANCE_RATIO = 0.7added toconfig/font-defaults.tsand used bymakeBlankGlyph. The0.7was previously a magic number that happened to matchCAP_HEIGHT_RATIO— but they're different concepts and shouldn't drift together.Test plan
pnpm test— 108 tests pass, including newflattenGlyph cachesuitepnpm build— type-check + production build cleanpnpm lint— no warnings.fnt+ PNG, export.bmffont.jsonand re-import — confirm no visible regressionbmf.xoffset + flat.xoffset + placement.trimXexport formula)🤖 Generated with Claude Code