<Text style={{ width }}>inside a flex row now renders at the requested width instead of the parent row's full width. A 0.10.2 regression positioned such text using the requested width but sized its box to the row width; combined withtextAlign: 'right'this pushed glyphs off the page (silent corruption — PDF bytes were deterministic so byte-hash snapshots passed).layout_textand the text branch ofmeasure_node_heightnow honor a resolved fixedstyle.width, matching howlayout_viewandImagealready behave
- Flex row children with percentage widths (e.g.
width: '30%') are no longer double-resolved against their own already-resolved width — the percentage now correctly resolves against the parent's content width. Two children at 100% now shrink to 50/50 instead of collapsing - Grid containers that wrap over a page break now page-break by row (all columns moved to the next page together) instead of letting each cell trigger its own page break, which was scattering the columns across separate pages
layout_nodenow accepts aforced_outer_width: Option<f64>parameter so flex parents can hand the distributed width to the child without re-running style resolution
Skipped — npm-only patch.
opacitynow cascades to children — wrapping happens at the element level (singleq ... Qcovering own paint and child recursion) instead of the previous per-Rect wrap that left text inside opaque parents at full alpha. Nested opacities multiply via the PDF graphics-state stackwordSpacingstyle property — user-facing, emits the PDFTwoperator. Stacks withtext-align: justify's computed slack- Rounded clipping when
overflow: hidden+borderRadius— clip path uses the rounded rectangle (m/c/h W n) instead of the rectangularre W n boxShadowstyle property — offset filled rect behind the element, honors borderRadius, alpha routed through ExtGState- Page
backgroundImagewithbackgroundOpacity/backgroundSize(fill/cover/contain) /backgroundPosition. XObjects dedupe across pages by URL backgroundstyle property accepting CSS linear and radial gradients. 2-stop gradients use a Type 2 (exponential) Shading; 3+ stops use a Type 3 (stitching) function. CSS angle convention (0deg = bottom→top, 180deg = top→bottom)
- CI now runs a PDF size regression check (
.github/scripts/check-pdf-size.sh) against a fixture that exercises all six new features. Fails on >5% byte growth over the committed baseline
- Redaction text-stripping now uses real per-CID glyph advances when locating regions, so partial-line redactions match the visible overlay precisely instead of dropping the surrounding text
- CID font decoding in the redaction text extractor — handles Type0/CIDFontType2 streams correctly
- PDF parsing in CID redaction is robust to binary font streams that previously confused the tokenizer
text_decorationis now part of the glyph style grouping key, so aline-throughspan inside an otherwise plain text node is no longer merged with its neighbors during PDF emission
Version bump only.
certify_pdf()— apply a PKCS#7 digital signature to an existing PDFredact_pdf()— redact regions from a PDF (removes underlying text)redact_text()— find text by pattern and redact matching regionsfind_text_regions()— find text regions in a PDF without redactingmerge_pdfs()— combine multiple PDFs into one- PKCS#1 private key auto-conversion:
parse_pem_private_key()now accepts both PKCS#8 (BEGIN PRIVATE KEY) and PKCS#1 (BEGIN RSA PRIVATE KEY) formats, falling back automatically
- WASI timestamp:
current_timestamp_secs()now usesstd::time::SystemTimeon wasm32-wasip1 targets instead ofjs_sys::Date(which is only available in browser WASM)
- SVG element opacity support:
opacity,fill-opacity, andstroke-opacityattributes rendered via PDF ExtGState with inheritance through<g>groups
- Page node style now resolves against root style, so properties like
fontFamilyset on<Page style={...}>correctly inherit to child nodes
- Fix PDF serializer ignoring custom font weights — multiple weights for the same family (e.g. 200, 400, 700) now produce distinct font objects instead of collapsing to 400/700
- Fix Latin Extended character widths in standard font tables (Å, Ä, Ö, etc. no longer stack)
- Fix page number placeholder width mismatch during layout ({{pageNumber}} measured at actual width)
- Two-pass rendering: sentinel width now matches actual page count digits (1-9→"0", 10-99→"00", 100+→"000")
- AcroForm support:
NodeKind::TextField,NodeKind::Checkbox,NodeKind::Dropdown,NodeKind::RadioButton - Form field layout functions and PDF AcroForm widget rendering
flattenFormsoption in render pipeline to convert form fields to static content- PDF/UA-1 compliance: structure tree (
StructTreeRoot), tab order, role map, artifact tagging for headers/footers pdf/tagged.rs: structure tree generation for tagged PDF- PDF/A compliance: sRGB output intent, XMP metadata with
pdfaid:part/conformance, full font embedding mode pdf/signing.rs: PKCS#7 detached digital signatures with ByteRange placeholderDocument.pdf_ua,Document.pdfa,Document.signaturefieldsImage.altandSvg.altemit/Altentries in structure elements for PDF/UA
extract_cn_from_cert_der()handles multi-byte DER lengths (CN > 127 bytes)- Checkbox appearance: checkmark instead of X; radio button: filled circle
flatten_formsrenders placeholder text in grey when value is empty- Signing preserves existing AcroForm
/NeedAppearancesand/DAmetadata - Unique signature field names (
Signature1,Signature2) for double-signing - Form fields tagged as
/Formrole in structure tree (PDF/UA compliance)
SignatureConfig.pagefield (was accepted but silently ignored)
chart/module with shared types (ChartPrimitive,TextAnchor) and per-type builders (bar.rs,line.rs,pie.rs,area.rs,dot.rs)- Five
NodeKindvariants:BarChart,LineChart,PieChart,AreaChart,DotPlot DrawCommand::Chart { primitives }with PDF rendering (Y-flip transform, arc sector bezier approximation, Helvetica labels)ChartDataPoint,ChartSeries,DotPlotGroupdata structs- 10 integration tests for chart rendering
Version bump only.
barcode.rs: 1D barcode generation viabarcoderscrate (Code128, Code39, EAN13, EAN8, Codabar)NodeKind::Barcodevariant withdata,format,width,heightfieldslayout_barcode()function (followslayout_qrcodepattern)DrawCommand::Barcodewith filled rectangle emission in PDF serializerwasm_rawfeature with C-ABI exports for non-JS WASM hosts (wasmtime, wasmer)
Document.embedded_datafield for embedding JSON as a FlateDecode-compressed PDF file attachment- PDF serializer emits EmbeddedFile stream + Names tree for
forme-data.json
No changes.
No changes.
- Builtin Noto Sans Regular (400) and Bold (700) fonts via
include_bytes!()(font/builtin.rs) Document.default_stylefield for global style defaults (inherited by all children)- Automatic per-character font fallback to Noto Sans for chars not covered by the primary font
FontRegistry::new()now registers Noto Sans alongside standard PDF fontsresolve_for_char()tries Noto Sans before Helvetica as last-resort fallbacksegment_by_font()checks glyph coverage even for single-family textchar_width()uses per-char resolution when primary font lacks a glyph
- Skip Arabic font fallback test when system font unavailable (CI fix)
- Per-character font fallback (
font/fallback.rs,segment_by_font) overflow: hiddenvia PDF clip path operators (q / re W n / Q)- Canvas drawing primitive (
CanvasOpenum, reuses SVG command pipeline) - SVG arc (
A/a) path commands (svg_arc_to_curves, W3C F.6.5/F.6.6) - Watermarks with rotation matrix and opacity in PDF output
- Justified text via PDF
Tw(word spacing) operator - PDF standard font
/Widthsarrays for Helvetica, Times, Courier lineBreakingtoggle
- Cross-axis stretch propagation (
cross_axis_heightparameter inlayout_node) - Font weight fallback with opposite weight resolution (700 to 400 and vice versa)
- Shaping cluster byte-to-char conversion for multi-byte characters
measure_intrinsic_widthaccounts fortextTransform
- Canvas clipping to bounds via
DrawCommand::Svg { clip: true } - Arc counterclockwise parameter support
- Knuth-Plass optimal line breaking algorithm
- UAX#14 Unicode line breaking
- Multi-language hyphenation via hypher crate (35+ languages)
- OpenType shaping via rustybuzz
- BiDi text support (unicode-bidi + unicode-script)
- CSS Grid layout (track sizing, auto/explicit placement)
- Tagged PDF / PDF/A-2a compliance with structure tree
- Visual regression test framework
- QR code generation (
qrcode.rs, vector PDF rendering) textOverflow(ellipsis/clip) truncation- Font fallback chains (comma-separated
fontFamilyresolution) - Alt text field on
LayoutElement - Document language (
/Langin PDF Catalog) - Clickable images/SVGs via
href
- Template expression evaluator (
template.rs) - Custom font registration and base64 font loading
- Font subsetting for embedded custom fonts
- Page-native layout engine with
PageCursor - PDF 1.7 serializer (from scratch)
- TrueType font embedding with CIDFont objects and subsetting
- Standard font metrics (Helvetica, Times, Courier) with WinAnsi mapping
- Flex layout (row/column, grow/shrink/wrap)
- Table layout with header repetition across pages
- Image loading (JPEG, PNG, WebP, data URIs)
- SVG parsing and rendering
- Widow/orphan control
align-contentfor flex wrap- Table cell overflow preservation
- Bookmarks and internal anchor links
- Letter-spacing
- Absolute positioning
- Fixed height containers
- Background/border on breakable views across page splits