mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
eps: apply the Large Canvas scale to EPS files only; a .ai keeps its art space (#2031)
This commit is contained in:
@@ -114,9 +114,12 @@ pub(crate) fn slot_frame(name: Option<&str>) -> usize {
|
||||
name.and_then(|n| n.strip_prefix(TEXT_SLOT)).and_then(|rest| rest.split_once(':')).and_then(|(_, f)| f.parse().ok()).unwrap_or(0)
|
||||
}
|
||||
|
||||
/// Read the structure of the editing data `data`.
|
||||
pub fn read(data: &[u8]) -> Result<Structure, String> {
|
||||
/// Read the structure of the editing data `data`, applying the file's `%AI24_LargeCanvasScale` only
|
||||
/// when `large_canvas` is set: an EPS's page is drawn at the full size, but a `.ai`'s PDF part may
|
||||
/// keep the reduced one, which the PDF import reads as it is (#2031).
|
||||
pub fn read(data: &[u8], large_canvas: bool) -> Result<Structure, String> {
|
||||
let mut r = Reader::new(data);
|
||||
r.large_canvas = large_canvas.then_some(1.0);
|
||||
r.run()?;
|
||||
r.finish()
|
||||
}
|
||||
@@ -392,8 +395,9 @@ struct Reader<'a> {
|
||||
art_size: Option<(f64, f64)>,
|
||||
template_center: Option<(f64, f64)>,
|
||||
/// `%AI24_LargeCanvasScale`: a Large Canvas document's editing data is written at 1/N scale
|
||||
/// (see [`Reader::ensure_space`]); 1 (no scaling) when the file doesn't declare one.
|
||||
large_canvas: f64,
|
||||
/// (see [`Reader::ensure_space`]); 1 (no scaling) when the file doesn't declare one, `None`
|
||||
/// when the declared factor is not applied ([`read`]).
|
||||
large_canvas: Option<f64>,
|
||||
/// This reader reads a pattern's definition (see [`Reader::define_pattern`]).
|
||||
pattern: Option<PatternHead>,
|
||||
/// The tile's top left (y down) of each pattern read, by name.
|
||||
@@ -528,7 +532,7 @@ impl<'a> Reader<'a> {
|
||||
slot_names: HashMap::new(),
|
||||
art_size: None,
|
||||
template_center: None,
|
||||
large_canvas: 1.0,
|
||||
large_canvas: None,
|
||||
pattern: None,
|
||||
pattern_tiles: HashMap::new(),
|
||||
text: None,
|
||||
@@ -669,10 +673,10 @@ impl<'a> Reader<'a> {
|
||||
// being this; the printed page applies the same factor, so the art reaches the page's
|
||||
// size once it is applied to the art space ([`Self::ensure_space`]). A value outside
|
||||
// the range Illustrator writes is left alone.
|
||||
if let Ok(n) = v.trim().parse::<f64>()
|
||||
if let (Some(scale), Ok(n)) = (&mut self.large_canvas, v.trim().parse::<f64>())
|
||||
&& (1.0..=100.0).contains(&n)
|
||||
{
|
||||
self.large_canvas = n;
|
||||
*scale = n;
|
||||
}
|
||||
} else if let Some(v) = line.strip_prefix("AI9_ColorModel:") {
|
||||
self.color_model = Some(v.trim() == "2");
|
||||
@@ -1881,7 +1885,7 @@ impl<'a> Reader<'a> {
|
||||
}
|
||||
let first = self.first_board().or_else(|| self.bbox_board());
|
||||
let top_left = first.map_or(Point::new(0.0, 792.0), |r| Point::new(r.x0, r.y1));
|
||||
let s = self.large_canvas;
|
||||
let s = self.large_canvas.unwrap_or(1.0);
|
||||
let m = Affine::new([s, 0.0, 0.0, -s, -s * top_left.x, s * top_left.y]);
|
||||
self.to_doc = Some(m);
|
||||
m
|
||||
|
||||
@@ -9,6 +9,11 @@ use vectorcraft_doc::{AppearanceItem, ColorMode, Document, Knockout, LayerColor,
|
||||
|
||||
use super::*;
|
||||
|
||||
/// [`super::read`] as an EPS reads it.
|
||||
fn read(data: &[u8]) -> Result<Structure, String> {
|
||||
super::read(data, true)
|
||||
}
|
||||
|
||||
/// Editing data: header comments (crop marks 0 0 200 100), then `body`.
|
||||
fn stream(body: &str) -> String {
|
||||
format!(
|
||||
|
||||
@@ -872,7 +872,9 @@ struct Frame<'a> {
|
||||
/// nothing is compared. `outlined`: the page's type was read as outlines, so it has none to put in
|
||||
/// the text objects.
|
||||
fn build(data: &[u8], visible: Option<&Document>, page: Page, outlined: bool, trust: bool) -> Result<(Document, Vec<String>), String> {
|
||||
let Structure { mut doc, to_doc, bbox, artboard, template, hidden_unread, slot_names, warnings } = ai::read(data)?;
|
||||
// An EPS (its page is its art) draws a Large Canvas page at full size; a `.ai` keeps its art
|
||||
// space, as its PDF part may (#2031).
|
||||
let Structure { mut doc, to_doc, bbox, artboard, template, hidden_unread, slot_names, warnings } = ai::read(data, matches!(page, Page::Art))?;
|
||||
let (mut shown, mut hidden) = (vec![], vec![]);
|
||||
let mut frame = None;
|
||||
if let Some(visible) = visible {
|
||||
|
||||
@@ -269,6 +269,10 @@ fn a_large_canvas_eps_keeps_its_layers_at_the_pages_size() {
|
||||
let r = import(&eps(&page_square(10, 10), &art)).unwrap();
|
||||
assert_eq!(names(&r.document), ["Layer 1"], "{:?}", r.warnings);
|
||||
assert!(r.warnings.iter().any(|w| w.contains("different page")), "{:?}", r.warnings);
|
||||
// A `.ai` keeps its art space: its PDF part is read at the size it declares.
|
||||
let art = native_large_canvas(100.0, 10.0, &layer("Art", true, &square(10, 10)));
|
||||
let (d, w, read) = crate::layered_ai(&private(&art), pdf_part(10.0, 86.0), vec![], false, false);
|
||||
assert!(read && names(&d) == ["Art"], "{w:?}");
|
||||
}
|
||||
|
||||
/// A `.ai` whose layers can't be read comes in as its PDF part, a page per artboard in a row; its
|
||||
|
||||
Reference in New Issue
Block a user