From Newsgroup: comp.lang.tcl
ANNOUNCE: tclpdf 1.0 released
=============================
tclpdf is a pure Tcl extension for creating PDF documents: pages and
graphics, embedded TrueType fonts subset to the glyphs actually used,
JPEG and PNG images, tables, and electronic invoices as ZUGFeRD /
Factur-X in PDF/A-3B. Developed by Alexander Schoepe, it requires only
Tcl 8.6.11+ and runs under Tcl 9 as well; zlib is a built-in command
rather than a package, and Tk is not used.
1.0 is the first release.
Download / Repository:
https://fossil.sowaswie.de/tclpdf
English
-------
Highlights:
* Documents are TclOO objects with Tcl-style options throughout - "$doc
text ... -at {20 30} -size 12" - and the topical modules load on first
use, so a caller who only writes text never loads the image, table or
SVG code.
* Graphics: paths, rectangles with rounded corners, circles, ellipses, polygons and Beziers, clipping to a rectangle or to an arbitrary path, transformations about a fixed point, constant alpha, tiling patterns,
axial and radial shadings, RGB / CMYK / grey / separation colours and
147 colour names resolved without Tk.
* Fonts: the fourteen standard faces, and TrueType embedded as Type0/CIDFontType2 with Identity-H and a ToUnicode CMap so the text
stays copyable and searchable - subset to the glyphs actually used,
measured at 8664 bytes from a 757076-byte face in 0.9 ms. A character
the font has no glyph for raises an error instead of disappearing silently.
* Images: JPEG and PNG go in unchanged wherever possible - a JPEG as /DCTDecode, a PNG without alpha as /FlateDecode with /Predictor 15,
neither ever decoded. Only an alpha channel is separated out, at 338 ms
for 640 by 480; extracted and compared pixel by pixel against the
originals, colour, alpha and palette match exactly.
* Tables: column widths, cell wrapping, page breaks with repeated header
and footer rows, rowSpan and colSpan, alignment on the decimal separator measured across head, body and foot together, four hooks per cell, and a
group spanning several rows moves to the next page as a whole.
* SVG: shapes, paths, transforms, groups, reuse, viewBox and gradients
become PDF path operators rather than a rasterised picture, so a logo
stays sharp at any zoom and the file stays small.
* Electronic invoices: ZUGFeRD / Factur-X as PDF/A-3B with ICC profile, OutputIntent, XMP carrying the Factur-X extension schema, embedded XML,
file specification, /AF entry and name tree. The conformance level is
read from BT-24 of the invoice rather than taken on trust, and both
example invoices pass veraPDF for PDF/A-3B.
* File attachments are a core feature rather than an invoice special
case, so a document can carry several, each with its own relationship, description and modification date.
* Form XObjects store a drawing once and place it as often as wanted, at
any scale, rotation or opacity - a logo on five pages is embedded once.
* Output goes to a file with "$doc write" or straight into an open
channel with "$doc writeChannel", which is what a CGI response or a
socket needs.
* The document language ("$doc language de-DE") reaches the catalog as
/Lang, checked against RFC 3066.
Notes:
* Tested against Tcl 8.6.18 and Tcl 9.0.4 on macOS: 328 tests green
under both, 18 examples writing 20 documents, every one of them accepted
by "qpdf --check".
* tdom is optional and used by the SVG module when present: it parses 27
to 48 times faster than the parser tclpdf brings along and refuses an
entity expansion bomb. Without it SVG still works, through the built-in element tree parser. Nothing else is optional, because nothing else is used.
* Build in the source directory. A separate build directory configures
cleanly but cannot run the tests, because the generated pkgIndex.tcl
locates the modules through $dir while the sources stay where they are. Nothing is lost by building in-tree - "make install" puts index and
modules together again either way.
* Write a document once. A second "$doc write" builds a second set of
objects on top of the first, so the file stays valid and renders
correctly but carries the earlier objects along unreferenced.
* No font is part of the package. The faces under examples/assets/fonts
exist so that the tests and examples have something to embed and travel
in the source archive alone; "make install" installs none. Whether you
may embed a font into a PDF that tclpdf writes is a question for that
font's licence, not for this one.
* Progressive JPEG and interlaced (Adam7) PNG are refused with a message naming the reason and the way out. A progressive JPEG cannot be passed
through as /DCTDecode at all - ISO 32000-1 7.4.8 does not cover it - and
an interlaced PNG would have to be decoded and re-encoded, which is a different feature. Save the file baseline or non-interlaced.
* What tclpdf covers is roughly a third of ISO 32000-1, weighted by the
page count of its chapters. The remainder is almost entirely what a
reader of foreign PDFs needs rather than a writer; encryption, form
fields (AcroForm), tagged PDF and multimedia are not implemented.
Planned:
* Reading foreign PDFs, so that an existing letterhead can be taken over
as a background instead of being rebuilt. That needs the parser side of
the format - cross-reference and object streams above all, plus the
filters a writer never emits (LZW, CCITT, RunLength) - and it is the
largest single piece still ahead.
* Encryption. The standard security handler needs MD5 and either RC4 or
AES, and none of them is available here without either a rebuilt TclTLS
or a pure-Tcl implementation shipped along; which of the two it becomes
is still open. Note that PDF/A-3 and therefore ZUGFeRD forbid encryption anyway.
* Barcodes, QR codes and EPC-QR in particular, so that an invoice can
carry a payment code a bank app scans off the page.
* OpenType with CFF outlines (CIDFontType0). TrueType outlines are
embedded today; a face that carries its glyphs as CFF has no glyf table,
and the whole subsetting path builds on that one - so it is a route of
its own rather than a small addition.
* Kerning from the kern table or GPOS. The setting is metrically correct
today but not optically balanced, which shows in headings on pairs like
AV, To and Ta.
* Tagged PDF, and with it PDF/A-3a and PDF/UA. PDF/A-3b is what ZUGFeRD
asks for and what is delivered; the accessible levels need a structure
tree that does not exist yet. The document language is already written.
* Drawing a Tk canvas into a PDF - every item type, as vectors rather
than as a screenshot. This is the one planned feature that involves Tk
at all, and it stays outside the core: a caller who has a canvas has
loaded Tk already, while the package itself neither requires nor loads
it. Its postscript method is the alternative today, and it produces PostScript, not PDF.
None of this is promised for a particular release, and nothing on the
list is needed for what 1.0 does.
Deutsch
-------
Neuerungen:
* Dokumente sind TclOO-Objekte mit durchgaengig Tcl-eigenen Optionen -
"$doc text ... -at {20 30} -size 12" -, und die Themenmodule laden beim
ersten Gebrauch, sodass ein Aufrufer, der nur Text schreibt, den Bild-, Tabellen- und SVG-Code nie laedt.
* Grafik: Pfade, Rechtecke mit runden Ecken, Kreise, Ellipsen, Polygone
und Bezierkurven, Beschneiden auf ein Rechteck oder einen beliebigen
Pfad, Transformationen um einen festen Punkt, konstante Deckung,
Kachelmuster, axiale und radiale Verlaeufe, RGB / CMYK / Grau /
Schmuckfarben und 147 Farbnamen ohne Tk.
* Schriften: die vierzehn Standardschnitte, dazu TrueType eingebettet
als Type0/CIDFontType2 mit Identity-H und ToUnicode-CMap, damit der Text kopierbar und durchsuchbar bleibt - reduziert auf die tatsaechlich
benutzten Glyphen, gemessen 8664 Byte aus einer 757076 Byte grossen
Schrift in 0,9 ms. Ein Zeichen, fuer das die Schrift keine Glyphe hat,
ist ein Fehler und verschwindet nicht stillschweigend.
* Bilder: JPEG und PNG gehen unveraendert hinein, wo immer es geht - ein
JPEG als /DCTDecode, ein PNG ohne Alpha als /FlateDecode mit /Predictor
15, keines von beiden wird je dekodiert. Nur ein Alphakanal wird herausgeloest, in 338 ms fuer 640 mal 480; extrahiert und pixelweise
gegen die Originale gehalten stimmen Farbe, Alpha und Palette exakt
ueberein.
* Tabellen: Spaltenbreiten, Zellenumbruch, Seitenumbruch mit
wiederholtem Kopf und Fuss, rowSpan und colSpan, Ausrichtung am Dezimaltrennzeichen ueber Kopf, Rumpf und Fuss gemeinsam gemessen, vier
Haken je Zelle, und eine ueber mehrere Zeilen laufende Gruppe wandert geschlossen auf die naechste Seite.
* SVG: Formen, Pfade, Transformationen, Gruppen, Wiederverwendung,
viewBox und Verlaeufe werden zu PDF-Pfadoperatoren statt zu einem
gerasterten Bild, sodass ein Logo bei jeder Vergroesserung scharf bleibt
und die Datei klein.
* Elektronische Rechnungen: ZUGFeRD / Factur-X als PDF/A-3B mit
ICC-Profil, OutputIntent, XMP samt Factur-X-Erweiterungsschema,
eingebetteter XML, Dateispezifikation, /AF-Eintrag und Namensbaum. Die Konformitaetsstufe wird aus BT-24 der Rechnung gelesen statt geglaubt,
und beide Beispielrechnungen bestehen veraPDF fuer PDF/A-3B.
* Dateianhaenge sind eine Kernfunktion und kein Rechnungs-Sonderfall,
deshalb kann ein Dokument mehrere tragen, jeden mit eigener Beziehung, Beschreibung und Aenderungszeit.
* Form-XObjects speichern eine Zeichnung einmal und platzieren sie
beliebig oft, in jeder Groesse, Drehung und Deckung - ein Logo auf fuenf Seiten wird einmal eingebettet.
* Die Ausgabe geht mit "$doc write" in eine Datei oder mit "$doc
writeChannel" direkt in einen offenen Kanal, was eine CGI-Antwort oder
ein Socket braucht.
* Die Dokumentsprache ("$doc language de-DE") landet als /Lang im
Katalog, geprueft gegen RFC 3066.
Hinweise:
* Geprueft gegen Tcl 8.6.18 und Tcl 9.0.4 unter macOS: 328 Tests gruen
unter beiden, 18 Beispiele mit 20 Dokumenten, jedes davon von "qpdf
--check" angenommen.
* tdom ist optional und wird vom SVG-Modul benutzt, wenn es vorhanden
ist: es parst 27- bis 48-mal schneller als der mitgelieferte Parser und
wehrt eine Entity-Bombe ab. Ohne tdom laeuft SVG weiter, ueber den
eingebauten Elementbaum-Parser. Sonst ist nichts optional, weil sonst
nichts benutzt wird.
* Im Quellverzeichnis bauen. Ein eigenes Bauverzeichnis konfiguriert
sauber, kann die Tests aber nicht ausfuehren, weil die erzeugte
pkgIndex.tcl die Module ueber $dir sucht, waehrend die Quellen liegen
bleiben. In-tree geht nichts verloren - "make install" legt Index und
Module ohnehin wieder zusammen.
* Ein Dokument einmal schreiben. Ein zweites "$doc write" baut einen
zweiten Satz Objekte auf den ersten, sodass die Datei gueltig bleibt und richtig dargestellt wird, die frueheren Objekte aber unreferenziert
mitreist.
* Keine Schrift gehoert zum Paket. Die Schnitte unter
examples/assets/fonts sind da, damit Tests und Beispiele etwas zum
Einbetten haben, und reisen allein im Quellarchiv mit; "make install" installiert keine. Ob eine Schrift in ein von tclpdf geschriebenes PDF eingebettet werden darf, entscheidet die Lizenz jener Schrift, nicht
diese hier.
* Progressive JPEG und verschraenktes (Adam7) PNG werden mit einer
Meldung abgelehnt, die Grund und Ausweg nennt. Ein progressives JPEG
laesst sich ueberhaupt nicht als /DCTDecode durchreichen - ISO 32000-1
7.4.8 deckt es nicht ab -, und ein verschraenktes PNG muesste dekodiert
und neu kodiert werden, was eine andere Funktion waere. Die Datei
baseline beziehungsweise nicht verschraenkt speichern.
* Was tclpdf abdeckt, ist rund ein Drittel von ISO 32000-1, gewichtet
nach dem Seitenumfang der Kapitel. Der Rest ist fast durchweg das, was
ein Leser fremder PDFs braucht und kein Schreiber; Verschluesselung, Formularfelder (AcroForm), Tagged PDF und Multimedia sind nicht umgesetzt.
Geplant:
* Fremde PDFs lesen, damit ein vorhandener Briefbogen als Hintergrund uebernommen statt nachgebaut wird. Dafuer fehlt die Leseseite des
Formats - vor allem Querverweis- und Objektstroeme, dazu die Filter, die
ein Schreiber nie erzeugt (LZW, CCITT, RunLength) - und es ist der
groesste noch offene Einzelposten.
* Verschluesselung. Der Standard-Sicherheitshandler braucht MD5 und dazu
RC4 oder AES, und keines davon ist hier zu haben ohne ein neu gebautes
TclTLS oder eine mitgelieferte Umsetzung in reinem Tcl; welcher der
beiden Wege es wird, ist offen. Zu beachten: PDF/A-3 und damit ZUGFeRD verbieten Verschluesselung ohnehin.
* Barcodes, insbesondere QR und EPC-QR, damit eine Rechnung einen
Zahlungscode tragen kann, den eine Bank-App vom Beleg scannt.
* OpenType mit CFF-Umrissen (CIDFontType0). Eingebettet werden heute TrueType-Umrisse; eine Schrift, die ihre Glyphen als CFF fuehrt, hat
keine glyf-Tabelle, und der ganze Subset-Weg baut auf genau dieser auf -
das ist also ein eigener Weg und keine kleine Ergaenzung.
* Kerning aus der kern-Tabelle oder GPOS. Der Satz ist heute metrisch
richtig, aber nicht optisch ausgeglichen, was in Ueberschriften bei
Paaren wie AV, To und Ta auffaellt.
* Tagged PDF und damit PDF/A-3a und PDF/UA. Geliefert wird PDF/A-3b, das ZUGFeRD verlangt; die barrierefreien Stufen brauchen einen Strukturbaum,
den es noch nicht gibt. Die Dokumentsprache wird bereits geschrieben.
* Ein Tk-Canvas ins PDF zeichnen - jeder Elementtyp, als Vektoren statt
als Bildschirmfoto. Das ist das einzige geplante Merkmal, in dem Tk
ueberhaupt vorkommt, und es bleibt ausserhalb des Kerns: wer einen
Canvas hat, hat Tk ohnehin geladen, waehrend das Paket selbst es weder verlangt noch laedt. Heute bleibt dafuer nur dessen postscript-Methode,
und die liefert PostScript, kein PDF.
Nichts davon ist fuer eine bestimmte Fassung zugesagt, und nichts auf
dieser Liste wird fuer das gebraucht, was 1.0 leistet.
--- Synchronet 3.22a-Linux NewsLink 1.2