mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-24 10:27:00 -06:00
Keep hidden export roots from enlarging the exported image
Fixes #447 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
8482c3e85b
commit
dee13aefc5
@@ -765,12 +765,21 @@ pub fn export_bytes(doc: &Document, ids: &[NodeId], format: ExportFormat, scale:
|
||||
}
|
||||
|
||||
/// The page area exporting `ids` with `setting` covers: what they paint (a clipping frame's own
|
||||
/// area), or their boxes with "include bounding box" and for slices.
|
||||
/// area), or their boxes with "include bounding box" and for slices. Hidden layers paint nothing,
|
||||
/// so they take no room next to visible ones (a hidden-only export keeps its own area).
|
||||
pub fn export_area(doc: &Document, ids: &[NodeId], setting: &ExportSetting) -> Option<figcraft_geom::Rect> {
|
||||
let any_visible = ids.iter().any(|i| doc.node(*i).is_some_and(|n| n.visible));
|
||||
ids.iter()
|
||||
.filter_map(|i| {
|
||||
let slice = doc.node(*i).is_some_and(|n| matches!(n.kind, NodeKind::Slice));
|
||||
if setting.include_bounding_box || slice { doc.world_bounds(*i) } else { figcraft_render::export_bounds(doc, *i) }
|
||||
let node = doc.node(*i);
|
||||
let slice = node.is_some_and(|n| matches!(n.kind, NodeKind::Slice));
|
||||
if setting.include_bounding_box || slice {
|
||||
doc.world_bounds(*i)
|
||||
} else if any_visible && node.is_some_and(|n| !n.visible) {
|
||||
None
|
||||
} else {
|
||||
figcraft_render::export_bounds(doc, *i)
|
||||
}
|
||||
})
|
||||
.reduce(|a, b| a.union(b))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//! Hidden top-level layers in an export take no room in the image (issue #447).
|
||||
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
|
||||
mod common;
|
||||
|
||||
use common::{Client, png_dims};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
fn dimensions(result: Value) -> (u32, u32) {
|
||||
assert_eq!(result["isError"], false, "{result}");
|
||||
let image = result["content"].as_array().unwrap().iter().find(|block| block["type"] == "image").unwrap();
|
||||
png_dims(image["data"].as_str().unwrap())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hidden_root_does_not_expand_export() {
|
||||
let mut client = Client::new();
|
||||
let visible = client.create(json!({
|
||||
"type":"frame", "x":0, "y":0, "width":100, "height":100,
|
||||
"props":{"fill":"#FF0000"}
|
||||
}));
|
||||
let hidden = client.create(json!({
|
||||
"type":"frame", "x":900, "y":0, "width":300, "height":300,
|
||||
"props":{"visible":false}
|
||||
}));
|
||||
assert_eq!(client.node(&hidden)["visible"], false);
|
||||
|
||||
let control = dimensions(client.call("export", json!({"ids":[visible], "format":"png", "size":"200w"})));
|
||||
assert_eq!(control, (200, 200));
|
||||
let mixed = dimensions(client.call("export", json!({"ids":[visible, hidden], "format":"png", "size":"200w"})));
|
||||
assert_eq!(mixed, control, "hidden roots must not enlarge the painted area");
|
||||
let natural = dimensions(client.call("export", json!({"ids":[visible, hidden], "format":"png"})));
|
||||
assert_eq!(natural, (100, 100));
|
||||
|
||||
client.ok("select", json!({"ids":[visible, hidden]}));
|
||||
let selected = dimensions(client.call("export", json!({"format":"png", "size":"200w"})));
|
||||
assert_eq!(selected, (200, 200));
|
||||
client.ok("select", json!({"ids":[]}));
|
||||
let page = dimensions(client.call("export", json!({"format":"png"})));
|
||||
assert_eq!(page, (100, 100));
|
||||
|
||||
// Controls: the bounding-box option and a hidden-only export keep their areas.
|
||||
let boxed = dimensions(client.call("export", json!({"ids":[visible, hidden], "format":"png", "includeBoundingBox":true})));
|
||||
assert_eq!(boxed, (1200, 300));
|
||||
let alone = dimensions(client.call("export", json!({"ids":[hidden], "format":"png"})));
|
||||
assert_eq!(alone, (300, 300));
|
||||
}
|
||||
Reference in New Issue
Block a user