fullbleed 2.1.0__tar.gz → 2.2.2__tar.gz
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.
- fullbleed-2.2.2/Cargo.lock +37 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/Cargo.toml +4 -2
- {fullbleed-2.1.0 → fullbleed-2.2.2}/PKG-INFO +48 -12
- {fullbleed-2.1.0 → fullbleed-2.2.2}/README.md +47 -11
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/Cargo.lock +1 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/Cargo.toml +1 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/src/lib.rs +52 -15
- {fullbleed-2.1.0 → fullbleed-2.2.2}/pyproject.toml +1 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/_abi.py +19 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/core.py +21 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/assets.rs +7 -2
- fullbleed-2.2.2/src/canvas.rs +1852 -0
- fullbleed-2.2.2/src/doc_context.rs +89 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/doc_template.rs +395 -81
- fullbleed-2.2.2/src/flowable.rs +44293 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/font.rs +731 -76
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/font_subset.rs +1 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/frame.rs +89 -14
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html.rs +6033 -622
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/image_native.rs +388 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/jit.rs +56 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/lib.rs +4503 -213
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/native_shape.rs +52 -7
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/page_template.rs +58 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/pdf.rs +2833 -144
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/pdf_raster.rs +1 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/python/abi_exports.rs +33 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/python.rs +2 -1
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/raster.rs +2025 -137
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/raster_native.rs +148 -12
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/sfnt.rs +43 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/spill.rs +703 -21
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/style.rs +9888 -653
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/svg.rs +159 -35
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/text_shape.rs +121 -11
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/types.rs +101 -0
- fullbleed-2.1.0/Cargo.lock +0 -14
- fullbleed-2.1.0/src/canvas.rs +0 -892
- fullbleed-2.1.0/src/doc_context.rs +0 -14
- fullbleed-2.1.0/src/flowable.rs +0 -23941
- {fullbleed-2.1.0 → fullbleed-2.2.2}/COPYRIGHT +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/FONT_LICENSE_AUDIT.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/FONT_LICENSE_AUDIT.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/LICENSE +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/LICENSING.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/THIRD_PARTY_LICENSES.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/build.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/build_backend/fullbleed_build_backend.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/LICENSE +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/README.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/specs/fullbleed.audit_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/specs/section508_html_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/specs/wcag20aa_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/src/json.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/crates/fullbleed_audit_contract/src/sha256.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/docs/specs/fullbleed.a11y.verify.v1.schema.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/docs/specs/fullbleed.audit_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/docs/specs/fullbleed.pmr.v1.schema.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/docs/specs/section508_html_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/docs/specs/wcag20aa_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/__main__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/accessibility/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/accessibility/engine.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/accessibility/runtime.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/accessibility/types.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/audit_prototype.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/audit_section508.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/audit_wcag.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/accessibility.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/_core.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/agency_letter.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/court_motion_form.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/declaration_form.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/instruction_sheet.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/investment_portfolio_report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/marriage_record.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/profiles.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/recorded_plat.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/redaction_request_form.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/cav/warranty_deed.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/primitives.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed/ui/style.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/bootstrap.min.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/fonts/Inter-Variable.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/fonts/NotoSans-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/fonts/NotoSansMath-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/fonts/NotoSansSymbols-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/fonts/NotoSansSymbols2-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_assets/icons/bootstrap-icons.svg +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/__main__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/assets.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/cache.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/cli.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/finalize.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/COMPLIANCE.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/SCAFFOLDING.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/body.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/fb_ui.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/footer.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/header.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/primitives.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/styles/body.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/styles/footer.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/styles/header.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/components/styles/primitives.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/styles/report.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/init/styles/tokens.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/accessible/README.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/accessible/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/accessible/output/.gitkeep +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/accessible/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/accessible/styles/report.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/accessible/vendor/fonts/Inter-Variable.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/invoice/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/invoice/output/.gitkeep +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/invoice/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/invoice/templates/invoice.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/invoice/templates/invoice.html +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/COMPLIANCE.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/README.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/SCAFFOLDING.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/assets/brand-mark.svg +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/assets/reference-pattern.svg +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/appendix.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/architecture.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/cover.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/data_pages.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/fb_ui.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/primitives.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/appendix.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/architecture.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/cover.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/data.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/primitives.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/visuals.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/components/visuals.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/data/reference.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/styles/report.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/reference/styles/tokens.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/statement/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/statement/output/.gitkeep +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/statement/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/statement/templates/statement.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/python/fullbleed_cli/scaffold_templates/new/statement/templates/statement.html +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/base64.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/css_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/css_queries.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/debug.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/error.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/finalize.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/flate_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/glyph_report.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_dom.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities_0.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities_1.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities_2.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities_3.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities_4.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/html_entities_5.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/jpeg_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/math.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/metrics.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/page_data.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/parallel.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/pdf_encodings.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/pdf_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/pdfinspect.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/perf.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/plan.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/python_abi.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/sfnt_cff.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/sfnt_outline.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/unicode_data.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.2}/src/xml.rs +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "fullbleed"
|
|
7
|
+
version = "2.2.2"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"fullbleed_audit_contract",
|
|
10
|
+
"subsetter",
|
|
11
|
+
"unicode-bidi",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "fullbleed_audit_contract"
|
|
16
|
+
version = "0.1.3"
|
|
17
|
+
|
|
18
|
+
[[package]]
|
|
19
|
+
name = "rustc-hash"
|
|
20
|
+
version = "2.1.3"
|
|
21
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
22
|
+
checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
|
|
23
|
+
|
|
24
|
+
[[package]]
|
|
25
|
+
name = "subsetter"
|
|
26
|
+
version = "0.2.6"
|
|
27
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
28
|
+
checksum = "38803281d1c23166c5ebcb455439a5d2afe711cc909cf88af72448c297756ad6"
|
|
29
|
+
dependencies = [
|
|
30
|
+
"rustc-hash",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[[package]]
|
|
34
|
+
name = "unicode-bidi"
|
|
35
|
+
version = "0.3.18"
|
|
36
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
37
|
+
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "fullbleed"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.2.2"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
rust-version = "1.85"
|
|
6
6
|
license = "MIT"
|
|
@@ -37,4 +37,6 @@ inherits = "release"
|
|
|
37
37
|
debug = true
|
|
38
38
|
|
|
39
39
|
[dependencies]
|
|
40
|
-
fullbleed_audit_contract = { version = "0.1.
|
|
40
|
+
fullbleed_audit_contract = { version = "0.1.3", path = "crates/fullbleed_audit_contract" }
|
|
41
|
+
subsetter = { version = "0.2.6", default-features = false }
|
|
42
|
+
unicode-bidi = "0.3.18"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fullbleed
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Classifier: Development Status :: 5 - Production/Stable
|
|
5
5
|
Classifier: License :: OSI Approved :: MIT License
|
|
6
6
|
Classifier: Operating System :: MacOS
|
|
@@ -91,7 +91,8 @@ Additional focused references are in `docs/`:
|
|
|
91
91
|
- Python-first extension surface for hackability and custom workflows.
|
|
92
92
|
- Python render calls release the GIL while Rust rendering executes.
|
|
93
93
|
- Ordered standard-library worker pools for batch rendering and selected internal workloads.
|
|
94
|
-
-
|
|
94
|
+
- A deliberately small, license-audited Rust dependency graph and no required third-party Python
|
|
95
|
+
runtime or build packages.
|
|
95
96
|
|
|
96
97
|
## Concurrency Model
|
|
97
98
|
|
|
@@ -100,11 +101,11 @@ Additional focused references are in `docs/`:
|
|
|
100
101
|
- The same bounded worker implementation serves selected internal hotspots such as table layout and JIT paint paths.
|
|
101
102
|
- Do not assume every single-document render path will fully saturate all cores end-to-end.
|
|
102
103
|
|
|
103
|
-
## Performance in 2.
|
|
104
|
+
## Performance in 2.2
|
|
104
105
|
|
|
105
|
-
Fullbleed 2.
|
|
106
|
-
the five independent benchmark fixtures, PDFs are 95.5-97.3% smaller and ordinary
|
|
107
|
-
is 2.90x faster by geometric mean than released 2.0.0.
|
|
106
|
+
Fullbleed 2.2 retains exact TrueType glyph subsetting and adds compiled fixed-geometry variable-data
|
|
107
|
+
binding. Across the five independent benchmark fixtures, PDFs are 95.5-97.3% smaller and ordinary
|
|
108
|
+
warm rendering is 2.90x faster by geometric mean than released 2.0.0.
|
|
108
109
|
|
|
109
110
|
The new compile-once API freezes an immutable Q32.32 display document and can link it repeatedly
|
|
110
111
|
without rerunning HTML parsing, selector matching, layout, pagination, or command planning. For
|
|
@@ -113,8 +114,24 @@ source page's content stream across the copied page dictionaries. The measured 2
|
|
|
113
114
|
200.7x faster per page by geometric mean than the released 2.0.0 warm renderer; a 1,000-page stress
|
|
114
115
|
run sustained 304,479-666,622 pages/s.
|
|
115
116
|
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
The 2.2 compiler includes a genuine fixed-geometry variable-data lane. A compiled invoice
|
|
118
|
+
with six bound fields rendered 100,000 distinct records in a five-run median of 283.807 ms to
|
|
119
|
+
memory (**352,352 pages/s**) and 295.999 ms directly to a flushed 88.1 MB PDF
|
|
120
|
+
(**337,839 pages/s**). Including the one-time 4.168 ms compile gives 333,147 direct-file pages/s.
|
|
121
|
+
The harness verified all 100,000 unique invoice IDs in page order, exact page count, resolved
|
|
122
|
+
markers, deterministic bytes, and equal buffer/file SHA-256. Reproduce it with:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
python tools/benchmark_fullbleed_vdp.py --records 100000 --repeats 5
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Fixed-geometry slots may remain inside immutable page-space transforms and clips. The compiler
|
|
129
|
+
captures that active coordinate-state program once and replays it in each compact record overlay;
|
|
130
|
+
it does not rerun layout or clone the complete page display list.
|
|
131
|
+
|
|
132
|
+
The fixed-copy result remains scoped to identical content; the variable-data result is scoped to
|
|
133
|
+
paint-only text whose geometry does not reflow. Neither is a claim that arbitrary new HTML or
|
|
134
|
+
size-changing records render 200x faster. See
|
|
118
135
|
[`docs/performance-pass-2026-08-04.md`](docs/performance-pass-2026-08-04.md) for measurements and
|
|
119
136
|
[`docs/performance-architecture.md`](docs/performance-architecture.md) for the packed vector IR,
|
|
120
137
|
typed-binding, virtual-linker, and shader roadmap.
|
|
@@ -130,7 +147,7 @@ python -m pip install fullbleed
|
|
|
130
147
|
From a local wheel:
|
|
131
148
|
|
|
132
149
|
```bash
|
|
133
|
-
python -m pip install C:\path\to\fullbleed-2.
|
|
150
|
+
python -m pip install C:\path\to\fullbleed-2.2.2-cp310-abi3-win_amd64.whl
|
|
134
151
|
```
|
|
135
152
|
|
|
136
153
|
From a source checkout with Rust installed, no Python build package is needed:
|
|
@@ -776,6 +793,20 @@ Summary as of May 19, 2026:
|
|
|
776
793
|
- Canonical validation artifact: `_css_working/tmp/fixture_full_latest.json`
|
|
777
794
|
- Canonical validation artifact: `_css_working/css_broad_coverage_sprint_s14.md`
|
|
778
795
|
|
|
796
|
+
The complete pinned independent Wheel265 gate closed on August 9, 2026 with `1,642 PASS`,
|
|
797
|
+
`0 FAIL`, and `20 REFERENCE-DISPUTED` across 1,662 fixtures. That is strict `100%` parity for
|
|
798
|
+
every adjudicable fixture in this named corpus; disputed references remain visible and are not
|
|
799
|
+
relabeled as implementation passes. Broader web-platform coverage remains bounded by the module
|
|
800
|
+
and known-gap contract in `docs/css-coverage.md`.
|
|
801
|
+
|
|
802
|
+
Flow/reflow hardening validated on August 5, 2026 adds fixed-height block,
|
|
803
|
+
one-column grid, and column-flex continuation slicing; avoids content
|
|
804
|
+
duplication; retains empty styled captions inside avoided figures; preserves
|
|
805
|
+
`display: contents` grid paint phase; and keeps positioned containing blocks
|
|
806
|
+
atomic. The independent review's targeted 18-case regression cluster passes
|
|
807
|
+
`18/18` (13 pixel-exact, maximum above-floor difference `0.97030199%`). This
|
|
808
|
+
targeted diagnostic does not replace the full external-corpus report.
|
|
809
|
+
|
|
779
810
|
Current validated behavior includes first-class parser -> evaluator -> calculator -> layout/paint coverage across broad static-document CSS domains (values math, layout primitives, pagination/fragmentation baselines, transforms phase-1, gradient/effects subsets including color-first and interleaved-color `filter: drop-shadow(...)` with computed lengths, modern `rgb()` shadow colors with `mm` lengths, duplicate `drop-shadow(...)` color rejection, empty optional filter-function defaults, explicit/currentColor `backdrop-filter: drop-shadow(...)` raster paint, strict `box-shadow` length/color grammar with modern `rgb()` plus `mm` paint coverage, softened blurred inset edge paint, and directional inset offset edge paint, overflow-gated `text-overflow: ellipsis`, physical min/max box constraints, horizontal-tb RTL `direction` inline inset/margin/padding/border mapping, vertical writing-mode `direction: rtl` inline inset remapping, vertical-rl logical sizing/insets/margin/padding/border/min-max constraints, vertical-lr logical sizing/min-max/insets/margin/padding/border remapping, basic vertical text columns with `vertical-rl` leftward and `vertical-lr` rightward line progression, and deterministic diagnostics).
|
|
780
811
|
|
|
781
812
|
Known gap categories are explicitly tracked for the final parity push:
|
|
@@ -972,9 +1003,14 @@ Module exports:
|
|
|
972
1003
|
| `render_pdf(deterministic_hash=None)` | `bytes` |
|
|
973
1004
|
| `render_pdf_to_file(path, deterministic_hash=None)` | `int` |
|
|
974
1005
|
| `render_pdf_batch(copies, deterministic_hash=None)` | `bytes` |
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1006
|
+
| `render_pdf_bindings(bindings, deterministic_hash=None)` | `bytes` |
|
|
1007
|
+
| `render_pdf_bindings_to_file(bindings, path, deterministic_hash=None)` | `int` |
|
|
1008
|
+
|
|
1009
|
+
The compiled lane runs parsing/layout once. `render_pdf_batch` virtualizes identical untagged page
|
|
1010
|
+
content. The binding methods instead accept columnar `dict[str, list[str]]` data and emit distinct
|
|
1011
|
+
fixed-geometry text overlays per record while sharing static paint. They require exact slot keys,
|
|
1012
|
+
equal non-zero column lengths, page-local WinAnsi-compatible text, and an untagged profile; bound
|
|
1013
|
+
values do not trigger reflow.
|
|
978
1014
|
|
|
979
1015
|
When `deterministic_hash` is set, engine writes PDF SHA-256 to the provided file path.
|
|
980
1016
|
|
|
@@ -54,7 +54,8 @@ Additional focused references are in `docs/`:
|
|
|
54
54
|
- Python-first extension surface for hackability and custom workflows.
|
|
55
55
|
- Python render calls release the GIL while Rust rendering executes.
|
|
56
56
|
- Ordered standard-library worker pools for batch rendering and selected internal workloads.
|
|
57
|
-
-
|
|
57
|
+
- A deliberately small, license-audited Rust dependency graph and no required third-party Python
|
|
58
|
+
runtime or build packages.
|
|
58
59
|
|
|
59
60
|
## Concurrency Model
|
|
60
61
|
|
|
@@ -63,11 +64,11 @@ Additional focused references are in `docs/`:
|
|
|
63
64
|
- The same bounded worker implementation serves selected internal hotspots such as table layout and JIT paint paths.
|
|
64
65
|
- Do not assume every single-document render path will fully saturate all cores end-to-end.
|
|
65
66
|
|
|
66
|
-
## Performance in 2.
|
|
67
|
+
## Performance in 2.2
|
|
67
68
|
|
|
68
|
-
Fullbleed 2.
|
|
69
|
-
the five independent benchmark fixtures, PDFs are 95.5-97.3% smaller and ordinary
|
|
70
|
-
is 2.90x faster by geometric mean than released 2.0.0.
|
|
69
|
+
Fullbleed 2.2 retains exact TrueType glyph subsetting and adds compiled fixed-geometry variable-data
|
|
70
|
+
binding. Across the five independent benchmark fixtures, PDFs are 95.5-97.3% smaller and ordinary
|
|
71
|
+
warm rendering is 2.90x faster by geometric mean than released 2.0.0.
|
|
71
72
|
|
|
72
73
|
The new compile-once API freezes an immutable Q32.32 display document and can link it repeatedly
|
|
73
74
|
without rerunning HTML parsing, selector matching, layout, pagination, or command planning. For
|
|
@@ -76,8 +77,24 @@ source page's content stream across the copied page dictionaries. The measured 2
|
|
|
76
77
|
200.7x faster per page by geometric mean than the released 2.0.0 warm renderer; a 1,000-page stress
|
|
77
78
|
run sustained 304,479-666,622 pages/s.
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
The 2.2 compiler includes a genuine fixed-geometry variable-data lane. A compiled invoice
|
|
81
|
+
with six bound fields rendered 100,000 distinct records in a five-run median of 283.807 ms to
|
|
82
|
+
memory (**352,352 pages/s**) and 295.999 ms directly to a flushed 88.1 MB PDF
|
|
83
|
+
(**337,839 pages/s**). Including the one-time 4.168 ms compile gives 333,147 direct-file pages/s.
|
|
84
|
+
The harness verified all 100,000 unique invoice IDs in page order, exact page count, resolved
|
|
85
|
+
markers, deterministic bytes, and equal buffer/file SHA-256. Reproduce it with:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
python tools/benchmark_fullbleed_vdp.py --records 100000 --repeats 5
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Fixed-geometry slots may remain inside immutable page-space transforms and clips. The compiler
|
|
92
|
+
captures that active coordinate-state program once and replays it in each compact record overlay;
|
|
93
|
+
it does not rerun layout or clone the complete page display list.
|
|
94
|
+
|
|
95
|
+
The fixed-copy result remains scoped to identical content; the variable-data result is scoped to
|
|
96
|
+
paint-only text whose geometry does not reflow. Neither is a claim that arbitrary new HTML or
|
|
97
|
+
size-changing records render 200x faster. See
|
|
81
98
|
[`docs/performance-pass-2026-08-04.md`](docs/performance-pass-2026-08-04.md) for measurements and
|
|
82
99
|
[`docs/performance-architecture.md`](docs/performance-architecture.md) for the packed vector IR,
|
|
83
100
|
typed-binding, virtual-linker, and shader roadmap.
|
|
@@ -93,7 +110,7 @@ python -m pip install fullbleed
|
|
|
93
110
|
From a local wheel:
|
|
94
111
|
|
|
95
112
|
```bash
|
|
96
|
-
python -m pip install C:\path\to\fullbleed-2.
|
|
113
|
+
python -m pip install C:\path\to\fullbleed-2.2.2-cp310-abi3-win_amd64.whl
|
|
97
114
|
```
|
|
98
115
|
|
|
99
116
|
From a source checkout with Rust installed, no Python build package is needed:
|
|
@@ -739,6 +756,20 @@ Summary as of May 19, 2026:
|
|
|
739
756
|
- Canonical validation artifact: `_css_working/tmp/fixture_full_latest.json`
|
|
740
757
|
- Canonical validation artifact: `_css_working/css_broad_coverage_sprint_s14.md`
|
|
741
758
|
|
|
759
|
+
The complete pinned independent Wheel265 gate closed on August 9, 2026 with `1,642 PASS`,
|
|
760
|
+
`0 FAIL`, and `20 REFERENCE-DISPUTED` across 1,662 fixtures. That is strict `100%` parity for
|
|
761
|
+
every adjudicable fixture in this named corpus; disputed references remain visible and are not
|
|
762
|
+
relabeled as implementation passes. Broader web-platform coverage remains bounded by the module
|
|
763
|
+
and known-gap contract in `docs/css-coverage.md`.
|
|
764
|
+
|
|
765
|
+
Flow/reflow hardening validated on August 5, 2026 adds fixed-height block,
|
|
766
|
+
one-column grid, and column-flex continuation slicing; avoids content
|
|
767
|
+
duplication; retains empty styled captions inside avoided figures; preserves
|
|
768
|
+
`display: contents` grid paint phase; and keeps positioned containing blocks
|
|
769
|
+
atomic. The independent review's targeted 18-case regression cluster passes
|
|
770
|
+
`18/18` (13 pixel-exact, maximum above-floor difference `0.97030199%`). This
|
|
771
|
+
targeted diagnostic does not replace the full external-corpus report.
|
|
772
|
+
|
|
742
773
|
Current validated behavior includes first-class parser -> evaluator -> calculator -> layout/paint coverage across broad static-document CSS domains (values math, layout primitives, pagination/fragmentation baselines, transforms phase-1, gradient/effects subsets including color-first and interleaved-color `filter: drop-shadow(...)` with computed lengths, modern `rgb()` shadow colors with `mm` lengths, duplicate `drop-shadow(...)` color rejection, empty optional filter-function defaults, explicit/currentColor `backdrop-filter: drop-shadow(...)` raster paint, strict `box-shadow` length/color grammar with modern `rgb()` plus `mm` paint coverage, softened blurred inset edge paint, and directional inset offset edge paint, overflow-gated `text-overflow: ellipsis`, physical min/max box constraints, horizontal-tb RTL `direction` inline inset/margin/padding/border mapping, vertical writing-mode `direction: rtl` inline inset remapping, vertical-rl logical sizing/insets/margin/padding/border/min-max constraints, vertical-lr logical sizing/min-max/insets/margin/padding/border remapping, basic vertical text columns with `vertical-rl` leftward and `vertical-lr` rightward line progression, and deterministic diagnostics).
|
|
743
774
|
|
|
744
775
|
Known gap categories are explicitly tracked for the final parity push:
|
|
@@ -935,9 +966,14 @@ Module exports:
|
|
|
935
966
|
| `render_pdf(deterministic_hash=None)` | `bytes` |
|
|
936
967
|
| `render_pdf_to_file(path, deterministic_hash=None)` | `int` |
|
|
937
968
|
| `render_pdf_batch(copies, deterministic_hash=None)` | `bytes` |
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
969
|
+
| `render_pdf_bindings(bindings, deterministic_hash=None)` | `bytes` |
|
|
970
|
+
| `render_pdf_bindings_to_file(bindings, path, deterministic_hash=None)` | `int` |
|
|
971
|
+
|
|
972
|
+
The compiled lane runs parsing/layout once. `render_pdf_batch` virtualizes identical untagged page
|
|
973
|
+
content. The binding methods instead accept columnar `dict[str, list[str]]` data and emit distinct
|
|
974
|
+
fixed-geometry text overlays per record while sharing static paint. They require exact slot keys,
|
|
975
|
+
equal non-zero column lengths, page-local WinAnsi-compatible text, and an untagged profile; bound
|
|
976
|
+
values do not trigger reflow.
|
|
941
977
|
|
|
942
978
|
When `deterministic_hash` is set, engine writes PDF SHA-256 to the provided file path.
|
|
943
979
|
|
|
@@ -298,6 +298,9 @@ fn hash_memoized(cell: &OnceLock<String>, text: &str) -> String {
|
|
|
298
298
|
static AUDIT_REGISTRY_HASH: OnceLock<String> = OnceLock::new();
|
|
299
299
|
static WCAG20AA_REGISTRY_HASH: OnceLock<String> = OnceLock::new();
|
|
300
300
|
static SECTION508_HTML_REGISTRY_HASH: OnceLock<String> = OnceLock::new();
|
|
301
|
+
static AUDIT_REGISTRY_TEXT: OnceLock<String> = OnceLock::new();
|
|
302
|
+
static WCAG20AA_REGISTRY_TEXT: OnceLock<String> = OnceLock::new();
|
|
303
|
+
static SECTION508_HTML_REGISTRY_TEXT: OnceLock<String> = OnceLock::new();
|
|
301
304
|
static CONTRACT_FINGERPRINT: OnceLock<String> = OnceLock::new();
|
|
302
305
|
static AUDIT_REGISTRY_JSON_VALUE: OnceLock<Value> = OnceLock::new();
|
|
303
306
|
static WCAG20AA_REGISTRY_JSON_VALUE: OnceLock<Value> = OnceLock::new();
|
|
@@ -306,23 +309,45 @@ static A11Y_DEFAULT_GATE_LEVELS: OnceLock<BTreeMap<String, String>> = OnceLock::
|
|
|
306
309
|
static A11Y_PROFILE_GATE_OVERRIDES: OnceLock<BTreeMap<String, BTreeMap<String, String>>> =
|
|
307
310
|
OnceLock::new();
|
|
308
311
|
|
|
312
|
+
fn canonical_lf(text: &str) -> String {
|
|
313
|
+
text.replace("\r\n", "\n").replace('\r', "\n")
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
fn audit_registry_text() -> &'static str {
|
|
317
|
+
AUDIT_REGISTRY_TEXT
|
|
318
|
+
.get_or_init(|| canonical_lf(AUDIT_REGISTRY_V1_JSON))
|
|
319
|
+
.as_str()
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
fn wcag20aa_registry_text() -> &'static str {
|
|
323
|
+
WCAG20AA_REGISTRY_TEXT
|
|
324
|
+
.get_or_init(|| canonical_lf(WCAG20AA_REGISTRY_V1_JSON))
|
|
325
|
+
.as_str()
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
fn section508_html_registry_text() -> &'static str {
|
|
329
|
+
SECTION508_HTML_REGISTRY_TEXT
|
|
330
|
+
.get_or_init(|| canonical_lf(SECTION508_HTML_REGISTRY_V1_JSON))
|
|
331
|
+
.as_str()
|
|
332
|
+
}
|
|
333
|
+
|
|
309
334
|
fn audit_registry_value() -> &'static Value {
|
|
310
335
|
AUDIT_REGISTRY_JSON_VALUE.get_or_init(|| {
|
|
311
|
-
json::parse(
|
|
336
|
+
json::parse(audit_registry_text())
|
|
312
337
|
.expect("embedded audit registry must be valid JSON-formatted YAML")
|
|
313
338
|
})
|
|
314
339
|
}
|
|
315
340
|
|
|
316
341
|
fn wcag20aa_registry_value() -> &'static Value {
|
|
317
342
|
WCAG20AA_REGISTRY_JSON_VALUE.get_or_init(|| {
|
|
318
|
-
json::parse(
|
|
343
|
+
json::parse(wcag20aa_registry_text())
|
|
319
344
|
.expect("embedded wcag20aa registry must be valid JSON-formatted YAML")
|
|
320
345
|
})
|
|
321
346
|
}
|
|
322
347
|
|
|
323
348
|
fn section508_html_registry_value() -> &'static Value {
|
|
324
349
|
SECTION508_HTML_REGISTRY_JSON_VALUE.get_or_init(|| {
|
|
325
|
-
json::parse(
|
|
350
|
+
json::parse(section508_html_registry_text())
|
|
326
351
|
.expect("embedded section508 html registry must be valid JSON-formatted YAML")
|
|
327
352
|
})
|
|
328
353
|
}
|
|
@@ -350,25 +375,25 @@ fn worst_verdict<'a>(verdicts: impl IntoIterator<Item = &'a str>) -> Option<&'a
|
|
|
350
375
|
}
|
|
351
376
|
|
|
352
377
|
pub fn audit_registry_v1_json() -> &'static str {
|
|
353
|
-
|
|
378
|
+
audit_registry_text()
|
|
354
379
|
}
|
|
355
380
|
|
|
356
381
|
pub fn wcag20aa_registry_v1_json() -> &'static str {
|
|
357
|
-
|
|
382
|
+
wcag20aa_registry_text()
|
|
358
383
|
}
|
|
359
384
|
|
|
360
385
|
pub fn audit_registry_v1_hash_sha256() -> String {
|
|
361
|
-
hash_memoized(&AUDIT_REGISTRY_HASH,
|
|
386
|
+
hash_memoized(&AUDIT_REGISTRY_HASH, audit_registry_text())
|
|
362
387
|
}
|
|
363
388
|
|
|
364
389
|
pub fn wcag20aa_registry_v1_hash_sha256() -> String {
|
|
365
|
-
hash_memoized(&WCAG20AA_REGISTRY_HASH,
|
|
390
|
+
hash_memoized(&WCAG20AA_REGISTRY_HASH, wcag20aa_registry_text())
|
|
366
391
|
}
|
|
367
392
|
|
|
368
393
|
pub fn section508_html_registry_v1_hash_sha256() -> String {
|
|
369
394
|
hash_memoized(
|
|
370
395
|
&SECTION508_HTML_REGISTRY_HASH,
|
|
371
|
-
|
|
396
|
+
section508_html_registry_text(),
|
|
372
397
|
)
|
|
373
398
|
}
|
|
374
399
|
|
|
@@ -404,15 +429,15 @@ pub fn contract_fingerprint_sha256() -> String {
|
|
|
404
429
|
|
|
405
430
|
pub fn registry_json(name: &str) -> Option<&'static str> {
|
|
406
431
|
match name {
|
|
407
|
-
AUDIT_REGISTRY_ID => Some(
|
|
408
|
-
WCAG20AA_REGISTRY_ID => Some(
|
|
409
|
-
SECTION508_HTML_REGISTRY_ID => Some(
|
|
432
|
+
AUDIT_REGISTRY_ID => Some(audit_registry_text()),
|
|
433
|
+
WCAG20AA_REGISTRY_ID => Some(wcag20aa_registry_text()),
|
|
434
|
+
SECTION508_HTML_REGISTRY_ID => Some(section508_html_registry_text()),
|
|
410
435
|
_ => None,
|
|
411
436
|
}
|
|
412
437
|
}
|
|
413
438
|
|
|
414
439
|
pub fn section508_html_registry_v1_json() -> &'static str {
|
|
415
|
-
|
|
440
|
+
section508_html_registry_text()
|
|
416
441
|
}
|
|
417
442
|
|
|
418
443
|
pub fn wcag20aa_coverage_from_rule_verdicts<'a, I>(rule_verdicts: I) -> Wcag20AaCoverageSummary
|
|
@@ -860,7 +885,7 @@ pub fn metadata() -> AuditContractMetadata {
|
|
|
860
885
|
mod tests {
|
|
861
886
|
use super::*;
|
|
862
887
|
fn parse_embedded_audit_registry() -> Value {
|
|
863
|
-
json::parse(
|
|
888
|
+
json::parse(audit_registry_text()).expect("embedded audit registry JSON should parse")
|
|
864
889
|
}
|
|
865
890
|
|
|
866
891
|
#[test]
|
|
@@ -871,7 +896,7 @@ mod tests {
|
|
|
871
896
|
);
|
|
872
897
|
assert_eq!(
|
|
873
898
|
wcag20aa_registry_v1_hash_sha256(),
|
|
874
|
-
"
|
|
899
|
+
"108d4e5062ede7c5c3893fff78153a58f35749d2dd9df58173fc2dd0dbcd36b6"
|
|
875
900
|
);
|
|
876
901
|
assert_eq!(
|
|
877
902
|
section508_html_registry_v1_hash_sha256(),
|
|
@@ -882,10 +907,22 @@ mod tests {
|
|
|
882
907
|
assert_eq!(a, b);
|
|
883
908
|
assert_eq!(
|
|
884
909
|
a,
|
|
885
|
-
"
|
|
910
|
+
"83123c2d5ff2a8b459326a360e3eeac1134fb1eef4c704c433dadfd3e32606d5"
|
|
886
911
|
);
|
|
887
912
|
}
|
|
888
913
|
|
|
914
|
+
#[test]
|
|
915
|
+
fn registry_payloads_are_canonical_lf() {
|
|
916
|
+
for id in [
|
|
917
|
+
AUDIT_REGISTRY_ID,
|
|
918
|
+
WCAG20AA_REGISTRY_ID,
|
|
919
|
+
SECTION508_HTML_REGISTRY_ID,
|
|
920
|
+
] {
|
|
921
|
+
let payload = registry_json(id).expect("known registry should have a payload");
|
|
922
|
+
assert!(!payload.contains('\r'), "{id} contains a carriage return");
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
889
926
|
#[test]
|
|
890
927
|
fn registry_lookup_returns_known_payloads() {
|
|
891
928
|
assert!(
|
|
@@ -200,6 +200,25 @@ class CompiledDocument(metaclass=_NativeFacadeType):
|
|
|
200
200
|
deterministic_hash,
|
|
201
201
|
)
|
|
202
202
|
|
|
203
|
+
def render_pdf_bindings(self, /, bindings, deterministic_hash=None):
|
|
204
|
+
"""Render one fixed-geometry page set per row of columnar text bindings."""
|
|
205
|
+
return _call(
|
|
206
|
+
self._handle,
|
|
207
|
+
"CompiledDocument.render_pdf_bindings",
|
|
208
|
+
bindings,
|
|
209
|
+
deterministic_hash,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def render_pdf_bindings_to_file(self, /, bindings, path, deterministic_hash=None):
|
|
213
|
+
"""Stream a columnar fixed-geometry binding batch directly to ``path``."""
|
|
214
|
+
return _call(
|
|
215
|
+
self._handle,
|
|
216
|
+
"CompiledDocument.render_pdf_bindings_to_file",
|
|
217
|
+
bindings,
|
|
218
|
+
path,
|
|
219
|
+
deterministic_hash,
|
|
220
|
+
)
|
|
221
|
+
|
|
203
222
|
|
|
204
223
|
class PdfEngine(metaclass=_NativeFacadeType):
|
|
205
224
|
__slots__ = ("_handle",)
|
|
@@ -9,6 +9,25 @@ from typing import Any, Callable
|
|
|
9
9
|
from .style import style_to_css
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
_HTML_VOID_ELEMENTS = frozenset(
|
|
13
|
+
{
|
|
14
|
+
"area",
|
|
15
|
+
"base",
|
|
16
|
+
"br",
|
|
17
|
+
"col",
|
|
18
|
+
"embed",
|
|
19
|
+
"hr",
|
|
20
|
+
"img",
|
|
21
|
+
"input",
|
|
22
|
+
"link",
|
|
23
|
+
"meta",
|
|
24
|
+
"source",
|
|
25
|
+
"track",
|
|
26
|
+
"wbr",
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
12
31
|
def _normalize_css_href(value: str | None) -> str | None:
|
|
13
32
|
if value is None:
|
|
14
33
|
return None
|
|
@@ -256,6 +275,8 @@ def render_node(node: Any) -> str:
|
|
|
256
275
|
return ""
|
|
257
276
|
if isinstance(node, Element):
|
|
258
277
|
attrs = _render_attrs(node.props)
|
|
278
|
+
if node.tag.casefold() in _HTML_VOID_ELEMENTS:
|
|
279
|
+
return f"<{node.tag}{attrs}>"
|
|
259
280
|
children_html = "".join(render_node(child) for child in node.children)
|
|
260
281
|
return f"<{node.tag}{attrs}>{children_html}</{node.tag}>"
|
|
261
282
|
return escape(str(node))
|
|
@@ -115,7 +115,10 @@ pub fn is_supported_font_path(path: &Path) -> bool {
|
|
|
115
115
|
let Some(ext) = path.extension().and_then(|v| v.to_str()) else {
|
|
116
116
|
return false;
|
|
117
117
|
};
|
|
118
|
-
matches!(
|
|
118
|
+
matches!(
|
|
119
|
+
ext.to_ascii_lowercase().as_str(),
|
|
120
|
+
"ttf" | "otf" | "ttc" | "otc"
|
|
121
|
+
)
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
#[cfg_attr(not(feature = "python"), allow(dead_code))]
|
|
@@ -512,9 +515,11 @@ mod tests {
|
|
|
512
515
|
}
|
|
513
516
|
|
|
514
517
|
#[test]
|
|
515
|
-
fn
|
|
518
|
+
fn supported_font_path_accepts_sfnt_fonts_and_collections() {
|
|
516
519
|
assert!(super::is_supported_font_path(Path::new("demo.ttf")));
|
|
517
520
|
assert!(super::is_supported_font_path(Path::new("demo.otf")));
|
|
521
|
+
assert!(super::is_supported_font_path(Path::new("demo.ttc")));
|
|
522
|
+
assert!(super::is_supported_font_path(Path::new("demo.otc")));
|
|
518
523
|
assert!(!super::is_supported_font_path(Path::new("demo.woff2")));
|
|
519
524
|
}
|
|
520
525
|
|