mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-26 19:36:46 -06:00
Merge branch 'pr-495' into batch/t5
# Conflicts: # contributors/people.toml
This commit is contained in:
+13
-2
@@ -665,8 +665,19 @@ fn screenshot(b: &mut dyn Backend, a: &Map<String, Value>) -> Result<ToolResult,
|
||||
let side = (x1 - x0).max(y1 - y0).max(1e-6);
|
||||
scale = scale.min(max / side);
|
||||
}
|
||||
let bytes = b.render_png(&ids, scale)?;
|
||||
let (w, h) = png_info(&bytes);
|
||||
let mut bytes = b.render_png(&ids, scale)?;
|
||||
let (mut w, mut h) = png_info(&bytes);
|
||||
// Layer bounds leave out effects (shadows) and overflow of unclipped frames, but the render
|
||||
// includes them: shrink to the measured image until it fits `maxSize` (rounding can add a pixel).
|
||||
for _ in 0..4 {
|
||||
let side = f64::from(w.max(h));
|
||||
if side <= max {
|
||||
break;
|
||||
}
|
||||
scale *= max / side;
|
||||
bytes = b.render_png(&ids, scale)?;
|
||||
(w, h) = png_info(&bytes);
|
||||
}
|
||||
Ok(ToolResult::image(
|
||||
&bytes,
|
||||
"image/png",
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//! `screenshot` with `ids` must honour `maxSize` for the rendered paint area (shadows, overflow).
|
||||
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
||||
mod common;
|
||||
use common::{Client, png_dims};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
fn dimensions(client: &mut Client, args: Value) -> (u32, u32) {
|
||||
let result = client.call("screenshot", args);
|
||||
assert_eq!(result["isError"], false, "{result}");
|
||||
let size = png_dims(result["content"][0]["data"].as_str().unwrap());
|
||||
let meta: Value = serde_json::from_str(result["content"][1]["text"].as_str().unwrap()).unwrap();
|
||||
assert_eq!(meta["width"], size.0, "{meta}");
|
||||
assert_eq!(meta["height"], size.1, "{meta}");
|
||||
size
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layer_screenshots_fit_the_requested_size() {
|
||||
let mut shadow_client = Client::new();
|
||||
let shadow = shadow_client.create(json!({
|
||||
"type": "rectangle", "x": 0, "y": 0,
|
||||
"width": 100, "height": 100,
|
||||
"props": {"effects": [{
|
||||
"type": "dropShadow", "color": "#00000080",
|
||||
"offset": [0, 40], "radius": 60
|
||||
}]}
|
||||
}));
|
||||
let shadow_size = dimensions(&mut shadow_client, json!({"ids": [shadow], "maxSize": 100}));
|
||||
|
||||
let mut frame_client = Client::new();
|
||||
let frame = frame_client.create(json!({
|
||||
"type": "frame", "x": 0, "y": 0,
|
||||
"width": 100, "height": 100, "props": {"clip": false}
|
||||
}));
|
||||
frame_client.create(json!({
|
||||
"type": "rectangle", "parent": frame,
|
||||
"x": 900, "y": 900, "width": 100, "height": 100
|
||||
}));
|
||||
let frame_size = dimensions(&mut frame_client, json!({"ids": [frame], "maxSize": 100}));
|
||||
|
||||
assert!(shadow_size.0 <= 100 && shadow_size.1 <= 100, "shadow screenshot exceeds maxSize: {shadow_size:?}");
|
||||
assert!(shadow_size.0 >= 90 && shadow_size.1 >= 90, "shadow screenshot shrank too far: {shadow_size:?}");
|
||||
assert!(frame_size.0 <= 100 && frame_size.1 <= 100, "frame screenshot exceeds maxSize: {frame_size:?}");
|
||||
assert!(frame_size.0 >= 90 && frame_size.1 >= 90, "frame screenshot shrank too far: {frame_size:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plain_layer_screenshot_sizes_are_unchanged() {
|
||||
let mut client = Client::new();
|
||||
let rect = client.create(json!({"type": "rectangle", "x": 0, "y": 0, "width": 100, "height": 100}));
|
||||
assert_eq!(dimensions(&mut client, json!({"ids": [rect], "maxSize": 100})), (100, 100));
|
||||
assert_eq!(dimensions(&mut client, json!({"ids": [rect], "scale": 2})), (200, 200));
|
||||
}
|
||||
Reference in New Issue
Block a user