Commit Graph
13 Commits
Author SHA1 Message Date
bflatastic b3f6edddfe Fix #1499: PDF and EPS another app copied paste as editable vector art
Paste read PDF only from the Windows clipboard and EPS nowhere, so on macOS a copied
equation or drawing pasted nothing new (the last thing copied in the app came back).
- macOS: the pasteboard's PDF, EPS and SVG are read, ahead of text and bitmaps.
- Windows: EPS is read beside PDF.
- Everywhere: an .eps file copied in a file manager pastes.
- clipboard.importEps loads an EPS into the clipboard as document.open reads one.
2026-10-13 06:34:12 +07:00
arhammusheer 5beac4f122 #1244: smaller objects: Node 352 -> 152 bytes, NodeKind 200 -> 80, and a cheaper undo estimate
Rarely set fields move into one optional boxed NodeExtras, and large NodeKind payloads (images,
live shapes, blends, envelopes) are boxed. Every object, and every undo step that copies it,
shrinks: a 50k-path move keeps ~24.5 MB per step instead of ~40 MB. Files stay byte-identical
(Node keeps its flat JSON through a borrowed Serialize and a from-wire Deserialize, no flatten),
and loading is slightly faster. Undo and redo reuse their step's size estimate instead of
walking the document again (8.3 -> 5.6 ms for a 50k-path move).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmMmc1J8XeNLxhRihWv9cc

# Conflicts:
#	crates/engine/src/cmd/graph.rs
#	crates/svg/src/export.rs
2026-10-12 11:02:32 +07:00
bflatasticandClaude Opus 5.5 8c69173bb7 #1089: an image copied in a browser pastes as the picture, also from its markup
A browser's Copy Image puts the picture on the clipboard with text next
to it. Paste already took the picture when that text was only the
image's address (#597), but some browsers (seen on Fedora with KDE) put
the image's HTML there instead, `<img src="…" class="…" style="…">`,
which isn't an address, so the markup was pasted as type.

names_a_picture also takes markup whose only content is <img> elements
(no text outside its tags) as naming the picture, and Paste then reads
the bitmap. Markup with words in it, and an address alone, still paste
as text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:51:41 +07:00
bflatastic 564a3ae662 Merge #616: Fix #597: an image copied in a browser pastes as the picture, not its address
# Conflicts:
#	ROADMAP.md
2026-10-09 05:26:43 +07:00
bflatasticandClaude Opus 5.5 54eed6ec4c Fix #597: an image copied in a browser pastes as the picture, not its address
A browser's Copy Image puts the picture on the clipboard with the image's
address as text (and HTML). Paste takes text before bitmaps, as word
processors offer a picture of copied text, so it pasted the address.

- `clipboard::is_address`: text that is only an address (http, https,
  file, ftp, data or blob).
- Desktop paste (Windows, macOS, Linux): such text gives way to the
  clipboard's bitmap when it has one. An address alone pastes as text, as
  before; nothing is fetched.
