Place: an image placed into a frame leaves Auto-Fit off (#528)

* Place: an image placed into a frame fills it once and leaves Auto-Fit off

* Place: the fitting test names its fitting, since a placed image no longer auto-fits
This commit is contained in:
aiongg 2026-10-11 20:49:56 -04:00 committed by GitHub
parent 597f0e649f
commit ca1a8a12bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 6 deletions

View File

@ -351,14 +351,14 @@ fn file_place(s: &mut Session, p: &Value) -> Result<Value> {
let id = if let Some(fid) = target_frame {
let it = d.item_mut(fid).ok_or(designcraft_doc::DocError::NoItem(fid))?;
let r = it.inner_bounds();
// Fill frame proportionally.
// Fill the frame proportionally once. Auto-Fit stays off, so resizing the frame crops.
let k = (r.width() / nw).max(r.height() / nh);
let (gw, gh) = (nw * k, nh * k);
it.content = Content::Graphic(Graphic {
asset: aid,
size: (nw, nh),
xf: Affine::translate((r.x0 + (r.width() - gw) / 2.0, r.y0 + (r.height() - gh) / 2.0)) * Affine::scale(k),
auto_fit: designcraft_doc::Fitting::FillProportionally,
auto_fit: Default::default(),
fit_align: 4,
crop: [0.0; 4],
});
@ -473,7 +473,7 @@ fn place_drop(s: &mut Session, p: &Value) -> Result<Value> {
asset: aid,
size: (nw, nh),
xf: Affine::translate((r.x0 + (r.width() - nw * k) / 2.0, r.y0 + (r.height() - nh * k) / 2.0)) * Affine::scale(k),
auto_fit: designcraft_doc::Fitting::FillProportionally,
auto_fit: Default::default(),
fit_align: 4,
crop: [0.0; 4],
});

View File

@ -2463,8 +2463,8 @@ mod fitting_tests {
s.execute("object.fittingOptions", &json!({"ids": [f], "fitting": "fitProportionally", "align": 0})).unwrap();
let c = content(&s);
assert!((c.x0 - 100.0).abs() < 1e-6 && (c.y0 - 100.0).abs() < 1e-6 && (c.width() - 200.0).abs() < 1e-6, "{c:?}");
// Crop 10 pt on every side: the content spreads past the frame.
s.execute("object.fittingOptions", &json!({"ids": [f], "crop": 10, "align": 4})).unwrap();
// Crop 10 pt on every side and fit again: the content spreads past the frame.
s.execute("object.fittingOptions", &json!({"ids": [f], "fitting": "fitProportionally", "crop": 10, "align": 4})).unwrap();
let c = content(&s);
assert!((c.width() - 220.0).abs() < 1e-6, "{c:?}");
// Auto-fit: resizing the frame refits the content.

View File

@ -284,7 +284,15 @@ fn place_gun_click_drag_and_into_frame() {
let f = s.execute("frame.create", &json!({"rect": [300, 300, 400, 400], "content": "graphic"})).unwrap()["id"].as_u64().unwrap();
s.execute("place.load", &json!({"base64": b64})).unwrap();
s.execute("place.drop", &json!({"frame": f})).unwrap();
assert!(matches!(s.doc().unwrap().doc.item(designcraft_doc::ItemId(f)).unwrap().content, designcraft_doc::Content::Graphic(_)));
let graphic_xf = |s: &Session| match &s.doc().unwrap().doc.item(designcraft_doc::ItemId(f)).unwrap().content {
designcraft_doc::Content::Graphic(g) => g.xf,
_ => panic!("not a graphic"),
};
let placed = graphic_xf(&s);
// Dragging the top edge down crops the top only: the image stays where it is.
s.execute("selection.set", &json!({"ids": [f]})).unwrap();
s.execute("transform.resize", &json!({"from": [300, 300, 400, 400], "to": [300, 340, 400, 400]})).unwrap();
assert_eq!(graphic_xf(&s), placed);
}
#[test]