diff --git a/crates/engine/src/cmd/clipboard/flavours.rs b/crates/engine/src/cmd/clipboard/flavours.rs index 8e4c57d06..b2e1114e1 100644 --- a/crates/engine/src/cmd/clipboard/flavours.rs +++ b/crates/engine/src/cmd/clipboard/flavours.rs @@ -127,6 +127,8 @@ pub struct Flavour { const COPY_PNG_SIDE: f64 = 4096.0; /// The smallest scale (pixels a point) the PNG encoder renders at. const MIN_COPY_PNG_SCALE: f64 = 0.01; +/// What Copy says when the art is too large for its PNG. +const TOO_LARGE_FOR_PNG: &str = "The art is too large to copy as a picture: other apps get no PNG of it"; /// Most bytes of text `clipboard.importText` takes. const MAX_TEXT: usize = 1 << 20; /// Most bytes of images the SVG markup may embed and still go out as plain text. A paste reads the @@ -290,7 +292,18 @@ impl Clipboard { let text = (svg && self.image_bytes() <= COPY_TEXT_IMAGE_BYTES) || self.nodes.iter().all(type_only); // Art without an area (a lone guide-like line) has no page or picture. let area = self.bounds().is_some_and(|b| b.width() > 0.0 && b.height() > 0.0); - [(TEXT, text), (SVG, svg), (PDF, pdf && area), (PNG, area)].into_iter().filter_map(|(m, on)| on.then_some(m)).collect() + [(TEXT, text), (SVG, svg), (PDF, pdf && area), (PNG, area && self.png_scale().is_some())] + .into_iter() + .filter_map(|(m, on)| on.then_some(m)) + .collect() + } + + /// The scale (pixels a point) of the PNG Copy offers: at most [`COPY_PNG_SIDE`] pixels a side, + /// and `None` when even [`MIN_COPY_PNG_SCALE`], the encoder's smallest, can't bring it that small + /// (rather than a PNG of up to a gigabyte of pixels). + fn png_scale(&self) -> Option { + let side = self.bounds().map_or(1.0, |b| b.width().max(b.height())); + Some((COPY_PNG_SIDE / side).min(1.0)).filter(|s| *s >= MIN_COPY_PNG_SCALE) } /// What Copy offers other apps, best first, with Include SVG Code (`svg`) and On Copy: PDF @@ -308,6 +321,9 @@ impl Clipboard { let svg = types.contains(&SVG).then(|| self.svg()).flatten(); let mut out = vec![]; let mut warnings: Vec = vec![]; + if !self.is_empty() && self.png_scale().is_none() { + warnings.push(TOO_LARGE_FOR_PNG.to_string()); + } let mut keep = |(bytes, notes): (Vec, Vec)| { for w in notes { if !warnings.contains(&w) { @@ -321,18 +337,10 @@ impl Clipboard { TEXT => self.text().or_else(|| svg.clone()).map(String::into_bytes), SVG => svg.clone().map(String::into_bytes), PDF => self.pdf().inspect_err(|e| log::warn!("clipboard PDF: {e}")).ok().flatten().map(&mut keep), - _ => { - let side = self.bounds().map_or(1.0, |b| b.width().max(b.height())); - let scale = (COPY_PNG_SIDE / side).min(1.0); - // The encoder renders at no fewer than MIN_COPY_PNG_SCALE pixels a point: art - // too large to fit COPY_PNG_SIDE at that scale gets no PNG, rather than one - // of up to a gigabyte of pixels. - if scale < MIN_COPY_PNG_SCALE { - log::warn!("clipboard PNG: art {side} pt across is too large to copy as a picture"); - continue; - } - self.png(scale).inspect_err(|e| log::warn!("clipboard PNG: {e}")).ok().flatten().map(|(png, _, _, notes)| keep((png, notes))) - } + _ => self + .png_scale() + .and_then(|scale| self.png(scale).inspect_err(|e| log::warn!("clipboard PNG: {e}")).ok().flatten()) + .map(|(png, _, _, notes)| keep((png, notes))), }; out.extend(data.map(|data| Flavour { mime, data })); } diff --git a/crates/engine/src/tests/clipflavours.rs b/crates/engine/src/tests/clipflavours.rs index c490c2684..313935c21 100644 --- a/crates/engine/src/tests/clipflavours.rs +++ b/crates/engine/src/tests/clipflavours.rs @@ -358,8 +358,10 @@ fn copy_leaves_out_the_png_of_art_too_large_to_scale_down() { let id = run(&mut s, "shape.rectangle", json!({"x": 0, "y": 0, "width": 1_000_000, "height": 1_000_000}))["id"].clone(); run(&mut s, "select.set", json!({"ids": [id]})); run(&mut s, "edit.copy", json!({})); - assert!(s.clipboard.flavour_types(false, false).contains(&PNG)); - assert!(s.clipboard.flavours(false, false).iter().all(|f| f.mime != PNG)); + assert!(!s.clipboard.flavour_types(false, false).contains(&PNG), "not offered either"); + let (flavours, notes) = s.clipboard.flavours_with_warnings(false, false); + assert!(flavours.iter().all(|f| f.mime != PNG)); + assert!(notes.iter().any(|n| n.contains("too large to copy as a picture")), "{notes:?}"); // Art that fits at that scale still gets its PNG, at most 4096 pixels a side. let id = run(&mut s, "shape.rectangle", json!({"x": 0, "y": 0, "width": 200_000, "height": 100}))["id"].clone(); run(&mut s, "select.set", json!({"ids": [id]})); diff --git a/crates/ui-egui/src/i18n/bg.tsv b/crates/ui-egui/src/i18n/bg.tsv index 39cc049f3..78ac89840 100644 --- a/crates/ui-egui/src/i18n/bg.tsv +++ b/crates/ui-egui/src/i18n/bg.tsv @@ -6134,3 +6134,4 @@ breakText Glyphs Глифи Bow Дъга Spike Връх Skip Spaces Пропускане на интервалите +@msg The art is too large to copy as a picture: other apps get no PNG of it Графиката е твърде голяма, за да се копира като изображение: другите приложения не получават PNG от нея diff --git a/crates/ui-egui/src/i18n/bs.tsv b/crates/ui-egui/src/i18n/bs.tsv index 61fcd183f..5ab5671ff 100644 --- a/crates/ui-egui/src/i18n/bs.tsv +++ b/crates/ui-egui/src/i18n/bs.tsv @@ -6168,3 +6168,4 @@ shape Open Otvoren Bow Luk Spike Šiljak Skip Spaces Preskoči razmake +@msg The art is too large to copy as a picture: other apps get no PNG of it Grafika je prevelika da bi se kopirala kao slika: druge aplikacije ne dobijaju njen PNG diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv index 18b9e6b3c..8688a6a91 100644 --- a/crates/ui-egui/src/i18n/ca.tsv +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -6268,3 +6268,4 @@ breakText Glyphs Glifs Bow Arc Spike Pic Skip Spaces Omet els espais +@msg The art is too large to copy as a picture: other apps get no PNG of it La il·lustració és massa gran per copiar-la com a imatge: les altres aplicacions no en reben cap PNG diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index d05064235..5346f44c9 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -6282,3 +6282,4 @@ breakText Glyphs Glyfy Bow Oblouk Spike Špička Skip Spaces Přeskočit mezery +@msg The art is too large to copy as a picture: other apps get no PNG of it Kresba je příliš velká na zkopírování jako obrázek: ostatní aplikace z ní nedostanou PNG diff --git a/crates/ui-egui/src/i18n/da.tsv b/crates/ui-egui/src/i18n/da.tsv index bb2b7b471..00085ce51 100644 --- a/crates/ui-egui/src/i18n/da.tsv +++ b/crates/ui-egui/src/i18n/da.tsv @@ -6150,3 +6150,4 @@ breakText Glyphs Glyffer Bow Bue Spike Spids Skip Spaces Spring mellemrum over +@msg The art is too large to copy as a picture: other apps get no PNG of it Grafikken er for stor til at blive kopieret som et billede: andre programmer får ingen PNG af den diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index 5c57b5895..6fc63d81b 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -5868,3 +5868,4 @@ breakText Glyphs Glyphen Bow Bogen Spike Spitze Skip Spaces Leerzeichen überspringen +@msg The art is too large to copy as a picture: other apps get no PNG of it Das Bildmaterial ist zu groß, um es als Bild zu kopieren: Andere Apps erhalten kein PNG davon diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index 2a17c0bab..2b52852d4 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -6234,3 +6234,4 @@ breakText Glyphs Γλύφοι Bow Τόξο Spike Αιχμή Skip Spaces Παράλειψη κενών +@msg The art is too large to copy as a picture: other apps get no PNG of it Το γραφικό είναι πολύ μεγάλο για αντιγραφή ως εικόνα: οι άλλες εφαρμογές δεν λαμβάνουν PNG του diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 3ca5ebf1f..1b2d552b8 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -6224,3 +6224,4 @@ breakText Glyphs Glifos Bow Arco Spike Pico Skip Spaces Omitir espacios +@msg The art is too large to copy as a picture: other apps get no PNG of it La ilustración es demasiado grande para copiarla como imagen: las demás aplicaciones no reciben un PNG de ella diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index 78d810c7a..7333ab988 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -6312,3 +6312,4 @@ breakText Glyphs Merkit Bow Kaari Spike Piikki Skip Spaces Ohita välilyönnit +@msg The art is too large to copy as a picture: other apps get no PNG of it Grafiikka on liian suuri kopioitavaksi kuvana: muut sovellukset eivät saa siitä PNG-kuvaa diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index d5972a384..a74435b31 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -6277,3 +6277,4 @@ breakText Glyphs Glyphes Bow Arc Spike Pointe Skip Spaces Ignorer les espaces +@msg The art is too large to copy as a picture: other apps get no PNG of it L’illustration est trop grande pour être copiée en tant qu’image : les autres applications n’en reçoivent pas de PNG diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index c9a798077..eeb182f47 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -6266,3 +6266,4 @@ breakText Glyphs Glifák Bow Ív Spike Csúcs Skip Spaces Szóközök kihagyása +@msg The art is too large to copy as a picture: other apps get no PNG of it A grafika túl nagy ahhoz, hogy képként másolható legyen: más alkalmazások nem kapnak róla PNG-t diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index 1b315d849..2c77ab5f4 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -6150,3 +6150,4 @@ breakText Glyphs Glif Bow Busur Spike Puncak Skip Spaces Lewati Spasi +@msg The art is too large to copy as a picture: other apps get no PNG of it Gambar terlalu besar untuk disalin sebagai gambar: aplikasi lain tidak mendapatkan PNG darinya diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index 0b07d6769..c45f0baa1 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -5902,3 +5902,4 @@ breakText Glyphs Glifi Bow Arco Spike Picco Skip Spaces Salta gli spazi +@msg The art is too large to copy as a picture: other apps get no PNG of it La grafica è troppo grande per essere copiata come immagine: le altre app non ne ricevono un PNG diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index de9c692c6..2d1245dac 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -5967,3 +5967,4 @@ breakText Glyphs 字形 Bow 弓形 Spike 山形 Skip Spaces スペースをスキップ +@msg The art is too large to copy as a picture: other apps get no PNG of it アートワークが大きすぎるため画像としてコピーできません:他のアプリには PNG が渡されません diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index 0eb9cd390..430966ec7 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -6270,3 +6270,4 @@ breakText Glyphs გლიფები Bow რკალი Spike პიკი Skip Spaces ჰარების გამოტოვება +@msg The art is too large to copy as a picture: other apps get no PNG of it ნახატი ზედმეტად დიდია სურათად დასაკოპირებლად: სხვა აპები მის PNG-ს ვერ მიიღებენ diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index e4c58c1d5..e8ee81e82 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -5863,3 +5863,4 @@ breakText Glyphs 글리프 Bow 활 모양 Spike 뾰족한 모양 Skip Spaces 공백 건너뛰기 +@msg The art is too large to copy as a picture: other apps get no PNG of it 아트워크가 너무 커서 이미지로 복사할 수 없습니다: 다른 앱에는 PNG가 전달되지 않습니다 diff --git a/crates/ui-egui/src/i18n/nl.tsv b/crates/ui-egui/src/i18n/nl.tsv index af1269a7f..0443844e5 100644 --- a/crates/ui-egui/src/i18n/nl.tsv +++ b/crates/ui-egui/src/i18n/nl.tsv @@ -6194,3 +6194,4 @@ breakText Glyphs Glyphs Bow Boog Spike Piek Skip Spaces Spaties overslaan +@msg The art is too large to copy as a picture: other apps get no PNG of it Het illustratiewerk is te groot om als afbeelding te kopiëren: andere apps krijgen er geen PNG van diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 08f91930e..e593cbfa2 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -6137,3 +6137,4 @@ breakText Glyphs Glify Bow Łuk Spike Szpic Skip Spaces Pomiń spacje +@msg The art is too large to copy as a picture: other apps get no PNG of it Grafika jest zbyt duża, aby skopiować ją jako obraz: inne aplikacje nie otrzymają jej w formacie PNG diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 40a253846..4444c9ae1 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -6355,3 +6355,4 @@ swatch Yellow Green Verde-amarelado Bow Arco Spike Pico Skip Spaces Ignorar espaços +@msg The art is too large to copy as a picture: other apps get no PNG of it A arte é grande demais para ser copiada como imagem: outros aplicativos não recebem um PNG dela diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 199d7a06d..0564fc9b6 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -6371,3 +6371,4 @@ shape Open Открытый Bow Дуга Spike Пик Skip Spaces Пропускать пробелы +@msg The art is too large to copy as a picture: other apps get no PNG of it Графика слишком велика для копирования в виде изображения: другие приложения не получат её PNG diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index 8fb160cea..47dfc5154 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -6338,3 +6338,4 @@ digits Hindi Hindi Bow Båge Spike Spets Skip Spaces Hoppa över mellanslag +@msg The art is too large to copy as a picture: other apps get no PNG of it Teckningen är för stor för att kopieras som en bild: andra appar får ingen PNG av den diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index fe8244ad8..48d39c44e 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -6239,3 +6239,4 @@ breakText Glyphs Glifler Bow Yay Spike Sivri Uç Skip Spaces Boşlukları Atla +@msg The art is too large to copy as a picture: other apps get no PNG of it Çizim, resim olarak kopyalanamayacak kadar büyük: diğer uygulamalar bunun PNG'sini almaz diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index b676cbf4d..2f4fc4214 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -5882,3 +5882,4 @@ breakText Glyphs Гліфи Bow Дуга Spike Пік Skip Spaces Пропускати пробіли +@msg The art is too large to copy as a picture: other apps get no PNG of it Графіка завелика, щоб скопіювати її як зображення: інші програми не отримають її PNG diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 1575decd9..c9da14955 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -5883,3 +5883,4 @@ breakText Glyphs Glyph Bow Cung Spike Đỉnh nhọn Skip Spaces Bỏ qua khoảng trắng +@msg The art is too large to copy as a picture: other apps get no PNG of it Hình vẽ quá lớn để sao chép dưới dạng ảnh: các ứng dụng khác không nhận được PNG của nó diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 204aee9b7..4f01a034a 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -6123,3 +6123,4 @@ breakText Glyphs 字形 Bow 弓形 Spike 尖峰 Skip Spaces 跳过空格 +@msg The art is too large to copy as a picture: other apps get no PNG of it 图稿太大,无法作为图片复制:其他应用不会获得它的 PNG diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index 23b253f0e..5b56d39e7 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -5920,3 +5920,4 @@ breakText Glyphs 字符 Bow 弓形 Spike 尖峰 Skip Spaces 略過空格 +@msg The art is too large to copy as a picture: other apps get no PNG of it 圖稿太大,無法作為圖片複製:其他應用程式不會取得它的 PNG