mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Image Trace: pressing and holding the eye button shows the source image
The Image Trace panel had no way to compare a trace with its source image except changing View and changing it back. The panel now has an eye button to the right of View, enabled with an Image Trace object selected. While it is held down, the canvas draws the selected Image Trace objects with their source image, whatever their View, and draws their View again on release. The document, its View and the undo history are unchanged. The renderer takes the objects in RenderOptions::trace_source, which is also part of the canvas frame key and the raster-effect cache key.
This commit is contained in:
@@ -2130,6 +2130,7 @@ impl Renderer {
|
||||
if reads.images {
|
||||
let o = f.opts;
|
||||
(doc.images, self.dim_images.map(f32::to_bits), o.smooth_images, o.image_mips, o.trace_views, o.progressive_placed).hash(&mut h);
|
||||
o.trace_source.as_deref().hash(&mut h);
|
||||
}
|
||||
if reads.brushes {
|
||||
self.brushes.library_key(f.doc, self.stamp).hash(&mut h);
|
||||
|
||||
@@ -159,6 +159,10 @@ pub struct RenderOptions {
|
||||
/// Screen view: Image Trace objects draw as their View asks (outlines, the source image…);
|
||||
/// off, they draw their tracing result, as exports and printing do.
|
||||
pub trace_views: bool,
|
||||
/// Screen view with `trace_views` on: the Image Trace objects drawn with the Source Image view
|
||||
/// for this render only, whatever View they have (the Image Trace panel's eye button, while it
|
||||
/// is held down).
|
||||
pub trace_source: Option<Arc<Vec<NodeId>>>,
|
||||
/// Images are sampled smoothly when scaled or rotated; off, each pixel takes its nearest image
|
||||
/// pixel (Pixel Preview with File Handling › Display Bitmaps as Anti-aliased Images off).
|
||||
pub smooth_images: bool,
|
||||
@@ -266,6 +270,7 @@ impl Default for RenderOptions {
|
||||
anti_alias: AntiAlias::Art,
|
||||
progressive_placed: false,
|
||||
trace_views: false,
|
||||
trace_source: None,
|
||||
smooth_images: true,
|
||||
isolated: None,
|
||||
precise: false,
|
||||
@@ -1301,8 +1306,8 @@ impl Renderer {
|
||||
/// What `n` draws inside its transparency group (`knockout`: its children knock each other out).
|
||||
fn draw_content(&mut self, ctx: &mut RenderContext, f: &Frame, n: &Node, knockout: bool) {
|
||||
match &n.kind {
|
||||
NodeKind::Group { children, clip: false } if f.opts.trace_views && !f.opts.outline && n.trace_view() != TraceView::Result => {
|
||||
self.draw_trace_view(ctx, f, children, n.trace_view(), knockout)
|
||||
NodeKind::Group { children, clip: false } if f.opts.trace_views && !f.opts.outline && Self::trace_view(f, n) != TraceView::Result => {
|
||||
self.draw_trace_view(ctx, f, children, Self::trace_view(f, n), knockout)
|
||||
}
|
||||
NodeKind::Layer { children, clip: false, .. } | NodeKind::Group { children, clip: false } => {
|
||||
self.draw_children(ctx, f, children, knockout)
|
||||
@@ -1429,6 +1434,15 @@ impl Renderer {
|
||||
self.live_root = outer;
|
||||
}
|
||||
|
||||
/// The View `n` draws with on screen: Source Image when it is an Image Trace object listed in
|
||||
/// [`RenderOptions::trace_source`], else its own.
|
||||
fn trace_view(f: &Frame, n: &Node) -> TraceView {
|
||||
match &f.opts.trace_source {
|
||||
Some(ids) if n.extras().trace.is_some() && ids.contains(&n.id) => TraceView::Source,
|
||||
_ => n.trace_view(),
|
||||
}
|
||||
}
|
||||
|
||||
/// An Image Trace object's `children` (the hidden source image, then the traced shapes) as
|
||||
/// `view` shows them on screen.
|
||||
fn draw_trace_view(&mut self, ctx: &mut RenderContext, f: &Frame, children: &[Arc<Node>], view: TraceView, knockout: bool) {
|
||||
|
||||
@@ -579,6 +579,57 @@ fn outline_view_draws_paths_from_kept_geometry() {
|
||||
}
|
||||
}
|
||||
|
||||
/// An Image Trace object listed in `trace_source` draws its source image on screen whatever its
|
||||
/// View, also inside a group whose raster effect a renderer keeps; without the list, and in
|
||||
/// exports, it draws its result. A group that is not an Image Trace object draws its members.
|
||||
#[test]
|
||||
fn trace_source_draws_the_source_image_of_the_listed_objects() {
|
||||
use vectorcraft_doc::{ImageBlob, ImageObject};
|
||||
let img = image::RgbaImage::from_pixel(1, 1, image::Rgba([255, 0, 0, 255]));
|
||||
let mut png = vec![];
|
||||
img.write_to(&mut std::io::Cursor::new(&mut png), image::ImageFormat::Png).unwrap();
|
||||
let mut d = Document::new(100.0, 100.0);
|
||||
d.images.insert("red".into(), ImageBlob::new("image/png", png));
|
||||
// A group at `x`: the hidden red source image, then a blue traced square over it.
|
||||
let group = |d: &mut Document, x: f64, traced: bool| {
|
||||
let xf = Affine::translate((x, 10.0)) * Affine::scale(20.0);
|
||||
let im = ImageObject { key: "red".into(), width: 1, height: 1, xf, link: None, placement: Default::default(), pixels: None };
|
||||
let mut source = Node::new(d.alloc_id(), NodeKind::Image(Box::new(im)));
|
||||
source.visible = false;
|
||||
let shape = rect_node(d, Rect::new(x, 10.0, x + 20.0, 30.0), Paint::solid(Color::rgb(0.0, 0.0, 1.0)), Paint::None, 0.0);
|
||||
let mut g = Node::group(d.alloc_id(), vec![Arc::new(source), Arc::new(shape)]);
|
||||
if traced {
|
||||
g.extras_mut().trace = Some(Box::new(serde_json::json!({ "view": "tracingResult" })));
|
||||
}
|
||||
g
|
||||
};
|
||||
let plain = group(&mut d, 10.0, true);
|
||||
let blurred = group(&mut d, 40.0, true);
|
||||
let other = group(&mut d, 70.0, false);
|
||||
let ids = Arc::new(vec![plain.id, blurred.id, other.id]);
|
||||
let mut holder = Node::group(d.alloc_id(), vec![Arc::new(blurred)]);
|
||||
holder.appearance.effects.push(vectorcraft_doc::Effect { id: "blur.gaussian".into(), params: serde_json::json!({ "radius": 1 }), visible: true });
|
||||
let l = d.layers[0].id;
|
||||
for n in [plain, holder, other] {
|
||||
d.insert(Some(l), usize::MAX, n).unwrap();
|
||||
}
|
||||
let screen = RenderOptions { trace_views: true, background: Some([255; 4]), ..Default::default() };
|
||||
let held = RenderOptions { trace_source: Some(ids.clone()), ..screen.clone() };
|
||||
let export = RenderOptions { trace_source: Some(ids), background: Some([255; 4]), ..Default::default() };
|
||||
let red = |p: [u8; 4]| p[0] > 200 && p[2] < 60;
|
||||
let blue = |p: [u8; 4]| p[2] > 200 && p[0] < 60;
|
||||
let mut kept = Renderer::new();
|
||||
for (opts, source) in [(&screen, false), (&held, true), (&screen, false), (&export, false)] {
|
||||
for r in [kept.render(&d, 100, 100, Affine::IDENTITY, opts), Renderer::new().render(&d, 100, 100, Affine::IDENTITY, opts)] {
|
||||
for (x, what) in [(20, "the Image Trace object"), (50, "the one in the blurred group")] {
|
||||
let p = r.pixel(x, 20);
|
||||
assert!(if source { red(p) } else { blue(p) }, "{what} with trace_source {source}: {p:?}");
|
||||
}
|
||||
assert!(blue(r.pixel(80, 20)), "the plain group draws its square: {:?}", r.pixel(80, 20));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artboards_white_on_pasteboard() {
|
||||
let d = Document::new(50.0, 50.0);
|
||||
|
||||
@@ -419,6 +419,8 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
rich_black: app.session.prefs.black_on_screen == "rich",
|
||||
// A tool's drag on the canvas, during an interaction (not a dialog's preview).
|
||||
dragging: app.session.in_interaction() && ui.data(|d| d.get_temp::<Drag>(drag_id())) == Some(Drag::Tool),
|
||||
// The Image Trace panel's eye button, only while a pointer button is down.
|
||||
trace_source: app.ui.trace_hold_source.clone().filter(|_| ui.input(|i| i.pointer.any_down())),
|
||||
};
|
||||
// Placed documents' bitmaps are being made: draw again when they are ready.
|
||||
if vectorcraft_render::placed_document::busy() {
|
||||
@@ -487,6 +489,8 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
anti_alias: if app.session.prefs.anti_aliased_artwork { vectorcraft_render::AntiAlias::Art } else { vectorcraft_render::AntiAlias::None },
|
||||
progressive_placed: true,
|
||||
trace_views: true,
|
||||
// Image Trace › the eye button held: the source image of the selected objects.
|
||||
trace_source: key.trace_source.clone(),
|
||||
smooth_images,
|
||||
// Isolation mode: the art around the isolated group or layer is dimmed (#833).
|
||||
isolated: key.isolated.map(vectorcraft_doc::NodeId),
|
||||
|
||||
@@ -3013,6 +3013,7 @@ font-technology Variable Променливи
|
||||
Outlines Контури
|
||||
Outlines with Source Image Контури с изходно изображение
|
||||
Source Image Изходно изображение
|
||||
Press and hold to view the source image Задръжте натиснато, за да видите изходното изображение
|
||||
Image Trace View Изглед на трасиране на изображение
|
||||
Snap Options Опции за прилепване
|
||||
Snap to Glyph Прилепване към глиф
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3932,6 +3932,7 @@ font-technology Variable Variabilní
|
||||
View: Zobrazení:
|
||||
Tracing Result Výsledek vektorizace
|
||||
Outlines with Source Image Obrysy se zdrojovým obrazem
|
||||
Press and hold to view the source image Podržením zobrazíte zdrojový obraz
|
||||
SVG Options Možnosti SVG
|
||||
Maximize Maximalizovat
|
||||
Restore Obnovit
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3675,6 +3675,7 @@ font-technology Variable Variable
|
||||
View: Visning:
|
||||
Tracing Result Sporingsresultat
|
||||
Outlines with Source Image Konturer med kildebillede
|
||||
Press and hold to view the source image Hold nede for at se kildebilledet
|
||||
SVG Options SVG-indstillinger
|
||||
Maximize Maksimér
|
||||
Restore Gendan
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3051,6 +3051,7 @@ effect Points Punkte
|
||||
Outlines Pfade
|
||||
Outlines with Source Image Pfade mit Quellbild
|
||||
Source Image Quellbild
|
||||
Press and hold to view the source image Gedrückt halten, um das Quellbild anzuzeigen
|
||||
Image Trace View Bildnachzeichner-Ansicht
|
||||
Snap Options Einrastoptionen
|
||||
Snap to Glyph An Glyphe ausrichten
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1881,6 +1881,7 @@ font-technology Variable Μεταβλητές
|
||||
Absolute Απόλυτο
|
||||
View: Προβολή:
|
||||
Outlines Περιγράμματα
|
||||
Press and hold to view the source image Πατήστε παρατεταμένα για να δείτε την αρχική εικόνα
|
||||
Snap to Grid Προσκόλληση στο πλέγμα
|
||||
Snap to Pixel Προσκόλληση σε εικονοστοιχείο
|
||||
Snap to Point Προσκόλληση σε σημείο
|
||||
|
||||
|
@@ -3081,6 +3081,7 @@ font-technology Variable Variables
|
||||
Outlines Contornos
|
||||
Outlines with Source Image Contornos con imagen de origen
|
||||
Source Image Imagen de origen
|
||||
Press and hold to view the source image Mantén pulsado para ver la imagen de origen
|
||||
Image Trace View Vista del calco de imagen
|
||||
Snap Options Opciones de ajuste
|
||||
Snap to Glyph Ajustar a glifo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3856,6 +3856,7 @@ font-technology Variable Muuttuvat
|
||||
View: Näkymä:
|
||||
Tracing Result Jäljityksen tulos
|
||||
Outlines with Source Image Ääriviivat ja lähdekuva
|
||||
Press and hold to view the source image Pidä painettuna nähdäksesi lähdekuvan
|
||||
SVG Options SVG-asetukset
|
||||
Maximize Suurenna
|
||||
Restore Palauta
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3078,6 +3078,7 @@ font-technology Variable Variables
|
||||
Outlines Contours
|
||||
Outlines with Source Image Tracés avec l’image source
|
||||
Source Image Image source
|
||||
Press and hold to view the source image Maintenez le bouton enfoncé pour afficher l’image source
|
||||
Image Trace View Affichage de la vectorisation de l’image
|
||||
Snap Options Options de magnétisme
|
||||
Snap to Glyph Magnétisme du glyphe
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2039,6 +2039,7 @@ file-filter Templates Sablonok
|
||||
The file writes keys and modifiers as codes. Check the proposed meanings and answer the codes that are not known yet. A fájl a billentyűket és a módosítóbillentyűket kódként tárolja. Ellenőrizd a javasolt jelentéseket, és add meg a még ismeretlen kódok jelentését.
|
||||
Click, then press the key this code stands for (Esc cancels) Kattints, majd nyomd le azt a billentyűt, amelyet ez a kód jelöl (Esc: mégse)
|
||||
Press a key… Nyomj le egy billentyűt…
|
||||
Press and hold to view the source image Tartsd lenyomva a forráskép megtekintéséhez
|
||||
from your earlier imports a korábbi importálásaidból
|
||||
from the format's public description a formátum nyilvános leírásából
|
||||
not known yet még ismeretlen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3675,6 +3675,7 @@ font-technology Variable Variabel
|
||||
View: Tampilan:
|
||||
Tracing Result Hasil penelusuran
|
||||
Outlines with Source Image Kontur dengan gambar sumber
|
||||
Press and hold to view the source image Tekan dan tahan untuk melihat gambar sumber
|
||||
SVG Options Opsi SVG
|
||||
Maximize Maksimalkan
|
||||
Restore Pulihkan
|
||||
|
||||
|
@@ -3115,6 +3115,7 @@ mark-style Japanese Giapponese
|
||||
Outlines Contorni
|
||||
Outlines with Source Image Contorni con immagine di origine
|
||||
Source Image Immagine di origine
|
||||
Press and hold to view the source image Tieni premuto per visualizzare l'immagine di origine
|
||||
Image Trace View Vista del ricalco immagine
|
||||
Snap Options Opzioni di aggancio
|
||||
Snap to Glyph Aggancia a glifo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2889,6 +2889,7 @@ mark-style Japanese 日本式
|
||||
Outlines アウトライン
|
||||
Outlines with Source Image アウトライン(元画像付き)
|
||||
Source Image 元画像
|
||||
Press and hold to view the source image 押している間、元画像を表示
|
||||
Image Trace View 画像トレースの表示
|
||||
Snap Options スナップオプション
|
||||
Snap to Unit 単位にスナップ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3456,6 +3456,7 @@ font-technology Variable ცვლადი
|
||||
View: ხედი:
|
||||
Tracing Result ვექტორიზაციის შედეგი
|
||||
Outlines with Source Image კონტურები საწყისი გამოსახულებით
|
||||
Press and hold to view the source image ხანგრძლივად დააჭირეთ საწყისი გამოსახულების სანახავად
|
||||
SVG Options SVG-ის პარამეტრები
|
||||
Maximize გაშლა
|
||||
Restore აღდგენა
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2883,6 +2883,7 @@ mark-style Japanese 일본식
|
||||
Outlines 윤곽선
|
||||
Outlines with Source Image 원본 이미지 포함 윤곽선
|
||||
Source Image 원본 이미지
|
||||
Press and hold to view the source image 누르고 있는 동안 원본 이미지 보기
|
||||
Image Trace View 이미지 추적 보기
|
||||
Snap Options 스냅 옵션
|
||||
Snap to Unit 단위에 스냅
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3689,6 +3689,7 @@ font-technology Variable Variabel
|
||||
View: Weergave:
|
||||
Tracing Result Traceringresultaat
|
||||
Outlines with Source Image Contouren met bronafbeelding
|
||||
Press and hold to view the source image Ingedrukt houden om de bronafbeelding te bekijken
|
||||
SVG Options SVG-opties
|
||||
Maximize Maximaliseren
|
||||
Restore Herstellen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3771,6 +3771,7 @@ font-technology Variable Zmienne
|
||||
View: Widok:
|
||||
Tracing Result Wynik obrysu
|
||||
Outlines with Source Image Kontury z obrazem źródłowym
|
||||
Press and hold to view the source image Przytrzymaj, aby wyświetlić obraz źródłowy
|
||||
SVG Options Opcje SVG
|
||||
Maximize Maksymalizuj
|
||||
Restore Przywróć
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3294,6 +3294,7 @@ font-technology Variable Variáveis
|
||||
Outlines Contornos
|
||||
Outlines with Source Image Contornos com imagem de origem
|
||||
Source Image Imagem de origem
|
||||
Press and hold to view the source image Mantenha pressionado para ver a imagem de origem
|
||||
Image Trace View Exibição de vetorização de imagem
|
||||
Stroke (X), double-click for the Color Picker Traço (X), clique duas vezes para o seletor de cores
|
||||
Swap Fill and Stroke (Shift+X) Trocar preenchimento e traço (Shift+X)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -3111,6 +3111,7 @@ mark-style Japanese Японский
|
||||
Outlines Контуры
|
||||
Outlines with Source Image Контуры с исходным изображением
|
||||
Source Image Исходное изображение
|
||||
Press and hold to view the source image Удерживайте, чтобы увидеть исходное изображение
|
||||
Image Trace View Просмотр трассировки изображения
|
||||
Snap Options Параметры привязки
|
||||
Snap to Glyph Привязать к глифу
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3013,6 +3013,7 @@ font-technology Variable Variabla
|
||||
Outlines Konturlinjer
|
||||
Outlines with Source Image Konturlinjer med källbild
|
||||
Source Image Källbild
|
||||
Press and hold to view the source image Håll ned för att visa källbilden
|
||||
Image Trace View Vy för bildkalkering
|
||||
Snap Options Fästalternativ
|
||||
Snap to Glyph Fäst mot glyf
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -2921,6 +2921,7 @@ font-technology Variable Değişken
|
||||
Outlines Ana hatlar
|
||||
Outlines with Source Image Kaynak Resimli Ana Hatlar
|
||||
Source Image Kaynak Resim
|
||||
Press and hold to view the source image Kaynak resmi görmek için basılı tutun
|
||||
Image Trace View Görüntü İzleme Görünümü
|
||||
Snap Options Yapış Seçenekleri
|
||||
Snap to Glyph Glif'e Yapış
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -3108,6 +3108,7 @@ effect Points Точки
|
||||
Outlines Контури
|
||||
Outlines with Source Image Контури з вихідним зображенням
|
||||
Source Image Вихідне зображення
|
||||
Press and hold to view the source image Утримуйте, щоб побачити вихідне зображення
|
||||
Image Trace View Перегляд трасування зображення
|
||||
Snap Options Параметри прив’язки
|
||||
Snap to Glyph Прив’язати до гліфу
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 747 and column 40.
|
@@ -1779,6 +1779,7 @@ file-filter Templates Mẫu
|
||||
The file writes keys and modifiers as codes. Check the proposed meanings and answer the codes that are not known yet. Tệp ghi phím và phím bổ trợ dưới dạng mã. Hãy kiểm tra các nghĩa được đề xuất và trả lời những mã chưa biết.
|
||||
Click, then press the key this code stands for (Esc cancels) Bấm, rồi nhấn phím mà mã này biểu thị (Esc để hủy)
|
||||
Press a key… Nhấn một phím…
|
||||
Press and hold to view the source image Nhấn giữ để xem ảnh nguồn
|
||||
from your earlier imports từ các lần nhập trước của bạn
|
||||
from the format's public description từ mô tả công khai của định dạng
|
||||
not known yet chưa biết
|
||||
|
||||
|
@@ -2947,6 +2947,7 @@ font-script Japanese 汉字
|
||||
Outlines 轮廓
|
||||
Outlines with Source Image 轮廓(带源图像)
|
||||
Source Image 源图像
|
||||
Press and hold to view the source image 按住以查看源图像
|
||||
Image Trace View 图像描摹视图
|
||||
Snap Options 对齐选项
|
||||
Snap to Glyph 靠齐字符
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3878,6 +3878,7 @@ font-script Japanese 漢字
|
||||
Outlines 外框
|
||||
Outlines with Source Image 外框(含來源影像)
|
||||
Source Image 來源影像
|
||||
Press and hold to view the source image 按住以檢視來源影像
|
||||
Image Trace View 影像描圖檢視
|
||||
Snap Options 靠齊選項
|
||||
Snap to Glyph 靠齊字符
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -430,6 +430,9 @@ pub struct CacheKey {
|
||||
pub rich_black: bool,
|
||||
/// Colour and style of guide paths ([`vectorcraft_render::RenderOptions::guide`]).
|
||||
pub guide: ([u8; 3], bool),
|
||||
/// The Image Trace objects drawn with their source image
|
||||
/// ([`vectorcraft_render::RenderOptions::trace_source`]).
|
||||
pub trace_source: Option<std::sync::Arc<Vec<vectorcraft_doc::NodeId>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
|
||||
@@ -135,6 +135,25 @@ fn set_view(app: &mut VectorcraftApp, view: TraceView) {
|
||||
}
|
||||
}
|
||||
|
||||
/// While `down`, the selected Image Trace objects show their source image on the canvas, whatever
|
||||
/// their View. The document and the undo history stay as they are. The panel's eye button next to
|
||||
/// View calls it; per the public documentation of the panel, that control is pressed and held to
|
||||
/// view the source image
|
||||
/// (<https://web.archive.org/web/20250831090623/https://helpx.adobe.com/illustrator/using/image-trace.html>).
|
||||
fn hold_source(app: &mut VectorcraftApp, ctx: &egui::Context, down: bool) {
|
||||
let ids = app
|
||||
.session
|
||||
.active()
|
||||
.filter(|_| down)
|
||||
.map(|st| st.selection.objects.iter().copied().filter(|id| st.doc.node(*id).is_some_and(is_trace)).collect::<Vec<_>>())
|
||||
.filter(|ids| !ids.is_empty())
|
||||
.map(std::sync::Arc::new);
|
||||
if ids != app.ui.trace_hold_source {
|
||||
app.ui.trace_hold_source = ids;
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/// The selected Image Trace object's View row (Control bar, Properties).
|
||||
pub(crate) fn view_row(app: &mut VectorcraftApp, ui: &mut Ui, current: TraceView, width: f32) {
|
||||
widgets::dim_label(ui, tl!("View:"));
|
||||
@@ -295,12 +314,19 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
widgets::dim_label(ui, tl!("View:"));
|
||||
if let Some(v) = view_dropdown(ui, st.view, 170.0) {
|
||||
let eye = 24.0;
|
||||
if let Some(v) = view_dropdown(ui, st.view, (ui.available_width() - eye - ui.spacing().item_spacing.x).min(170.0)) {
|
||||
st.view = v;
|
||||
if is_trace {
|
||||
set_view(app, v);
|
||||
}
|
||||
}
|
||||
let held = app.ui.trace_hold_source.is_some();
|
||||
let r = widgets::icon_button_enabled(ui, "eye", tl!("Press and hold to view the source image"), held, is_trace, eye);
|
||||
if cfg!(test) {
|
||||
ui.ctx().data_mut(|d| d.insert_temp(egui::Id::new("trace-hold-source"), r.rect));
|
||||
}
|
||||
hold_source(app, ui.ctx(), is_trace && r.is_pointer_button_down_on());
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
widgets::dim_label(ui, tl!("Mode:"));
|
||||
@@ -837,6 +863,39 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// Holding the eye button next to View down lists the selected Image Trace object for the
|
||||
/// canvas to draw with its source image; releasing it shows the object's View again. The
|
||||
/// document, its View and the undo history stay as they were. With a plain image selected the
|
||||
/// button is disabled.
|
||||
#[test]
|
||||
fn holding_the_eye_button_shows_the_source_image_until_released() {
|
||||
let mut app = traced_app();
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
frame(&mut app, &ctx, vec![]);
|
||||
let id = first_selected(&app).unwrap().id;
|
||||
let undo = |app: &VectorcraftApp| app.session.active().unwrap().history.undo.len();
|
||||
let revision = |app: &VectorcraftApp| app.session.active().unwrap().revision;
|
||||
let (steps, rev) = (undo(&app), revision(&app));
|
||||
let at = ctx.data(|d| d.get_temp::<Rect>(egui::Id::new("trace-hold-source"))).unwrap().center();
|
||||
let press = |pressed| Event::PointerButton { pos: at, button: PointerButton::Primary, pressed, modifiers: Default::default() };
|
||||
frame(&mut app, &ctx, vec![Event::PointerMoved(at), press(true)]);
|
||||
assert_eq!(app.ui.trace_hold_source.as_deref(), Some(&vec![id]), "held: the object shows its source image");
|
||||
frame(&mut app, &ctx, vec![]);
|
||||
assert!(app.ui.trace_hold_source.is_some(), "still held on the next frame");
|
||||
frame(&mut app, &ctx, vec![press(false)]);
|
||||
assert_eq!(app.ui.trace_hold_source, None, "released: the object shows its View again");
|
||||
assert_eq!(undo(&app), steps, "no undo step");
|
||||
assert_eq!(revision(&app), rev, "the document is unchanged");
|
||||
assert_eq!(selected_trace(&app).map(|t| t.1), Some(TraceView::Result), "its View is unchanged");
|
||||
app.run("imageTrace.release", json!({})).unwrap();
|
||||
assert!(matches!(first_selected(&app).unwrap().kind, NodeKind::Image(_)));
|
||||
frame(&mut app, &ctx, vec![]);
|
||||
frame(&mut app, &ctx, vec![Event::PointerMoved(at), press(true)]);
|
||||
assert_eq!(app.ui.trace_hold_source, None, "a plain image has no source image to show");
|
||||
frame(&mut app, &ctx, vec![press(false)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn properties_can_reopen_the_trace_controls() {
|
||||
let mut app = traced_app();
|
||||
|
||||
@@ -549,6 +549,10 @@ pub struct UiState {
|
||||
/// becoming active, leaves it.
|
||||
#[serde(skip)]
|
||||
pub home: Option<(Option<u64>, usize)>,
|
||||
/// The Image Trace objects the canvas draws with the Source Image view while the Image Trace
|
||||
/// panel's eye button is held down ([`vectorcraft_render::RenderOptions::trace_source`]).
|
||||
#[serde(skip)]
|
||||
pub trace_hold_source: Option<std::sync::Arc<Vec<vectorcraft_doc::NodeId>>>,
|
||||
/// Layers panel › Panel Options… (row size, thumbnails, Show Layers Only, Locate Selected Objects).
|
||||
#[serde(default)]
|
||||
pub layers_panel: crate::panels::layers::PanelOptions,
|
||||
@@ -902,6 +906,7 @@ impl Default for UiState {
|
||||
move_options: Value::Null,
|
||||
dxf_import: Value::Null,
|
||||
home: None,
|
||||
trace_hold_source: None,
|
||||
layers_panel: Default::default(),
|
||||
layers_filter: Default::default(),
|
||||
image_trace_advanced: true,
|
||||
|
||||
@@ -788,6 +788,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Image Trace, thin closed outlines:** generated `fit::snap_area_tests` verify nonzero interiors after straightening, opposite closed-boundary winding and Noise controls; see [quality notes](image-trace-quality.md#thin-closed-outlines-with-snap-curves-to-lines). Scores and hours unchanged; open-piece fitting is unchanged.
|
||||
- **Image Trace, flattened slivers:** in a Color, Grayscale or Black and White trace with Fills, a traced region whose outline straightens onto one line (a single pixel, or a one-pixel row along an edge, its pieces shared with the regions beside it) is left out instead of becoming a selectable path with no area, which paints nothing. Snap Curves To Lines straightens more outlines, so it leaves out more of these. Without Fills, the region's 1 px stroke draws it, and it is kept. Code-drawn tests in `crates/trace`.
|
||||
- **Image Trace, Auto Color rare colours:** the Automatic palette keeps colours too rare for its area count when they are distinct (Oklab) and drawn as coherent regions, at most six, protected from mixed-colour merging and Noise; code-drawn stem, highlight, low-contrast and scattered-noise tests (see [quality notes](image-trace-quality.md#auto-color-keeps-rare-colours)).
|
||||
- **Image Trace, source image on hold:** while the eye button next to the Image Trace panel's View is held down, the canvas shows the selected Image Trace objects' source image whatever their View, and shows their View again on release, with no change to the document or the undo history.
|
||||
- **Image Trace, large images:** images over 1500 px on a side trace with a warning in the result and the status bar; the anchor limit is 8,000,000 (2,000,000 on the web), measured at about 90 bytes an anchor (see [quality notes](image-trace-quality.md#large-images)).
|
||||
- **Image Trace, Preview:** the Image Trace panel's Preview checkbox, before Trace, is on by default, and a setting change traces the selected Image Trace object again at once. Off, changes wait in the panel until Trace applies them as one undo step, or until Preview is turned on again. Preview is kept with the UI preferences, and Reset to Default leaves it.
|
||||
- **Image Trace small contours:** closed fits too small to form an editable subpath retain their positioned outline, including holes. Source-generated island, hole/winding and stepped-region regressions cover Corners and Noise; defaults, parity scores and estimates are unchanged.
|
||||
|
||||
@@ -274,6 +274,7 @@ empty), without opening the dialog.
|
||||
| Panels outside the app window (another monitor) | missing | single OS window |
|
||||
| Edit Toolbar (•••): the All Tools drawer opens beside the toolbar by its button (Escape or a click outside closes it), dims the tools already in the toolbar; while it is open, tools drag from it onto the toolbar (between two tools, or onto one to join its group), from the toolbar into it, and within the toolbar; each toolbar keeps its edits | done | #1018; `window.editToolbar`, `toolbar.addTool`/`removeTool`/`reset`; the drawer's Reset (Illustrator has it in a drawer menu); dragging a toolbar button moves the tool it shows, not its whole group; New/Manage Toolbars missing; tool flyouts are as wide as their longest translated name and shortcut need (#1616) |
|
||||
| Quick Image Trace presets trace at once and leave the panel as it was; the Image Trace button (Control bar, Properties) opens the editable controls | done | Per the public documentation, choosing a preset traces the image with it straight away, and the panel is opened with the Image Trace button in the Control panel or in Properties' Image Trace section (<https://helpx.adobe.com/illustrator/using/image-trace-results-optimization.html>). The controls show Threshold, Paths, Corners and Noise with Advanced open; `panels/image_trace.rs` headless tests (`a_quick_trace_leaves_the_panel_as_it_was`, `sketch_quick_trace_reveals_all_adjustments_and_keeps_the_source` for the button's route). No algorithm parity claim. |
|
||||
| Image Trace panel: holding the eye button next to View down shows the selected Image Trace objects' source image on the canvas | done | Per the public documentation, the control next to View is pressed and held to compare the trace result with the source image (<https://web.archive.org/web/20250831090623/https://helpx.adobe.com/illustrator/using/image-trace.html>). On release the objects show their View again; the document, its View and the undo history are unchanged. `RenderOptions::trace_source`; `panels/image_trace.rs` headless test `holding_the_eye_button_shows_the_source_image_until_released`, render test `trace_source_draws_the_source_image_of_the_listed_objects`. The Control bar and Properties have no such button |
|
||||
| Live trace result bounds and selection highlights exclude the retained bitmap; source-image views retain it | done | All TraceView modes and rotated result bounds regression-covered; ordinary hidden group behavior retained |
|
||||
| Image Trace panel: the Preview checkbox before Trace chooses whether a setting change traces the selected Image Trace object again at once | done | Per the public documentation, Preview shows the result of the current settings and Trace traces with them (<https://web.archive.org/web/20250831090623/https://helpx.adobe.com/illustrator/using/image-trace.html>). Preview is on by default and kept with the UI preferences; Reset to Default leaves it. Off, changes wait in the panel until Trace applies them as one undo step, or until Preview is turned on again. `ui.set {imageTracePreview}`; `panels/image_trace.rs` headless tests (`with_preview_off_a_slider_change_waits_for_trace`, `turning_preview_on_traces_the_changes_that_waited`, `preview_turned_on_with_nothing_selected_traces_when_the_object_is_selected_again`, `settings_that_wait_stay_with_their_object`, `preview_is_kept_with_the_preferences_and_reset_to_default_leaves_it`) |
|
||||
| Toolbar without group labels by default, one or two columns; All Tools drawer by flyout group with shortcuts, its menu (Reset, Basic, Advanced) and Show section | done | #1751; a preference brings the labels back; `toolbar.show` sets the Fill/Stroke, Coloring, Draw Mode and Screen Mode controls |
|
||||
|
||||
Reference in New Issue
Block a user