PdfKmp 1.2.0 is the largest release to date: a new Web (Kotlin/Wasm) target, a new pdfkmp-markdown module, and a wave of ~40 features across the text engine, pagination, graphics, navigation, document security, and the viewer. The public API (pdf { … }, pdfAsync { … }, save(...), toByteArray()) is unchanged — everything below is additive.
✨ Highlights
🌐 New: Web (Kotlin/Wasm) target
pdfkmp,pdfkmp-compose-resources, andpdfkmp-markdownnow ship awasmJstarget — PdfKmp runs in the browser. Browsers expose no PDF engine to Wasm, so a new pure-Kotlin PDF 1.7 writer backs the target: vector text, shapes, gradients, QR/barcodes/charts, freeDraw, rotation/opacity, JPEG + PNG embedding, links, outline, and the info dictionary.- TrueType subsetting + embedding in pure Kotlin —
PdfFont.Customworks on the web, and non-WinAnsi text (e.g. Cyrillic) falls back to a bundled-Inter subset out of the box. Content streams are Flate-compressed by a pure-Kotlin DEFLATE. PdfDocument.openInNewTab()hands the bytes to the browser's own viewer;save(...)becomes a download.
📦 New module: pdfkmp-markdown
io.github.conamobiledev:pdfkmp-markdown— renders a CommonMark-lite subset (headings, emphasis, code, lists, pipe tables, blockquotes, links, rules) straight into the PdfKmp DSL viamarkdown(text, theme). Android + iOS + JVM + Wasm, Compose-free. First release on Maven Central.
✍️ Text engine
TextAlign.Justifynow actually justifies (inter-word slack, bothtextandrichText), with kashida elongation for Arabic (kashidaJustify = true).- Right-to-left support —
TextDirection { Auto, Ltr, Rtl }with automatic detection; the JVM backend runs its own bidi reorder + Arabic contextual shaping. maxLines+TextOverflow { Clip, Ellipsis }, soft hyphens (U+00AD), automatic hyphenation (hyphenation = Hyphenators.EnUs, Liang's algorithm), and mid-word breaking for over-wide words.- Superscript / subscript rich-text spans; orphan/widow control (
minLinesBeforeBreak/minLinesAfterBreak).
📄 Layout & pagination
- Table row slicing with repeating headers (
repeatHeader = trueby default) andcolSpan/rowSpancell merging. - Recursive column slicing,
keepTogether { }, newspaper-stylecolumns(count, gap), andgrid(columns). - Over-wide tables shrink to fit; oversized images scale down instead of overflowing;
PageSize.landscape/.portrait+PageContext.isFirst/isLast/isEven/isOddfor book-style chrome.
🎨 Graphics & content
- QR codes (full ISO 18004, versions 1–40), Code 128, EAN-13 / UPC-A, and Data Matrix (ECC 200) — all pure-Kotlin, pure vector.
- Charts —
barChart,lineChart(multi-series),pieChart,donutChart,stackedBarChart, with legends, value captions, and grid lines. freeDraw { path { … } }, drop shadows, dashed/dotted borders, rotation & opacity on containers.- Full SVG file support —
<rect>,<circle>,<ellipse>,<line>,<polyline>,<polygon>, nested<g>transforms, inline styles, named colors, viewBox offsets.
🧭 Navigation & document features
- Bookmarks/outline, internal links (
anchor+linkToAnchor), and an automatic table of contents with resolved page numbers — on all three native platforms; Android gains metadata, clickable links, and the outline via a pure-Kotlin incremental-update post-processor. - Encryption (AES-256 on JVM), file attachments, AcroForm fields (
textField/checkBox), PDF/A best-effort + tagged-PDF basics, and digital signing (PdfSigner, JVM). PdfTools(JVM) —merge,split,extractPages, watermarks, pageoverlay, plus a Factur-X/ZUGFeRD MINIMUM-profile invoice helper.
🖥️ Viewer (pdfkmp-viewer)
- Print, dark mode (
invertColors), search in external PDFs (iOS + Desktop), and clipboard support. - Highlight annotations with drag-to-highlight — and on Desktop they can be written into the PDF as real
Highlightannotations. - Password-protected PDFs open via
password = ...with a typedPdfViewerError(Desktop + iOS). - Two-page book layout (
pageLayout = PdfPageLayout.TwoPageBook) and an adaptive cache for 200+-page documents.
📚 Documentation
- New documentation site — 20 hand-written guides + the aggregated Dokka API reference: https://conamobiledev.github.io/PdfKmp/
🐛 Fixed
- iOS outline entries now reference page numbers —
CGPDFContextSetOutlinecrashed on named destinations / emptyChildrenwheneverbookmark()was used. TextAlign.Justifyno longer silently falls back to start alignment.- An adversarial-review pass over the wave fixed 11 edge cases (TOC inside
columns { }, sliced-table headers, rich-text justification precision, Android post-processor xref offsets, and more — see the CHANGELOG).
All four modules ship together at 1.2.0: pdfkmp, pdfkmp-compose-resources, pdfkmp-viewer, and pdfkmp-markdown.
Full details in the CHANGELOG.