Everything in this release came out of one converted template — a restaurant menu built on tables — and most of it turned out to be older than that template.
Converted documents no longer get borders InDesign does not draw. Frames came through with a black outline they were never given, and every table came through with a full black grid: all four borders and every rule between rows and columns. In both cases what InDesign records is not a line but the absence of one, and the conversion was reading a factory default as if the designer had chosen it.
Converted text uses the colour its paragraph styles name. Every text frame arrived claiming a colour of its own — black — which outranks the styles, so a document whose styles were set in a deep red drew none of it.
A table at the top of its frame is drawn. A frame holding nothing but a table showed as empty and reported that its text overflowed. InDesign sizes such a frame to fit its table exactly, and the table was being placed one line of text lower than it belongs, which pushed it out of the frame it fitted. Every menu-style table in a converted document was affected.
Paragraphs keep their own alignment. A frame could only have one alignment throughout, so a menu row could not have its dish name on the left and its price on the right — the two sit in one row of one table, and the document had always recorded that they differ. The alignment control follows the paragraph the caret is in, and changes that paragraph.
Text keeps the line spacing set on the text, rather than the one its style suggests. A paragraph style's line spacing was overriding spacing set on the words themselves; InDesign treats line spacing as a property of the text, so text that states its own now wins. A paragraph that states none still follows its style, as before.
A text frame containing a table can be resized with the mouse again. Clicking anywhere in such a frame put the caret in a cell — including on the frame's own resize handles — and on a frame sized to its table there was no edge left that was not a cell, so the parameter panel was the only way to change its size.
Borders can be removed from a whole table. Selecting a table and clearing its borders reached only the lines the cells own, so on a converted table — where the lines belong to the table itself — nothing happened, except that the bottom line appeared to respond. The palette also reports what such a table is actually drawn with, instead of "no border".
The first two of these apply to templates converted from now on. They change what a conversion writes into a document rather than how a document is drawn, so a template converted before this release keeps the borders and the black text it was given until its InDesign package is converted again. Everything else here is drawing, and applies to every document the moment it is opened.
PDF output had three faults that only came to light once the conversion stopped writing things no one had asked for. They are all older than this release; a document saying less is simply what was needed to reach them.
PDFs generate again. A document whose text had never been given a colour failed outright with "Unexpected color object" and produced no file at all — the whole document lost to one word's colour.
Paragraph styles are applied in the PDF. They never had been, in any document: the text of a converted template was rendered with whatever each word carried and nothing its styles said. Every converted document's PDF changes with this, and the difference is the styles finally arriving — colour here, and leading, indents or a font wherever a style carries them.
Text with no colour of its own is black rather than whatever colour was used last. Colour carries forward from one element to the next in a PDF, and text that stated none inherited it: one block of the menu came out white on white paper and vanished, while the identical block below it looked correct only because the element before it happened to be the right colour.
Table cell text takes its colour from the cell, rather than from the frame around it.
A default is not a design. InDesign expresses "no border" as a stroke colour, not as a
weight of zero, and object styles are not extracted by the converter at all — so an absent stroke
colour was being filled in with black, and any item that stated a weight got a border. The default
is now Swatch/None, which is what [None], [Normal Text Frame] and [Normal Grid] all state;
[Normal Graphics Frame] is the only default style saying black and it supplies a weight we
ignore anyway, so nothing that inherits from it changes.
The table half of that is a different mechanism, and worth knowing before touching table styles.
InDesign does not draw a table's lines from its style — it resolves the style onto the cells and
draws the cell edges. Every table reaches [No table style] through [Basic Table]'s BasedOn,
and that carries 1 pt black on all four borders and both interior rules as a factory default. The
measurement that settled it: nine tables in one template, 224 cell edges, every one carrying an
explicit weight of zero, and not one table declaring a stroke of its own. The six stroke families
now read the table element alone; fills, banding, spacing and direction still resolve through the
chain.
ColorMapper ends its lookup in a fallback to the first collected swatch, so a package whose
Graphic.xml does not define Swatch/None would have resolved "no colour" to whatever came
first — commonly black. Now that an absent stroke colour means none, that fallback was a loaded
gun; None answers before the lookup.
One value, several readers — three times in one epic, and each cost a wrong fix first. A
table's top (top_ly) has eight readers: draw, overflow splitting, mouse hit-testing, the
structural edge zones, in-cell drag, caret geometry and the emitted layout. Correcting it where
the table is drawn left it clickable somewhere else. Overflow is decided in three independent
places — maxHeight, the draw loop's per-line clip (which raises the marker itself, nothing to do
with has_overflow()) and the multi-column scan — so fixing one left the marker on, and
suppressing the second removed the marker for tables that genuinely do not fit. Alignment has five
consumers and was routed through one function from the start, having learned it twice.
top_ly is measured in BASELINE space: every reader adds the first line's baseline offset back,
so a table whose top edge belongs at frame y=0 has to say -offset. Zero placed it as if it
were a line of text sitting on that baseline, when the line whose baseline it is comes after the
table. The value is on the wire and the PDF generator reads it with the same convention, so the
PDF took the correction without a change of its own — unusual for two codebases that implement the
same rules twice.
A story that is nothing but a table still composes one line: linalyze() opens one before the
block loop and pushes it at the end, empty. It is where the caret lives, not content — it holds no
characters and draws nothing — so nothing may measure the frame against it. caret_only_line()
names that fact once, and a table-only story raises its own overset marker because it has no
content line to trip the usual one.
Line spacing resolves in three ordered layers now: what the paragraph states for itself (the toolbar's override), then the largest any of its runs asks for, then the style chain. The previous order read the fully merged properties first, which folds the style chain and the paragraph's own overrides into one value and cannot tell "the toolbar set this to 13" from "the style it inherited says 13". That conflation is what put a style above the text it styles.
Alignment is the third property a paragraph style states that never reached the text — the font
was the first, line spacing the second. The chain walk that stops before the seeded default
style is now one generalised helper rather than a third copy: canvas seeds every document with
that style and every other is based on it, so a fully resolved chain always states a value and
honouring it would re-align every paragraph in every document. Both IDML's vocabulary and the
canvas's own are accepted, because a converted document writes RightAlign where one authored
here writes Right; anything unrecognised — InDesign's spine-relative alignments included —
leaves the frame's alignment alone rather than guessing.
Aligning whole cells through a structural table selection still writes only the cell's value, so it will not move a paragraph that states its own alignment. That path has no caret to resolve against and needs an API of its own; the equivalent case was left alone for line spacing for the same reason.
A table's lines can be owned two ways and the stroke control only wrote one. Cell top/left edges own the interior lines, and the table's own bottom and right borders own the last row and column — which is exactly why the bottom line was the only one that appeared to respond. Both representations are written now: writing only the table-level field would leave an already-authored table's cell edges drawing the line.
'' means "never set", and ?? does not catch it. The canvas spells "this element has no
colour of its own" as the empty string rather than null, because null had to go on meaning
"nothing recorded". The PDF generator did not know that, so the empty string was passed on as a
swatch id — and this is the second time in one release cycle that this distinction has failed at a
repository boundary. Worth sweeping the other direction rather than waiting for the third.
Two things turned that into a total failure rather than one wrong word, and both are fixed with
it: drawTextColor had no guard where its two siblings return early for an unresolvable swatch,
and all three "Unexpected color object" messages named nothing — no uuid, no swatch, no colour
mode. Diagnosing it needed the messenger's stack trace to read the argument.
A story references a style by NAME, and the resolver looked it up by uuid. The canvas writes
the style's name, and a converted document writes it with IDML's prefix
(ParagraphStyle/Platte tekst); neither matched an id, so the lookup returned null every time and
no paragraph style has ever been applied in a PDF. Table and cell styles have been looked up by
name since the table work; paragraph and character styles were the pair left behind. The id is
still tried first.
A PDF's text colour is document state that outlives the element that set it, and a span that stated none set none — so it inherited the previous element's. That was invisible while every element carried a colour, which the converter's invented black guaranteed. Two identical blocks of one page rendered differently because of what happened to be drawn before each: one inherited a banner's white and disappeared, the other inherited a heading's red and looked correct by luck. A span with no colour is black now, which is what the canvas falls back to.
Table cell spans read their colour from the frame and nowhere else. Cell words are matched to the cell's own runs by character offset now, exactly as top-level text already was — the only difference between the two paths is that a cell's layout words carry a paragraph index local to the cell. Both now share one segment builder, which is also what keeps them from drifting on how a word maps to a run.
Known, not fixed: typing in a table cell can rewrap it wider than it was laid out at, which grows the row and can push a tightly fitted table out of its frame. The evidence is on the ticket; it is specifically the in-edit path, since a forced re-layout reproduces the original wrapping.
These tables have almost no room in either direction — 0.67 px of spare width and two ten-thousandths of a pixel of height, because InDesign built each frame to its table. That is their own sizing rather than anything the conversion did, but it means small measurement differences show up immediately as an extra line, and an extra line grows the row past the frame.