mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 02:37:01 -06:00
Fix #735: Illustrator EPS and .ai files match their page in Fit to Artwork Bounds and the page check
- Fit to Artwork Bounds fits the art exports draw: hidden objects and layers, guides and template layers don't count, and the bounds stop at a layer's clip. - The comparison with the page catches an object one draws that the other doesn't (pixels whose neighbours all differ, away from type), a light colour against white, and, for an EPS whose page is its art's box, art the layers print outside it. - textAs: outlines opens a .ai whose type shows from its PDF part, which has the outlines. - document.open takes editingData: false to open an Illustrator EPS or .ai as its page or PDF part only, for print pipelines. Part of #637. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
569b4ac240
commit
c599522061
@@ -86,7 +86,7 @@ impl RasterExportOptions {
|
||||
self.ppi / 72.0
|
||||
}
|
||||
|
||||
/// What the renderer draws for `format`: template layers left out, over the background
|
||||
/// What the renderer draws for `format`: template layers and guides left out, over the background
|
||||
/// (white for a JPEG or a flat PSD without one).
|
||||
pub fn render_options(&self, format: RasterFormat) -> RenderOptions {
|
||||
let flat = format == RasterFormat::Jpeg || (format == RasterFormat::Psd && !self.psd.layers);
|
||||
@@ -193,7 +193,7 @@ fn drawn_bounds(n: &Node) -> Option<Rect> {
|
||||
}
|
||||
match &n.kind {
|
||||
NodeKind::Layer { template: true, .. } | NodeKind::Path { guide: true, .. } => None,
|
||||
NodeKind::Layer { children, .. } | NodeKind::Group { children, clip: false } => {
|
||||
NodeKind::Layer { children, clip: false, .. } | NodeKind::Group { children, clip: false } => {
|
||||
children.iter().fold(None, |acc, c| vectorcraft_geom::union_opt(acc, drawn_bounds(c)))
|
||||
}
|
||||
_ if fx::has_fx(n) => fx::visual_bounds(n),
|
||||
|
||||
@@ -189,3 +189,35 @@ fn art_bounds_cover_visible_art_only() {
|
||||
let empty = Document::new(10.0, 10.0);
|
||||
assert_eq!(art_bounds(&empty), None);
|
||||
}
|
||||
|
||||
/// A black path round `r` in the first layer of `d`, made a guide when `guide`.
|
||||
fn add_rect(d: &mut Document, r: Rect, guide: bool) {
|
||||
let id = d.alloc_id();
|
||||
let mut n = Node::path(id, shapes::rectangle(r), Appearance::basic(Paint::solid(Color::BLACK), Paint::None, 0.0));
|
||||
if let NodeKind::Path { guide: g, .. } = &mut n.kind {
|
||||
*g = guide;
|
||||
}
|
||||
let l = d.layers[0].id;
|
||||
d.insert(Some(l), 0, n).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn guides_dont_count_in_the_arts_bounds() {
|
||||
let mut d = circle_doc();
|
||||
add_rect(&mut d, Rect::new(0.0, 15.0, 400.0, 15.0), true);
|
||||
let b = art_bounds(&d).unwrap();
|
||||
assert!((b.x0 - 5.3).abs() < 1e-6 && (b.x1 - 31.1).abs() < 1e-6, "the guide doesn't count: {b:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn art_bounds_end_at_a_clipping_layers_clip() {
|
||||
let mut d = Document::new(40.0, 30.0);
|
||||
// The layer clips its art to its first object (added last): what lies beyond isn't drawn.
|
||||
add_rect(&mut d, Rect::new(-100.0, -100.0, 200.0, 200.0), false);
|
||||
add_rect(&mut d, Rect::new(2.0, 3.0, 20.0, 10.0), false);
|
||||
let layer = std::sync::Arc::make_mut(&mut d.layers[0]);
|
||||
if let NodeKind::Layer { clip, .. } = &mut layer.kind {
|
||||
*clip = true;
|
||||
}
|
||||
assert_eq!(art_bounds(&d), Some(Rect::new(2.0, 3.0, 20.0, 10.0)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user