fullbleed 2.1.0__tar.gz → 2.2.0__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.0/Cargo.lock +30 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/Cargo.toml +2 -1
- {fullbleed-2.1.0 → fullbleed-2.2.0}/PKG-INFO +30 -12
- {fullbleed-2.1.0 → fullbleed-2.2.0}/README.md +29 -11
- {fullbleed-2.1.0 → fullbleed-2.2.0}/pyproject.toml +1 -1
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/_abi.py +19 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/core.py +21 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/assets.rs +7 -2
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/canvas.rs +26 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/flowable.rs +5531 -470
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/font.rs +427 -27
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/font_subset.rs +1 -1
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html.rs +1943 -290
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/image_native.rs +170 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/lib.rs +589 -16
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/pdf.rs +681 -26
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/python/abi_exports.rs +25 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/raster.rs +74 -11
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/sfnt.rs +8 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/spill.rs +8 -3
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/style.rs +4903 -371
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/svg.rs +138 -10
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/types.rs +1 -0
- fullbleed-2.1.0/Cargo.lock +0 -14
- {fullbleed-2.1.0 → fullbleed-2.2.0}/COPYRIGHT +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/FONT_LICENSE_AUDIT.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/FONT_LICENSE_AUDIT.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/LICENSE +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/LICENSING.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/THIRD_PARTY_LICENSES.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/build.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/build_backend/fullbleed_build_backend.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/Cargo.lock +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/Cargo.toml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/LICENSE +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/README.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/specs/fullbleed.audit_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/specs/section508_html_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/specs/wcag20aa_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/src/json.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/src/lib.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/crates/fullbleed_audit_contract/src/sha256.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/docs/specs/fullbleed.a11y.verify.v1.schema.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/docs/specs/fullbleed.audit_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/docs/specs/fullbleed.pmr.v1.schema.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/docs/specs/section508_html_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/docs/specs/wcag20aa_registry.v1.yaml +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/__main__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/accessibility/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/accessibility/engine.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/accessibility/runtime.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/accessibility/types.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/audit_prototype.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/audit_section508.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/audit_wcag.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/accessibility.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/_core.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/agency_letter.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/court_motion_form.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/declaration_form.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/instruction_sheet.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/investment_portfolio_report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/marriage_record.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/profiles.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/recorded_plat.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/redaction_request_form.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/cav/warranty_deed.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/primitives.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed/ui/style.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/bootstrap.min.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/fonts/Inter-Variable.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/fonts/NotoSans-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/fonts/NotoSansMath-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/fonts/NotoSansSymbols-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/fonts/NotoSansSymbols2-Regular.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_assets/icons/bootstrap-icons.svg +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/__main__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/assets.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/cache.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/cli.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/finalize.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/COMPLIANCE.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/SCAFFOLDING.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/body.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/fb_ui.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/footer.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/header.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/primitives.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/styles/body.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/styles/footer.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/styles/header.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/components/styles/primitives.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/styles/report.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/init/styles/tokens.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/accessible/README.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/accessible/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/accessible/output/.gitkeep +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/accessible/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/accessible/styles/report.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/accessible/vendor/fonts/Inter-Variable.ttf +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/invoice/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/invoice/output/.gitkeep +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/invoice/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/invoice/templates/invoice.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/invoice/templates/invoice.html +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/COMPLIANCE.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/README.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/SCAFFOLDING.md +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/assets/brand-mark.svg +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/assets/reference-pattern.svg +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/__init__.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/appendix.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/architecture.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/cover.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/data_pages.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/fb_ui.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/primitives.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/appendix.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/architecture.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/cover.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/data.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/primitives.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/styles/visuals.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/components/visuals.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/data/reference.json +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/styles/report.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/reference/styles/tokens.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/statement/output/.gitignore +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/statement/output/.gitkeep +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/statement/report.py +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/statement/templates/statement.css +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/python/fullbleed_cli/scaffold_templates/new/statement/templates/statement.html +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/base64.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/css_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/css_queries.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/debug.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/doc_context.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/doc_template.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/error.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/finalize.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/flate_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/frame.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/glyph_report.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_dom.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities_0.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities_1.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities_2.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities_3.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities_4.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/html_entities_5.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/jit.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/jpeg_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/math.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/metrics.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/native_shape.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/page_data.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/page_template.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/parallel.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/pdf_encodings.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/pdf_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/pdf_raster.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/pdfinspect.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/perf.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/plan.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/python.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/python_abi.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/raster_native.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/sfnt_cff.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/sfnt_outline.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/text_shape.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/unicode_data.rs +0 -0
- {fullbleed-2.1.0 → fullbleed-2.2.0}/src/xml.rs +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
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.0"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"fullbleed_audit_contract",
|
|
10
|
+
"subsetter",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[[package]]
|
|
14
|
+
name = "fullbleed_audit_contract"
|
|
15
|
+
version = "0.1.2"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "rustc-hash"
|
|
19
|
+
version = "2.1.3"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
|
|
22
|
+
|
|
23
|
+
[[package]]
|
|
24
|
+
name = "subsetter"
|
|
25
|
+
version = "0.2.6"
|
|
26
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
27
|
+
checksum = "38803281d1c23166c5ebcb455439a5d2afe711cc909cf88af72448c297756ad6"
|
|
28
|
+
dependencies = [
|
|
29
|
+
"rustc-hash",
|
|
30
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "fullbleed"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.2.0"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
rust-version = "1.85"
|
|
6
6
|
license = "MIT"
|
|
@@ -38,3 +38,4 @@ debug = true
|
|
|
38
38
|
|
|
39
39
|
[dependencies]
|
|
40
40
|
fullbleed_audit_contract = { version = "0.1.2", path = "crates/fullbleed_audit_contract" }
|
|
41
|
+
subsetter = { version = "0.2.6", default-features = false }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fullbleed
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
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,20 @@ 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
|
+
The fixed-copy result remains scoped to identical content; the variable-data result is scoped to
|
|
129
|
+
paint-only text whose geometry does not reflow. Neither is a claim that arbitrary new HTML or
|
|
130
|
+
size-changing records render 200x faster. See
|
|
118
131
|
[`docs/performance-pass-2026-08-04.md`](docs/performance-pass-2026-08-04.md) for measurements and
|
|
119
132
|
[`docs/performance-architecture.md`](docs/performance-architecture.md) for the packed vector IR,
|
|
120
133
|
typed-binding, virtual-linker, and shader roadmap.
|
|
@@ -130,7 +143,7 @@ python -m pip install fullbleed
|
|
|
130
143
|
From a local wheel:
|
|
131
144
|
|
|
132
145
|
```bash
|
|
133
|
-
python -m pip install C:\path\to\fullbleed-2.
|
|
146
|
+
python -m pip install C:\path\to\fullbleed-2.2.0-cp310-abi3-win_amd64.whl
|
|
134
147
|
```
|
|
135
148
|
|
|
136
149
|
From a source checkout with Rust installed, no Python build package is needed:
|
|
@@ -972,9 +985,14 @@ Module exports:
|
|
|
972
985
|
| `render_pdf(deterministic_hash=None)` | `bytes` |
|
|
973
986
|
| `render_pdf_to_file(path, deterministic_hash=None)` | `int` |
|
|
974
987
|
| `render_pdf_batch(copies, deterministic_hash=None)` | `bytes` |
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
988
|
+
| `render_pdf_bindings(bindings, deterministic_hash=None)` | `bytes` |
|
|
989
|
+
| `render_pdf_bindings_to_file(bindings, path, deterministic_hash=None)` | `int` |
|
|
990
|
+
|
|
991
|
+
The compiled lane runs parsing/layout once. `render_pdf_batch` virtualizes identical untagged page
|
|
992
|
+
content. The binding methods instead accept columnar `dict[str, list[str]]` data and emit distinct
|
|
993
|
+
fixed-geometry text overlays per record while sharing static paint. They require exact slot keys,
|
|
994
|
+
equal non-zero column lengths, page-local WinAnsi-compatible text, and an untagged profile; bound
|
|
995
|
+
values do not trigger reflow.
|
|
978
996
|
|
|
979
997
|
When `deterministic_hash` is set, engine writes PDF SHA-256 to the provided file path.
|
|
980
998
|
|
|
@@ -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,20 @@ 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
|
+
The fixed-copy result remains scoped to identical content; the variable-data result is scoped to
|
|
92
|
+
paint-only text whose geometry does not reflow. Neither is a claim that arbitrary new HTML or
|
|
93
|
+
size-changing records render 200x faster. See
|
|
81
94
|
[`docs/performance-pass-2026-08-04.md`](docs/performance-pass-2026-08-04.md) for measurements and
|
|
82
95
|
[`docs/performance-architecture.md`](docs/performance-architecture.md) for the packed vector IR,
|
|
83
96
|
typed-binding, virtual-linker, and shader roadmap.
|
|
@@ -93,7 +106,7 @@ python -m pip install fullbleed
|
|
|
93
106
|
From a local wheel:
|
|
94
107
|
|
|
95
108
|
```bash
|
|
96
|
-
python -m pip install C:\path\to\fullbleed-2.
|
|
109
|
+
python -m pip install C:\path\to\fullbleed-2.2.0-cp310-abi3-win_amd64.whl
|
|
97
110
|
```
|
|
98
111
|
|
|
99
112
|
From a source checkout with Rust installed, no Python build package is needed:
|
|
@@ -935,9 +948,14 @@ Module exports:
|
|
|
935
948
|
| `render_pdf(deterministic_hash=None)` | `bytes` |
|
|
936
949
|
| `render_pdf_to_file(path, deterministic_hash=None)` | `int` |
|
|
937
950
|
| `render_pdf_batch(copies, deterministic_hash=None)` | `bytes` |
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
951
|
+
| `render_pdf_bindings(bindings, deterministic_hash=None)` | `bytes` |
|
|
952
|
+
| `render_pdf_bindings_to_file(bindings, path, deterministic_hash=None)` | `int` |
|
|
953
|
+
|
|
954
|
+
The compiled lane runs parsing/layout once. `render_pdf_batch` virtualizes identical untagged page
|
|
955
|
+
content. The binding methods instead accept columnar `dict[str, list[str]]` data and emit distinct
|
|
956
|
+
fixed-geometry text overlays per record while sharing static paint. They require exact slot keys,
|
|
957
|
+
equal non-zero column lengths, page-local WinAnsi-compatible text, and an untagged profile; bound
|
|
958
|
+
values do not trigger reflow.
|
|
941
959
|
|
|
942
960
|
When `deterministic_hash` is set, engine writes PDF SHA-256 to the provided file path.
|
|
943
961
|
|
|
@@ -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
|
|
|
@@ -164,6 +164,7 @@ pub enum Command {
|
|
|
164
164
|
height: Pt,
|
|
165
165
|
resource_id: String,
|
|
166
166
|
filter: PaintFilterSpec,
|
|
167
|
+
css_shadow: bool,
|
|
167
168
|
},
|
|
168
169
|
BeginTag {
|
|
169
170
|
role: String,
|
|
@@ -365,6 +366,10 @@ impl Canvas {
|
|
|
365
366
|
self.current.commands.push(Command::SetStrokeColor(color));
|
|
366
367
|
}
|
|
367
368
|
|
|
369
|
+
pub(crate) fn set_stroke_color_to_fill(&mut self) {
|
|
370
|
+
self.set_stroke_color(self.current_state.fill_color);
|
|
371
|
+
}
|
|
372
|
+
|
|
368
373
|
pub fn set_line_width(&mut self, width: Pt) {
|
|
369
374
|
let width = if width < Pt::ZERO { Pt::ZERO } else { width };
|
|
370
375
|
if self.current_state.line_width == width {
|
|
@@ -703,6 +708,27 @@ impl Canvas {
|
|
|
703
708
|
height,
|
|
704
709
|
resource_id: resource_id.into(),
|
|
705
710
|
filter,
|
|
711
|
+
css_shadow: false,
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
pub fn draw_css_shadow_filtered_form(
|
|
716
|
+
&mut self,
|
|
717
|
+
x: Pt,
|
|
718
|
+
y: Pt,
|
|
719
|
+
width: Pt,
|
|
720
|
+
height: Pt,
|
|
721
|
+
resource_id: impl Into<String>,
|
|
722
|
+
filter: PaintFilterSpec,
|
|
723
|
+
) {
|
|
724
|
+
self.current.commands.push(Command::DrawFilteredForm {
|
|
725
|
+
x,
|
|
726
|
+
y,
|
|
727
|
+
width,
|
|
728
|
+
height,
|
|
729
|
+
resource_id: resource_id.into(),
|
|
730
|
+
filter,
|
|
731
|
+
css_shadow: true,
|
|
706
732
|
});
|
|
707
733
|
}
|
|
708
734
|
|