An envelope mapped type from its laid-out box: ascent to descent for
point type, the frame for area type. The distorted glyphs then filled
less of the envelope than other art does, with room above the capitals
and below the baseline.
The envelope now maps type from the bounds of its glyph outlines,
underlines and strikethroughs when the type is on its own, in groups
and layers, or used as a clipping path. Inline graphics count by their
boxes. Rotated type and type in perspective map from their outlines as
they are drawn. Make with Mesh,
Make with Top Object and Reset with Mesh without Maintain Shape use
those bounds. Type that draws nothing keeps its laid-out box, and so
does type inside any other object, such as a blend, a repeat or a
symbol instance. Shrink Text to Fit type is measured as it is laid out
on the page.
vectorcraft-text's envelope_ink measures the type, and
register_envelope_ink registers it with the document crate. The engine
session, Renderer::new, live evaluation in vectorcraft-effects and the
.ai reader register it. The document crate keeps the measured boxes per
thread, by object and by a hash of the content, and measures again when
the type, the fonts, the hyphenation exceptions or the transform's
scale or rotation change.
This is VectorCraft's own rule. Envelopes of type made in VectorCraft
and in saved files map from the glyph outline bounds instead of the
type's laid-out box, so they redraw differently.
Holding a single-key tool shortcut becomes temporary: releasing it
returns to the previous tool (a quick tap still switches for good).
With the Pen chosen, holding S chooses Scale; letting go of S after
0.25 s or more, or after Scale was used while S was down, chooses the
Pen again. A press shorter than 0.25 s, with nothing done in between,
keeps Scale chosen as before. The 0.25 s threshold is VectorCraft's own
value. A Cmd/Ctrl click, which the selection tool takes, does not count
as using Scale. A drag of the Hand, Zoom or Rotate View tool chosen
this way counts as using it.
A key let go during a drag, with the pointer button held or with a
dialog open, goes back once that ends. A key let go while the tool
waits for its next click (the Dimension tool after its first point)
goes back once the tool finishes or is canceled. With S held from the
Pen and then V held, letting go of V returns to Scale, and letting go
of S then returns to the Pen. Choosing a tool on the toolbar or from a
menu while the key is down, the held tool included, ends the hold and
keeps that tool, and so does the window losing the keyboard.
While the preference is on, the key's repeats do not choose the tool
again.
The new General preference Hold a Tool Shortcut to Use the Tool
Temporarily (`holdToolKeys`, on by default) turns the behavior off.
With it off, every press and every repeat chooses the tool, as before.
Its label has a row in every catalog.
Docs: docs/mcp.md, docs/target-app-parity.md.
Commands that read `id` and otherwise act on the selection, the highlighted
layer row or a new object read it with a lenient helper, so `{"id": "abc"}`,
`true` or `{}` acted on the selection instead. They now read it with
`object_param`, which refuses any value that is not a non-negative integer
with "`id` must be a whole number" under the command's name and changes
nothing; an omitted or null `id` keeps the default.
Commands: object.isolate, layer.locate, layer.releaseToLayers,
graphicStyle.new and redefine, charStyle and paraStyle new, apply and
redefine, image.info, links.info, links.goTo, links.unembed, shaper.release,
shaper.expand (whose errors now carry their own name),
transparency.editOpacityMask, transparency.viewOpacityMask, symbol.edit, the
object.blend.spine commands, path.curvature and the type commands that read
type ranges.
targets() read `id` as an object only when it was a number. Any other
value ("abc", "5", true, {}, [1]) fell through to the selection, so a
command such as css.export, whose `id` the shared check does not read,
acted on the selected objects instead of failing. targets() now reads
`ids` and `id` through named_ids(): a value that is not a non-negative
integer is an error, and an omitted or null `id` still means the
selection. A numeric string is refused, as it already is in `ids`.
effect.apply and appearance.addEffect accept the effect as `id` when
`effect` is left out; they now read their targets with that `id` set to
null, so the effect still applies to the selection as before.
Each of the locator's nine squares was a Tab stop of its own, so Tab from
the field before it in the Transform panel, the Properties panel, the
Control bar and the dialogs that show it stopped up to nine times before
it reached the next field. The locator is now one Tab stop. While it has
the focus it shows an outline, and the arrow keys move the reference
point one square, stopping at the edges. A click on a square works as
before.
Screen readers get a radio group holding the nine squares as radio
buttons, with the current point as its value. The group is named after
the label next to the locator: Reference Point, or Pivot, Alignment,
Registration or Placement where the locator sets one of those.
New crate vectorcraft-js reads ECMAScript 5.1 source into a syntax tree
with source positions: a UTF-16 lexer (line and column tracking, automatic
semicolon insertion, the regexp and division goals), preprocessor lines
read as directive tokens, a recursive-descent parser to an arena tree, and
the ES5 early errors, strict mode included. Nesting deeper than
Options::max_depth (200 by default) gives a SyntaxError with its line and
column rather than overflowing the stack. Nothing runs scripts yet.
cargo xtask test262 downloads test262 at a pinned commit, checks its
SHA-256, unpacks it into the gitignored corpus/ folder and runs the ES5
syntax tests. A differential test in the engine compares the lexer with
scriptcheck on line counts, directives and unterminated literals.
With several objects selected, Shading, Revolve's Cap, Keep visible surfaces
only when expanding and the other checkboxes read a setting the effects hold
with different values as off. A mixed Shading also turned off the Lighting
tab's controls.
- A mixed checkbox shows a dash with its reset dot filled; a click turns it on
for every selected effect, and other changes leave it as each effect has it.
- A mixed Shading leaves the light settings available.
- A mixed menu choice shows its default; a mixed light color fills its reset dot.
- Add Light is unavailable while a setting of a single light is mixed.
The panel opens from Window › 3D and Materials (window.panel {panel:
"threeD"}). Its object types Plane, Extrude, Revolve and Inflate apply
Rotate, Extrude & Bevel, Revolve or Inflate to each selected object
without a 3D effect, and change the 3D effect of each other selected
object in place, all as one undo step. Below them are the effect
dialog's Object, Rotation and Lighting tabs with the same controls.
A changed setting goes to every selected 3D effect that takes it, as
one undo step; a drag previews and records one step on release, and a
change of selection during a drag commits it first, and so does closing
or hiding the panel. A setting the
selected effects hold with different values shows its default with its
reset dot filled. A light list edit reaches only the objects whose list
matches the first object's.
effect.setParams takes threeDType (plane, extrude, revolve, inflate):
the settings both effects take keep their values, rotation angles wrap
into -180..180 outside Revolve, and the rest start at the new effect's
defaults. Another value, or a non-3D effect at index, is refused; the
type an effect already has, with nothing else to change, records no
undo step.
Materials, shadows and ray-traced rendering are not part of this.
Docs: docs/three-d.md, docs/mcp.md, docs/effects-parity.md,
docs/target-app-parity.md.
Fixes#3672
A numeric field's up/down spinner and the chevron that opens its presets
were Tab stops, so Tab took three presses to get from one field to the
next in the Stroke, Character and Transform panels and two in a text
field with presets (Export for Screens' scale). The Transparency row's
opacity slider chevron was a Tab stop after the Opacity field too. All
three now sense clicks without taking the keyboard focus; clicking them
works as before, and Up/Down in the field still step it.
Without the chevron in the Tab order, Alt+Down (with no other modifier)
in a field with presets opens its preset list with the keyboard focus on
the chosen preset, or on the first one. Before, Alt+Down stepped such a
field down by one; Shift+Alt+Down still steps it by ten, and fields
without presets still step on Alt+Down. Enter on the focused preset picks
it and closes the list without also pressing a dialog's OK, as the combo
boxes do, and after a pick or Escape the field has the keyboard focus
again.
document.open, file.place and document.pdfInfo read cropTo (and its
older name crop), password, colorMode and textAs as strings and used
the default when a value was not a string, so "textAs": true or
"colorMode": 5 opened the file with the defaults. They now return an
error naming the param, and nothing opens or is placed. A wrong crop is
refused even when cropTo is given. document.pdfInfo also rejects a
thumbnailSize that is not a number, with or without a thumbnail.
Leaving a param out or giving null keeps its default, and an empty
password still means no password.
charStyle.load, paraStyle.load and textStyle.loadAll imported the styles
into a copy of the document to see whether anything changed, then ran the
same import again inside the edit. The edit now takes the copy the first
import made. While a typing session is open the import still runs inside
the edit, because the edit ends the session first and that can change the
document.
Matching a loop of definitions parsed the document's brush library again
for every comparison, and placing brushes in use order parsed it again for
every brush. Each now reads it once.
The params text and docs/mcp.md now say that the symbols and brushes the
patterns use come along, that `skipped` lists names in the file, and that
charStyle.load and paraStyle.load list only the styles of their own kind.
A loaded character style kept a size, scale, leading, shift or stroke width that
charStyle.new refuses. Such a style is now skipped and listed in the reply's skipped names.
Load Character Styles and Load Paragraph Styles left out every style of the other kind,
so a pattern that a loaded style paints with kept a reference to a paragraph or character
style the document did not get. The styles of the kind not loaded now come along when such a
pattern or symbol sets type in them, renamed like any other.
The order in which styles, symbols and patterns are placed is worked out from one graph of
their uses instead of scanning every definition left in each round.
The Character Styles and Paragraph Styles panel menus get Load Character
Styles... or Load Paragraph Styles..., and Load All Styles..., which add the
styles of a document picked in an open dialog in one undo step
(charStyle.load, paraStyle.load, textStyle.loadAll). The swatches,
patterns and symbols the styles use come along as Paste brings them, in
use order, so a style or pattern renamed on the way in keeps its links.
A style the document already has, under its name or a numbered copy of
it, is not added again; another style whose name is taken is added under
a free name. The file's Normal styles, and styles with a blank name or
attributes that do not read, are not loaded.
Warped type that a text variable binds stays type with the effect live,
so it keeps its binding. Before, a failed comparison replaced it with
its drawn art and the binding was skipped.
When drawn art replaces warped type with a wrap setting, the wrap shapes
are checked against the file's limit on wrap work again, so a file whose
drawn art would go past it opens from its page, as one with too many
text objects does.
A Warp on type, on the object or on one of its fills or strokes, opened
as a live effect with no check. Where the live warp draws a different
shape from the art saved in the file, the type moved and changed size.
Warped type is now compared with its saved art once it is laid out,
with the comparison and the per-file budget that envelopes use. Type
that draws as its saved art stays editable with the effect live. Other
warped type opens as that art, not as editable type, with one note that
counts them, and saving over the file asks first. The art's box goes
back into the comparison with the page. Type stays live without a
comparison when its saved art paints nothing or draws type of its own,
and in frames of threaded type.
Smooth Color now counts the steps between each pair of keys from the
keys' colors and visible bounds, which changes the step count of most
Smooth Color blends. The counts are VectorCraft's own values:
- When the keys' solid fills or strokes differ (in groups, member by
member; in text, run by run), the count is 255 times the largest
change of one channel as a fraction of its range, a half step
rounding down, from 1 to 254. An RGB channel's range is 256 values,
CMYK and gray count in percent, and two tints of one swatch by their
tints. It is at most eight per point of the largest of the keys'
widths and heights and the distance between their centers. Black to
white was 128 steps and is now 254.
- When the colors match, a solid paint meets no paint, or a key holds
a gradient or a pattern, the count is the largest distance between
corresponding visible bounding-box edges divided by the keys' mean
width or height, rounded, less one, from 1 to 1000. Two 20 pt
squares 200 pt apart were 100 steps and are now 9.
Keys without bounds make the color count when their colors differ,
and 1 step otherwise.
A blend nested in another blend's keys counts toward the step limit
by its color steps when its colors differ, and as up to 1000 steps
when they match (256 before). An outer blend of 200 steps between two
such same-color Smooth Color blends now draws 99 steps.
A Smooth Color blend in an .ai file whose drawn steps follow this rule
now opens as a live blend.
Blend Options: https://web.archive.org/web/20241217212108/https://helpx.adobe.com/illustrator/using/blending-objects.html
Docs: docs/mcp.md, docs/target-app-parity.md.
A colors value that is not an array, such as "#fff" or 5, was ignored and the command checked the selection or the whole document instead. It is now an error. A null colors still checks the selection or document, as an omitted one does.
The color management commands read their params with helpers that fell
back to the default for a value of the wrong type, so "bpc": "no" kept
the old setting, "on": "true" toggled the view and "convert": "no"
converted the colors. They now go through switch_or and text_param:
such a value is an error and nothing changes. Omitting a param or
giving null keeps its default.
- edit.colorSettings: rgb, cmyk, intent, bpc
- file.documentColorMode (and its alias): convert, intent, grays,
checked before the early return for the current mode; PDF import's
grays reads the same way
- color.convert: to, intent
- color.loadProfile: path; color.removeProfile: name
- view.proofSetup: target, intent, simulatePaper, proof
- view.proofColors and view.overprintPreview: on
- view.separationsPreview: on, only, toggle, and plates, which must be
an array of plate names
- swatch.setSpot: name, spot
With an unclipped raster/vector balance between 0 and 100, a group that
splits into more than 10^(balance/20) regions is rasterized whole and
none of its regions are used. The region build now stops at the first
region past that limit (pathops `regions_within`) instead of building
every region and then discarding them. Groups at or under the limit,
and every group with Clip Complex Regions on, still build every region.
Flatten Transparency, the flattened document and EPS export come out
the same as with every region built, for groups under the limit, at it,
just over it and far over it.
A corner tile was turned so that its x axis followed the mean of the
directions the path arrives and leaves in. A tile drawn as a right-angle
corner then came out turned 45° at every corner, so a rectangle drew its
corners as diagonal chevrons.
Outer and inner corner art are now both read as the corner that joins a
side tile on its right to one below it, as in the help's steps for
making corner tiles. Each corner tile is turned so that those two arms
meet the sides: on a rectangle the tile is square to the side tiles and
turns 90° from one corner to the next, and at other angles it is turned
halfway between the two sides. The arms follow Flip Along and Flip
Across, and a corner that takes the other kind's art turns it the same
way. Which art each corner takes is unchanged.
The PatternBrush field docs, the brush.options params text, docs/mcp.md
and the progress doc describe how corner art is drawn.
object.envelope.makeWithWarp, resetWithWarp and options read `style`
and `orientation`, and options read `preserveShape`, as text and
ignored any other value, so `{"style": 5}` kept the default style and
`{"orientation": "diagonal"}` kept the current orientation. They now
return "`style` must be a string" or "`preserveShape` must be a
string" for a value other than text or null, and "`orientation` must
be one of horizontal, vertical" for any other orientation, through
the shared `choice` helper. object.envelope.options checks the warp
keys whatever is selected, so a call with no envelope or only mesh
envelopes selected gets the same errors, an unknown style name
included. Omitted and null values keep today's defaults.
Docs: docs/mcp.md, docs/target-app-parity.md.
Update Links, and opening a document with Update Links: Automatically,
now read a modified file again for the images and placed documents in
symbols, graph designs, patterns and opacity masks that show the same
content as the objects read in the layers. By default Update Links also
reads the files that only that art shows. Each nested object takes the
file's place as its own Placement Options say, including the clip, and
its link takes the new path, size, modification time and hash.
Saving a document also refreshes the placed copies of it inside symbols,
graph designs, patterns and opacity masks of the other open documents,
not only those in the layers.
Relink, Embed and Unembed still change only the objects they are given.
A save wrote the path relative to the document only for linked images and
placed documents in the layers. Links inside symbols, graph designs,
patterns and opacity masks kept only their absolute path, so after the
document and its files moved to another folder together, those files were
not found.
- The save sets the relative path of every link the document holds.
- On open, a link inside that art whose file was found away from its path
takes the new path, as a link in the layers does, so the next save
writes the right relative path.
- Document::update_links_where changes only the links it picks and copies
only the nodes on the way to them.
Docs: docs/mcp.md (Linked images), docs/target-app-parity.md.
Six buttons above the Image Trace panel's Preset dropdown choose a preset as the dropdown does:
Auto Color chooses Auto Color, High Color chooses High Fidelity Photo, Low Color chooses Low
Fidelity Photo, Grayscale chooses Shades of Gray, Black and White chooses Black and White Logo,
and Outline chooses Outline. With Preview on, a click traces the selected Image Trace object again
as one undo step; with nothing traced selected, it changes the panel's settings only. The button of
the panel's preset shows as selected, and its tooltip names the preset.
The help page lists these options before Preset:
https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/image-trace-panel-options.html
Which preset each button chooses is VectorCraft's own.
High Color and Low Color get rows in every catalog.
With Fade Region Outside Artboard on, the canvas now draws the fade over the
art as well as the pasteboard: one mesh of black at 40% opacity covers the
canvas outside the artboards, so the pasteboard and any art on it show each
channel at 60% of its value, and art inside an artboard is unchanged. It
replaces the darker pasteboard fill.
Artboard Options sets the Global checkboxes' preferences only after
artboard.setProps or artboard.new succeeds. When the artboard command
refuses a value, the preferences stay as they were and the dialog stays
open. A Global value that is not true or false is refused before anything
changes.
Docs: docs/mcp.md, docs/target-app-parity.md.
Artboard Options gets a Global group with Fade Region Outside Artboard and
Update While Dragging. Both are application preferences
(fadeRegionOutsideArtboard, artboardUpdateWhileDragging), on by default and
also listed under Preferences > General > Artboard Options.
While the Artboard tool is active, the canvas draws the pasteboard with each
color channel at 60% of its value. With Update While Dragging off, the
pasteboard draws as usual while the tool moves or resizes an artboard and
darker again when the drag ends. Exports and print do not change.
Docs: docs/mcp.md, docs/target-app-parity.md.
Find and Replace, Find Next, Change Case, Smart Punctuation, Insert
Character and Type on a Path Options read their params with helpers that
fell back to the default for a value of the wrong type: Find and Replace
with `replace: 5` replaced every match with nothing, and `flip: "true"`
did not flip. They now return an error and leave the document, the
selection and the undo history unchanged:
- `find`, `replace`, `case`, `char`, `text`, `unicode`, `effect` and
`alignToPath` must be a string or null.
- `matchCase`, `wholeWord`, `dashes`, `ellipsis`, `quotes` and `flip`
must be true, false or null.
- Smart Punctuation's `scope` must be `selection` or `document`.
- Type on a Path Options' `spacing` must be a number or null.
- Insert Character's `code` must be a whole number or null.
- Find and Replace's `ids` must be a list of existing object ids.
Insert Character checks `char`, `text`, `code` and `unicode` before it
picks one, so `{"char":"bullet","unicode":176}` is refused too. The
order the sources are used in is unchanged. Null counts as left out, so
`type.insert {code: null, unicode}` inserts the Unicode character.
Omitted params keep their defaults.
Legacy type in a composite font such as HeiseiMin-W3-83pv-RKSJ-H was
decoded one byte to a character, so Japanese, Chinese and Korean type
opened as unrelated single-byte characters, and the font name kept the
CMap.
Tf now finds a predefined CMap at the end of the font name, unless a TZ
gives the font encoding pairs, and the font is the name without it.
Strings in that font are read by the CMap's code space, mapped to CIDs
with the predefined CMaps craft-pdf carries, then to Unicode by the
character collection's CID-to-Unicode CMap. Codes the CMap doesn't map
are dropped. A -V CMap is read with its -H form's codes. Codes in the
Unicode CMaps (UCS2, UTF8, UTF16, UTF32) are read as Unicode; those
helpers follow mockydevs' #6067. A 0x0D byte ends a paragraph and a 0x09
byte is a tab in these fonts too.
The predefined CMaps craft-pdf doesn't carry (RKSJ, 78-RKSJ, 78ms-RKSJ,
78-EUC, 78, Add, Ext, NWP, GB, CNS1, KSC, B5 and the Hong Kong B5 sets
other than HKscs-B5) are read with the nearest
carried CMap, which can give a different character for some codes.
GBT, GBT-EUC, GBTpc-EUC, CNS2 and KSC-Johab type still decodes byte by
byte, with the CMap removed from the font name.
Docs: docs/file-format-parity.md.
Recent Colors now keeps up to 30 solid colors instead of 10, newest
first and each once; applying a 31st drops the oldest. The Session
holds the list, so it stays the same when another document is opened
or made active, and it lasts for the session.
The Color and Swatches panels wrap the chips onto further rows when
the panel is too narrow for one row, so every color can be clicked.
A list that fits one row draws as before.
Docs: paint.recent params text, docs/mcp.md, docs/target-app-parity.md.
The overlap sweep moves a horizontal line down the page, and its time
per event grows with the number of segments on that line. A long, low
path, such as rows of a zigzag, puts a whole row on the line at once.
stroke_region, unite_all_with and try_unite_all_with now estimate how
many segments the sweep holds at once in each direction, from up to
4,096 segment boxes (one from each run of segments, at a position that
changes from run to run). When the estimate for the input turned a
quarter turn is under two thirds of the upright one (2,048 segments or
more), the operation runs on the turned input and the result is turned
back. A quarter turn swaps and negates coordinates, so no point moves
by rounding. Offset Path is not turned. Callers of unite_all,
try_unite_all and outline_stroke take the turned sweep through these
functions.
Tidy's lookups of the input curves around a piece and of the kept
anchors can search along y: once lookups with more than 64 candidates
along x have scanned 16 per item, a lookup sorts the list along y once
and uses that window when it holds fewer candidates (under a quarter as
many for curves). Where the y window rarely helps, only one lookup in
32 measures it. is_kept counts the few points within its tolerance
directly instead of searching for the window's end.
In the sweep_axis tests, a turned result has as many subpaths as the
result without the turn, and the area where the two differ is no
larger than the refit precision times the outline's length.
On one open path of 200,000 anchors in rows of 1,000, Outline Stroke
takes 17.3 s of processor time instead of 31.3 s and Unite 2.9 s
instead of 6.5 s in a release build. Unite of 2,000 circles takes the
same time as before.
Reset Bounding Box set the angle to 0 on the selected objects only. A
rotation changes the box angle of the selected objects and of every
object inside them, so the members of a rotated group kept their angle:
after rotating two rectangles 20 degrees, grouping them, rotating the
group 10 degrees and resetting, Ungroup brought back a box at 30
degrees, and a second reset reported 2 objects to change.
The command now also squares every object inside the selected ones: the
children of groups, compound paths, clip groups, blends, envelopes,
repeats and intertwines, and the art of linked opacity masks. The art of
an unlinked mask does not turn with the object, so it keeps its angle.
Ungroup, Release Clipping Mask, Release Compound Path, Blend Expand,
Release Envelope, Release Repeat, Release Intertwine and Release Opacity
Mask then bring back boxes square to the page. The whole reset stays one
undo step.
Two results change. `changed` counts every object reset, the objects
inside included, so the steps above return 3 where they returned 1. A
group whose own box is square but whose members are turned used to
return 0 with no undo step; it now squares the members in one step.
Docs: params text, docs/mcp.md, docs/target-app-parity.md.
When only anchors of a path or compound path move, the area an edit
changed is now the box of the segments that start or end at a moved
anchor (and the line that closes an open subpath's fill at a moved
end), before and after, grown by the farthest the strokes reach. The
canvas then draws that part of the frame again instead of the whole
object. Objects with a non-solid paint, dashes, a width profile,
arrowheads, a brush, effects or an opacity mask still count whole.
At 1600 x 1200, single-threaded, the frame after one anchor of a filled
closed path moves takes 16.6 million CPU cycles instead of 56.4 million
with 50,000 anchors, and 65.6 million instead of 180.0 million with
200,000 anchors.
A PDF saved with some of its artboards has a page for each of them, while
the editing data keeps them all. The importer took the pages after the
first to show the artboards right after the first page's artboard. In a
PDF of artboards 2 and 4 of 4, the second page's type went to artboard 3.
In a PDF of artboards 1 and 3 of 4, the second page's type went to the
left edge of artboard 2.
Each page after the first now goes to an artboard of its size that comes
after the previous page's artboard and leaves an artboard for each later
page. The artboard chosen for the first page also leaves one for each
later page. When several artboards fit a later page, the importer
compares their art with the page and takes the closest one, or the first
of them on a tie. It compares at most 16 artboards for all the later
pages together, the same limit it uses for the first page. A later page
with no comparisons left takes the first artboard that fits it.
When the PDF has fewer pages than artboards and its first page shows the
first artboard, the first page's type and page art still go to the art's
box or to the editing data's artboard.
The Preferences dialog has a Search Preferences field above the category
list. It has the keyboard focus when the dialog opens, and Cmd/Ctrl+F
focuses it again. While it has text, the list shows every setting whose
label, section or category contains it (ignoring case, in the interface
language or in English), or "No settings found". Choosing a setting shows
its category, scrolls to its row and highlights it. Escape in the field
with text clears it; Escape in the empty field closes the dialog.
The dialog's `__search` field holds the text, so `ui.dialog.set` drives
the search too.
A short move with View > Snap to Pixel on returned to where it began and
showed a "last location" label, skipping the pixel step. Snap to Last
Location is now off while Snap to Pixel is on, for the Selection tool and
for paths Direct Selection moves by an anchor, so the move lands on whole
pixels as it does with the option off.
Preferences > Smart Guides gets Snap to Last Location (`snapToLastLocation`,
off by default). With it and Smart Guides on, a selection moved by dragging
with the Selection, Group Selection or Direct Selection tool, Shift too, goes
back to where the move began while the move is within Snapping Tolerance,
labeled "last location". An Alt copy is not pulled back onto its original.
Source: https://helpx.adobe.com/illustrator/desktop/measure-and-align/grids-and-guides/smart-guides-options.html
The distance, the label and the copy rule are VectorCraft's own.
Layout kept no record of a run's face, so each paragraph looked up the face
of its first character three times for its line metrics and once more to
shape it. The layout now keeps each run's face the first time it is looked
up and uses it for shaping, for paragraph metrics, for on-path type's empty
line and for the column offset of vertical point type. Glyphs, positions,
bounds and baselines do not change.
A test-only helper lays text out looking every face up at each use, and a
new test requires point, vertical point, area and path type laid out both
ways to match exactly.
The layouts of 5,000 short point type objects take a median of 215 million
CPU cycles of the laying-out thread instead of 236 million in a release
build (11 alternating runs of each build on Windows 11, measured while
other builds were running).
While the Type tool edits text, Cmd+Enter on macOS and Ctrl+Enter on
Windows and Linux typed a line break. It now ends editing as Escape
does: the typed text stays, the type stays selected, and the tool used
before editing is selected again. A held chord ends editing once; its
repeats type nothing and do not open the Move dialog.
Enter, Shift+Enter and Ctrl+Enter on macOS still type line breaks, and
so does the chord with Alt or Shift. Cmd+Ctrl+Enter on macOS ends
editing too. A command bound to the chord still runs instead, and
editing continues. While an IME composes, the chord stays the IME's.
The bundled craft-fonts Japanese, Georgian and Devanagari faces now get
the same baseline shift as installed fallback faces, so every glyph in
an interface label sits on the baseline of its family's first face.
Each fallback face's shift is measured against the first face of the
family it is added to (Inter for the proportional families, JetBrains
Mono for `mono`, egui's face for `Monospace`). Families whose first
faces need the same shift share one copy of the face; the others get a
copy named after their first face.
Tests: craft_fonts_sit_on_the_baseline_of_each_family checks each
bundled face in every family against its own baseline, and
fallback_faces_sit_on_the_ui_baseline now checks every family,
monospace ones included.
An installed face added for characters the interface fonts lack (Microsoft
YaHei for Simplified Chinese on Windows, for example) now gets a FontTweak
y_offset_factor computed from its ascent, descent and line gap against the
first face of the Proportional family, so its glyphs share that face's
baseline instead of centering the difference in row height. The bundled
faces and Latin text do not move.
This follows designcraft#394 (baseline_tweak from line metrics) and
effectcraft#1395. vectorcraft-text gains line_metrics, and a test face with
a CJK system face's vertical proportions checks the baseline at 13, 24 and
40 pt in the interface families.
The Symbols panel menu's Reset Transformation and the Control bar's Reset
(shown while symbol instances are selected) give the selected instances
their symbol's own scale again, without rotation, shear or reflection, as
one undo step (symbol.instance.resetTransform). Each instance keeps the
center of its art's bounding box in place. Instances in perspective and
instances already at their symbol's scale are left as they are, no undo
step is added when nothing changes, and both controls are enabled only
while a selected instance would change.
Docs: docs/mcp.md, docs/target-app-parity.md.
The History panel gets a New Document from State button at its bottom,
which runs the new edit.newDocumentFromState command. The command makes
a new document holding the art of a History panel row ({index?}, the
current state when omitted) and makes it the active document. An index
that names no state is an error and changes nothing.
The new document takes the next Untitled-N name, is marked unsaved, has
nothing selected, no steps to undo or redo and no modified date, and
leaves symbol, opacity-mask and pattern editing; the art drawn in a
pattern's tile is stored in the pattern, as Done stores it. Its links point at the files the
source finds, including files found in the source's folder away from the
links' paths. Those files are looked for only within the folders the
asking caller may read; for a caller without limits, within the folders
the caller that opened the source may read. The source
document, its steps and its saved state stay as they are; typing or a
drag in progress is first kept as a step, as Undo keeps it. While an IME
composes, the command waits, as Undo does.
Docs: docs/mcp.md, docs/target-app-parity.md.