Commit Graph

1447 Commits

Author SHA1 Message Date
bflatastic c599522061 Fix #735: Illustrator EPS and .ai files match their page in Fit to Artwork Bounds and the page check
- Fit to Artwork Bounds fits the art exports draw: hidden objects and
  layers, guides and template layers don't count, and the bounds stop at
  a layer's clip.
- The comparison with the page catches an object one draws that the
  other doesn't (pixels whose neighbours all differ, away from type), a
  light colour against white, and, for an EPS whose page is its art's
  box, art the layers print outside it.
- textAs: outlines opens a .ai whose type shows from its PDF part, which
  has the outlines.
- document.open takes editingData: false to open an Illustrator EPS or
  .ai as its page or PDF part only, for print pipelines.

Part of #637.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:51:50 +07:00
BFlat 569b4ac240
Merge pull request #853 from storytold/fix/clippy-typecmd-borrow
Fix clippy on main: Create Outlines passes the text, not a reference to it
2026-10-10 06:35:13 +07:00
bflatastic 2c1a1526df Fix clippy on main: Create Outlines passes the text, not a reference to it
needless_borrow from #850, which a stale lint result let through.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:27:19 +07:00
BFlat 5b27fdc321
Merge pull request #845 from dotCooCoo/feat/copy-to-user-defined
Swatches: swatch.library.copyToUser copies a loaded library into User Defined
2026-10-10 06:21:36 +07:00
BFlat 338ed529e4
Merge pull request #850 from storytold/fix/847-underline-strikethrough
Fix #847: draw Underline and Strikethrough
2026-10-10 06:17:48 +07:00
BFlat b2b3b4fe6a
Merge pull request #848 from storytold/fix/hyphen-test-race
Hyphenation exceptions: unit tests read only their thread's list
2026-10-10 06:17:39 +07:00
bflatastic 72c9cec0e0 Fix #847: draw Underline and Strikethrough
The styles were stored on the text and written to SVG's text-decoration,
but the type was drawn without the lines. vectorcraft_text::decorations
now gives each underlined or struck-through stretch of a run on a line
its bar, placed and sized from the font's own underline and strikeout
metrics (with fallbacks for fonts that have none). The canvas, Create
Outlines, PDF export (outlined and real text) and SVG's outlined text
draw them in the run's paint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:03:04 +07:00
bflatastic 4181755db6 Hyphenation exceptions: unit tests read only their thread's list
hyphenation_exceptions_override_the_pattern failed when the round-trip
test set the process-wide list at the same moment: words missing from the
thread's override fell through to the shared store.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:02:48 +07:00
BFlat c93d4ad995
Merge pull request #810 from Messhias/feat/394-hyphenation-exceptions
Part of #394: Hyphenation › Exceptions reach the hyphenator
2026-10-10 05:46:03 +07:00
dotCooCoo 975d4975ee Swatches: swatch.library.copyToUser copies a loaded library into User Defined
swatch.library.copyToUser {library} copies a library loaded from
another folder into the user library folder of the desktop app. A
.vcswatches, .gpl or .ase file is copied as it is; the swatches of a
document and a library loaded from the data or dataBase64 parameter are
written as a .vcswatches file. The copy gets a name that no file in the
folder has, and when a file with the same extension and bytes is
already there, that file is used. The library is then listed as User
Defined only. Until the app quits, commands given its loaded id use the
copy, unless another library is loaded under that id. Without a user
library folder (the web and headless sessions) the command is disabled.

