A right-to-left line draws the text before a tab after it, but its width
was measured in the order of its text. A right-aligned line such as
"אב גד<tab>הו זח" with a stop at 150 pt in a 300 pt frame ended 5.59 pt
past the frame's right edge, and right, center and decimal stops aligned
the text before the tab instead of the text drawn after it.
- The line's width is measured in drawing order, each tab up to its stop
from where the glyphs drawn before it end. Right, Auto and centered
lines are aligned by that width. Stops are still measured from the
left edge.
- Right, center and decimal stops align the text drawn after the tab.
- Area type breaks a line with a tab where it fits as drawn, and wraps a
line that fits only in the order of its text. Once the line holds a
tab, it reads on while the least it can be drawn at fits, then ends at
the latest break that fits as drawn: up to 256 breaks are measured
from the latest back, and earlier breaks without a hyphen are
bisected. Hyphenation points are measured as drawn the same way, so
the line hyphenates at a point that fits.
- Only lines of horizontal paragraphs with right-to-left text keep a
list of their break candidates.
- A tab that ends a wrapped right-to-left line is drawn before the line
at its own width instead of pushing the line to the right.
Docs: docs/target-app-parity.md.
With repeated names numbered when a brush library is read, a stroke that
names a repeated brush draws the first brush of that name, and a later
brush of the name is read as "Name 2". Three tests built a library with a
repeated name and expected the later brush:
- Document Info lists a name two stored brushes share with the first
brush's type (art), not the last one's.
- The two render memory tests add their own `Dots` scatter brush beside
the default library's `Dots`. They now remove the default `Dots` first,
so the stroke draws their brush.
- The .ai writer test that leaves out a Pattern brush "X" gets the
Calligraphic brush after it back as "X 2", the name it had in the
document.
With the selection as its scope, a fix that removes or unwraps objects
(Needless Groups, Stray Points, Empty Text and the others) kept the list
of selected objects current by searching it and splicing it once for each
object it changed. Removing many selected objects above a long run of
others took time that grew with the square of their number.
The list is now rebuilt in one walk after each pass: each changed object
gives way to what replaces it, in its place, and the others keep their
order. The objects found, the counts, the document and the undo step are
the same as before.
Empty Artboards deleted each empty artboard with its own Vec::remove and
walked every ruler guide again for each one. It now drops the empty
artboards in one walk and deletes their guides in one more. The same
artboards and guides are deleted as before.
Tests cover the order after unwrapping nested and empty groups, Fix All
reaching an unwrapped member on a later round, the rebuild itself, the
number of objects looked at for 150 and 300 removals, and the number of
walks over the artboards and guides when 40 empty artboards are deleted.
A command now counts as taking a file or folder when its params
description (with the commands its `…` entries name) or its schema takes
a file key as a param. A word in the description's prose or result no
longer counts; a description whose keys are not known keeps the text
scan. The code of the call-time scan of arguments is unchanged, but it
reads the changed exemption tables. The confined run is unchanged.
- NOT_FILES drops seven entries that named no param of their command
(object.setLiveShape path, path.reverse paths, object.pathfinder.options
paths, object.maskImage path, imageTrace.make paths,
svgInteractivity.info files, addon.cleanup.rejoin paths). A top-level
`path` to object.setLiveShape or object.maskImage, `paths` to
path.reverse, imageTrace.make or addon.cleanup.rejoin, and `files` to
svgInteractivity.info are now refused.
- Image Trace's path fidelity setting is exempt only inside `params` and
`savedPreset` of imageTrace.make and imageTrace.makeAndExpand, so a
call with it is no longer refused.
- every_command_is_sorted checks that each exemption names a param its
command takes, and that each nested exemption starts at one.
- effect.expandAsWireframes is reviewed as allowed and
stroke.arrowheads.list as refused.
stops and stop flattened the path twice, once for the points and once
for its length, and stop did both before rejecting an index past the
last object. place validated the path with attachable_path first, and
transform measured the old and new paths up to three times each.
A private Measured value now holds the flattened first subpath with its
length and closed flag, and path_length, stops, stop and transform use
it. stop returns None for an out-of-range index without measuring, and
a move of the group measures no path.
attachable_path now uses path_length, so a path whose length overflows
to infinity is no longer offered as one objects can attach to when
placement cannot measure it.