Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ jobs:
- run: python -m pip install pypdf==6.19.0 pypdfium2==5.14.0 fonttools==4.65.0 pillow==12.3.0
- run: python -m unittest discover -s test -p 'test_*.py'
- run: npm run verify:text
- name: Verify the installed engine fixes against independent expectations
run: |
node tools/render-engine-regressions.mjs
python tools/verify-engine-regressions.py
- name: Verify inline wrapping from the installed package
run: |
npm run render:inline
Expand All @@ -56,7 +60,7 @@ jobs:
npm run render:fonts -- --package-root output/font-baseline-consumer/node_modules/fullbleed --out output/font-baseline
npm run verify:fonts -- --evidence-root output/font-baseline --allow-legacy-metadata
npm run render:fonts
npm run verify:fonts -- --baseline output/font-baseline --reviewed-layout test/fixtures/inline-layout-2.5.11.json
npm run verify:fonts -- --baseline output/font-baseline --reviewed-layout test/fixtures/inline-layout-2.5.22.json
- name: Verify installed custom font families against explicit faces
run: |
npm run render:families
Expand Down Expand Up @@ -96,6 +100,7 @@ jobs:
output/standard-baseline-consumer/package-lock.json
output/standard-baseline/
output/standard-fonts/
output/engine-regressions/
retention-days: 7

installed:
Expand Down Expand Up @@ -136,13 +141,15 @@ jobs:
run: |
python -m pip install pypdf==6.19.0 pypdfium2==5.14.0 fonttools==4.65.0 pillow==12.3.0
npm run render:fonts
npm run verify:fonts -- --reviewed-layout test/fixtures/inline-layout-2.5.11.json
npm run verify:fonts -- --reviewed-layout test/fixtures/inline-layout-2.5.22.json
npm run render:families
npm run verify:families
npm run render:inline
npm run verify:inline
npm run render:standard
npm run verify:standard
node tools/render-engine-regressions.mjs
python tools/verify-engine-regressions.py
- uses: actions/upload-artifact@v4
if: always() && matrix.os == 'windows-latest' && matrix.node == '22'
with:
Expand All @@ -152,6 +159,7 @@ jobs:
output/font-families/
output/inline-wrapping/
output/standard-fonts/
output/engine-regressions/
retention-days: 7
- uses: actions/upload-artifact@v4
if: always()
Expand Down Expand Up @@ -208,6 +216,7 @@ jobs:
- run: python -m playwright install --with-deps ${{ matrix.browser }}
timeout-minutes: 5
- run: python tools/check-browser.py --browser ${{ matrix.browser }} --label ci
- run: python tools/verify-engine-regressions.py output/browser-${{ matrix.browser }}-ci --browser
- uses: actions/upload-artifact@v4
if: always()
with:
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ also includes a ZIP for local development.
Using Vue? The [Vue and TypeScript starter](examples/vue) includes editable
templates, automatic previews, downloads, and a reusable `usePdfPreview` composable.

