Commit Graph
3465 Commits
Author SHA1 Message Date
ljkx 45c89c5a73 M4: weight steps reach a weight family's italics and read W weights after a width (#1831)
A family installed as one family per weight ("Foo Bold" with Regular and
Italic faces) now lists Bold and Bold Italic, the names resolve draws them
by, with the faces' own weights when they are read. A W-numbered weight
counts after other words too ("Condensed W7 Italic" is 700).
2026-11-03 04:38:16 +01:00
ljkx 2c9226c021 M4: weight steps from an off-list weight compare the faces' own weights (#1831)
next_style compared a custom wght value or a style the family lacks with
the weights the style names say, so Segoe UI Variable's Semilight (350)
counted as 300 and a wght of 325 stepped up to Regular. The family's
styles now come with the weights the style menu sorts them by
(figcraft_text::family_style_weights), and "W7 Italic" reads as 700.
2026-11-03 03:44:58 +01:00
Dylan M. Taylor 19afdd21f9 fix(format): import a .fig blob once however many hashes name it
Distinct image hashes pointing at one embedded blob shared its copy, but
the import resolved each hash separately: the blob was copied out and
hashed again for every alias. Aliases without an images/ member of their
own are now renamed to the first hash naming the blob before layers are
built, so the blob is copied and hashed once.

