Main added a Layer menu item of its own, so after the rebase the menu
counts 663 items; raise the floor to match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the merged tree: the menu count goes to 662 of 662 live, main's 661
plus the Reset Transform item this PR adds, and the prefs audit counts
193 `Preferences` leaves where the committed scorecard still said 192
because main's #11322 added the pref `group_tools` without regenerating.
Both files are `cargo xtask parity` and `cargo xtask scorecard` output,
not hand-edited.
`docs/ui-parity.md`'s status line conflicted: the branch and main each
prepended a clause at the head of the change list, and the branch also
carried the newer `Last updated` date. The merged line keeps main's
toolbar tool-memory clause (#3569) word for word after our Reset
Transform clause (#11662), with one `Change:` header and the later date.
cargo xtask parity and scorecard on the merged tree: 661 of 661 menu items live (Layer 162 of 162, so the Reset Transform row is counted live), and the prefs audit is 10 of 191 now that upstream removed the Enable animations preference.
The Crop tool gets the reference application's contextual task bar: a small floating
bar centred 11 pt under the crop frame with a grip, the preset dropdown (the options
bar's own, so both stay in sync), Straighten, a ⋯ menu (Hide bar, Reset bar position,
Pin bar position) and, while a crop is pending, Cancel and Done. It follows the frame,
stays inside the canvas, and stays put once dragged or pinned. Window › Contextual Task
Bar (after Tools, as in the reference) shows and hides it.
The bar itself is a reusable widget (widgets/task_bar.rs): position rule, grip, ⋯ menu
and the hide/pin/place state in Panels (kept with the panel layout across restarts,
read by ui.inspect › taskBar, set by ui.set {panels}). A context supplies only its
controls and where ⋯ goes; the Crop contents are tools/crop_task_bar.rs. Generative
Expand stays out until #41.
Also: Lucide pin and rotate-ccw icons, six new strings in all 27 catalogues, parity
661/661 (FLOOR raised), control-protocol docs. Three tests about the options bar's
Ratio dropdown now hide the task bar, which shows the same dropdown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Windows now reads "Reveal in Explorer", Convert to Embedded is "Embed Linked", and a new Embed All Linked command (layer.smartObjects.embedAllLinked) embeds every linked smart object of the document in one history step, refusing the whole step with an error that names a missing file. The three Warp rows leave the submenu; their commands stay registered for scripts and the Edit menu.
The menu parity floor drops from 660 to 658 because three live catalog rows were removed and one added.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Type: add OpenType Stylistic Sets submenu (Set 1–20)
Type > OpenType > Stylistic Sets toggles ss01–ss20 through new
type.openType.stylisticSets.setN commands on the usual formatting scope
(selected characters while editing, else the selected type layers).
The toggle direction and the menu checkmark follow the style at the
selection start. Updates TYPE-218-5 and G8.
Closes#10285
* Stylistic Sets: round-trip test through a full PSD; scorecard parity count
* Stylistic Sets: test PSD round trip on an opened file; record the new-document PSD gap
Documents made in PhotoCraft get no Txt2 block on PSD save, and the set
mask lives only there, so their sets are not saved to PSD yet. The engine
test keeps the .pcraft round trip, an io test covers the PSD round trip
of a file with type objects, and TYPE-218-5 and G8 record the gap.
* Stylistic Sets: share one tag table between the engine and the menu
The engine exports STYLISTIC_SET_TAGS; the Set 1–20 commands index it and
the menu checkmarks read it, so the 20 tags are listed once.
* Stylistic Sets: check malformed menu ids through the resolver, not the menu list
* Scorecard: TYPE-218-5 notes PSD save of stylistic sets in documents made here (#10308)
---------
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
* Type: add OpenType Numerals submenu (figure styles)
Type › OpenType › Numerals sets lnum/onum/pnum/tnum as a radio style
(Default through Tabular Oldstyle). Checkmarks follow the selection
start; TYPE-218-5 scorecard/gaps updated; parity floor 640.
* refactor(engine): one style-at-character lookup for the OpenType menus
feature_on_at and numerals_style_at each walked the runs the same way;
they now share style_at. NumeralsStyle::from_id and numerals_style_of
read the existing tables instead of repeating them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(text): persist OpenType numeral tags through PSD EngineData
Map lnum/pnum/tnum as EngineData bools and the width×height combos as
FigureStyle (Krita/Illustrator), so Numerals choices survive PSD round-trip.
* docs(gaps): note Numerals PSD figure-tag round-trip
* revert(text): keep PSD EngineData to the keys Photoshop writes
Backs out the PSD half of 18610324 and its gaps note (58813de3); the
engine reformat in that commit stays.
- `LiningFigures`, `ProportionalFigures` and `TabularFigures` are not
Photoshop EngineData keys (the commit says Photoshop only has
`OldStyle`), so writing them puts keys of our own into users' PSDs.
- The `/FigureStyle` code table (1-4) has no oracle: no Photoshop-authored
file in photocraft-corpus, and neither ag-psd nor psd-tools reads it.
AGENTS.md rule 3 asks for public specs or observation. PSD persistence
of the numeral styles can come back with a Photoshop-authored oracle.
The Numerals menu still round-trips through .pcraft.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(text): lock PSD EngineData to Photoshop OldStyle for numerals
Document AGENTS.md clean-room: only onum survives TySh round-trip; lnum/pnum/tnum stay .pcraft-only until a Photoshop-authored corpus oracle.
---------
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
- menu_catalog: add Type › Anti-Alias › None before Sharp, as in Photoshop.
It used to come from the engine list, appended after Windows and built
without a checked state, so a layer set to None showed no check.
- view_cmds::type_checked reads type_tool::target_text (the edited layer,
else the active or a selected type layer), as the options bar and the
Type commands do, not only the active layer.
- Anti-alias and orientation items stay check items (Some(false)) with no
type layer, so the native menu doesn't rebuild.
- Parity floor 629 -> 630; docs/parity-checklist.md regenerated.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Add Layer > Rasterize > Layer Style; Rasterize Layer converts vector masks (#2245)
Nothing could bake layer effects into a layer's pixels, and Rasterize >
Layer refused a raster layer that has a vector mask.
New command layer.rasterize.layerStyle (Layer > Rasterize > Layer Style,
and in the Layers context menu). It renders the layer by itself through
the compositor at 100% opacity in Normal mode, so the effects, fill
opacity and masks end up in the pixels, including those past the canvas.
The layer's own opacity, blend mode, knockout and Blend If stay layer
properties. Type, shape, fill and Smart Object content is rasterized
first, all in one history step. With a Normal layer and Normal-mode
effects the composite is unchanged at 8, 16 and 32 bit. Effects in
another mode are evaluated against the isolated layer's transparent
backdrop, because one layer of pixels cannot hold several blend modes.
Rasterize > Layer and All Layers now also turn a vector mask into a
pixel mask ("all vector data") and leave effects live, as Photoshop
does. The menu enablement follows both changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Regenerate docs/scorecard.md after rebase (#2245)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* Add Background from Layer and keep the Background at the bottom (#2626)
Layer > New > Background from Layer was missing, and the Background was a
locked layer that Layer > Arrange (with an explicit layer), Reverse and
dragging in the Layers panel could move, or put other layers below.
The new layer.new.backgroundFromLayer command renders the active layer as
it looks over the background colour, drops it to the bottom and locks it
as the Background, in one undo step. It is unavailable when the document
already has a Background, and for groups and adjustment layers.
Arrange refuses to move the Background and stops other layers above it;
layer.moveTo and Reverse refuse edits that would move it off the bottom.
The Layers panel shows no drop indicator for those drops.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Parity floor 629; the empty-space drop test uses a document without a Background
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Fabio Lussi <198260595+itrycodinganditsbad@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Progress docs per craftrules standards/progress-docs.md: target-app parity (merges parity-estimate.md), gaps, roadmap with alpha gate, readiness by audience (full / mainstream / essentials) with Opus 5.5 hours, and UI, brush, format, hardware and localization parity docs. docs/parity.md is now docs/parity-checklist.md.
The Windows test failure (file_dialog::tests::save_dialogs_remember_where_each_document_was_last_saved) is pre-existing on main: the test hard-codes POSIX paths.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>