Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
50 most recent check-ins
|
2026-08-31
| ||
| 13:24 |
Version 1.4
- configure.ac and tclpdf.tcl carry 1.4, the manual synopsis follows | |
| 13:14 |
Document timestamps: new module timestamp.tcl, examples, tests, shared signing helpers
- timestamp.tcl - ::tclpdf::sign timestamp appends an RFC 3161 document timestamp (/Type /DocTimeStamp) to a finished file; no signature required, the authority is configurable through -url or a -tsa transport prefix, and the reply's digest, nonce and status are verified before the file is touched | |
|
2026-08-27
| ||
| 23:39 |
Download page: the label column no longer wraps
- uv/template-download.html - white-space nowrap and top alignment on the three label cells (tclpdf VERSION, source code, tdom), so the generated download.html keeps "tclpdf 1.3" and "source code" on one line check-in: 456b2e4724 user: alex tags: trunk | |
| 22:46 |
Skill reference: a structureResume snippet and -min on hyphenate load
- doc/claude/skills/tclpdf-tcl/reference/09-tagged-ua.md - a Sect resumed on a second pass takes a further child, and resuming a leaf is shown refused as TCLPDF STRUCTURE PLACE leaf; every call the manual describes has a snippet again | |
| 22:39 |
Version 1.3; the four decisions of round 8 named in the manual, an unknown path letter reported, the shipped profile found through a link, the suite run in its own directory
- configure.ac, tclpdf.tcl, configure - the package is 1.3 | |
| 22:03 |
Norm review round 8 built: object generations kept, one extension schema bag, transactional structure scripts, marks on the right ligature component, SVG transforms the right way round, rotation about the point named
- importRead.tcl, import.tcl, importInfo.tcl, update.tcl, filter.tcl - an object is identified by number and generation through parsing, resolution, copying, update and serialisation; a reference to a generation the file does not have is the null object and a null value is a missing entry; the header of an object stream is checked against the cross-reference table; literal strings read end-of-line as LF and cap an octal escape at a byte under Tcl 8.6 and 9 alike; ASCII85 and ASCIIHex refuse characters outside the encoding; the last of two equal dictionary keys wins and only one is written; every leading zero goes through one decimal reader; an integer beyond 2^31 is serialised as a real; an imported page raises the version to what its source claims and is refused where the document cannot follow; a layer only an XObject refers to reaches OCProperties; the Artifact brackets of an imported page are stripped with its marked content; a Flate stream is bounded at 64 MiB | |
| 13:38 |
Signature in the structure tree, sign add refuses PDF/UA, ModDate on every attachment, Inf refused as a colour, SVG colour values held finite
- sign.tcl - a visible signature (-rect) is a form field of the document: its widget carries /StructParent, /TU from -tooltip and /Contents from -contents, stands in a Form structure element with an object reference and in the /Fields record like any field, so the three PDF/UA questions read it; an invisible signature stays an artifact, since ISO 14289-2 makes a widget of zero extent one (8.9.2.4.13) and a structure element around it fails the file; sign add refuses a file that claims PDF/UA as TCLPDF SIGN STATE ua before a session is opened, naming the write-time signature as the way | |
| 09:25 |
Reader hardening, COLR radial rings, UA-2 list numbering, NaN colours, update error contract
- importRead.tcl - a number token is held to the grammar of 7.3.3 and anything else is refused as TCLPDF IMPORT SYNTAX with token and offset; an object stream is bounded by its own header before the loop (First inside the stream, N at most what the header can hold, every word a digit string with an offset inside the object part) instead of by whatever the file claims; an unknown cross-reference entry type is the null object of 7.5.8.3 and shadows an older live entry; object and generation numbers written with leading zeros are the numbers they mean, in the reference, at the object head and in the object stream header, through one Decimal helper; a missing path, a directory and an unreadable file are refused at the reader's one entry under TCLPDF IMPORT FILE, so pdf import and the five reading commands answer alike | |
| 06:06 |
Bitmap colour fonts: sbix faces, AAT morx shaping, and a TrueType collection read by face
- sfnt.tcl - a collection is opened by face (-face, default 0) and rebuilt as a face of its own; the picture tables sbix, CBDT and EBDT stay on disk and are read by offset through openFace, slice and extent, so a 192 MB face costs 0.06 seconds and 28 MB where reading it whole cost 13 seconds and 4.3 GB; a file that is neither a collection nor a bitmap face goes through the old path byte for byte; a table left on disk is refused by sfnt table rather than answered empty | |
|
2026-08-26
| ||
| 20:58 |
One equation under each skin-tone ramp of the emoji example
- examples/02.18-noto-color-emoji.tcl - under each of the three ramps a line "base + tone = toned base" out of the face's own glyphs, the modifier on its own drawn as the swatch the face has for it, the builder and the farmer with their third part, so that what the modifier does stands on the page beside the ramp that shows it; the five parts join the colour font's character list check-in: 4edc54d76b user: alex tags: trunk | |
| 20:41 |
Name the origin and the terms of the Tcl 9 logo
- examples/assets/README.md - Tcl9logo.svg is the Tcl/Tk 9.0 logo by Valerie Carroll with Steve Landers, taken unchanged from the published SVG, under the Tcl licence as the wiki page that introduced it says; the placeholder asking the author to confirm the terms is gone check-in: 051f014c92 user: alex tags: trunk | |
| 20:28 |
Put the library names back into the skill and one measurement comment
- doc/claude/TCLPDF.md, SKILL.md - the warning against writing a tclpdf call from memory of jsPDF, ReportLab, FPDF or pdf4tcl names them again, as intended: with the names the warning is sharper than without. The previous check-in had taken them out under the naming rule, and had cut the second half of the sentence in SKILL.md with them; both are restored to their earlier wording | |
| 20:21 |
Norm-review round seven: twenty-nine findings no validator sees, all built
- Graphics - overprint never writes /OP without a word on the fill side, a pattern belongs to the stream that carries it (canvas id), an integer beyond 2^31 is written as a real, a shading angle under -matrix is mapped once, an open arc under a fill in force is refused, save without restore and a q depth past 28 are refused at the stream end, a name past 127 bytes at the call, /Rotate is normalised, an ICC v4 profile binds PDF 1.7, Exif orientation is read into image info and not applied, and the one PDF number bound lives in pdfObj fits behind option number, option point and page distance | |
| 14:01 |
Source In as a clip path, and the winding that decides it
- colorFontRegion.tcl - new: the arithmetic behind a clip standing in for a mask - outlines flattened, the winding number asked at the faces of an outline's own arrangement rather than at its vertices, a contour turned to run the other way, and one shape tested for lying inside a union of others | |
| 12:27 |
Soft masks out of Type 3 glyphs where a plainer construction exists
- colorFontBand.tcl - new: a gradient with varying stop alphas is drawn as nested bands of constant alpha instead of a luminosity soft mask - level sets, each painting the same shading over a narrower clip with the alpha increment as ca, so that a band edge is an increment over painted ground and not a seam. Strips across a linear axis, even-odd rings for a nested radial, the wedges of the sweep. Two readers anchor the matrix of a soft mask set inside a Type 3 glyph stream to the page rather than the glyph and lose the masked shape; a clip and a constant alpha are misplaced by no reader. The technote of 2026-08-26 records the finding | |
| 10:07 |
Feature wiring behind the context machine, and emoji sequences
- forms.tcl - the closing stage runs in two hb-order stages, rlig first and then liga with clig under the resolved script, proved with a patched face whose lookup numbering would have caught a shared stage. The DejaVu lam-alef gap is closed; Arabic still matches hb-shape word for word, and -ligatures 0 keeps rlig, since shaping is not typography | |
| 05:25 |
Contextual substitution and COLR version 1
- gsubContext.tcl - new: contextual and chaining substitution, GSUB types 5 and 6 in all six formats plus the extension wrapper, read and matched but never applied here. gsubApply.tcl rebuilt onto one application walk whose nested lookups run through the same machine, with the HarfBuzz shift arithmetic for records that grow or shrink the run. With this the last Arabic refusal falls: rlig over chaining lookups is applied, and the shaped output of every Arabic face in the tree now matches hb-shape exactly, Nastaliq included | |
|
2026-08-25
| ||
| 23:00 |
A public arc command, and a Tk canvas drawn as vectors
- shape.tcl, geometry.tcl, svgPath.tcl, document.tcl - doc arc with -start, -extent and the styles arc, pieslice and chord, angles counter-clockwise from three o'clock as the page shows them. The Bezier approximation moves out of svgPath into geometry as arcSegments and both callers share it; svgPath writes the same bytes as before. Modules to 1.7, 1.4, 1.2 and 1.14 | |
| 20:24 |
Every refusal carries an error code, and two examples at the front
- forty-eight modules - the five hundred and eleven refusals that carried no -errorcode have one. With them, every refusal this package makes carries one. Fifty-four topics; where a topic has classes the third word is one, and it says what the caller has to do about it: ARGUMENT a wrong value, STATE a wrong order, NAME or ALIAS something that does not exist, FOREIGN a file this package did not write, DAMAGED a broken one, ROOM too little reserved space | |
| 17:48 |
Overprint, and the three examples that came out of it
- graphics.tcl, shape.tcl - overprint as a graphics state: doc overprint -fill -stroke -mode writes OP, op and OPM, and every shape takes -overprint for both sides inside its own q and Q. The version asked for is the one the call writes, a call naming none of the three is refused, and the shapes keep their own bracket so an overprint cannot leak into the rest of the page. Modules to 1.6 and 1.5 | |
| 14:21 |
Norm review round 6, and the work it turned up
- annot.tcl, field.tcl, import.tcl, font.tcl, writer.tcl, update.tcl - refusals that stood after an object number was reserved now stand before it, and what cannot be moved gives the number back through the new writer and update release, so an error the caller catches leaves the document writable | |
| 05:16 |
Eight reopened gaps closed: error codes, interpolate under PDF/A, fitting, anchors, emergency hyphen, function pool, geometry annotations, vertical breaking
- sfnt.tcl, type1.tcl, subset.tcl - forty-five refusals given an error code in seven classes, so a script can tell a wrong format from a broken file, an unsupported variant from a missing table, and a face that cannot be subsetted from any of them. Two new test files with them: these were the two largest private modules and neither had one | |
|
2026-08-24
| ||
| 20:55 |
Nine gaps closed: shadings, annotations, DeviceN, CCITT, inline images, vertical writing, bare CFF
- shading.tcl, shadingMesh.tcl - shading types 1 and 4 to 7: a colour that is a calculation over an area, and the four mesh types that carry their colours in the points. Type 1 needed a PostScript calculator function, since types 2 and 3 take one input by definition; the four mesh types share one packer, and the Decode range comes from the mesh rather than from the page | |
| 12:32 |
The break hyphen of a table, and two ways into a radio set
- textBlock.tcl, tableLayout.tcl, tableDraw.tcl, text.tcl - a broken table cell brackets its break hyphen the way a text -width paragraph does, so extracting a tagged table gives the word whole. The breaker already knew which line ends on an inserted hyphen and textLines threw it away; it now travels to the cell and on to text, which does the splitting inside one text object after the position of the whole line is fixed. The cell never cuts its own string | |
| 11:07 |
Hyphenation in table cells
- table.tcl, tableLayout.tcl - a cell with more than one line can be hyphenated: hyphenate joins the style keys beside direction, so it reaches a table, a head or body or foot, a column and a single cell, and the more specific one wins. Measuring passes it on to textLines; the drawing side needs nothing, since it sets lines the measure already broke - the same list, so the two cannot disagree | |
| 10:28 |
An errorcode for every option refusal, and the text field in a module of its own
- option.tcl - all seven refusals of the shared option parser threw with errorCode NONE, so a misspelt option name was the one error a trap could not catch. They now carry TCLPDF OPTION with six class words: UNKNOWN, PAIRS, DICT, KEY, REQUIRED and POINT, each followed by the facts and the calling context. No message wording changed | |
| 09:29 |
Interactive form fields, and reading one back
- field.tcl - the AcroForm core and the text field: the field tree, /AcroForm on the event bus, the document DA and DR, an appearance stream drawn for every widget, and a declaration that takes several widgets for one field. NeedAppearances is not written at all | |
|
2026-08-22
| ||
| 22:14 |
Correct what openssl can and cannot do under a PAdES claim
- sign.tcl - the refusal of a signing-time attribute said openssl and BouncyCastle offer no switch to leave it out and therefore cannot produce a PAdES signature. Measured with OpenSSL 3.6.3: "cms -sign -cades -no_signing_time" makes an object this package takes under /ETSI.CAdES.detached, and the same signer without the switch is refused. The message, the module comment, the manual and the skill reference now say what the switch is and that the LibreSSL shipped as /usr/bin/openssl on macOS has none | |
| 17:14 |
Version 1.2
- configure.ac, tclpdf.tcl - the package version is 1.2 | |
| 16:21 |
Norm review round five: what no validator sees
- importRead.tcl - a foreign file can no longer hang the reader or die in raw Tcl: an unclosed array bracket, a self-referential /Length, an object stream that contains itself, a page tree that names itself among its kids, a subsection count larger than the file, and an /Index whose numbers are not numbers each end in a named refusal now. Every refusal in the reader carries a TCLPDF IMPORT code | |
| 06:13 |
TIFF pictures are read, and a colour font reaches the page
- imageTiff.tcl, new - the structure of a TIFF: tag directories, the IFD chain, the strips with their offsets and lengths, the resolution, an ICC profile. What it will not read it refuses by name rather than half-reading: BigTIFF, tiled files, separate planes, an alpha channel, YCbCr outside a JPEG stream, and any depth, sample format or predictor PDF cannot be told about. The format is recognised by its magic bytes, never by the file name | |
|
2026-08-21
| ||
| 17:39 |
Colour font stage 1, the two readers - plus two defects in the checked-in state
- colr.tcl, new - COLR version 0 and CPAL are read: a base glyph answers its layers bottom-up, a palette entry answers colour and alpha, and the 0xFFFF sentinel answers the caller's text colour. Version 1, an empty table and a damaged one are each refused by name | |
| 17:04 |
01.14 carries its specimens on both pages, one language each
- examples/01.14-hyphenation.tcl - the specimen block is split by language: the German words close the first page, the English ones the second, both drawn by one shared procedure instead of a single block at the end of the document check-in: c01711095a user: alex tags: trunk | |
| 15:44 |
Combining marks are placed, and words are hyphenated by language
- markPos.tcl, new - GPOS mark attachment, lookup types 4, 5 and 6: a combining mark is put where its anchors say instead of at the pen. otLayout gains the anchor reader, since cursive attachment reads the same table. Script resolution is two-stage - the resolved script stays authoritative and a fallback lookup is offered only where the first stage left a mark alone, because a union lets one script's coverage overrule another's | |
| 12:33 |
Layers, an inventory of a foreign file, Lab colour, drawn glyphs, and a fallback chain
- layer.tcl, new - optional content (8.11): layer create declares a group, layer draw -script puts content into it between /OC ... BDC and EMC, and state, radio and configure make the default configuration. It hangs on the bus, so the core knows one line about it. In a tagged document the layer bracket and the structure marks nest rather than cross, which the test asserts by walking the ORDER of the brackets - the right count in the wrong order passes a count | |
| 08:08 |
An existing file can be continued, and signed a second time
- update.tcl, new - ::tclpdf::update open gives a session on a finished PDF and appends to it as an incremental update (7.5.6): add and addStream write objects the file does not have, replace writes a second copy of one it does, body hands back what the file currently says, and write puts the original bytes and the appendix behind each other. The original is not touched, which is checked by comparing bytes rather than by asking qpdf - a flipped byte inside a Flate stream leaves qpdf reporting success | |
| 05:13 |
Text rendering modes, image masks, and a bounding box that encloses what it says it does
- text.tcl - -render takes a word rather than a number: fill, stroke, fillStroke, invisible, with -stroke and -strokeWidth routed through the existing colour and line paths. All three are font state, so a paragraph, textPath, leader and pageNumbers get them for free; Tr is written only where it differs from the initial mode, so existing documents keep their bytes | |
|
2026-08-20
| ||
| 22:10 |
Raise the version of every module changed since 1.1.1
- 32 modules, package provide and pkgIndex.tcl.in alike check-in: 0850a9af3b user: alex tags: trunk | |
| 20:44 |
A signature with a timestamp is no longer refused, and an example for the ICC path
- sign.tcl - the check that refuses a signing-time under cades read the whole DER and found the OID inside an RFC 3161 timestamp token as well, so it refused a PAdES B-T signature the standard allows; it now reads the ORDER of two OIDs, since RFC 5652 puts signedAttrs before unsignedAttrs and a time behind the token belongs to the token. What that costs is written at the code: an OID inside a certificate would still be read as the signer's own | |
| 19:26 |
Stage 8b: digital signatures, invisible and visible, in one and in two stages
- sign.tcl - $doc sign writes the signature dictionary, the widget, the /AcroForm entry and a /Contents placeholder of a fixed size; beforeWrite builds the objects and afterWrite fills /ByteRange and the signature into the finished file, both edits length-neutral and checked to be | |
| 12:29 |
Sample data in the examples: real IBANs, and the manual no longer counts encryption as missing
- Manual: the DESCRIPTION sentence listed encryption among what the package does not do - it names reading an encrypted file instead check-in: e301f13fb4 user: alex tags: trunk | |
| 11:13 |
Stage 8: encryption, the standard security handler in revision 6
- crypto.tcl - AES-256 in CBC and single-block ECB, SHA-256, SHA-384, SHA-512 and random bytes from /dev/urandom, all in pure Tcl and checked against FIPS 197, NIST SP 800-38A and FIPS 180-4; the S-box is computed rather than transcribed, and a missing random source is refused by name instead of weakened | |
| 08:29 |
Add make publish-examples: the example PDFs go to the unversioned area
- new target after the publish pattern: builds the examples, uploads each PDF as examples/name to the unversioned area, syncs and counts - the "examples" wiki page lists and links them; unversioned content is replaced, not versioned, so re-publishing does not grow the repository check-in: 42160d2ef6 user: alex tags: trunk | |
| 07:59 |
The two round-4 leftovers: absolute error position, no orphan profile object
- textBlock - a refused glyph names its position in the string as handed in on every road of the paragraph breaker, found by searching that string rather than by offset arithmetic, and the -avoid road no longer reports position zero; the manual drops its exception sentence | |
| 07:52 |
Retire the measured pdf4tcl comparison in favour of a short notice
- doc/TCLPDF-VS-PDF4TCL.md carries a friendly notice instead of the feature table: the actively maintained fork at github.com/gregnix/pdf4tcl closes publicly named gaps within a day, so keeping a measured list current would cost nearly as much as extending the software - the page now points there, notes that tclpdf is MIT and taking what is useful is welcome, and keeps the one stable statement: the two projects complement each other | |
| 06:29 |
Norm review round 4: twelve violations fixed, gray areas and hardenings built
- import.tcl - inherited page attributes take the nearest ancestor, CropBox intersected with the MediaBox, name #-escapes decoded and re-escaped, OCG configurations merged across imports and OCMDs resolved to their groups, stream /Length verified against endstream, imported forms carry a transparency group, whitespace reduced to the six PDF bytes, integer-valued /Rotate reals read | |
|
2026-08-19
| ||
| 21:38 |
Machine-readable errorcode for character refusals
- every character refusal throws -errorcode {TCLPDF FONT GLYPH codepoint position fontname}, standard faces, Type 1 and embedded faces alike, trappable by prefix with try/trap - asked for on the mailing list | |
| 21:14 | Add doc/TCLPDF-VS-PDF4TCL.md - the measured tclpdf versus pdf4tcl comparison check-in: 3fedc783b1 user: alex tags: trunk | |
| 20:53 |
Etappe 7: pdf import - a page of an existing PDF becomes a form
- import.tcl: $doc pdf import alias path ?-page n?, placed with form place - real tokenizer, classic xref tables and cross-reference/object streams with PNG predictors and hybrid files, inherited page attributes, CropBox and /Rotate folded into the form's BBox and Matrix, resources copied byte for byte with their filters untouched, content streams decoded and merged, OCProperties written for optional content | |
| 12:30 |
Version 1.1.1
- configure.ac, tclpdf.tcl, manual header - the three version sites, configure regenerated check-in: 6a5c9009c1 user: alex tags: trunk, release, version-1.1.1 | |