A file with the same extension and bytes as a User Defined library
opens as that User Defined library. The unchanged original of a copied
.ase file is one such file. Graphic style libraries open the same way.
2026-10-09 13:32:59 -07:00
BFlat 4cf912fa94
Merge pull request #820 from storytold/fix/812-ellipse-pie
Part of #812: an ellipse's Pie Start and End Angle and Invert Pie
2026-10-10 03:00:32 +07:00
bflatastic 78f0297127 Part of #812: an ellipse's Pie Start and End Angle and Invert Pie
An ellipse kept pie angles in its model, but nothing drew or set them. Now
the Transform and Properties panels show Ellipse Properties with Pie Start
Angle, Pie End Angle and Invert Pie, as in Illustrator, and
object.setLiveShape takes {pieStart, pieEnd, invertPie}. The pie runs
counterclockwise on screen from the start angle (0 at 3 o'clock) to the
end angle and closes through the centre; 0 to 360 is the whole ellipse,
an end of 0 means 360, and Invert Pie swaps the angles to show the other
part. One undo step each; a bad angle is an error. The labels are
translated in every complete language. The on-canvas pie widget is still
to come.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:00:15 +07:00
BFlat d857d2c0b7
Merge pull request #814 from jmverges/font-versions
Fix #813: type can name an installed version of its font
2026-10-10 02:44:09 +07:00
BFlat 9df597a46d
Merge pull request #816 from storytold/fix/807-all-tools-drawer
Fix #807: All Tools shows every tool with its icon, under headings
2026-10-10 02:33:18 +07:00
BFlat 4c175ed099
Merge pull request #815 from storytold/fix/808-slim-toolbar-scrollbar
Fix #808: the toolbar's scroll bar stays a slim line
2026-10-10 02:33:10 +07:00
bflatastic a262ee5c9e Fix #807: All Tools shows every tool with its icon, under headings
The toolbar's All Tools drawer listed the tools' names as plain buttons.
It now shows each tool with its icon and name in a grid, under the
toolbar's group headings (Select, Shapes, Draw, Modify, Type, Navigate,
Color) and headings for the tools only the Advanced toolbar shows
(Perspective, Symbols, Graph, Artboards, Slices). The active tool is
highlighted, a tool's tooltip gives its name and shortcut, and picking one
selects it and closes the drawer. The headings use labels translated
already.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:32:52 +07:00
bflatastic 986b83280f Fix #808: the toolbar's scroll bar stays a slim line
The toolbar and the dock's icon column scroll when the window is too
short for them. Their scroll bar was egui's floating one, which widens to
10 pt while scrolled or dragged and covered the group labels and the
icons' right edge. It now stays at most 4 pt wide (2 pt at rest), at the
column's edge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:32:27 +07:00
Fabio William Conceição 445bceb681 Part of #394: look up hyphenation exceptions under the lock; drop ~ syntax.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 20:26:56 +01:00
Fabio William Conceição 4f9b292213 Part of #394: headless tests for Hyphenation › Exceptions UI and layout.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 20:26:56 +01:00
Fabio William Conceição c9ba5db4fb Part of #394: Preferences › Hyphenation › Exceptions reach the hyphenator.
Comma-separated words never break, or break only at marked hyphens; prefs.set and restore push the list so type reflows.
2026-10-09 20:26:56 +01:00
Juan Manuel Verges Solanas 562e09707a Fix #813: type can name an installed version of its font
A font library can hold two versions of one family and style (a new
Montserrat-Bold.ttf beside an old montserrat.ttf). The font database kept
only the first one loaded, so type set in the other couldn't be matched
when a PDF or .ai was opened: it came in as outlines. Now every version
loads (the first stays the one family and style resolve to), PDF import
tries the other versions when the glyphs differ, and type set in a version
the family and style alone wouldn't pick names it in CharStyle::font_version
(left out when None, so documents without it are unchanged). Layout,
shaping, the substituted-glyph highlight, Find Font, Package and Document
Info follow it; changing the font clears it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:26:51 +00:00
BFlat b43e633329
Merge pull request #754 from hamada147/feature/support-arabic-language
feat(text): load craft-fonts' Arabic families, fetch them on web
2026-10-10 02:08:29 +07:00
bflatastic 8c1be41e08 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	ROADMAP.md
2026-10-10 01:56:46 +07:00
BFlat cbacb47fdb
Merge pull request #770 from dotCooCoo/feat/swatch-libraries
Swatches: Save Swatch Library writes swatch exchange (.ase) files
2026-10-10 01:53:32 +07:00
BFlat 116573ba86
Merge pull request #782 from dotCooCoo/feat/package-font-resolution
Package: fonts found by any of their names are copied, and skipped fonts are named
2026-10-10 01:43:01 +07:00
BFlat 783540a34a
Merge pull request #781 from dotCooCoo/feat/macos-registered-fonts
Part of #579: macOS fonts registered from other folders are listed too
2026-10-10 01:42:54 +07:00
BFlat 35a6015d88
Merge pull request #803 from haranishi/i18n-japanese-messages
i18n: Japanese translations for error and status-bar messages
2026-10-10 01:15:02 +07:00
BFlat 71ea5c4215
Merge pull request #802 from dmatviichuk/i18n/ukrainian-dictionary-review
i18n: correct Ukrainian wording and spelling
2026-10-10 01:14:55 +07:00
BFlat 3e1d9b7bbb
Merge pull request #795 from DWAA1660/fix/selection-validation-and-clear
Validate selection IDs and clear exact compound members
2026-10-10 01:05:58 +07:00
Ikki Nishihara cee9feea2e i18n: Japanese translations for error and status-bar messages
Japanese now translates the status-bar and error messages (`@msg`
templates) like Spanish, French, Italian, Russian and Ukrainian do:
556 rows at the end of ja.tsv, the 498 message literals the test scan
finds plus the 58 that the other catalogs also carry (web start-up,
relinking, export notes, PostScript read errors).