- Web: a paste whose text is only an address takes its picture file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 05:22:09 +07:00
haven f7761bf5bc M7: per-paragraph paragraph attributes
Each paragraph has its own alignment, indents, spacing, hyphenation, tab
stops and paragraph style (TextObject.paras; para stays paragraph 0's, so
old files and readers work). Layout, editing (split/merge), threads, the
Paragraph/Tabs/Paragraph Styles panels, ranged text.setStyle/setFormat/
tabs/paraStyle.apply, SVG export/import and the fuzzers follow.
2026-10-08 15:07:13 -07:00
haven 6d56195eda Placed documents: the object, drawn exactly and kept as art by every exporter 2026-10-08 12:20:51 -07:00
bflatasticandClaude Opus 5.5 afb438367d Type Object Selection by Path Only: every baseline, Type tool and Eyedropper (review of #475)
- Type is picked on the baseline of any of its lines (point type and area
  type, besides area type's frame), as in Illustrator, not only the first
  one: the layout's baselines are cached with its bounds
  (`TextObject::cached_baselines`, from `TextLayout::baselines`), with the
  first one across the bounds as the fallback. Vertical type's runs down
  each column's centre line.
- Type in perspective is picked where it is drawn (through its projection).
- The bounds rule type out before its path is built, so hovering stays
  free of allocations away from type.
- The Type tools still edit type clicked among its characters (they made
  new type there with the preference on), and the Eyedropper still samples
  it there, as it does inside fills with Object Selection by Path Only.
- Tests for all of it; docs/mcp.md and ROADMAP say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 18:59:47 +07:00
bflatasticandClaude Opus 5.5 4767ec7113 Fix #398: Linux/Wayland bitmap paste, copied files paste as art
Under Wayland the window is native but arboard was built without its
data-control backend, so it read the X11 clipboard through XWayland,
which only holds what X11 apps copied: Paste found nothing and reported
an empty clipboard (egui's text paste into fields uses smithay-clipboard,
which is why that worked). arboard now has `wayland-data-control`, the
same as PhotoCraft; it falls back to X11 where the compositor lacks the
protocol (GNOME's Mutter).

The reporter's clipboard also held text/uri-list: with a file copied in a
file manager, Paste would have taken the path as text before the bitmap.
Copied files now paste first, as the first one that is art (SVG, PDF,
EMF/WMF or a bitmap), told from its first 4 KiB by the engine's format
detection (`clipboard::file_flavour`): text/uri-list through arboard on
Linux and macOS (a trailing CR from CRLF lists trimmed), CF_HDROP on
Windows, read with the clipboard closed again.

Dropping files on the window can't work under Wayland yet: winit 0.30,
which eframe 0.36 runs on, has no Wayland drag and drop (winit#1881,
added in 0.31), so no dropped_files arrive. docs/development.md documents
it and the workarounds (copy and paste the files, File > Place, or run
under XWayland with `WAYLAND_DISPLAY=`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 07:44:23 +07:00
bflatasticandClaude Opus 5.5 961ca75a28 M4.95: EMF and WMF open, place and paste as vector objects
crates/metafile import: EMF and WMF (placeable or not) records play on a
small device-context model (objects numbered as GDI does, saved DCs, world
transforms and mapping modes, path brackets, the current position) into one
artboard (the picture's frame) and one layer: paths with fills and strokes
(pens with caps, joins, dashes), clipping groups for clips, images from DIBs
(StretchDIBits, BitBlt, StretchBlt, AlphaBlend, StretchDIB, DIBBitBlt) and
point type in the font the file names. Lines drawn one after another join
into one path; a clip around the whole picture is dropped; objects far
outside it are left out; unknown records are skipped with one warning.

document.open and file.place read .emf and .wmf through the shared loader
(Open and Place filters list them). clipboard.importEmf loads a picture into
the clipboard, and Paste takes image/emf from a system clipboard service
ahead of text and bitmaps. The import fuzzer covers mutated and random-record
metafiles opened, placed and pasted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 15:24:27 +07:00
bflatasticandClaude Opus 5.5 2925e7f9b5 M4.63: Links panel with status, Relink, Go To, Update, Edit Original, Embed/Unembed, Link Info and Placement Options
The Links panel lists every image (thumbnail, name, page, missing/modified/embedded
badge) with Show filters, sorting and thumbnail sizes; its buttons and flyout relink
(to a file or a folder), go to, update, edit the original, embed and unembed, show in
folder and open Placement Options. Link Info shows format, colour space, location, ppi
and effective ppi, dimensions, scale, rotation, size and dates. Edit > Edit Original
and the Properties panel's image section reach the same commands.

Engine: links.list, links.goTo, links.embed, links.unembed, links.info and
links.placementOptions; links.relink and links.update now place the new file as the
image's Placement Options say (transforms, bounds, file dimensions, fit, fill, the
alignment point, clip to the old bounds). Model: ImageObject.placement.
UI: links.editOriginal, links.reveal, ui.placementOptionsDialog; Services.open_file
and pick_folder on the desktop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:40:05 +07:00
bflatasticandClaude Opus 5.5 0968e34e7e M4.57: PNG, PDF and text clipboard flavours in and out
Copy and Cut also offer other apps a PNG of the copied objects, a PDF
with On Copy: PDF, and plain text when every copied object is type
(clipboard.flavours; clipboard.exportPng {scale?}, exportPdf,
exportText). Paste outside text editing takes what another app copied:
SVG, then PDF (clipboard.importPdf), then plain text as point text
(clipboard.importText), then a bitmap embedded at the view centre
(clipboard.importImage {dataBase64, mime?, center?}); pasting our own
copy keeps the lossless internal clipboard, and Cmd+V pastes a bitmap
that comes with no text. Services gains system_clipboard
(SystemClipboard: write, holds_ours, read, has): on Windows every
format at once, on macOS and Linux one (the text, else the PNG); the
web keeps SVG text only. With When pasting text: Keep Plain Text, text
the Type tool copied pastes without its formatting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:52:01 +07:00
bflatasticandClaude Opus 5.5 ee2aa96dcd M4.22: pasting between documents carries the objects' resources
Copy keeps the copied objects with every document resource they use
(Session.clipboard: Clipboard {nodes, images, symbols, patterns,
swatches, graphic_styles, char_styles, para_styles, brushes,
source_artboard, source_layers, source_doc}), following symbols,
patterns, graphic styles and text styles into what they use. Every
edit.paste* brings them in within its undo step: identical resources are
reused, missing ones added, different ones of the same name added
renamed (an earlier paste's copy is reused) and the pasted objects
relinked, graphic style links by id. Global and spot swatches that
conflict ask Merge or Add (swatchConflict; clipboard.conflicts lists
them; the app's Swatch Conflict dialog asks one by one, with Apply to
All). Tint swatches, linked gradient stops, Lab spots and the target's
Spot Colors option are honoured; [Registration] is never copied.
Clipboard SVG exports them too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:45:34 +07:00