Repository navigation
RR-55: fonts handle, deck-level renderSvg, core 0.14 names (lockstep) - #150
Merged
Merged
Conversation
michaeljgrimm
force-pushed
the
codex/rr-55-short-verb-api
branch
from
October 7, 2026 00:01
5cb678d to
0871205
Compare
michaeljgrimm
force-pushed
the
codex/rr-55-short-verb-api
branch
from
October 7, 2026 06:21
085263b to
4cf2529
Compare
michaeljgrimm
marked this pull request as ready for review
October 7, 2026 06:21
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: fc53bd4b-e775-4a4b-8399-2da0c33f40de) |
… (lockstep with core 0.14)
- renderSvg(deck, { fonts }) returns string[]; renderSlideSvg(deck, index, { fonts }) returns one SVG; renderSvgDeck and slideIndex are removed.
- loadFonts() from /fonts-node and /fonts-browser replaces prepareNodeFonts, loadOfficeFontRegistry, loadBundledFontRegistry, loadBrowserFontRegistry and createFontRegistry (now internal). Every deck-level function takes { fonts }.
- Slide canvas, layout, theme, colour scheme, font scheme, families and darkBackground come from core resolveSlideContext; inferLayoutId is removed and unknown ids fall back and are reported instead of throwing.
- OPFRenderError invalid-opf carries findings (core validate, format only).
- Engine names are imported from @openpresentation/opf/composition; /fonts re-exports core's font-policy and symbol-code helpers instead of snapshots.
- Tests: core-features, slide-context and fonts-handle added; every golden hash is unchanged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…d suites before core 0.14 is published Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the short-verb API) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…res lists the FA names Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
michaeljgrimm
force-pushed
the
codex/rr-55-short-verb-api
branch
from
October 7, 2026 07:49
4cf2529 to
cbfc08c
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: f8906af9-0855-48ca-b9b4-bbea1c93aa2b) |
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.
Depends-On: OpenPresentation/opf#423
Depends-On: OpenPresentation/opf-pptx#196
Depends-On: OpenPresentation/opf-editor#116
Summary
RR-55 lockstep for opf-render (core 0.14.0): one fonts handle, whole-deck and one-slide render functions, core's slide context, and core's new import paths. Old names are deleted, not aliased. Output is unchanged: every golden raster hash is identical.
renderSvg(deck, options)returnsstring[];renderSlideSvg(deck, index, options)returns one SVG.loadFonts(options)(/fonts-node,/fonts-browser) returns the one handle; every deck-level function takes{ fonts }.darkBackgroundcome from coreresolveSlideContext.@openpresentation/opf/composition;/fontsre-exports core's font-policy and symbol helpers instead of snapshots.core-features(63 required core exports, every imported core name resolves, no feature detection,/fontsre-exports are core's own objects),slide-context(arobotodeck measures with Roboto),fonts-handle.Old to new
renderSvg(deck, { slideIndex })(one slide)renderSlideSvg(deck, index, options)renderSvgDeck(deck, options)renderSvg(deck, options)(string[])slideIndexoptionprepareNodeFonts,loadOfficeFontRegistry,loadBundledFontRegistry,loadBrowserFontRegistry,createFontRegistryloadFonts(options)per subpath;createFontRegistryis internal (src/font-registry.js, not an entry point)prepareNodeFonts().options,{ textMeasurement, embeddedFonts, fontFiles, useBundledFonts, loadSystemFonts }spread{ fonts }(handle:textMeasurement, embeddedFonts, fontFiles, useBundledFonts, loadSystemFonts, registry, manifest, substitutions, ensure, pending, browser alsodispose)textMeasurement/embeddedFontsonrenderSvg,resolvePresentation,renderOptionsfontsfontFiles/useBundledFonts/loadSystemFontsonsvgToPng,svgToPdffonts(fontDirsstays)/export-browsersvgToPdffonts(embeds the handle's faces);fontDatakept for use without a handle<opf-deck>.fontRegistry;fontsattribute onlyfontsproperty takes a URL or a handle;fontRegistryremovedrenderDeckHtml({ fonts: string })fontsstring (root URL attribute) or object (draws the markup)present({ fonts })registrycreateFontGate(registry)createFontGate(fontsHandle)fonts.ensure(presentation)/fonts.pending(presentation)(registry keepsensureLazyFonts,ensureScripts,pendingLazyFonts,pendingScripts,loadScripts)OPFRenderError('invalid-opf').issues.findings(corevalidate(deck, { only: ['format'] })error findings;details.reportis the whole report)details.issuesdetails.diagnosticsvalidatePresentationvalidate(x, { only: ['format'] })@openpresentation/opf@openpresentation/opf/composition/fontsFONT_POLICY(array),FONT_POLICY_SOURCE,FONT_POLICY_DECISIONS,SYMBOL_ENCODINGS,SYMBOL_ENCODINGS_SOURCE,symbolEncodingForFONT_POLICY(table:.families,.provisionalDecisions),fontPolicyFor,isSymbolEncodedFamily,symbolCodeOf,mapSymbolText,scriptFontRolere-exported (the same objects)language-preview-unavailable,paragraph-direction-unavailablecatalog-resolution-failedfor an unknown layout, theme or colour scheme idunresolved-layout,unresolved-theme,unresolved-color-scheme(font scheme:unresolved-font-scheme, unchanged)resolvePresentation(...).slides[i].layout(inferred)Vetoable calls
loadFonts({ pack: 'none' })is new: only thefacesyou supply (throwsempty-font-registrywithout any).createFontRegistry,pickFaceandskipUndecodableLookupslive in the internalsrc/font-registry.js(not an entry point); tests import it fromdist/by path.symbolPreviewFacesstays insymbol-fonts.js;mapSymbolAdvancesthere is private.inferLayoutIdandresolveLayoutare deleted. A slide with no layout, or an unknown id, composes with no layout record. Unknown layout/theme/colour-scheme ids no longer throw; core's diagnostics are forwarded. The inline-objectlayoutfallback is gone.darkBackgroundis taken from core; the renderer's own computation is deleted (equivalence checked on the corpus and on synthetic backgrounds).contextCatalogs()feeds hostcatalogsandcatalogSourcesinto the context in the renderer's old order (doc source, host catalogs, engine default source, bundled). Theme, colour-scheme and font-scheme records keep sorted keys.OPFRenderError.issuesbecomes.findings(alsodetails.findings,details.report); layout-overflow and variable errors carrydetails.diagnostics./fontsre-exports core's font-policy, symbol-code and script-slot helpers. Parity checked: the renderer's rows equal core's minussources/note; symbol codes, advances andscriptFontRolematch (core also accepts lowercase'arab'). Core'smapSymbolTexthas noadvance, so the preview adds it privately. Cost: the browser bundle grows by roughly 250 KB minified (core's symbol-font table is about 170 KB; total about 2.0 MB).<opf-deck>.fontstakes a URL or a handle (a handle wins),fontRegistryis deleted,renderDeckHtml({ fonts })takes a string or an object,present({ fonts })a string or a handle. The deck store passes only the handle'stextMeasurementto inline slides, as before.resolvePresentationkeeps its name (it returns the deck with every slide's geometry;resolveDeckadds nothing).RenderSvgOptions, servesrenderSvgandrenderSlideSvg, so there is room forskipHidden.Legacy removed
resolveScriptFonts,paragraphDirection,patternRuns,metricTrendMark,tokenizeCode,resolveChartOptions,resolveChartData,chartPaletteForFill,glyphFallbackFamilies,resolveVariables.*-unavailablediagnostics and the hand-drawn pattern fallbacks.scriptFontRole, and its font-policy and symbol-encoding snapshots, generators and the CI snapshot check.hasCore,hasFallback, "skipped, no resolveLogo").build-browser-check.mjsnow really assertsparagraphDirectionis in a browser bundle that draws a slide (the old check was silently skipped once the name left the root).Tests (against core 1d7c57fd)
scripts/fixtures/opf-examples-png.example-decks.sha256.json).npm test: 72 tests passed.npm run typecheck: 187 files, 0 failed.npm run validate,check:changes,check:fontspass.themeandcolorSchemerender byte-identically to the same record laid overminimal/cool-horizon(the old behaviour).Cannot pass yet / follow-ups
test:packed(and any job that installs published core) cannot pass until core 0.14.0 is published:package.jsonstill says@openpresentation/opf ^0.13.0. The core range and the version move in the release-prep PR, perAGENTS.md.test:variable-font-gateneeds../archive, so it was not run locally.skipHiddenlands onRenderSvgOptionswhen this branch is rebased onto it (RenderSvgDeckOptionsis deleted withrenderSvgDeck).🤖 Generated with Claude Code
Note
High Risk
Breaking public API across render, fonts, player, and export paths with deep core 0.14 coupling; integrators must migrate every call site even though raster goldens are unchanged.
Overview
RR-55 (breaking, core 0.14.0) reshapes the public API around a single
loadFonts()handle and deck-level{ fonts }instead of scatteredtextMeasurement,embeddedFonts, andfontFilesoptions.renderSvgnow returns one SVG per slide (formerlyrenderSvgDeck);renderSlideSvg(deck, index)replaces single-sliderenderSvg+slideIndex.prepareNodeFonts,loadOfficeFontRegistry,loadBrowserFontRegistry, andcreateFontRegistryas exports are removed in favor ofloadFonts(/fonts-node,/fonts-browser), withensure/pendingon the handle andcreateFontRegistrymoved internal.Slide theme/layout/colour/font context and
darkBackgroundcome from coreresolveSlideContext; unknown catalog ids no longer throw—they fall back withonDiagnostic(unresolved-*).OPFRenderErrorinvalid-opfusesfindings(notissues). Composition, charts, and fonts import core by name (no runtime “old core” guards);/fontsre-exports coreFONT_POLICYand symbol helpers and drops local policy/symbol snapshots and the CI font-policy snapshot step.<opf-deck>, player,renderDeckHtml, and browsersvgToPdftake a fonts URL or handle (fontRegistryremoved). Golden output is claimed unchanged.Reviewed by Cursor Bugbot for commit cbfc08c. Configure here.