`ja` joins COMPLETE_MESSAGES, so complete_languages_translate_every_message
keeps it complete. The registry comment, docs/development.md and the
ROADMAP line now list Japanese with the other five. The messages
themselves stay English for agents and MCP.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 02:53:14 +09:00
BFlat d522c1d7be
Merge pull request #800 from storytold/fix/793-artboard-options-and-layouts
Part of #793: Artboard Options lists Name, Width, Height; one-key shortcuts follow the key on any layout
2026-10-10 00:52:17 +07:00
Dmytro Matviichuk 01f329aa99
i18n: correct Ukrainian wording and spelling (#747)
Co-authored-by: Codex <noreply@openai.com>
2026-10-09 19:51:43 +02:00
bflatastic f300321e28 Part of #793: Artboard Options lists Name, Width, Height; one-key shortcuts follow the key on any layout
- Artboard Options listed its fields by key (Height, Name, Width); it now
  lists Name, then Width and Height.
- One-key tool and command shortcuts (V, P, X, D…) matched the character
  typed, so with a layout without Latin letters (Persian, Arabic, Russian,
  Greek…) they did nothing. When the text typed holds no ASCII character,
  the key's position stands in: the V key selects the Selection tool
  whatever it types. Latin layouts (AZERTY…) keep the letter typed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:51:18 +07:00
BFlat 0b14b45610
Merge pull request #796 from storytold/fix/flaky-native-menu-test
Native menu test: judge idle frames while the global generations hold still
2026-10-10 00:36:35 +07:00
bflatastic 0928cafab2 Native menu test: judge idle frames while the global generations hold still
key_equivalents_run_through_the_normal_shortcut_path_once failed about one
full ui-egui run in four ("the menus weren't read again", 5 vs 4). Each
app mirrors its shortcut overrides into a process-wide store every frame,
bumping shortcut_editor::GENERATION, and the plug-in registry's revision is
process-wide too. Tests running alongside with other shortcuts flip them,
which rightly makes the menus read again. The test now checks two idle
frames during which those generations held still (trying up to 50 times),
so it still fails if idle frames re-read the menus on their own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:36:14 +07:00
DWAA1660 636d9b24c8 Fix #786: clear exact compound members and explicit targets 2026-10-09 11:33:23 -06:00
DWAA1660 04439bb01d Fix #784: validate selection IDs and report the resulting selection 2026-10-09 11:19:08 -06:00
BFlat 21355945ea
Merge pull request #794 from storytold/fix/776-pen-joins-paths
Fix #776: the Pen continues any open path and joins two paths
2026-10-10 00:01:01 +07:00
bflatastic bd8fa795ed Fix #776: the Pen continues any open path and joins two paths
As in Illustrator, the Pen shows its continue cursor over an end of any
open path, selected or not, and a click there selects the path and draws
on from that end (reversing it from its first end). While drawing, it
shows a join cursor over an end of another open path, and a click joins
the two into one path, in one undo step, which finishes the path.

path.join takes {ids: [a, b], ends: ["first"|"last", "first"|"last"]}
to join the ends asked for (the Pen's join); without them it joins the
selected paths' nearest ends as before. Joining a path with itself, or
anything that isn't a path, is an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:59:50 +07:00
BFlat 825d4fdb8b
Merge pull request #791 from storytold/fix/734-crop-image-box
Fix #734: Crop Image shows a crop box on the image
2026-10-09 23:40:58 +07:00
bflatastic 4b44265965 Fix #734: Crop Image shows a crop box on the image
Object › Crop Image and the image's Crop Image buttons (Control bar,
Properties) now show a crop box on the selected image, as Illustrator
does, instead of cropping straight to the artboard (which did nothing for
an image inside its artboard). The box starts on the image's part over its
artboard; its handles and its inside drag it, always within the image, and
the image outside it is dimmed. The Control bar shows its X/Y/W/H with
Apply and Cancel; Enter applies and Escape cancels, both back to the
Selection tool. Apply runs object.cropImage {rect}, one undo step.

- tools: the Crop Image tool (cropimage.rs), with crop_box shared by the
  tool and the Control bar.
- ui: ui.cropImage (enabled with an image selected), the Control bar's
  crop fields and buttons, "Apply" translated (es, fr, it, ru, uk, ja,
  zh-hans, zh-hant).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:40:12 +07:00
bflatastic 9de418a4a4 ROADMAP: the Arabic families come with a craft-fonts checkout that has them
craft-fonts main holds only Noto Sans Arabic so far (the other eleven are in
storytold/craft-fonts#11), and releases pin an older craft-fonts commit, so
say which builds list them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:16:41 +07:00
BFlat 8e0e2eb904
Merge pull request #790 from storytold/fix/clippy-199-affinity-tests
Clippy 1.99: as_chunks in the Affinity raster tests
2026-10-09 23:15:59 +07:00
bflatastic 8124cf7b43 Clippy 1.99: as_chunks in the Affinity raster tests
#763 landed beside #771 with five chunks_exact(4) calls in
crates/affinity/tests/raster.rs, which clippy 1.99's chunks_exact_to_as_chunks
rejects, so cargo xtask ci failed at clippy on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:15:36 +07:00
dotCooCoo 75f2145b92 Package: fonts found by any of their names are copied, and skipped fonts are named
File › Package and Document Info › Font Details looked fonts up with
FontDb::face and compared the face's family with the name the document
stores. A font a document named by another of its names (a PostScript
or localized name, as SVG and PDF files do) was reported as not
available and left out of the package, although the canvas drew it and
exports embedded it.

- Package and Font Details resolve fonts with FontDb::resolve, as
  text.fonts and the renderer do. A style the family lacks is still
  copied as its closest style; the report now names the style it
  copies, and Font Details lists the font as substituted, with that
  style's file and permission.
- FontFace::embeddable reads fsType as exports do (Embedding), so fonts
  that allow bitmap embedding only (bit 9), or that set the restricted
  bit together with reserved bit 0 (0x0003), are no longer copied.
  Document Info's permission labels follow the same rule: when a font
  sets more than one usage bit, the label names the most permissive
  one.
- The Package dialog and its status line name the fonts it didn't copy.
2026-10-09 08:35:16 -07:00
BFlat d168d4f843
Merge pull request #771 from DisasterAreaDesigns/affinity-as-chunks
Clippy 1.99: use as_chunks for constant-size chunks
2026-10-09 22:32:02 +07:00
BFlat 9ff0277306
Merge pull request #763 from callmeBalloch/feat/affinity-af-validation
AF.4: harden current .af artboards, text and images with a pinned corpus
2026-10-09 22:21:20 +07:00
bflatastic 573f27e6c9 AF.4 docs: leave out shop listings and sandbox notes
The source audit linked commercial template listings and other pages it
didn't use, and described the environment it ran in. Keep the two sources
the corpus uses, say in a sentence what kinds of sources were left out and
why, and state plainly that reopening our output in Affinity is still to do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:20:39 +07:00
dotCooCoo 4b00c2d968 Part of #579: macOS fonts registered from other folders are listed too
The font scan read only the macOS font folders and the Additional
Fonts Folder, so fonts that apps and font managers register with
CoreText from their own folders were missing from the font menus, and
exports set such type in the fallback font. CoreText's font manager
lists them with the installed fonts.

- `mac_fonts.rs` lists the files of the fonts the font manager has
  available (`CTFontManagerCopyAvailableFontURLs`, through
  objc2-core-text), keeping only file URLs as `open_documents.rs` does
  (#433). The desktop app and `vectorcraft-cli` install it as they
  install the DirectWrite lister on Windows, and the scan reads the
  files outside the font folders in place.
- The scan leaves out faces with no outlines the font engine draws (no
  glyf, CFF, CFF2 or VARC table), on every platform. CoreText lists
  Apple's PingFang UI interface font (macOS 27), whose outlines are in
  an hvgl table; if the scan cataloged it, PingFang SC would count as
  installed, and Chinese characters in fallback text, Japanese kanji
  included, would draw blank.
- Tests: the list holds the installed fonts by full path, a font
  registered from another folder is listed while it is registered, and
  a face without outlines the engine draws isn't cataloged.
2026-10-09 08:16:33 -07:00
dotCooCoo a61d058f1b Swatches: Save Swatch Library writes swatch exchange (.ase) files
The Save Swatch Library dialog lists Swatch Exchange (.ase) as a
format, and swatch.library.save takes format: "ase" or a path ending
in .ase. Each solid color keeps its model (RGB, CMYK, Lab or Gray) and
its type (spot, global or process), and color groups stay groups.
Gradients and patterns are left out, and a tint swatch is written as
the color it shows. Without a path or user: true, the command returns
the file as dataBase64.

A swatch exchange library opens under the name of its file. When Save
Swatch Library or Save Graphic Style Library saves to a file, the save
panel suggests the Name from the dialog as the file name, as a save to
User Defined does, and the web app downloads the file under that name.
A name made only of dots and spaces, such as "...", gives the file name
Library (Library.vcswatches) in place of a hidden file.

palette_io::write returns the file's bytes. A property test writes
generated libraries and reads them back, and an import fuzz test loads
mutated copies of a file the writer wrote.
2026-10-09 08:15:09 -07:00