mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 08:20:13 +00:00
A linked image (`ImageObject.link`, now a LinkInfo: absolute path, path relative to the document, size, modification time, hash, page; old path strings still load) keeps a low-resolution preview (`ImageBlob.proxy`, at most 256 px a side) that a native save writes in place of the pixels of images only linked images show. Opening a native document reads the linked files again, looking for each at its path, then relative to the document and by name in its folder: missing files show their preview, modified ones are read again only with Update Links: Automatically. `document.open` reports `missingLinks`, `modifiedLinks` and `updatedLinks`. links.check reports each link's status, links.update reads modified files again and links.relink points images at another file or at same-named files in a folder (each keeps its bounds; one undo step). In the app, a document opened without its linked files asks about each (Replace…, Ignore, Apply to All), then offers to update modified links when the preference asks. The renderer caches previews apart from the file's pixels; the Eyedropper samples previews in the object's pixel space. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.4 KiB
Rust
32 lines
1.4 KiB
Rust
//! Document Setup options the renderer honours.
|
||
|
||
use vectorcraft_doc::{Document, ImageBlob, ImageObject, Node, NodeKind};
|
||
|
||
use super::*;
|
||
|
||
fn doc_with_red_image() -> Document {
|
||
let mut d = Document::new(40.0, 40.0);
|
||
let mut png = Vec::new();
|
||
image::RgbaImage::from_pixel(4, 4, image::Rgba([255, 0, 0, 255])).write_to(&mut std::io::Cursor::new(&mut png), image::ImageFormat::Png).unwrap();
|
||
d.images.insert("red".into(), ImageBlob::new("image/png", png));
|
||
let (id, layer) = (d.alloc_id(), d.layers[0].id);
|
||
let im = ImageObject { key: "red".into(), width: 40, height: 40, xf: Affine::IDENTITY, link: None };
|
||
d.insert(Some(layer), 0, Node::new(id, NodeKind::Image(im))).unwrap();
|
||
d
|
||
}
|
||
|
||
#[test]
|
||
fn outline_mode_draws_images_in_grey_only_when_the_setup_asks() {
|
||
let mut d = doc_with_red_image();
|
||
let outline = RenderOptions { outline: true, ..Default::default() };
|
||
let centre = |d: &Document| Renderer::new().render(d, 40, 40, Affine::IDENTITY, &outline).pixel(20, 20);
|
||
assert_eq!(centre(&d)[3], 0, "outline mode draws only the image frame");
|
||
d.setup.outline_images = true;
|
||
let [r, g, b, a] = centre(&d);
|
||
// Red's luma (0.2126 × 255 ≈ 54) in every channel.
|
||
assert_eq!(a, 255);
|
||
assert!(r == g && g == b && (50..=58).contains(&r), "{:?}", [r, g, b]);
|
||
// Preview mode keeps the colours.
|
||
assert_eq!(Renderer::new().render(&d, 40, 40, Affine::IDENTITY, &RenderOptions::default()).pixel(20, 20), [255, 0, 0, 255]);
|
||
}
|