An edit that moves lines into other frames composes on until a paragraph
starts in the same frame and place as before, or to the story's end, as
an_edit_that_moves_lines_composes_up_to_the_next_frame_the_text_starts_in
shows. The ROADMAP line no longer cites an issue about selection lag.
data.placeholder.add with role qr and the insertion point in text bound
the QR code to the first selected frame, which the caret was not in. It
now returns "qr placeholders bind to a frame", as a QR field there does.
A field inserted at the insertion point left the caret before its
marker, so a second field went in front of the first. The caret now
moves past the marker, as after typing.
Docs: docs/agents.md.
* Automation roots: refuse COM¹ to LPT³ and a device name before a colon
is_device_name missed COM¹, COM², COM³ and LPT¹, LPT², LPT³, which Windows reserves as it does COM1.
It also cut the name only at a period, so COM1: and NUL:x were not seen as device names.
* Credit my name in the About window
* Automation roots: document the device-name tests
CodeRabbit's docstring check counts the touched tests. same_component stays without a doc comment, because #2205 deletes that function and a doc line above it conflicts.
* Automation roots: record the device-name refusal
The MCP roots description and the roadmap now name COM¹ to LPT³ and a device name before a colon.
docs/gaps.md now lists the same cases as docs/architecture.md and
reuse::plain. A doc comment on rejoin says that a run style an edit uses
for the first time stops the reuse until the old composition reaches the
same style at the same index.
Every edit of a story composed it from its first paragraph, so a typed
character in a long threaded story cost as much as laying out the whole
story: 456 ms in a story threaded over 300 pages.
A composition that lays every paragraph once keeps its state before each
paragraph. After an edit, composing starts one paragraph above the first
changed one, in the kept state and with the lines above copied. It stops
at the first unchanged paragraph it reaches in the state kept for that
paragraph, and copies the lines from there on with their story offsets
moved by the length of the edit.
- The cache does this when only the story differs from its entry.
- Composed whole as before: stories with footnotes, endnotes, tables,
anchored objects, named lists, tracked deletions, balanced columns,
vertical justification other than Top, column rules, type on a path,
spanning or split paragraphs, paragraph borders or shading, and a
layout that goes back over a paragraph (keep options).
- An edit that moves lines into other frames is composed to the end of
the story.
In a 240-paragraph story a typed character composes 3 paragraphs
(240 before).
Docs: docs/architecture.md, docs/gaps.md (gap 20), ROADMAP.
Refs #2298
With the insertion point in a table cell or a note, data.placeholder.add
with an image field returned "a hyperlink field can't go in a table cell
or a note". It now returns a message about image fields that names the
two ways on: bind the field to a frame, or pass role text to merge its
path. Nothing is inserted on the error, and role text still puts the
marker in the cell.
Docs: docs/agents.md and the command's params text.
A clipped contour now looks only at the edges of the outline and its clips
that reach a line band, and charges its work budget for those alone. An
outline with thousands of points elsewhere no longer exhausts the budget
and falls back to the projections' common part. The Text wrap row of
docs/typography-parity.md notes that an image over 40 megapixels, or one
that can't be decoded, follows the frame's path.
- each traced Alpha Channel outline has a serial number, and the composition signatures include the outlines in use, so a relink or link update that changes only the image data no longer leaves text laid out around the old image
- a wrap with the default alpha threshold is saved without it, as before thresholds were stored
- docs/typography-parity.md says Alpha Channel contours follow the image's visible pixels
Paste ignored a bitmap on the system clipboard: a screenshot or an image
copied in a browser had to be saved and placed. Paste now places it.
- edit.pasteImage {base64, name?, spread?, at?} embeds the image in the
selected empty frame, or in a new frame centered on `at` at its stored
resolution (72 ppi when none) and at most 60% of the page width, as
File > Place sizes it. Save and reopen and IDML export keep the pixels.
Images over 64 million pixels and names without an image extension are
refused.
- Ctrl/Cmd+V pastes the image egui delivers with no text, and Edit >
Paste reads the clipboard's bitmap, or the first image file of a copied
file list, when there is no text or the text is only an address.
- The menu read waits at most 1.5 s on its own thread, with one read in
flight at a time.
- With a native menu, objects copied here still paste as objects until
the pasteboard's change count shows a newer copy.
- ui.paste takes {image} for the control channel.
A call with an `ids` or `id` that is not an object id used to fall back
to the selected frame or the caret's frame. It now fails and leaves the
document unchanged.
The Properties panel's Text Frame section shows the frame Text Frame
Options change: with the Type tool, the frame the caret is drawn in.
Type > Justification and Paragraph Style Options > Justification now show
Auto Leading (0% to 500% of the type size) and Single Word Justification
(Align Left, Align Center, Align Right, Full Justify). Both fields show the
selected paragraphs' values, or blank where they differ, and OK writes
autoLeading and singleWordJustify only when they were edited. An Auto
Leading outside 0% to 500% keeps the dialog open with the reason.
With the insertion point in footnote text or a table cell and no stored
frame on the caret, Text Frame Options changed the last frame of the
thread. They now change the frame the caret is drawn in: the frame that
holds the placed footnote, or the cell's own occurrence (not a repeated
header or footer), else the frame that shows the footnote reference or
the table's anchor.
object.textFrameOptions refuses a gutter outside 0 to 15552 pt, a column
count outside 1 to 40 (it was clamped) and an on/off option that is not
true or false (it was skipped). The Control bar's Columns field stops at
40, as the other column fields do. The params text gives the ranges and
lists flexibleWidth.
type.para and paragraph style create and edit refuse left and right
indents outside 0 to 15552 pt and first and last line indents outside
-15552 to 15552 pt. A style made from the selection is checked with the
values it takes from the selection.
style.paragraph.apply and style.paragraph.redefine check that Minimum,
Desired and Maximum stay in order in each justification row they change,
over the overrides paragraphs keep, and refuse the change otherwise.
Object > Text Frame Options and Cmd+B are enabled with a text caret or a
text selection. Without ids or selected objects, object.textFrameOptions
changes the frame that shows the insertion point, or every frame that
holds part of the selected text, instead of every frame of the story.
The dialog shows that frame's options and keeps the frames it opened
with while the preview reflows the text.
An empty ids list and an id that is not in the document are refused.
Options a frame already has leave the document unchanged and add no
undo step.
Fixes#2396
Insert Field with a QR column and the text cursor in a frame added a text placeholder, so a merge wrote the QR payload as plain text. It now returns "qr placeholders bind to a frame" and leaves the story unchanged.
type.para, style.paragraph.create and style.paragraph.edit accepted any
number for paragraph spacing and justification. They now refuse Space
Before, Space After and same-style spacing outside 0 to 15552 pt, word
spacing outside 0% to 1000%, letter spacing outside -100% to 500%, glyph
scaling outside 50% to 200%, Auto Leading outside 0% to 500%, and a
Single Word Justification other than left, center, right or
fullyJustified. Each justification row needs Minimum <= Desired <=
Maximum over the values the paragraph or style resolves to after the
change, including the styles based on an edited style and the
paragraphs, table cells and notes that use them.
object.textFrameOptions refuses an inset outside 0 to 15552 pt or a list
that is not four sides, and a verticalJustification, firstBaseline,
autoSize or columnsKind that is not one of its names. These were applied
or skipped without an error before. IDML import reads these values as
before.
An image field inserted at a text insertion point, or typed there as
<<name>>, merged as text, so each record showed the image's path.
It now merges as an inline image at its natural size, scaled down to
fit the smallest text column of the story's frames. A missing file is
listed in missingImages and its marker is removed. An explicit image
role at a text insertion point places an inline image too.
An image path that starts with one separator (\Photos\a.jpg) is tried
from the drive's root first, then beside the data file and the
document.
For an oval, a polygon or a frame with corner options, Inset Spacing dims
Top, Left, Bottom, Right and the link and shows one Inset field. OK sends
it as `object.textFrameOptions {inset: <number>}`, which sets all four
sides; compose keeps that inset from the frame's outline. Rectangular
frames keep the four fields.