mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
Images: declare a graphic's clipping path beside its transform
This commit is contained in:
@@ -243,10 +243,10 @@ pub fn synthetic(spec: &Spec) -> Result<Document, String> {
|
||||
asset,
|
||||
size: (nw, nh),
|
||||
xf: Affine::translate((r.x0 + (r.width() - nw * s) / 2.0, r.y0 + (r.height() - nh * s) / 2.0)) * Affine::scale(s),
|
||||
clip: None,
|
||||
auto_fit: designcraft_doc::Fitting::FillProportionally,
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
if k == 0 && pi == 0 {
|
||||
it.effects.drop_shadow.on = true;
|
||||
|
||||
@@ -286,10 +286,10 @@ mod tests {
|
||||
asset: AssetId(asset),
|
||||
size: (10.0, 10.0),
|
||||
xf: Affine::translate((crop, 0.0)),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [crop; 4],
|
||||
clip: None,
|
||||
});
|
||||
it
|
||||
}
|
||||
|
||||
@@ -447,6 +447,9 @@ pub struct Graphic {
|
||||
pub size: (f64, f64),
|
||||
/// Graphic space (0,0)-(w,h) → frame inner space.
|
||||
pub xf: Affine,
|
||||
/// Clipping path: only the part of the graphic inside it shows.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub clip: Option<Arc<ClippingPath>>,
|
||||
#[serde(default)]
|
||||
pub auto_fit: Fitting,
|
||||
/// Frame Fitting Options › Align From: the reference point (0–8, row-major; 4 = centre).
|
||||
@@ -455,9 +458,6 @@ pub struct Graphic {
|
||||
/// Frame Fitting Options › Crop Amount: top, left, bottom, right (negative adds space).
|
||||
#[serde(default)]
|
||||
pub crop: [f64; 4],
|
||||
/// Clipping path: only the part of the graphic inside it shows.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub clip: Option<Arc<ClippingPath>>,
|
||||
}
|
||||
|
||||
fn center_ref() -> u8 {
|
||||
@@ -1305,10 +1305,10 @@ mod tests {
|
||||
asset: AssetId(3),
|
||||
size: (40.0, 30.0),
|
||||
xf: Affine::translate((5.0, 5.0)),
|
||||
clip: None,
|
||||
auto_fit: Fitting::None,
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
};
|
||||
let v = serde_json::to_value(&g).unwrap();
|
||||
assert!(v.get("clip").is_none(), "{v}");
|
||||
|
||||
@@ -264,10 +264,10 @@ fn flatten(d: &designcraft_doc::Document, cache: &designcraft_compose::Cache, pp
|
||||
size: (w as f64, h as f64),
|
||||
xf: designcraft_geom::Affine::translate((r.x0, r.y0))
|
||||
* designcraft_geom::Affine::scale_non_uniform(r.width() / w as f64, r.height() / h as f64),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
it.stroke.weight = 0.0;
|
||||
it
|
||||
@@ -430,10 +430,10 @@ fn rasterize_where(
|
||||
asset: aid,
|
||||
size: (w as f64, h as f64),
|
||||
xf: designcraft_geom::Affine::translate((reach.x0, reach.y0)) * designcraft_geom::Affine::scale(1.0 / k),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
img_item.stroke.weight = 0.0;
|
||||
img_item.alt_text = it.alt_text.clone();
|
||||
|
||||
@@ -358,10 +358,10 @@ fn file_place(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
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),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
fid
|
||||
} else {
|
||||
@@ -377,10 +377,10 @@ fn file_place(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
asset: aid,
|
||||
size: (nw, nh),
|
||||
xf: Affine::translate((x - bx * k, y - by * k)) * Affine::scale(k),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(spread, it, None)?;
|
||||
id
|
||||
@@ -471,10 +471,10 @@ 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),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
fid
|
||||
}
|
||||
@@ -494,10 +494,10 @@ fn place_drop(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
asset: aid,
|
||||
size: (nw, nh),
|
||||
xf: Affine::translate((frame_r.x0, frame_r.y0)) * Affine::scale(k),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(sr, it, None)?;
|
||||
id
|
||||
|
||||
@@ -417,10 +417,10 @@ mod shared_asset_tests {
|
||||
asset: sid,
|
||||
size: (4.0, 4.0),
|
||||
xf: designcraft_geom::Affine::IDENTITY,
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [1.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
src.insert_item(SpreadRef::Doc(0), it, None).unwrap();
|
||||
let ids = super::super::object::duplicate_from(&mut dst, &src, &[iid], SpreadRef::Doc(0), designcraft_geom::Vec2::ZERO).unwrap();
|
||||
|
||||
@@ -30,10 +30,10 @@ fn math_item(d: &mut designcraft_doc::Document, latex: &str, size: f64, lid: des
|
||||
asset: aid,
|
||||
size: (w, h),
|
||||
xf: Affine::translate(at),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
it.alt_text = latex.to_string();
|
||||
it.name = "Math".into();
|
||||
|
||||
@@ -35,10 +35,10 @@ pub(crate) fn place_media(s: &mut Session, p: &Value, name: String, mime: &str,
|
||||
asset: aid,
|
||||
size: (r.width(), r.height()),
|
||||
xf: Affine::translate((r.x0, r.y0)),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
it.media = Some(MediaOptions { controls: true, ..Default::default() });
|
||||
fid
|
||||
@@ -52,10 +52,10 @@ pub(crate) fn place_media(s: &mut Session, p: &Value, name: String, mime: &str,
|
||||
asset: aid,
|
||||
size: (w, h),
|
||||
xf: Affine::translate((x, y)),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
it.media = Some(MediaOptions { controls: true, ..Default::default() });
|
||||
d.insert_item(spread, it, None)?;
|
||||
|
||||
@@ -1423,10 +1423,10 @@ fn place_graphic(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
asset: aid,
|
||||
size: (nw, nh),
|
||||
xf,
|
||||
clip: None,
|
||||
auto_fit: if fill { designcraft_doc::Fitting::FillProportionally } else { designcraft_doc::Fitting::FitProportionally },
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
clamp_selection(d, sel);
|
||||
Ok(json!({"asset": aid.0, "row": r, "col": c}))
|
||||
|
||||
@@ -82,10 +82,10 @@ fn graphic_frame(d: &mut Document, sr: SpreadRef, r: Rect, asset: AssetId, px: (
|
||||
asset,
|
||||
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),
|
||||
clip: None,
|
||||
auto_fit: designcraft_doc::Fitting::FillProportionally,
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
it.object_style = designcraft_doc::BASIC_GRAPHICS_FRAME.into();
|
||||
d.insert_item(sr, it, None)?;
|
||||
|
||||
@@ -847,10 +847,10 @@ mod tests {
|
||||
asset: aid,
|
||||
size: (1.0, 1.0),
|
||||
xf: Affine::IDENTITY,
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(SpreadRef::Doc(0), item, None).unwrap();
|
||||
|
||||
|
||||
@@ -248,10 +248,10 @@ mod tests {
|
||||
asset,
|
||||
size: (1.0, 1.0),
|
||||
xf: Affine::translate((crop, crop)),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [crop; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(SpreadRef::Doc(0), it, None).unwrap();
|
||||
id
|
||||
|
||||
@@ -2276,10 +2276,10 @@ impl<'r> Importer<'r> {
|
||||
asset,
|
||||
size,
|
||||
xf: gxf * Affine::translate((l, t)),
|
||||
clip: clip.clone(),
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: clip.clone(),
|
||||
})
|
||||
};
|
||||
let mut data = g.prop_el("Contents").map(|c| base64_decode(&c.text_content())).unwrap_or_default();
|
||||
|
||||
@@ -477,10 +477,10 @@ mod tests {
|
||||
asset,
|
||||
size,
|
||||
xf: Affine::translate(at) * Affine::scale(100.0 / size.0),
|
||||
clip: None,
|
||||
auto_fit: Fitting::FillProportionally,
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(SpreadRef::Doc(0), it, None).unwrap();
|
||||
}
|
||||
|
||||
@@ -233,10 +233,10 @@ fn place(d: &mut Document, data: Vec<u8>, px: (u32, u32)) {
|
||||
asset,
|
||||
size: (px.0 as f64, px.1 as f64),
|
||||
xf: designcraft_geom::Affine::translate((72.0, 72.0)) * designcraft_geom::Affine::scale(50.0),
|
||||
clip: None,
|
||||
auto_fit: designcraft_doc::Fitting::FillProportionally,
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(SpreadRef::Doc(0), it, None).unwrap();
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ fn place_named(d: &mut Document, data: Vec<u8>, x: f64, name: &str, mime: &str,
|
||||
asset: aid,
|
||||
size: (20.0, 20.0),
|
||||
xf: Affine::translate((x, 36.0)),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(SpreadRef::Doc(0), item, None).unwrap();
|
||||
}
|
||||
|
||||
@@ -1469,10 +1469,10 @@ mod tests {
|
||||
asset: aid,
|
||||
size: (100.0, 100.0),
|
||||
xf: Affine::translate((100.0, 100.0)),
|
||||
clip: None,
|
||||
auto_fit: Default::default(),
|
||||
fit_align: 4,
|
||||
crop: [0.0; 4],
|
||||
clip: None,
|
||||
});
|
||||
d.insert_item(SpreadRef::Doc(0), it, None).unwrap();
|
||||
let cache = Cache::new();
|
||||
|
||||
Reference in New Issue
Block a user