mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 17:44:02 +00:00
Merge pull request #6579 from dotCooCoo/fix/legacy-ai-flatten-side-limit
Legacy .ai export: a long transparent image is flattened whole
This commit is contained in:
@@ -270,7 +270,9 @@ fn flattened(src: &Document, at: usize, id: NodeId) -> Result<Option<Flat>> {
|
||||
let pt = im.xf.determinant().abs().sqrt();
|
||||
let ppi = if pt.is_finite() && pt > 0.0 { (72.0 / pt).clamp(MIN_PPI, MAX_PPI) } else { MIN_PPI };
|
||||
let area = (bounds.width() * bounds.height()).max(1.0);
|
||||
let scale = (ppi / 72.0).min((super::super::menucmds::MAX_PIXELS / area).sqrt());
|
||||
// No side longer than the renderer draws (rounded up to whole pixels below).
|
||||
let longest = (f64::from(vectorcraft_render::MAX_RASTER_SIDE) - 2.0) / bounds.width().max(bounds.height()).max(1.0);
|
||||
let scale = (ppi / 72.0).min((super::super::menucmds::MAX_PIXELS / area).sqrt()).min(longest);
|
||||
if !(scale.is_finite() && scale > 0.0) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -368,6 +368,31 @@ fn a_transparent_image_is_flattened_with_the_art_under_it_which_stays() {
|
||||
assert_eq!(colour_at(page, 10.0, 20.0), [255, 0, 0], "the square outside the image");
|
||||
}
|
||||
|
||||
/// A transparent image longer than the renderer draws at its own resolution (32,768 pixels a
|
||||
/// side) is flattened whole, at a lower resolution.
|
||||
#[test]
|
||||
fn a_long_transparent_image_is_flattened_whole() {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"width": 100, "height": 4600})).unwrap();
|
||||
s.execute("shape.rectangle", &json!({"x": 0, "y": 0, "width": 100, "height": 4600})).unwrap();
|
||||
s.execute("paint.setFill", &json!({"color": "#ff0000"})).unwrap();
|
||||
s.execute("paint.setStroke", &json!({"none": true})).unwrap();
|
||||
let p = json!({"name": "i.png", "dataBase64": vectorcraft_format::base64_encode(&png(2000, 1600, [0, 0, 0, 128])), "at": [50, 50]});
|
||||
s.execute("file.place", &p).unwrap();
|
||||
// 10 × 4500 pt: about 600 ppi, so 37,500 pixels long.
|
||||
s.execute("object.setBounds", &json!({"x": 10, "y": 10, "width": 10, "height": 4500, "reference": 0})).unwrap();
|
||||
let before = [colour_at(&s.doc().unwrap().doc, 15.0, 100.0), colour_at(&s.doc().unwrap().doc, 15.0, 4400.0)];
|
||||
assert!(before.iter().all(|c| c[0] < 200), "the image darkens the red: {before:?}");
|
||||
let r = s.execute("file.saveCopy", &json!({"format": "ai", "aiVersion": "7"})).unwrap();
|
||||
assert!(warnings(&r).iter().any(|w| w.contains("flattened with the art under them")), "{r}");
|
||||
s.execute("document.open", &json!({"name": "t.ai", "dataBase64": r["dataBase64"]})).unwrap();
|
||||
let d = &s.doc().unwrap().doc;
|
||||
let after = [colour_at(d, 15.0, 100.0), colour_at(d, 15.0, 4400.0)];
|
||||
for (a, b) in before.iter().zip(&after) {
|
||||
assert!(a.iter().zip(b).all(|(a, b)| a.abs_diff(*b) <= 3), "{before:?} {after:?}");
|
||||
}
|
||||
}
|
||||
|
||||
/// A `size`×`size` PNG of a black disk of radius `r` pixels with an anti-aliased edge, clear
|
||||
/// around it, 72 ppi.
|
||||
fn disk(size: u32, r: f64) -> Vec<u8> {
|
||||
|
||||
Reference in New Issue
Block a user