Skip to content

Releases: radicle-it/rad_pdf

v1.7.0 - Native charts, template QR tag, PDF/A-2b

11 Jun 22:42

Choose a tag to compare

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_colors override, 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; value supports #BIND# tokens; ec, color and align attributes.
  • 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_LOB positions are 1-based, so numTables always 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 on load_ttf before any text was written. Embedded-font documents now render correctly in every viewer.
  • Trailer /ID and strict stream/endstream framing 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

11 Jun 19:34

Choose a tag to compare

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_ascii for extended mode.
  • Facade shortcuts: rad_pdf.qrcode(...) and generic rad_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_pages on set_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_COMPRESS cannot inflate zlib streams (it validates a gzip CRC32 that does not exist in PNG data). flate_decode is now a pure PL/SQL inflate — RGBA and grey+alpha PNGs load correctly and produce a proper SMask (real transparency in the PDF).
  • flate_encode produced 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

30 May 12:53

Choose a tag to compare

Full Changelog: v1.2.0...v1.5.2

RAD_PDF v1.2.0 - Template Engine

27 May 16:18

Choose a tag to compare

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_cell vertical alignment - text baseline was clipped; now centred correctly
  • rad_pdf_table cursor leak - DBMS_SQL cursors always closed in BEGIN/EXCEPTION guard
  • extract_attr truncation - return type widened to VARCHAR2(32767) (was 4000)
  • find_tag_end ORA-06502 - buffer enlarged to VARCHAR2(2048) for multi-byte UTF-8
  • <LI> / <IF> uppercase - Phase 0 normalises uppercase tags via CLOB-aware REPLACE
  • Post-<hr> spacer - increased to 14pt before <h1>/<h2> to avoid visual overlap
  • default_font_name/style/size in t_template_options now correctly applied

Install

-- From src/ in SQL*Plus or SQLcl
@install.sql

Requires 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

25 May 08:02

Choose a tag to compare

Added

  • Cell wrapping in table cells: set wrap = TRUE on t_column_def to enable multi-line cell text with dynamic row height; wrap = FALSE by default so all existing tables are unaffected
  • rad_pdf.get_info(p_doc, p_info) in the public facade; delegates to rad_pdf_canvas.get_info; accepts c_info_* constants from rad_pdf_types
  • rad_pdf_types.c_version constant and rad_pdf.version() function
  • docs/apex/apex_sample05.sql: complete cover page example with header/footer from page 2 using IF #PAGE_NR# > 1 guard
  • docs/apex/apex_sample06.sql and docs/sample10.sql: cell wrap examples
  • Cover page pattern documented in docs/README.md and docs/apex/README.md

Fixed

  • num_format on t_column_def.data_fmt was ignored when rendering table data cells
  • has_wrap_cols declared after measure_table in rad_pdf_table.pkb caused PLS-00313 forward reference error on recompilation
  • install_phase2.sql compiled the final rad_pdf_ctx.pkb before rad_pdf_layout existed, causing PLS-00201
  • install_phase6.sql incorrectly included @@rad_pdf_ctx.pkb

Upgrade from v1.0.0

Recompile all packages:

@src/install.sql

No changes required in calling code. All new features are opt-in (wrap = FALSE by default).

Installation

See docs/README.md for full installation instructions.