@openpresentation/opf-render 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +4 -4
  2. package/package.json +10 -5
package/README.md CHANGED
@@ -10,7 +10,7 @@ Version 0.8.1 required core 0.10.1, including metric, quote and timeline layout
10
10
 
11
11
  Unfinished prepared shaping work is preserved in the [September 15 roadmap](docs/roadmap-shaping-20260915.md); it is not part of the published runtime.
12
12
 
13
- Version 0.8.0 and this checkout require Node 24 (`24.x`). Use `.nvmrc` for local development. Earlier published versions retain their original engine declarations. Browser entrypoints remain browser-safe; native application compatibility is verified separately.
13
+ This checkout supports Node 22 or later (`engines.node` `>=22`; CI tests Node 22, 24 and 26). Versions 0.8.0 to 0.12.0 declared `24.x`, so npm on Node 22 or 26 silently installed an older release instead (RR-20); upgrade past 0.12.0. Use `.nvmrc` (Node 24) for local development. Earlier published versions retain their original engine declarations. Browser entrypoints remain browser-safe; native application compatibility is verified separately.
14
14
 
15
15
  Version 0.8.0 adds optional font-registry vector outlines and shared heading/scalar/rich line placement. Pass identical `textMeasurement` and `textRasterPadding` options to preview, pagination and export; padding defaults to one scaled reference pixel. SVG consumes accepted origins without remeasuring. See the [source contract and limits](https://github.com/OpenPresentation/opf/blob/f94125a1ff95bf0974a055fe1c081d348dad54f2/docs/plans/text-placement.md). Native raster certification remains separate.
16
16
 
@@ -404,7 +404,7 @@ npm run golden:update
404
404
 
405
405
  Public npm package publication is handled by `.github/workflows/npm-publish.yml` through npm Trusted Publishing (GitHub Actions OIDC) with npm provenance; no npm token is stored. The owner authorized agents to prepare and publish npm releases whenever a release is required (2026-09-29). This authorization does not waive any gate.
406
406
 
407
- 1. Open a release-prep PR containing only the version bump, `CHANGELOG.md`, dependency ranges, lockfile and current-instruction docs. Publish in dependency order (core, then renderer and PPTX, then editor): refresh this repo's lockfile only after the required `@openpresentation/opf` version is on the registry (`npm install --package-lock-only`), then run `npm run test:packed` against it.
407
+ 1. Open a release-prep PR containing only the version bump, `CHANGELOG.md` (assembled from `changes/` with `node scripts/changelog-fragments.mjs assemble --version X.Y.Z`), dependency ranges, lockfile and current-instruction docs. Publish in dependency order (core, then renderer and PPTX, then editor): refresh this repo's lockfile only after the required `@openpresentation/opf` version is on the registry (`npm install --package-lock-only`), then run `npm run test:packed` against it.
408
408
  2. Merge after CI is green, then publish by pushing the git tag `opf-render-v<version>` (or `@openpresentation/opf-render@v<version>`) at the merge commit. The workflow verifies that the tag matches `package.json` and reruns audit, typecheck, validate, tests, packed and browser checks before `npm publish --access public --provenance`. A manual `workflow_dispatch` runs the same job without the tag check and is a fallback only.
409
409
  3. Verify with `npm view @openpresentation/opf-render@<version> version gitHead dist.attestations` and, from the core repo, `node scripts/test-renderer-publication.mjs <version> <release-commit> <this-checkout>`. Never republish an existing version.
410
410
 
@@ -418,7 +418,7 @@ Version 0.2.x requires the published `@openpresentation/opf@^0.4.1` for composit
418
418
 
419
419
  For actual font measurement, load `loadBundledFontRegistry()` from `@openpresentation/opf-render/fonts-node`, then pass its `textMeasurement` to rendering and its `embeddedFonts` to SVG export. Pass its `fontFiles` to PNG/PDF conversion. The browser-safe `@openpresentation/opf-render/fonts` entry accepts local font bytes. Missing fonts/glyphs fail explicitly; aliases and fallback are opt-in and recorded in `registry.substitutions`. Bundled font license notices travel with embedded SVG fonts.
420
420
 
421
- Raster updates produce an HTML gallery and `artifacts/golden/candidate.json`; they never overwrite the approved baseline automatically. See [baseline review and known limitations](test/golden/README.md).
421
+ Raster updates produce an HTML gallery and `artifacts/golden/candidate.json`; they never overwrite the approved baseline automatically (baselines are directories with one file per deck; `npm run golden:promote` writes only the decks that moved). See [baseline review and known limitations](test/golden/README.md).
422
422
 
423
423
  Version 0.1.1 adds rich-text line offsets and measured boxes to opt-in SVG tracing, including blank lines, for editor caret placement. Normal SVG/PNG output is unchanged.
424
424
 
@@ -426,7 +426,7 @@ Version 0.1.1 adds rich-text line offsets and measured boxes to opt-in SVG traci
426
426
 
427
427
  PNG and PDF conversion now decode embedded WebP image data URIs to static PNG before rasterization. This preserves fit/crop, transparency, EXIF orientation and the first animation frame. The source SVG and OPF document remain unchanged; browser SVG output keeps the original embedded image. Both href and legacy xlink:href are supported, including base64 and percent-encoded data. This step does not resolve local filenames, download remote images or change the existing host imageResolver contract.
428
428
 
429
- The Node-only raster path lazily loads pinned Sharp 0.35.4, requiring Node 24 for this package and normal installation of its optional platform binaries. Browser exports do not include the decoder. Malformed embedded WebP produces image-conversion-failed with its data-opf-path when present, otherwise svg.images.N. Decoding has a 40-megapixel limit. PNG/PDF are static outputs; animation beyond the first frame and original image metadata are not retained.
429
+ The Node-only raster path lazily loads pinned Sharp 0.35.4, requiring Node 22 or later for this package and normal installation of its optional platform binaries. Browser exports do not include the decoder. Malformed embedded WebP produces image-conversion-failed with its data-opf-path when present, otherwise svg.images.N. Decoding has a 40-megapixel limit. PNG/PDF are static outputs; animation beyond the first frame and original image metadata are not retained.
430
430
 
431
431
  Regression checks compare six fixtures against independent Pillow pixels, verify fit/crop, inspect actual PDF image streams and transparency masks, and exercise input encodings and diagnostics. All 805 existing raster baselines remain unchanged. Test fixtures are project-authored and MIT licensed; the decoder and its bundled codecs retain their upstream licenses.
432
432
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openpresentation/opf-render",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Deterministic local OPF renderer for SVG, PNG, and PDF output.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "private": false,
8
8
  "engines": {
9
- "node": "24.x"
9
+ "node": ">=22"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
@@ -82,15 +82,19 @@
82
82
  ],
83
83
  "scripts": {
84
84
  "build": "node scripts/build.mjs",
85
- "typecheck": "node --check src/index.js && node --check src/annotations.js && node --check test/annotations.mjs && node --check src/color-fonts.js && node --check test/emoji-math.mjs && node --check test/emoji-math-browser.mjs && node --check src/symbol-fonts.js && node --check src/symbol-encodings.js && node --check scripts/update-symbol-encodings.mjs && node --check test/symbol-fonts.mjs && node --check test/symbol-fonts-browser.mjs && node --check scripts/build.mjs && node --check scripts/validate-package.mjs && node --check test/smoke.mjs && node --check test/golden.mjs && node --check src/fonts.js && node --check src/script-fonts.js && node --check src/script-font-pack.js && node --check test/script-fonts.mjs && node --check test/theme-slots.mjs && node --check test/arabic-size-adjust.mjs && node --check test/glyph-fallback.mjs && node --check test/script-fonts-browser.mjs && node --check test/script-fonts-auto.mjs && node --check test/script-fonts-auto-robust.mjs && node --check test/mongolian-shaping.mjs && node --check scripts/script-corpora.mjs && node --check scripts/measure-script-references.mjs && node --check scripts/script-line-breaks.mjs && node --check test/script-corpora.mjs && node --check test/script-corpora-raster.mjs && node --check test/script-corpora-browser.mjs && node --check test/script-corpora-slides-browser.mjs && node --check src/raster-text.js && node --check test/raster-script-clusters.mjs && node --check test/script-fonts-auto-browser.mjs && node --check src/fonts-node.js && node --check src/font-compatibility.js && node --check test/office-fonts.mjs && node --check test/font-policy.mjs && node --check test/open-fonts.mjs && node --check test/aptos-preview.mjs && node --check test/aptos-preview-browser.mjs && node --check test/lazy-fonts.mjs && node --check test/extra-lazy-fonts.mjs && node --check test/extra-lazy-fonts-browser.mjs && node --check test/lazy-faces.mjs && node --check test/lazy-fonts-browser.mjs && node --check test/lazy-face-fallback.mjs && node --check test/lazy-face-fallback-browser.mjs && node --check src/font-policy.js && node --check scripts/update-font-policy.mjs && node --check src/fonts-browser.js && node --check test/fonts-browser.mjs && node --check src/svg.js && node --check src/raster.js && node --check src/raster-images.js && node --check test/webp.mjs && node --check test/jpeg-orientation.mjs && node --check scripts/build-browser-check.mjs && node --check test/jpeg-browser.js && node --check test/rich-table.mjs && node --check test/rich-tab.mjs && node --check test/rich-tab-browser.mjs && node --check test/rich-tab-estimated-browser.mjs && node --check scripts/variable-font-gate.mjs && node --check test/platform-residual-probe.mjs && node --check test/variable-font-retained-gate.mjs && node --check test/styled-table.mjs && node --check test/color-references.mjs && node --check test/catalog-source-array-and-background-refs.mjs && node --check test/default-font-scheme.mjs && node --check test/chart-colors.mjs && node --check test/chart-axis.mjs && node --check test/chart-category-labels.mjs && node --check src/charts.js && node --check src/chart-options.js && node --check test/chart-options.mjs && node --check test/chart-types.mjs && node --check test/chart-scale.mjs && node --check test/chart-catalog.mjs && node --check test/image-placeholders.mjs && node --check test/svg-image.mjs && node --check test/image-placeholders-browser.mjs && node --check test/accepted-text.mjs && node --check test/accepted-text-fixtures.mjs && node --check test/accepted-text-browser.mjs && node --check test/rich-spacing-browser.mjs && node --check test/rich-flow-browser.mjs && node --check test/rich-flow-review-sheets.mjs && node --check test/furniture.mjs && node --check test/socials.mjs && node --check test/slide-image.mjs && node --check test/slide-image-treatments.mjs && node --check test/item-alignment.mjs && node --check test/rtl-layout.mjs && node --check test/numbered-lists.mjs && node --check test/tag-colour.mjs && node --check test/design-fields.mjs && node --check test/cover-centering.mjs && node --check scripts/font-license.mjs && node --check test/font-licenses.mjs && node --check scripts/check-font-hotlinks.mjs && node --check scripts/check-font-hotlinks.test.mjs && node --check test/gallery-layout-alignment.mjs && npm run test:pdf-vector && node --check src/pdf-vector.js && node --check src/pdf-text.js && node --check src/pdf-fonts.js && node --check src/pdf-subset.js && node --check src/pdf-style.js && node --check src/pdf-xml.js && node --check src/pdf-writer.js && node --check test/pdf-helpers.mjs && node --check test/pdf-vector.mjs && node --check test/pdf-vector-visual.mjs && node --check src/sha256.js && node --check src/export-browser.js && node --check test/export-browser.mjs && node --check src/deck-runtime.js && node --check src/preview-fonts.js && node --check src/preview-fonts-node.js && node --check src/preview-fonts-cli.js && node --check src/element.js && node --check src/element-define.js && node --check src/player.js && node --check test/player-unit.mjs && node --check test/player-browser.mjs && node --check test/latin-family-fixture.mjs && node --check test/latin-family-hosts.mjs && node --check test/latin-family-hosts-browser.mjs && node --check test/preview-polish.mjs && node --check scripts/derive-pattern-bitmaps.mjs",
85
+ "typecheck": "node scripts/check-syntax.mjs src test scripts",
86
86
  "validate": "node scripts/validate-package.mjs",
87
- "test": "npm run build && npm run check:fonts && node test/furniture.mjs && node test/emoji-math.mjs && node test/socials.mjs && node test/font-outlines.mjs && node test/symbol-fonts.mjs && node test/accepted-text.mjs && node test/image-placeholders.mjs && node test/svg-image.mjs && node test/slide-image.mjs && node test/slide-image-treatments.mjs && node test/chart-colors.mjs && node test/chart-axis.mjs && node test/chart-options.mjs && node test/chart-category-labels.mjs && node test/chart-types.mjs && node test/chart-scale.mjs && node test/chart-catalog.mjs && node test/smoke.mjs && node test/webp.mjs && node test/jpeg-orientation.mjs && node test/fonts.mjs && node test/office-fonts.mjs && node test/font-policy.mjs && node test/open-fonts.mjs && node test/aptos-preview.mjs && node test/lazy-fonts.mjs && node test/extra-lazy-fonts.mjs && node test/lazy-faces.mjs && node test/lazy-face-fallback.mjs && node test/timeline.mjs && node test/quote-footer.mjs && node test/shared-quote.mjs && node test/rich-trace.mjs && node test/rich-table.mjs && node test/rich-tab.mjs && node test/color-references.mjs && node test/template-variables.mjs && node test/catalog-source-array-and-background-refs.mjs && node test/default-font-scheme.mjs && node test/golden-gate.mjs && node test/golden.mjs && node test/fonts-browser.mjs && node test/raster-script-clusters.mjs && node test/script-fonts.mjs && node test/theme-slots.mjs && node test/arabic-size-adjust.mjs && node test/glyph-fallback.mjs && node test/script-fonts-auto.mjs && node test/script-fonts-auto-robust.mjs && node test/mongolian-shaping.mjs && node test/design-preview.mjs && node test/item-alignment.mjs && node test/rtl-layout.mjs && node test/numbered-lists.mjs && node test/tag-colour.mjs && node test/preview-polish.mjs && node test/design-fields.mjs && node test/gallery-layout-alignment.mjs && node test/cover-centering.mjs && node test/annotations.mjs && npm run build:browser-check && npm run test:styled-table && npm run test:pdf-vector && node test/player-unit.mjs && node test/latin-family-hosts.mjs",
87
+ "test": "npm run build && npm run check:fonts && node scripts/run-tests.mjs && npm run build:browser-check && npm run check:runners && npm run check:changes",
88
+ "test:contract": "npm run build && npm run check:fonts && node scripts/run-tests.mjs --suite contract && npm run build:browser-check",
89
+ "check:runners": "node --test scripts/run-tests.test.mjs",
90
+ "check:changes": "node --test scripts/changelog-fragments.test.mjs && node scripts/changelog-fragments.mjs check",
88
91
  "check:fonts": "node test/font-licenses.mjs && npm run check:font-hotlinks",
89
92
  "check:font-hotlinks": "node --test scripts/check-font-hotlinks.test.mjs && node scripts/check-font-hotlinks.mjs",
90
93
  "test:golden": "npm run build && node test/golden.mjs",
91
94
  "test:packed": "node test/packed-install.mjs",
92
95
  "test:browser": "npm run build:browser-check && node test/browser-check.mjs && node test/rich-tab-browser.mjs && node test/rich-tab-estimated-browser.mjs",
93
96
  "golden:update": "npm run build && node test/golden.mjs --update",
97
+ "golden:promote": "node scripts/golden-promote.mjs",
94
98
  "prepack": "npm run build",
95
99
  "build:browser-check": "node scripts/build-browser-check.mjs",
96
100
  "test:styled-table": "node test/styled-table.mjs",
@@ -110,6 +114,7 @@
110
114
  "test:lazy-face-fallback-browser": "node test/lazy-face-fallback-browser.mjs artifacts/lazy-face-fallback",
111
115
  "test:lazy-fonts-browser": "node test/lazy-fonts-browser.mjs artifacts/lazy-fonts",
112
116
  "test:latin-family-hosts-browser": "node test/latin-family-hosts-browser.mjs artifacts/latin-family-hosts",
117
+ "test:script-family-hosts-browser": "node test/script-family-hosts-browser.mjs artifacts/script-family-hosts",
113
118
  "test:extra-lazy-fonts-browser": "node test/extra-lazy-fonts-browser.mjs artifacts/extra-lazy-fonts",
114
119
  "test:script-fonts-browser": "node test/script-fonts-browser.mjs artifacts/script-fonts-browser.json",
115
120
  "test:script-corpora-browser": "node test/script-corpora-browser.mjs artifacts/script-corpora-browser.json && node test/script-corpora-slides-browser.mjs artifacts/script-corpora-slides-browser.json",
@@ -133,7 +138,7 @@
133
138
  "@expo-google-fonts/roboto": "0.4.3",
134
139
  "@expo-google-fonts/roboto-mono": "0.4.2",
135
140
  "@expo-google-fonts/tinos": "0.4.2",
136
- "@openpresentation/opf": "^0.12.0",
141
+ "@openpresentation/opf": "^0.12.2",
137
142
  "@resvg/resvg-js": "^2.6.2",
138
143
  "bidi-js": "1.1.0",
139
144
  "fontkit": "^2.0.4",