Merge pull request #4915 from dotCooCoo/fix/issue-3602

Part of #3602: a node thumbnail reports the size it is drawn at
This commit is contained in:
BFlat
2026-10-31 23:47:40 +07:00
committed by GitHub
2 changed files with 20 additions and 3 deletions
+4 -3
View File
@@ -347,9 +347,10 @@ impl Renderer {
self.check_plugins();
self.check_symbols(doc);
let b = brush_fx::cull_bounds(&doc.symbol_boxes(), n)?;
let s = (size as f64 - 2.0) / b.width().max(b.height()).max(1e-6);
let view = Affine::translate((size as f64 / 2.0, size as f64 / 2.0)) * Affine::scale(s) * Affine::translate(-b.center().to_vec2());
let w = size.clamp(1, MAX_CONTEXT_SIDE) as u16;
// A 1-pixel margin on each side, unless the thumbnail is too small to keep one.
let s = (w as f64 - 2.0).max(1.0) / b.width().max(b.height()).max(1e-6);
let view = Affine::translate((w as f64 / 2.0, w as f64 / 2.0)) * Affine::scale(s) * Affine::translate(-b.center().to_vec2());
let mut ctx = single_threaded_context(w, w);
if let Some(bg) = background {
ctx.set_paint(peniko::Color::from_rgba8(bg[0], bg[1], bg[2], bg[3]));
@@ -364,6 +365,6 @@ impl Renderer {
self.draw_forced_arc(&mut ctx, &frame, &Arc::new(n.clone()));
let pm = self.finish(&mut ctx, vello_cpu::RasterizerSettings::default());
self.end_frame();
Some(Rendered { width: size, height: size, pixels: pm.data_as_u8_slice().to_vec() })
Some(Rendered { width: w as u32, height: w as u32, pixels: pm.data_as_u8_slice().to_vec() })
}
}
+16
View File
@@ -869,6 +869,22 @@ fn node_thumbnail_applies_the_root_mask() {
assert_eq!(img.pixel(75, 50), [255, 255, 255, 255]);
}
/// #3602: a thumbnail reports the size it was drawn at, and one too small for its 1-pixel margin
/// still draws the art.
#[test]
fn node_thumbnail_reports_the_size_it_draws() {
let mut d = Document::new(100.0, 100.0);
let node = rect_node(&mut d, Rect::new(10.0, 10.0, 90.0, 90.0), Paint::solid(Color::rgb(1.0, 0.0, 0.0)), Paint::None, 0.0);
let mut r = Renderer::new();
for size in 0..4 {
let img = r.render_node_thumbnail(&d, &node, size, None).unwrap();
assert_eq!(img.pixels.len(), img.width as usize * img.height as usize * 4, "size {size}");
assert_eq!(img.width, size.max(1), "size {size}");
assert_eq!(img.height, size.max(1), "size {size}");
assert!(img.pixels.chunks(4).any(|p| p[3] > 0), "size {size}: the art is drawn");
}
}
#[test]
fn opacity_mask_with_undecodable_image_leaves_out_object() {
use vectorcraft_doc::{Effect, ImageBlob, ImageObject, NodeKind, OpacityMask};