mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-28 12:26:52 -06:00
M3: paint: colour profiles (Display P3), image adjustment presets, style picker (#54)
* M3: colour profiles: sRGB or Display P3 per file, convert or keep values, tagged exports
- color: ColorProfile (srgb, displayP3) with conversions derived from the primaries (shared D65
white and sRGB curve; out-of-gamut channels clip), table-driven pixel conversion, a generated
ICC v4 matrix/TRC profile and PNG cICP code points.
- doc: Document.color_profile (serde default sRGB, written only when set); every colour value
(paints, text runs, effects, grids, page and prototype backgrounds, overlay backdrops, styles,
colour variables, document colours) can be mapped; set_color_profile converts or reinterprets.
- engine: file.colorProfile {profile?, convert?} (File > Color profile...; without a profile it
opens the dialog); document.inspect reports colorProfile.
- render: images are taken as sRGB and managed into the file's space; encode_export tags PNG
(sRGB chunk, or iCCP + cICP for Display P3) and embeds the ICC profile in Display P3 JPG/WebP;
SVG and PDF export Display P3 files converted to sRGB. The CLI exports the same way.
- ui: Color profile dialog (keep appearance / keep values) and a Color profile row on the page
panel; the canvas, presenter, thumbnails, swatches and colour picker show a Display P3 file's
colours converted to the screen's sRGB, and Copy as PNG converts too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M3: image adjustment presets: built-in, saved in the file, reset
- color: ImageFilters::PRESETS (Vivid, Muted, Warm, Cool, Black & white, Fade, Reset), lookup by
id or label, and sanitized values.
- doc: Document.image_presets (name + adjustments; written only when there are some).
- engine: image.adjust {ids?, target?, index?, preset?, filters?} sets the adjustments of image
paints from a preset (built-in or saved) with values on top, one undo step; image.savePreset,
image.deletePreset and image.presets.
- ui: the colour picker's image section gets a presets menu named after the preset in effect
("Custom" otherwise), saved presets with delete, "Save as preset...", a Reset button, and
aligned adjustment sliders.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* M3: style picker: search, folders, list or swatch grid, edit, create, detach
The Fill, Stroke, Effects and Layout grid sections' Styles button opens a popover laid out like
the variable picker (crates/ui-egui/src/style_picker.rs):
- search over style names; styles grouped by the folders of their `/`-separated names, which
collapse (searching opens them); colour styles as a list or a grid of swatches;
- click applies, a check marks the applied style; the row's edit button (or a right-click) edits
the name, description and values: colour style paints open the colour picker on the style,
effect and grid styles update from the selection; delete;
- `+` creates a style from the selection's current values and opens it for naming; detach;
- colour slots still list colour variables to bind;
- the applied style chip opens the picker; new icons Adjust, ViewList, ViewGrid (drawn in code);
- control channel: ui.set {stylePicker, stylePickerEdit, stylePickerView}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,8 @@ Every command: `[{id, label, params, menu, shortcut, undoable}]`.
|
||||
|
||||
The active document as JSON: name, path, dirty, currentPage, selection, pages (the current page's
|
||||
layer tree to `depth`, default 8; others summarised unless `allPages`), styles, variable count,
|
||||
images, the text being edited and the undo history.
|
||||
images, the colour profile (`colorProfile`: `srgb` or `displayP3`), the text being edited and the
|
||||
undo history.
|
||||
|
||||
### `node.get {id, depth?}`
|
||||
|
||||
@@ -93,7 +94,7 @@ text tool).
|
||||
|
||||
Invoke a menu item exactly like clicking it (this may open a dialog). Returns `{ok, lastError}`.
|
||||
|
||||
### `ui.set {rightTab?, leftTab?, theme?, home?, palette?, mainMenu?, colorPicker?, variables?, layerFilter?, collapseLayers?, exportPreview?, preview?, presentScroll?}`
|
||||
### `ui.set {rightTab?, leftTab?, theme?, home?, palette?, mainMenu?, colorPicker?, variables?, layerFilter?, collapseLayers?, exportPreview?, preview?, presentScroll?, colorProfileDialog?, stylePicker?, stylePickerEdit?, stylePickerView?}`
|
||||
|
||||
Switch panels and modes: `rightTab` `design|prototype|inspect`, `leftTab` `file|assets`, `theme`,
|
||||
`home` (bool), `palette` (bool: the Actions palette), `mainMenu` (bool), `colorPicker`
|
||||
@@ -103,7 +104,11 @@ open the layers search with that filter; `null` closes it), `collapseLayers` (tr
|
||||
layers tree), `exportPreview` (bool: the Design panel Export section's preview), `preview` (true or a
|
||||
frame id: open the prototype preview pane like `proto.preview`; false or `null` closes it),
|
||||
`presentScroll` (`[x, y]`: scroll the presented screen, the full window's else the pane's, clamped
|
||||
to what it can scroll). Returns `ui.inspect`.
|
||||
to what it can scroll), `colorProfileDialog` (`srgb|displayP3`: open File ▸ Color profile with that
|
||||
profile chosen; `null` closes it), `stylePicker` (`fill|stroke|effect|grid`: open the style picker
|
||||
for the selection; `null` closes it) with `stylePickerEdit` (a style id or name: open its editor),
|
||||
`stylePickerView` (`list|grid`). Returns `ui.inspect` (which reports `stylePicker` and
|
||||
`stylePickerView`).
|
||||
|
||||
### `ui.screenshot {path}`
|
||||
|
||||
|
||||
+13
@@ -82,6 +82,19 @@ Or in a project's `.mcp.json`:
|
||||
tools, `color` may also be a hex string and gradients can be written
|
||||
`{"type": "linearGradient", "stops": ["#7048E8", "#1098AD"]}`; the server converts them to the
|
||||
engine's paint JSON.
|
||||
- **Colour profile**: colour values are in the file's profile, sRGB (default) or Display P3
|
||||
(`inspect_document` reports `colorProfile`). `file.colorProfile {profile: srgb|displayP3,
|
||||
convert?}` changes it: `convert` (default true) converts every colour value so colours keep their
|
||||
appearance; `false` keeps the values and reinterprets them. Images are treated as sRGB and managed
|
||||
into the file's space. PNG exports are tagged (`sRGB` chunk, or a Display P3 ICC profile plus
|
||||
`cICP`), Display P3 JPG and WebP embed the ICC profile, and SVG and PDF export Display P3 files
|
||||
converted to sRGB (out-of-gamut colours clip).
|
||||
- **Image adjustments**: image paints carry `filters` (exposure, contrast, saturation, temperature,
|
||||
tint, highlights, shadows; each -1..1). `image.adjust {ids?, target?: fill|stroke, index?,
|
||||
preset?, filters?}` applies a built-in preset (`vivid`, `muted`, `warm`, `cool`, `blackAndWhite`,
|
||||
`fade`, `reset`) or one saved in the file, with any `filters` values on top.
|
||||
`image.savePreset {name, filters?}` saves the current (or given) adjustments in the file,
|
||||
`image.deletePreset {name}` removes one and `image.presets` lists both kinds.
|
||||
- Text props (`fontFamily`, `fontStyle`, `fontSize`, `lineHeight`, `letterSpacing`, `textDecoration`,
|
||||
`textCase`, `textFills`, `fontVariations`…) apply to the whole layer, or to chars `start`..`end`
|
||||
when given (`text.style {id, start, end, …}` does the same). Styled ranges come back as
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
# Parity report
|
||||
|
||||
Generated by `cargo xtask parity`: FigCraft commands registered for the incumbent's main menu and toolbar (376 commands in the engine).
|
||||
Generated by `cargo xtask parity`: FigCraft commands registered for the incumbent's main menu and toolbar (381 commands in the engine).
|
||||
|
||||
**196 / 201 menu items (97.5%)**
|
||||
**197 / 202 menu items (97.5%)**
|
||||
|
||||
## Missing
|
||||
|
||||
|
||||
Reference in New Issue
Block a user