Releases: radicle-it/rad_pdf
v1.7.0 - Native charts, template QR tag, PDF/A-2b
Highlights
RAD_PDF 1.7.0 adds native vector charts, the <qrcode> template tag, and PDF/A-2b conformance for archival-grade documents — plus a major fix: TrueType font loading, broken since the modular refactor, now works correctly with full embedding.
Added
Native charts — new rad_pdf_chart package
bar_chart()— vertical bars with optional value labels and category labels.line_chart()— single series; negative values supported (the zero axis is drawn inside the plot).pie_chart()— slices as filled cubic-Bézier paths, legend with colour swatches and percentages.- "Nice numbers" y scale (1/2/5 × 10^k steps — gridline labels are always round values), built-in 10-colour palette with cycling
p_colorsoverride, pure vector output (no images, crisp at any zoom). - Facade shortcuts:
rad_pdf.bar_chart/line_chart/pie_chart. - Charts inherit the current document font — set an embedded font first and they are PDF/A-compatible.
<qrcode> template tag
<qrcode value="https://pay.example.com/inv/#INV#" size="40mm" align="C"/>— a QR code that participates in the template flow like an image;valuesupports#BIND#tokens;ec,colorandalignattributes.- Also available programmatically:
rad_pdf_layout.qrcode(...)flowable constructor.
PDF/A-2b conformance (ISO 19005-2)
rad_pdf.set_conformance(l_doc, 'PDF/A-2B')— one call produces an archival-grade document: XMP metadata synchronised with the Info dictionary, embedded sRGB OutputIntent, file/ID.- Every used font must be embedded: clear ORA-20700 naming the offending font otherwise (the standard 14 PDF fonts cannot be used in this mode).
- Validated with veraPDF:
isCompliant="true", 144 rules green — both vector-only documents and documents with embedded-TTF text, charts and QR codes.
Fixed
- TrueType loading was completely broken (latent since the modular refactor — no test ever loaded a TTF): the table directory was read with 0-based offsets, but
DBMS_LOBpositions are 1-based, sonumTablesalways parsed as 0 and no font data was ever read. Also fixed: dependency-ordered table processing, FontDescriptor metrics normalised to 1000/em, the page font resource pointing at the wrong object when embedding, a one-byte misread of the font name, and a NO_DATA_FOUND onload_ttfbefore any text was written. Embedded-font documents now render correctly in every viewer. - Trailer
/IDand strictstream/endstreamframing applied to every document (required by PDF/A, harmless and more correct otherwise).
Upgrade from v1.6.0
Run src/install/install_phase13.sql from src/. From v1.5.x: run install_phase12.sql followed by install_phase13.sql. Fresh installs: src/install.sql as usual.
New examples
| File | Shows |
|---|---|
docs/sample20.sql |
Dashboard with bar, line and pie charts |
docs/sample21.sql |
PDF/A-2b conformant document with embedded font |
Quality: 161 acceptance tests green on a from-scratch install; charts verified visually; QR template tag verified with a real scanner; PDF/A output validated with veraPDF. Full details in CHANGELOG.md.
v1.6.0 - QR codes & barcodes, bookmarks, PNG alpha fix
Highlights
RAD_PDF 1.6.0 adds native QR codes and 1D barcodes (pure vector, no raster images), PDF bookmarks/outline, and fixes a long-standing bug that made PNG images with an alpha channel fail to load.
Added
QR codes & 1D barcodes — new rad_pdf_barcode package
qrcode()— vector QR codes rendered as filled PDF paths: crisp at any print resolution. Automatic encoding mode (numeric / alphanumeric / byte / UTF-8) and version selection (1–40); error-correction levels L/M/Q/H; custom colour.code128()— subsets B/C selected automatically (digits pack two per symbol), Latin-1 support.ean13()— check digit computed for 12 digits, validated for 13 (catches data-entry errors); standard layout with descending guard bars.code39()— standard charset validated up front;p_full_asciifor extended mode.- Facade shortcuts:
rad_pdf.qrcode(...)and genericrad_pdf.barcode(p_type => 'CODE128' | 'CODE39' | 'EAN13', ...). - QR/barcode encoders ported from as_barcode by Anton Scheffer (MIT).
- Output verified end-to-end: PDF → raster → decoded with a real barcode scanner, including UTF-8 content (byte-perfect round-trip).
Bookmarks / document outline
rad_pdf.heading(..., p_bookmark => TRUE)— one parameter mirrors headings into the reader's sidebar; destinations point at the exact heading position, page breaks included.rad_pdf.add_bookmark()— manual anchors at any position; automatic hierarchy (levels 1–6).- Documents with bookmarks open with the sidebar visible; accented titles encoded as UTF-16BE (render correctly in every viewer).
Template engine & watermarks
<if bind="K" eq="V">/<if bind="K" ne="V">— case-insensitive value comparisons in conditional blocks. Plain<if bind="K">unchanged.p_pagesonset_watermark/set_watermark_image— apply the watermark to selected pages only:'1','2-5','3-'(open range),'1,3-5,8-'.
Fixed
- PNG with alpha channel (ORA-20710): every 8-bit PNG with an alpha channel failed to load. Root cause:
UTL_COMPRESScannot inflate zlib streams (it validates a gzip CRC32 that does not exist in PNG data).flate_decodeis now a pure PL/SQL inflate — RGBA and grey+alpha PNGs load correctly and produce a proper SMask (real transparency in the PDF). flate_encodeproduced invalid zlib streams (latent since v1.0): compressed streams (GIF pixels, alpha-stripped pixels, embedded fonts) carried gzip header garbage and failed in strict viewers. Now emits valid zlib.- Interlaced (Adam7) PNGs are rejected with a clear error instead of rendering silently corrupted output.
- Fresh-install ordering: on a virgin schema the facade compiled with errors (it references packages installed later). Install phases reordered; validated by installing from scratch.
Upgrade from v1.5.x
Run src/install/install_phase12.sql from src/ — it is the complete upgrade script. Fresh installs: src/install.sql as usual.
New examples
| File | Shows |
|---|---|
docs/sample17.sql |
QR codes: payment link, UTF-8 vCard, coloured QR |
docs/sample18.sql |
1D barcode label sheet (Code 128, EAN-13, Code 39) |
docs/sample19.sql |
Bookmarks: navigable multi-chapter report |
docs/apex/apex_sample13.sql |
Payment QR driven by APEX page items |
docs/apex/apex_sample14.sql |
Barcode labels from a query in APEX |
Quality: 150 acceptance tests green on a from-scratch install; barcode output verified with a real scanner; full CHANGELOG in CHANGELOG.md.
v1.5.2
Full Changelog: v1.2.0...v1.5.2
RAD_PDF v1.2.0 - Template Engine
What's new
Template engine (rad_pdf_template)
A new package rad_pdf_template turns a CLOB or VARCHAR2 template into a full PDF
document section - no manual canvas calls required.
Block tags
<p>, <h1>-<h6>, <ul>, <ol>, <li>,
<spacer height="Xpt"/>, <hr [color="RRGGBB"] [width="N"]/>,
<img id="N" [width="Xmm"] [height="Ymm"]/>,
<table columns="NAME" query="SQL" allow_query="true" .../>,
<pagebreak/>
Inline markup inside <p>, <li>, <h1>-<h6>
<b>, <i>, <br/>, <color rgb="RRGGBB">, <font size="Xpt"> -
unlimited LIFO nesting, mixed-style paragraphs rendered inline.
#KEY# bind substitution
CLOB-level scanner (no 32 767-char limit); ## escapes to #; unknown tokens
written verbatim; bind values auto-escaped (& < >) by default, bypass
per-entry with t_bind_entry.raw = TRUE.
<if bind="KEY">...</if> conditional blocks
Evaluated before bind substitution - suppressed blocks never trigger NULL-bind errors.
SQL injection protection for <table query>
#TOKEN# placeholders inside query attributes are automatically safe-quoted:
the raw bind value is wrapped in SQL single quotes with embedded quotes doubled.
No manual TO_NUMBER validation is required for safety.
<table> security double opt-in
Both allow_query="true" in the tag AND p_options.allow_queries = TRUE in
t_template_options are required to execute a query. Each check raises a distinct
error message naming the missing piece.
Column set registry
register_columns, drop_columns, clear_columns - pre-register t_columns
definitions once (e.g. in an APEX Application Process) and reference by name.
Four render overloads
(doc, CLOB, binds, opts), (doc, VARCHAR2, binds, opts),
(doc, CLOB, opts), (doc, VARCHAR2, opts).
rad_pdf.render_template facade - 4 matching overloads in the public package
for callers who import only rad_pdf.
New files
| File | Description |
|---|---|
src/rad_pdf_template.pks/pkb |
Template engine package |
src/install/install_phase9.sql |
Phase 9 installer |
tests/phase10_template.sql |
36 acceptance tests |
docs/TEMPLATE_GUIDE.md |
Complete tag catalogue and patterns |
docs/sample11.sql |
Standalone template example |
docs/sample12.sql |
DB-driven template store pattern |
docs/apex/apex_template_01.sql - apex_template_14.sql |
14 APEX worked examples |
Bug fixes
draw_cellvertical alignment - text baseline was clipped; now centred correctlyrad_pdf_tablecursor leak - DBMS_SQL cursors always closed inBEGIN/EXCEPTIONguardextract_attrtruncation - return type widened toVARCHAR2(32767)(was 4000)find_tag_endORA-06502 - buffer enlarged toVARCHAR2(2048)for multi-byte UTF-8<LI>/<IF>uppercase - Phase 0 normalises uppercase tags via CLOB-awareREPLACE- Post-
<hr>spacer - increased to 14pt before<h1>/<h2>to avoid visual overlap default_font_name/style/sizeint_template_optionsnow correctly applied
Install
-- From src/ in SQL*Plus or SQLcl
@install.sqlRequires Oracle 19c+. Run as the schema owner.
Full changelog: CHANGELOG.md
Template engine reference: docs/TEMPLATE_GUIDE.md
Full Changelog: v1.1.0...v1.2.0
RAD_PDF v1.1.0
Added
- Cell wrapping in table cells: set
wrap = TRUEont_column_defto enable multi-line cell text with dynamic row height;wrap = FALSEby default so all existing tables are unaffected rad_pdf.get_info(p_doc, p_info)in the public facade; delegates torad_pdf_canvas.get_info; acceptsc_info_*constants fromrad_pdf_typesrad_pdf_types.c_versionconstant andrad_pdf.version()functiondocs/apex/apex_sample05.sql: complete cover page example with header/footer from page 2 usingIF #PAGE_NR# > 1guarddocs/apex/apex_sample06.sqlanddocs/sample10.sql: cell wrap examples- Cover page pattern documented in
docs/README.mdanddocs/apex/README.md
Fixed
num_formatont_column_def.data_fmtwas ignored when rendering table data cellshas_wrap_colsdeclared aftermeasure_tableinrad_pdf_table.pkbcausedPLS-00313forward reference error on recompilationinstall_phase2.sqlcompiled the finalrad_pdf_ctx.pkbbeforerad_pdf_layoutexisted, causingPLS-00201install_phase6.sqlincorrectly included@@rad_pdf_ctx.pkb
Upgrade from v1.0.0
Recompile all packages:
@src/install.sqlNo changes required in calling code. All new features are opt-in (wrap = FALSE by default).
Installation
See docs/README.md for full installation instructions.