This is an optional integration around the published **Fullbleed 2.5.11** engine.
The package has its own version, **0.4.0**. Node applications can use a shared
This is an optional integration around the published **Fullbleed 2.5.22** engine.
The package has its own version, **0.4.1**. Node applications can use a shared
render queue to bound active renders and waiting requests, include queue time in
deadlines, cancel waiting jobs, and stop rendering cleanly during shutdown.
The browser entry renders in a Web Worker, and the Node API supports worker and
Expand All @@ -25,6 +25,11 @@ process isolation. See the [browser guide](docs/browser.md),
[font-family checks](https://github.com/fullbleed-engine/fullbleed-node/blob/main/docs/font-families.md), and
[embedded-font checks](https://github.com/fullbleed-engine/fullbleed-node/blob/main/docs/font-subsets.md) for the retained fixtures.

Version 0.4.1 brings the engine's recent layout fixes to both JavaScript entries.
The [engine update checks](https://github.com/fullbleed-engine/fullbleed-node/blob/main/docs/engine-2.5.22.md)
cover nested counters, clipped effects, border-image tiling, and floated initials
with independent text, color, and Chrome print expectations.

## Install and render

Use Node.js 22 or newer. Install the [npm package](https://www.npmjs.com/package/fullbleed):
Expand All @@ -33,7 +38,7 @@ Use Node.js 22 or newer. Install the [npm package](https://www.npmjs.com/package
npm install fullbleed
```

For a version-pinned installation, use `npm install --save-exact fullbleed@0.4.0`.
For a version-pinned installation, use `npm install --save-exact fullbleed@0.4.1`.
Package archives and retained PDF/PNG evidence are attached to each
[GitHub release](https://github.com/fullbleed-engine/fullbleed-node/releases).
The [installation verification records](https://github.com/fullbleed-engine/fullbleed-node/tree/main/verification)
Expand Down
6 changes: 3 additions & 3 deletions docs/browser.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Generate PDFs in a browser

The `fullbleed/browser` entry in Fullbleed 0.3.2 renders static HTML/CSS in a
dedicated Web Worker. It uses the same pinned 2.5.11 engine and bundled fonts as
The `fullbleed/browser` entry in Fullbleed 0.4.1 renders static HTML/CSS in a
dedicated Web Worker. It uses the same pinned 2.5.22 engine and bundled fonts as
the Node entry. The result is a `Uint8Array`, suitable for a PDF `Blob`, plus
optional PNG previews. No PDF server or account is required.

Expand All @@ -17,7 +17,7 @@ Install the package in your web project, then copy its browser files into the
directory your application serves as static files:

```sh
npm install --save-exact fullbleed@0.3.2
npm install --save-exact fullbleed@0.4.1
npx fullbleed-browser-assets public/fullbleed
```

Expand Down
55 changes: 55 additions & 0 deletions docs/engine-2.5.22.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Engine 2.5.22 in JavaScript

Package 0.4.1 bundles the unmodified published Fullbleed 2.5.22 crate. Its Node
and browser entries use the same WebAssembly engine. Install it with:

```sh
npm install --save-exact fullbleed@0.4.1
```

The adapter now enables the engine's `svg_raster` feature so SVG border images
can use its native raster fallback. This adds no external rendering dependency.
The build and copied browser manifests record the enabled feature.

The public JavaScript API and its memory limit are unchanged. Review existing
PDF baselines when upgrading: corrected layout can change document appearance.

The [fixture provenance](../test/fixtures/engine-2.5.22.json) retains thirteen
focused cases from the engine release, including the original expected results:

| Document behavior | Independent check |
| --- | --- |
| Numbered sections and nested counters | Extracted labels, including resets across pages |
| Filtered content inside clipped containers | Interior pixel colors in finalized previews and independently rendered PDFs |
| Border images with insufficient space or a zero edge | Raster and SVG tile colors and empty regions |
| Decorated left/right initials and pagination | Character positions and colored bounds from retained Chrome print references using identical font bytes |

The Node fixture runner renders through worker and process isolation and checks
repeat output and equality between the two modes. The native adapter comparison
covers these same fixtures. The browser checks download the actual PDFs and
previews, compare their hashes with the installed npm package, then apply the
independent expectations to the downloads.

The custom Noto Sans font is a licensed test asset. It is excluded from the npm
tarball and does not add an application dependency.

From a built source checkout, with the verifier dependencies installed:

```sh
npm run verify:pack
node tools/render-engine-regressions.mjs
python tools/verify-engine-regressions.py
npm run verify:browser:prepare
python tools/check-browser.py --browser chrome --label candidate
python tools/verify-engine-regressions.py output/browser-chrome-candidate --browser
```

Use a fresh output directory for each retained run. `render-engine-regressions.mjs`
accepts `--out` and `--package-root` to check a separate installed package. For
the public 0.4.0 comparison, pass `--negative-control` to the Python verifier;
it requires at least one failing case in each of the four fix families.

These are targeted integration checks. They do not establish complete CSS
parity or PDF/UA, PDF/A, PDF/X, or PDF/VT conformance. The known runtime diagnostic
in [issue #7](https://github.com/fullbleed-engine/fullbleed-node/issues/7) remains
separate from this engine update.
8 changes: 4 additions & 4 deletions docs/font-subsets.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Checking the installed package's embedded fonts

Node package 0.1.4 introduced the Fullbleed 2.5.7 font compaction described here;
0.3.2 retains these checks with engine 2.5.11. The engine's font subsetting
0.4.1 retains these checks with engine 2.5.22. The engine's font subsetting
removes unused metadata and metrics while retaining original glyph IDs and the
glyph outlines, instructions, advances, character mappings, and font notices
needed by the document. The JavaScript API and four bundled font faces are
Expand All @@ -20,8 +20,8 @@ horizontal metrics, and header extrema. Both readers must extract the same text.
The repeated PDFs must be byte-identical. In the comparison with 0.1.3, all seven
PDFs must be smaller and retain their normalized text and page counts. The five
font-only specimens must also retain exact text, native previews, and PDFium
page pixels. The invoice and report match the unchanged, reviewed 2.5.11 layout in
[`test/fixtures/inline-layout-2.5.11.json`](../test/fixtures/inline-layout-2.5.11.json),
page pixels. The invoice and report match the unchanged, reviewed 2.5.22 layout in
[`test/fixtures/inline-layout-2.5.22.json`](../test/fixtures/inline-layout-2.5.22.json),
including PDF hashes. Their tracked labels and footers stay on one line after
the inline-sizing correction. Reports explicitly record that these two layouts
differ from 0.1.3; they do not report unchanged pixels. Source HTML/CSS and font
Expand All @@ -37,7 +37,7 @@ npm install --prefix output/font-baseline-consumer --ignore-scripts --no-audit -
npm run render:fonts -- --package-root output/font-baseline-consumer/node_modules/fullbleed --out output/font-baseline
npm run verify:fonts -- --evidence-root output/font-baseline --allow-legacy-metadata
npm run render:fonts
npm run verify:fonts -- --baseline output/font-baseline --reviewed-layout test/fixtures/inline-layout-2.5.11.json
npm run verify:fonts -- --baseline output/font-baseline --reviewed-layout test/fixtures/inline-layout-2.5.22.json
```

The legacy flag applies only to the old package's metadata; outlines, metrics,
Expand Down
6 changes: 3 additions & 3 deletions engine/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions engine/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[package]
name = "fullbleed-node-adapter"
version = "0.4.0"
version = "0.4.1"
edition = "2024"
license = "MIT"
publish = false

[dependencies]
fullbleed = "=2.5.11"
fullbleed = { version = "=2.5.22", features = ["svg_raster"] }

[profile.release]
lto = true
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fullbleed",
"version": "0.4.0",
"version": "0.4.1",
"description": "Generate PDFs from HTML and CSS in Node.js or a browser worker with the Fullbleed Rust engine, bundled fonts, and optional PNG previews.",
"type": "module",
"main": "./src/index.cjs",
Expand Down Expand Up @@ -77,7 +77,7 @@
"access": "public"
},
"fullbleed": {
"engineVersion": "2.5.11"
"engineVersion": "2.5.22"
},
"devDependencies": {
"@types/node": "22.20.5",
Expand Down
2 changes: 1 addition & 1 deletion src/copy-browser-assets.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async function main() {
await writeFile(path, file.data);
}
await writeFile(join(destination, 'build.json'), JSON.stringify({ schema: manifest.schema,
packageVersion: pkg.version, engineVersion: manifest.engineVersion,
packageVersion: pkg.version, engineVersion: manifest.engineVersion, engineFeatures: manifest.engineFeatures,
files: Object.fromEntries(files.map(({ name, bytes, sha256 }) => [name, { bytes, sha256 }])) }, null, 2) + '\n');
console.log(JSON.stringify({ ok: true, directory: destination, packageVersion: pkg.version,
engineVersion: manifest.engineVersion, files: files.length + 1, bytes: files.reduce((sum, file) => sum + file.bytes, 0) }));
Expand Down
12 changes: 12 additions & 0 deletions test/engine-regressions.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
import { readFile } from 'node:fs/promises';

export const engineRegressionSource = JSON.parse(await readFile(new URL('./fixtures/engine-2.5.22.json', import.meta.url), 'utf8'));
export const engineRegressionFixtures = engineRegressionSource.cases.map(({ name, pages, html, css, previewDpi, fontFiles = [] }) =>
({ name, pages, html, css, previewDpi, fontFiles }));

export async function loadEngineRegressionFixtures() {
return Promise.all(engineRegressionFixtures.map(async ({ fontFiles, ...fixture }) => ({ ...fixture,
fonts: await Promise.all(fontFiles.map(name => readFile(new URL('./fonts/' + name, import.meta.url)))),
})));
}
Loading
Loading