Image paints also spelled out their whole hash as hex for every layer,
whatever its length; hashes longer than any image can be named by (64
bytes) now resolve to nothing, as a missing hash does.
2026-11-02 20:44:37 -05:00
NetterSilverandClaude Haiku 5.5 41ec33eeec Reject negative and fractional indexes in node.reorder
Found while testing crates/engine/src/cmd/edit.rs:329

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-03 01:41:31 +01:00
ljkx dc82e6cac9 M4: weight steps follow the family's order and keep widths and oblique slants (#1831)
Review follow-up. The step now finds the chars' style in the family's list
(the style menu's order, lightest first) and takes its neighbour, so a style
whose name gives no distinct weight (Semilight) is reachable; a style the
family lacks or a custom wght value still goes by weight, ties going to the
nearer one in that order. "Extra", "Ultra", "Semi" and "Demi" are weight
words only before a weight ("Extra Bold"), so "Extra Condensed" keeps its
width; Oblique names count as slanted for the current style too; W3-style
names are weights; and style_weight reads Hairline as 100, not 400. The
installed-font test picks a family the step actually moves.
2026-11-03 00:49:00 +01:00
ljkx 6365e4339b M4: Increase and decrease font weight step through the styles the family has (#1831)
text.weightUp/weightDown stepped the CSS weight by 100 and stored a canonical
name ("Medium", "Semi Bold", ...) whether the family had that face or not, so
the first press on Arial Regular changed nothing visible and the stored style
named a face no font provides. They now move to the nearest heavier or lighter
style of the family with the same slant and width (Narrow stays Narrow), and
stay put at either end. A family that isn't installed keeps the old 100 steps.
2026-11-02 20:32:37 +01:00
Trevor BrownandClaude Opus 5.5 66ab8566e0 Pick select: the pick holds only on the page it was made on
FigApp::picked() also requires the layer to be on the page shown, so after page.select the cursor isn't drawn and Space selects nothing there. Test extended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:51:24 -05:00
Trevor BrownandClaude Opus 5.5 aa2fed07e2 Region fills: fill.pattern stays on the layer; the canvas handles and the picker's image paths edit the region's paint
fill.pattern sets the layer's fill as its spec says. The gradient and crop handles read the paint from the stack fill.set writes (the selected regions' while there are any); for a region's paint, Upload from computer and image presets write the paint like any edit, and a drop on the picker goes to the canvas (image.replace and image.adjust edit layer paints). Tests in regions_tests, canvas/handles/region_tests and colorpicker image tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:49:10 -05:00
Trevor BrownandClaude Opus 5.5 81799aca09 Pick select: the pick carries its document's uid
UiState.pick is (uid, layer); FigApp::picked() answers only while that document is in front and the layer exists, so another document's layer with the same id is never walked to or selected. Test extended with a same-id layer in a new document.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:17:50 -05:00
Trevor BrownandClaude Opus 5.5 d2e7c49e57 Region fills: each region once, no override for a no-op, Copy fill reads the region, layer-only controls off region rows
Named regions are deduplicated; an inheriting region stays inheriting when an edit leaves its stack as it was, and its own stack is only replaced once the edit succeeds; fill.copy reads the selected regions' paint; the Fill section leaves the fill style, a variable bound to the layer's fill and the image crop off region rows. Tests in regions_tests and region_fill_rows_tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 09:14:55 -05:00
Trevor BrownandClaude Fable 5.1 da4a798323 M1: pick select: Tab while the keyboard selection box shows walks the layer tree with a pink outline, Space selects (#1836)
Tab or the chord again switches the box to a pick cursor; Tab/Shift+Tab move between sibling layers, Enter/Shift+Enter into and out of a layer, Space selects, Escape or a canvas press ends it; ui.key takes the same keys. Gesture and parity rows, catalog, test, docs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 08:13:54 -05:00
Trevor BrownandClaude Fable 5.1 2e392e99b1 M8: a fill per region: the Fill section and the fill commands edit the regions selected in vector edit mode (#1875)
fill.set/add/remove/move/paste on the edited layer go to the selected regions' own fill stacks (or those named by regions), the layer's fills untouched; the Fill section and the colour picker list them. Test regions_tests::the_fill_commands_edit_the_selected_regions; docs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 07:55:27 -05:00
Trevor BrownandClaude Fable 5.1 90bec33322 Crosshair: the board Shapes tool places on it, and the view pans to keep it in sight
draws_shape includes BoardShape (tool.place lets the tool centre its own shape); a nudge past an edge of the view pans by the overshoot. Tests; docs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 07:23:33 -05:00
Trevor BrownandClaude Fable 5.1 0a9ecbe596 Merge fix: 135 documented shortcut rows, 134 bound
Both sides of the merge added a documented row: the counts the parity test and the docs table quote move with them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 07:09:01 -05:00
Trevor BrownandClaude Fable 5.1 c9b02d69e0 Scrub speed: the pointer's last position counts on the frame it leaves
egui keeps the position in interact_pos() for the frame of PointerGone, so a move and the leaving in one frame give the speed of that move; test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 07:01:10 -05:00
Trevor BrownandClaude Fable 5.1 e5a3fcf028 Merge fix: text_link_tests is a test module
The merge's union of two mod lines left upstream's text_link_tests without its cfg(test), so the library build pulled a test module in.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 07:01:04 -05:00
Trevor BrownandClaude Fable 5.1 695ca07528 M3: text styles carry paragraph spacing and indent, the list style and the OpenType features (#1829)
ParagraphStyle beside TextStyle in StyleKind::Text: style.create takes it from the layer or a value, style.apply sets it (the list on the paragraphs touched for a range), style.update moves it, editing it unlinks, .fig files keep it with the style; tests in styles_behaviour_tests and fig_export_assets_tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:43:02 -05:00
Trevor BrownandClaude Fable 5.1 99d5e3e588 Formatting after the merge
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:05:20 -05:00
Trevor BrownandClaude Fable 5.1 69d3012d82 Merge upstream/main into fix/field-alt-scrub
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:02:49 -05:00
Trevor BrownandClaude Fable 5.1 e04e86f38d Merge upstream/main into fix/text-mixed-fill-section
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:02:49 -05:00
Trevor BrownandClaude Fable 5.1 41ee4584cb Merge upstream/main into fix/place-crosshair
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:02:48 -05:00
Trevor BrownandClaude Fable 5.1 b846d586a8 Merge upstream/main into fix/padding-all-sides
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:02:48 -05:00
Trevor BrownandClaude Fable 5.1 e87b46b4e3 Merge upstream/main into fix/scrub-speed
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 06:02:47 -05:00
Trevor BrownandClaude Fable 5.1 04d37b56b5 Scrub speed: a pointer gone from the window keeps its speed
egui reports the pointer gone (no hover position) with the button still down when it leaves the window during a scrub; the speed stayed at the last rise rather than falling back to 1x and announcing it. Test in field_tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 05:56:06 -05:00
Trevor BrownandClaude Fable 5.1 3d704ce4c0 M1: scrubbing a field faster or slower by the pointer's height, with a notice of the speed (#1837)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 05:32:33 -05:00
e65ce42000 M7: Minimize collapses the navigation bar and both sidebars, the right one back while something is selected (#1835) (#1865)
* M7: Minimize collapses the navigation bar and both sidebars, the right one back while something is selected (#1835)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M7: a narrow window ignores Minimize, and a rename started while minimized waits without repaints

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:31:32 -05:00
1f0acd2bbd M4: Alt+Enter while editing text opens the link at the caret (text.openLink) (#1860)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:31:21 -05:00
f9d507f7b0 M2: a child resized to the full available space of its auto layout frame becomes Fill container (#1859)
* M2: a child resized to the full available space of its auto layout frame becomes Fill container

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Auto layout: a child becomes Fill for the full space only across the flow or alone along it

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Auto layout: the full available space is what layout leaves (padding and an included inside stroke), judged after a new path's size

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M2: a rotated child resized to the frame's room stays Fixed (review)

CodeRabbit on #1859: a rotated layer's local size isn't the room layout
gives it, so Fill would squash its geometry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:31:11 -05:00
9f09b7163c M2: a double-click on an auto layout edge sets Hug contents, with Alt Fill container (#1838) (#1867)
* M2: a double-click on an auto layout edge sets Hug contents, with Alt Fill container (#1838)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Auto layout edges: a text child fills with Alt too, and still enters on a plain double-click

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:31:00 -05:00
c44cfc94af M4: superscript and subscript are synthesised where the font has no glyphs for them (#1828) (#1868)
* M4: superscript and subscript are synthesised where the font has no glyphs for them (#1828)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Text: a zero OS/2 script offset counts as unset, and the native-glyph check sees the case-mapped characters

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:30:50 -05:00
e9eb7ce7f4 M4: max lines on auto-width text keep it auto width, hugging that many lines (#1864)
* M4: max lines on auto-width text keep it auto width, hugging that many lines

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M4: an auto-width text with max lines hugs the ellipsis on its last line, and the editing test expects auto width

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:29:59 -05:00
3358961033 M4: Backspace or Delete at a list item's start keeps its indentation level (#1862)
* M4: Backspace or Delete at a list item's start keeps its indentation level

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Lists: the level is kept by Backspace and Delete alone, and the tests read the text's own glyph

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:29:33 -05:00
5d387bb3b4 M2: fill container children share the free space by their content area, border-box fashion (#1824) (#1861)
* M2: fill container children share the free space by their content area, border-box fashion (#1824)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Layout: rustfmt's line for the frozen-share closure

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* M2: one doc comment on distribute (review)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:29:23 -05:00
JonasandBrandon Thomas ebe60a4924 Complete German translation (192 missing entries) (#1863)
I completed all missing translations and checked them in de.toml.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-02 05:29:12 -05:00
Patrik LermonandClaude Opus 5.5 779a5c982e i18n(sv): translate 21 new strings (#1870)
Brings the Swedish catalog up to date with upstream main (f9b56936).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 05:29:02 -05:00
Trevor BrownandClaude Fable 5.1 56ad0ba14f Placement crosshair: kept with its page and document, gone with a pointer placement, kept when the same tool is chosen again
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 05:08:41 -05:00
Carbocode 06eb2a047a M8: merge main and address paint control review 2026-11-02 10:50:35 +01:00
Trevor BrownandClaude Fable 5.1 367f188b34 M6: the arrows show and move a placement crosshair with a shape or frame tool chosen, and Enter places there (#1839)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 04:39:07 -05:00
Trevor BrownandClaude Fable 5.1 96cd54b556 Fill section: mixed text has no fill rows to remove or crop, and a crop lifts the characters' fills only when it edits
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 04:09:51 -05:00
Trevor BrownandClaude Fable 5.1 a6e7920b24 Geometry: measurement allows a capped arc's control points past the cap
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 03:50:41 -05:00
Trevor BrownandClaude Fable 5.1 a4b07876a3 M2: a Cmd/Ctrl-click on a padding field reads the modifier at the press, clears its mark when no edit follows and commits a retyped value to all sides
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 03:32:39 -05:00
Trevor BrownandClaude Fable 5.1 badbe64440 Fill section: a removal that names no paint leaves the characters' fills, and Copy fill and Crop image use the list the rows show
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 03:23:36 -05:00
Trevor BrownandClaude Fable 5.1 5f89b05b74 Format: the unmeasurable text path case sits past the geometry cap
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 02:59:39 -05:00
Trevor BrownandClaude Fable 5.1 50eb28e0ac M2: a Cmd/Ctrl-click on a padding field sets all four sides with the value typed
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 02:06:57 -05:00
mortezanaeemi-ops 5c9bb79b1a Add files via upload 2026-11-02 10:34:09 +03:30
Trevor BrownandClaude Fable 5.1 8fb53baa64 SVG import: a filled and stroked path with an open subpath is tested through its split
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 02:02:35 -05:00
Trevor BrownandClaude Fable 5.1 5c34af35f8 Geom: the measurement bound includes the cap, as the builders clamp to it
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 02:00:21 -05:00
Trevor BrownandClaude Fable 5.1 6e78b7270c Merge upstream main into fix/geom-bounded-sizes
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 01:33:31 -05:00
Trevor BrownandClaude Fable 5.1 9783af9347 Field scrub: the field senses drags only with Alt held or a scrub going on, so a touch swipe stays the scroll area's
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 01:27:48 -05:00
Trevor BrownandClaude Fable 5.1 abf2eb9b3a M1: the Fill section shows a text's characters' fills, mixed when they differ, and a layer fill edit reaches every character (#1856)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 01:24:32 -05:00