mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 09:29:44 -06:00
.ai import: multi-layer masks open as a clipping group in each layer
Squashed from #5117 onto main.
This commit is contained in:
@@ -3322,6 +3322,48 @@ proptest! {
|
||||
let text = mutate_text(NAMED_PROLOG_AI, cut, &edits);
|
||||
survive("mutated PostScript-form .ai", || vectorcraft_engine::cmd::fileio::load("x.ai", text.as_bytes()).ok().map(|l| l.doc))?;
|
||||
}
|
||||
|
||||
/// Multi-layer masks (`Mb` <path> `W n` `Md` … `MB`) over any number of layers, with tokens
|
||||
/// dropped or put anywhere (the mask operators, layer ends, groups, clipping paths) and the
|
||||
/// data cut short.
|
||||
#[test]
|
||||
fn ai_multi_layer_masks_never_panic(
|
||||
layers in 1usize..5,
|
||||
aliases in any::<bool>(),
|
||||
edits in prop::collection::vec((0usize..64, prop::sample::select(vec!["", "Mb", "Md", "MB", "Mi", "LB", "u", "U", "q", "Q", "W n", "h W n"])), 0..4),
|
||||
cut in prop::option::of(0usize..64),
|
||||
) {
|
||||
use vectorcraft_testkit::ai;
|
||||
let (begin, define) = if aliases { ("Mv", "ME") } else { ("Mb", "Md") };
|
||||
let mut tokens: Vec<String> = vec![];
|
||||
for i in 0..layers {
|
||||
if i > 0 {
|
||||
tokens.push(format!("LB\n%AI5_EndLayer--\n%AI5_BeginLayer\n1 1 1 1 0 1 1 79 128 255 Lb\n(L{i}) Ln\n"));
|
||||
} else {
|
||||
tokens.extend([begin.to_string(), "40 40 m 120 40 L 120 120 L 40 120 L h W n".into(), define.to_string()]);
|
||||
}
|
||||
let x = 10 * i;
|
||||
tokens.push(format!("0.5 0 0 0 k {x} {x} m {} {x} L {} {} L f", x + 140, x + 140, x + 140));
|
||||
}
|
||||
tokens.extend(["MB".to_string(), "150 150 m 190 150 L 190 190 L f".into()]);
|
||||
for (at, with) in &edits {
|
||||
let at = at % (tokens.len() + 1);
|
||||
if with.is_empty() {
|
||||
if at < tokens.len() {
|
||||
tokens.remove(at);
|
||||
}
|
||||
} else {
|
||||
tokens.insert(at, with.to_string());
|
||||
}
|
||||
}
|
||||
if let Some(cut) = cut {
|
||||
tokens.truncate(cut);
|
||||
}
|
||||
let data = ai::editing_data(200.0, 100.0, &format!("%AI5_BeginLayer\n1 1 1 1 0 1 1 79 128 255 Lb\n(L0) Ln\n{}\nLB\n", tokens.join("\n")));
|
||||
survive("multi-layer masks", || Some(vectorcraft_eps::layered_ai(data.as_bytes(), Document::new(200.0, 100.0), vec![], false, false, 1.0).0))?;
|
||||
let eps = ai::eps(data.as_bytes(), ai::page_ps());
|
||||
survive("multi-layer masks in an EPS", || vectorcraft_engine::cmd::fileio::load("x.eps", &eps).ok().map(|l| l.doc))?;
|
||||
}
|
||||
}
|
||||
|
||||
/// An operand of a layer's options (`Lb`): a flag, a colour index or component, a percentage, or
|
||||
@@ -3390,6 +3432,13 @@ fn arb_ai_token() -> impl Strategy<Value = String> {
|
||||
"Lb",
|
||||
"Ln",
|
||||
"(name) Ln",
|
||||
"\n%AI5_BeginLayer\n1 1 1 1 0 1 1 79 128 255 Lb\n",
|
||||
"Mb",
|
||||
"Mv",
|
||||
"Md",
|
||||
"ME",
|
||||
"Mi",
|
||||
"MB",
|
||||
"g",
|
||||
"G",
|
||||
"k",
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
//! - Layers: `%AI5_BeginLayer`, `visible preview unlocked printing dimmed … colorIndex r g b
|
||||
//! template dimPercent … Lb` (ten operands in the legacy format, without the one before the
|
||||
//! colour index; see `Reader::layer_attrs`), `(name) Ln`, its art, `LB`.
|
||||
//! - Multi-layer masks `Mb` <path> `W n` `Md` … `MB`, whose objects can go on past `LB` into the
|
||||
//! next layers: a clipping group in each layer, read by [`masks`].
|
||||
//! - Ruler guides: a straight `(N) *` guide path, directly on a layer, that runs across the whole
|
||||
//! canvas (16,383 points around the template box's centre) or from edge to edge of one artboard
|
||||
//! is a ruler guide on that layer ([`Document::guides`]); other guide paths stay paths.
|
||||
@@ -87,6 +89,7 @@ mod art;
|
||||
mod containers;
|
||||
mod directives;
|
||||
mod document;
|
||||
mod masks;
|
||||
mod on_path;
|
||||
mod ops;
|
||||
mod types;
|
||||
@@ -308,6 +311,8 @@ struct Reader<'a> {
|
||||
type_state: legacy_text::TypeState,
|
||||
/// The graph being read (see [`Reader::graph_record`]).
|
||||
graph: Option<Graph>,
|
||||
/// The multi-layer mask being read (`Mb` … `MB`), which goes on past a layer's end.
|
||||
multi_mask: Option<masks::MultiMask>,
|
||||
}
|
||||
|
||||
/// A section comment's marker without its `AI<version>_` prefix and value (`AI14_BeginSymbol` →
|
||||
@@ -406,6 +411,7 @@ impl<'a> Reader<'a> {
|
||||
text: None,
|
||||
type_state: legacy_text::TypeState::default(),
|
||||
graph: None,
|
||||
multi_mask: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,6 +442,9 @@ impl<'a> Reader<'a> {
|
||||
if self.frames.iter().any(|f| matches!(f.kind, Kind::Layer(_))) {
|
||||
return Err("it ends inside a layer".into());
|
||||
}
|
||||
if self.multi_mask.is_some() {
|
||||
return Err("it ends inside a multi-layer mask".into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ impl<'a> Reader<'a> {
|
||||
}
|
||||
|
||||
pub(super) fn end_container(&mut self, what: &str, hidden: bool) -> Result<(), String> {
|
||||
self.multi_mask_container_ends()?;
|
||||
let f = match what {
|
||||
"U" => self.close(what, |k| matches!(k, Kind::Group))?,
|
||||
"*U" => self.close(what, |k| matches!(k, Kind::Compound))?,
|
||||
|
||||
@@ -130,7 +130,10 @@ impl<'a> Reader<'a> {
|
||||
_ => {}
|
||||
}
|
||||
if line.starts_with("AI5_BeginLayer") {
|
||||
return self.open(Kind::Layer(Box::default()), false);
|
||||
self.multi_mask_layer_starts()?;
|
||||
self.open(Kind::Layer(Box::default()), false)?;
|
||||
self.multi_mask_go_on();
|
||||
return Ok(());
|
||||
}
|
||||
if line.starts_with("AI5_BeginRaster") {
|
||||
self.raster = Some(Raster::default());
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
//! Multi-layer masks in the legacy format (version 7 specification §10): `Mb`, the mask's path
|
||||
//! painted with `W`, `Md`, the masked objects (in that layer and, past its `LB`, in the layers
|
||||
//! after it), `MB`. The objects of each layer the mask covers become one clipping group in that
|
||||
//! layer, its clipping path a copy of the mask's.
|
||||
|
||||
use super::types::{Frame, Kind, MAX_NODES};
|
||||
use super::{Arc, Node, NodeKind, Reader};
|
||||
|
||||
/// The note for a file with a multi-layer mask.
|
||||
pub(crate) const PER_LAYER: &str = "a mask that covers several layers comes in as a clipping group in each layer it covers";
|
||||
|
||||
/// A multi-layer mask being read.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct MultiMask {
|
||||
/// The mask's clipping path, once `Md` has defined it.
|
||||
mask: Option<Node>,
|
||||
/// What each copy of the mask adds to the objects read: its objects and their points.
|
||||
weight: usize,
|
||||
/// How many frames were open when the masked objects started in the frame they go in; 0
|
||||
/// outside the layers, until a layer starts.
|
||||
depth: usize,
|
||||
/// Where the masked objects start among that frame's children.
|
||||
start: usize,
|
||||
}
|
||||
|
||||
impl Reader<'_> {
|
||||
/// A multi-layer mask's operator `w`: `Mb` (or `Mv`) starts the mask, `Md` (or `ME`) defines
|
||||
/// it, `MB` ends it, and `Mi` changes nothing here.
|
||||
pub(super) fn multi_mask_op(&mut self, w: &str) -> Result<(), String> {
|
||||
match w {
|
||||
"Mb" | "Mv" => self.begin_multi_mask(),
|
||||
"Md" | "ME" => self.define_multi_mask(),
|
||||
"MB" => self.end_multi_mask(),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// `LB`: the layer ends, and a multi-layer mask goes on in the frame around it.
|
||||
pub(super) fn end_layer_in_mask(&mut self) -> Result<(), String> {
|
||||
self.multi_mask_layer_ends()?;
|
||||
self.end_layer()?;
|
||||
self.multi_mask_go_on();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `Mb`: a multi-layer mask starts.
|
||||
fn begin_multi_mask(&mut self) -> Result<(), String> {
|
||||
if self.multi_mask.is_some() {
|
||||
return Err("a multi-layer mask's operators are out of order".into());
|
||||
}
|
||||
self.end_path_quietly();
|
||||
let start = self.frames.last().map_or(0, |f| f.children.len());
|
||||
self.multi_mask = Some(MultiMask { mask: None, weight: 0, depth: self.frames.len(), start });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `Md`: the clipping path painted last since `Mb`, in the same group or layer, is the mask.
|
||||
fn define_multi_mask(&mut self) -> Result<(), String> {
|
||||
let depth = self.frames.len();
|
||||
let Some(m) = self.multi_mask.as_mut() else { return Err("a multi-layer mask's operators are out of order".into()) };
|
||||
if m.mask.is_some() || depth == 0 {
|
||||
return Err("a multi-layer mask's operators are out of order".into());
|
||||
}
|
||||
if m.depth != depth {
|
||||
return Err("a group crosses a multi-layer mask".into());
|
||||
}
|
||||
let Some(f) = self.frames.last_mut() else { return Err("a multi-layer mask's operators are out of order".into()) };
|
||||
let Some(at) = f.clips.iter().copied().filter(|i| *i >= m.start && *i < f.children.len()).max() else {
|
||||
return Err("a multi-layer mask needs one clipping path".into());
|
||||
};
|
||||
let mask = f.children.remove(at);
|
||||
f.clips.retain(|i| *i != at);
|
||||
for i in &mut f.clips {
|
||||
if *i > at {
|
||||
*i -= 1;
|
||||
}
|
||||
}
|
||||
let mut weight = mask.count_with_masks();
|
||||
mask.walk(&mut |n| {
|
||||
if let NodeKind::Path { path, .. } = &n.kind {
|
||||
weight = weight.saturating_add(path.anchor_count());
|
||||
}
|
||||
});
|
||||
m.weight = weight;
|
||||
m.mask = Some(mask);
|
||||
self.after_object = false;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `MB`: the masked objects end.
|
||||
fn end_multi_mask(&mut self) -> Result<(), String> {
|
||||
if !self.multi_mask.as_ref().is_some_and(|m| m.mask.is_some()) {
|
||||
return Err("a multi-layer mask's operators are out of order".into());
|
||||
}
|
||||
self.wrap_masked()?;
|
||||
self.multi_mask = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `%AI5_BeginLayer` in a multi-layer mask, before the layer opens: the objects masked so far
|
||||
/// in the frame around it are grouped, and the mask goes on in the new layer.
|
||||
pub(super) fn multi_mask_layer_starts(&mut self) -> Result<(), String> {
|
||||
let Some(m) = self.multi_mask.as_ref() else { return Ok(()) };
|
||||
if m.depth != 0 {
|
||||
if m.mask.is_none() {
|
||||
return Err("a multi-layer mask's operators are out of order".into());
|
||||
}
|
||||
self.wrap_masked()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A layer opened or closed in a multi-layer mask: the masked objects go on in the frame now
|
||||
/// innermost.
|
||||
pub(super) fn multi_mask_go_on(&mut self) {
|
||||
let (depth, start) = (self.frames.len(), self.frames.last().map_or(0, |f| f.children.len()));
|
||||
if let Some(m) = self.multi_mask.as_mut() {
|
||||
(m.depth, m.start) = (depth, start);
|
||||
}
|
||||
}
|
||||
|
||||
/// `LB` in a multi-layer mask, before the layer closes: its masked objects are grouped.
|
||||
fn multi_mask_layer_ends(&mut self) -> Result<(), String> {
|
||||
let Some(m) = self.multi_mask.as_ref() else { return Ok(()) };
|
||||
if m.mask.is_none() {
|
||||
return Err("a multi-layer mask's operators are out of order".into());
|
||||
}
|
||||
if !matches!(self.frames.last(), Some(Frame { kind: Kind::Layer(_), .. })) {
|
||||
return Err("a group crosses a multi-layer mask".into());
|
||||
}
|
||||
self.wrap_masked()
|
||||
}
|
||||
|
||||
/// A group, compound path or clipping group closing: it must have opened inside the mask.
|
||||
pub(super) fn multi_mask_container_ends(&self) -> Result<(), String> {
|
||||
match &self.multi_mask {
|
||||
Some(m) if m.depth == self.frames.len() => Err("a group crosses a multi-layer mask".into()),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// The masked objects in the innermost frame become a clipping group, a copy of the mask first.
|
||||
fn wrap_masked(&mut self) -> Result<(), String> {
|
||||
let Some(m) = self.multi_mask.as_ref() else { return Ok(()) };
|
||||
if m.depth == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
if m.depth != self.frames.len() {
|
||||
return Err("a group crosses a multi-layer mask".into());
|
||||
}
|
||||
let Some(mut mask) = m.mask.clone() else { return Err("a multi-layer mask's operators are out of order".into()) };
|
||||
let (start, weight) = (m.start, m.weight);
|
||||
let Some(f) = self.frames.last_mut() else { return Ok(()) };
|
||||
if start >= f.children.len() {
|
||||
return Ok(());
|
||||
}
|
||||
// A clipping path painted among the masked objects clips the whole layer or group, as
|
||||
// outside a mask: it stays in the frame, outside the masked objects' group.
|
||||
let painted: std::collections::HashSet<usize> = f.clips.iter().filter_map(|i| i.checked_sub(start)).collect();
|
||||
let (clips, kids): (Vec<_>, Vec<_>) = f.children.split_off(start).into_iter().enumerate().partition(|(i, _)| painted.contains(i));
|
||||
let (clips, kids): (Vec<Node>, Vec<Node>) = (clips.into_iter().map(|(_, k)| k).collect(), kids.into_iter().map(|(_, k)| k).collect());
|
||||
f.clips.retain(|i| *i < start);
|
||||
if !kids.is_empty() {
|
||||
self.nodes = self.nodes.saturating_add(weight).saturating_add(1);
|
||||
if self.nodes > MAX_NODES {
|
||||
return Err(format!("it has more than {MAX_NODES} objects"));
|
||||
}
|
||||
self.reid(&mut mask);
|
||||
let children = std::iter::once(mask).chain(kids).map(Arc::new).collect();
|
||||
let group = Node::new(self.doc.alloc_id(), NodeKind::Group { children, clip: true });
|
||||
if let Some(f) = self.frames.last_mut() {
|
||||
f.children.push(group);
|
||||
}
|
||||
self.warn(PER_LAYER);
|
||||
}
|
||||
if let Some(f) = self.frames.last_mut() {
|
||||
for c in clips {
|
||||
f.clips.push(f.children.len());
|
||||
f.children.push(c);
|
||||
}
|
||||
}
|
||||
self.after_object = false;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ impl<'a> Reader<'a> {
|
||||
self.graph = None;
|
||||
self.warn(GRAPH_UNENDED);
|
||||
}
|
||||
self.end_layer()?
|
||||
self.end_layer_in_mask()?
|
||||
}
|
||||
// Paths.
|
||||
"m" | "l" | "L" | "c" | "C" | "v" | "V" | "y" | "Y" => self.path_op(w, &vals)?,
|
||||
@@ -162,6 +162,7 @@ impl<'a> Reader<'a> {
|
||||
// Ends a path that stays open.
|
||||
"H" => {}
|
||||
"W" => self.clip_next = true,
|
||||
"Mb" | "Mv" | "Md" | "ME" | "MB" | "Mi" => self.multi_mask_op(w)?,
|
||||
// A text object's frame or path.
|
||||
"N" | "n" | "F" | "f" | "S" | "s" | "B" | "b" if self.in_text_path() => self.text_path(),
|
||||
"N" | "n" | "F" | "f" | "S" | "s" | "B" | "b" => self.paint(w, hidden, false)?,
|
||||
|
||||
@@ -3953,3 +3953,224 @@ fn a_graphs_records_take_their_operands() {
|
||||
assert_eq!(paths(&a[0]), 1, "the empty groups hold no art");
|
||||
assert_eq!(r.warnings, [GRAPH_PLAIN]);
|
||||
}
|
||||
|
||||
/// Editing data in the legacy format (`%AI5_FileFormat 2.0`, ten `Lb` operands), then `body`.
|
||||
fn mask_stream7(body: &str) -> String {
|
||||
format!(
|
||||
"%!PS-Adobe-3.0\n%%Creator: test\n%%BoundingBox: 0 0 200 200\n%AI5_FileFormat 2.0\n%AI5_ArtSize: 200 200\n\
|
||||
%AI3_TemplateBox: 100 100 100 100\n%%EndComments\n%%BeginProlog\n%%EndProlog\n%%BeginSetup\n%%EndSetup\n{body}\n\
|
||||
%%PageTrailer\ngsave annotatepage grestore showpage\n%%Trailer\n%%EOF\n"
|
||||
)
|
||||
}
|
||||
|
||||
/// The start of a legacy layer named `name`, `masks` its multi-layer mask flag (`Lb`'s sixth operand).
|
||||
fn begin7(name: &str, masks: u8) -> String {
|
||||
format!("%AI5_BeginLayer\n1 1 1 1 0 {masks} 1 79 128 255 Lb\n({name}) Ln\n")
|
||||
}
|
||||
|
||||
const END7: &str = "LB\n%AI5_EndLayer--\n";
|
||||
|
||||
/// `Mb`, an 80 by 80 point mask path painted `W n`, `Md` (the version 7 specification's §10.4 order).
|
||||
fn mask_start() -> String {
|
||||
format!("Mb\n{}h\nW\nn\nMd\n", rect_path(40.0, 40.0, 120.0, 120.0))
|
||||
}
|
||||
|
||||
/// A filled square at `x`.
|
||||
fn masked(x: f64) -> String {
|
||||
format!("0.5 0 0 0 k\n{}f\n", rect_path(x, x, x + 140.0, x + 140.0))
|
||||
}
|
||||
|
||||
/// A layer's objects as a tree: `p` a path, `c` a clipping path, `o` a compound path, `g[…]` a
|
||||
/// group, `k[…]` a clipping group, `l[…]` a sublayer.
|
||||
fn mask_tree(nodes: &[Arc<Node>]) -> String {
|
||||
let one = |n: &Arc<Node>| match &n.kind {
|
||||
NodeKind::Layer { children, .. } => format!("l[{}]", mask_tree(children)),
|
||||
NodeKind::Group { children, clip: false } => format!("g[{}]", mask_tree(children)),
|
||||
NodeKind::Group { children, clip: true } => format!("k[{}]", mask_tree(children)),
|
||||
NodeKind::Path { clipping: true, .. } => "c".into(),
|
||||
NodeKind::Path { .. } => "p".into(),
|
||||
NodeKind::Compound { .. } => "o".into(),
|
||||
k => format!("{k:?}"),
|
||||
};
|
||||
nodes.iter().map(one).collect::<Vec<_>>().join(" ")
|
||||
}
|
||||
|
||||
fn read7(body: &str) -> Structure {
|
||||
match read(mask_stream7(body).as_bytes()) {
|
||||
Ok(r) => r,
|
||||
Err(e) => panic!("{e}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Each layer's tree, and whether the layer itself clips.
|
||||
fn layer_trees(doc: &Document) -> Vec<(String, String, bool)> {
|
||||
doc.layers
|
||||
.iter()
|
||||
.map(|l| {
|
||||
let NodeKind::Layer { children, clip, .. } = &l.kind else { panic!("a layer") };
|
||||
(l.name.clone().unwrap_or_default(), mask_tree(children), *clip)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// A multi-layer mask (version 7 specification §10.4: `Mb`, the mask path, `Md`, objects in two
|
||||
/// layers, `MB`) comes in as a clipping group in each layer it covers, each clipped by a copy of
|
||||
/// the mask's path; what follows `MB` isn't clipped.
|
||||
#[test]
|
||||
fn a_multi_layer_mask_clips_each_layer_it_covers() {
|
||||
let body = format!("{}{}{}{END7}{}{}MB\n{}{END7}", begin7("A", 1), mask_start(), masked(15.0), begin7("B", 1), masked(30.0), masked(150.0));
|
||||
let r = read7(&body);
|
||||
assert_eq!(layer_trees(&r.doc), [("A".to_string(), "k[c p]".to_string(), false), ("B".to_string(), "k[c p] p".to_string(), false)]);
|
||||
let mask = |l: usize| r.doc.layers[l].children().unwrap()[0].children().unwrap()[0].clone();
|
||||
let (a, b) = (mask(0), mask(1));
|
||||
assert_ne!(a.id, b.id, "each layer has a copy of its own");
|
||||
assert_eq!(a.geometric_bounds(), b.geometric_bounds());
|
||||
let bounds = a.geometric_bounds().unwrap();
|
||||
assert_eq!((bounds.width(), bounds.height()), (80.0, 80.0));
|
||||
assert!(r.warnings.iter().any(|w| w.contains("clipping group in each layer")), "{:?}", r.warnings);
|
||||
// The layers' flag saying they have multi-layer masks changes nothing.
|
||||
let unflagged = read7(&body.replace(&begin7("A", 1), &begin7("A", 0)).replace(&begin7("B", 1), &begin7("B", 0)));
|
||||
assert_eq!(format!("{:?}", unflagged.doc.layers), format!("{:?}", r.doc.layers));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_multi_layer_mask_in_one_layer_or_over_three() {
|
||||
let one = format!("{}{}{}MB\n{}{END7}", begin7("A", 1), mask_start(), masked(15.0), masked(150.0));
|
||||
assert_eq!(layer_trees(&read7(&one).doc), [("A".to_string(), "k[c p] p".to_string(), false)]);
|
||||
let three = format!(
|
||||
"{}{}{}{END7}{}{}{END7}{}{}MB\n{END7}",
|
||||
begin7("A", 1),
|
||||
mask_start(),
|
||||
masked(15.0),
|
||||
begin7("B", 1),
|
||||
masked(30.0),
|
||||
begin7("C", 1),
|
||||
masked(45.0)
|
||||
);
|
||||
let trees: Vec<_> = layer_trees(&read7(&three).doc).into_iter().map(|(_, t, clip)| (t, clip)).collect();
|
||||
assert_eq!(trees, vec![("k[c p]".to_string(), false); 3]);
|
||||
// Objects before the mask's path are masked too; a layer between with nothing in it stays empty.
|
||||
let before = format!(
|
||||
"{}Mb\n{}{}h\nW\nn\nMd\n{END7}{}{END7}{}{}MB\n{END7}",
|
||||
begin7("A", 1),
|
||||
masked(15.0),
|
||||
rect_path(40.0, 40.0, 120.0, 120.0),
|
||||
begin7("B", 1),
|
||||
begin7("C", 1),
|
||||
masked(45.0)
|
||||
);
|
||||
let trees: Vec<_> = layer_trees(&read7(&before).doc).into_iter().map(|(_, t, _)| t).collect();
|
||||
assert_eq!(trees, ["k[c p]", "", "k[c p]"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_multi_layer_mask_in_a_group_or_sublayer() {
|
||||
// Begun and ended in a group of one layer.
|
||||
let grouped = format!("{}u\n{}{}MB\n{}U\n{END7}", begin7("A", 1), mask_start(), masked(15.0), masked(150.0));
|
||||
assert_eq!(layer_trees(&read7(&grouped).doc)[0].1, "g[k[c p] p]");
|
||||
// A sublayer in the mask: what the mask covers in the layer around it and in the sublayer.
|
||||
let nested = format!("{}{}{}{}{}{END7}{}MB\n{END7}", begin7("A", 1), mask_start(), masked(15.0), begin7("S", 1), masked(30.0), masked(45.0));
|
||||
assert_eq!(layer_trees(&read7(&nested).doc)[0].1, "k[c p] l[k[c p]] k[c p]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_multi_layer_masks_path_can_be_painted_or_compound() {
|
||||
// `W f`: the path also paints, under what the mask covers.
|
||||
let painted = format!("{}Mb\n0 0 0 1 k\n{}h\nW\nf\nMd\n{}MB\n{END7}", begin7("A", 1), rect_path(40.0, 40.0, 120.0, 120.0), masked(15.0));
|
||||
let doc = read7(&painted).doc;
|
||||
assert_eq!(layer_trees(&doc)[0].1, "k[c p p]");
|
||||
let group = doc.layers[0].children().unwrap()[0].clone();
|
||||
let kids = group.children().unwrap();
|
||||
assert_eq!(fill(&kids[1]).color(), Some(Color::cmyk(0.0, 0.0, 0.0, 1.0)), "the painted path first");
|
||||
// A compound path of clipping paths.
|
||||
let compound = format!(
|
||||
"{}Mb\n*u\n{}h\nW\nn\n{}h\nW\nn\n*U\nMd\n{}MB\n{END7}",
|
||||
begin7("A", 1),
|
||||
rect_path(40.0, 40.0, 80.0, 80.0),
|
||||
rect_path(90.0, 90.0, 120.0, 120.0),
|
||||
masked(15.0)
|
||||
);
|
||||
assert_eq!(layer_trees(&read7(&compound).doc)[0].1, "k[o p]");
|
||||
}
|
||||
|
||||
/// `Mv` starts a mask as `Mb` does, `ME` defines one as `Md` does, and `Mi` changes nothing.
|
||||
#[test]
|
||||
fn other_multi_layer_mask_operators() {
|
||||
let body = format!("{}{}{}{END7}{}{}MB\n{}{END7}", begin7("A", 1), mask_start(), masked(15.0), begin7("B", 1), masked(30.0), masked(150.0));
|
||||
let plain = format!("{:?}", read7(&body).doc.layers);
|
||||
let aliases = body.replace("Mb\n", "Mv\n").replace("Md\n", "ME\n");
|
||||
assert_eq!(format!("{:?}", read7(&aliases).doc.layers), plain);
|
||||
let with_mi = body.replace("Md\n", "Md\nMi\n").replace("MB\n", "Mi\nMB\n");
|
||||
assert_eq!(format!("{:?}", read7(&with_mi).doc.layers), plain);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_malformed_multi_layer_mask_is_an_error() {
|
||||
let path = format!("{}h\nW\nn\n", rect_path(40.0, 40.0, 120.0, 120.0));
|
||||
let sq = masked(15.0);
|
||||
let cases = [
|
||||
("an end without a start", format!("{sq}MB\n")),
|
||||
("a definition without a start", format!("{path}Md\n{sq}")),
|
||||
("no mask path", format!("Mb\n{sq}Md\n{sq}MB\n")),
|
||||
("a start inside another", format!("Mb\nMb\n{path}Md\n{sq}MB\n")),
|
||||
("an end before the definition", format!("Mb\n{path}MB\n")),
|
||||
("a definition in another group", format!("Mb\nu\n{path}Md\n{sq}MB\nU\n")),
|
||||
("a group crossing the end", format!("{}u\n{sq}MB\nU\n", mask_start())),
|
||||
("a group crossing the start", format!("u\n{}{sq}U\nMB\n", mask_start())),
|
||||
];
|
||||
for (why, art) in cases {
|
||||
let body = format!("{}{art}{END7}", begin7("A", 1));
|
||||
let e = read(mask_stream7(&body).as_bytes()).unwrap_err();
|
||||
assert!(e.contains("mask"), "{why}: {e}");
|
||||
}
|
||||
let layered = [
|
||||
("a layer ends before the definition", format!("{}Mb\n{sq}{END7}{}{path}Md\nMB\n{END7}", begin7("A", 1), begin7("B", 1))),
|
||||
("a group open at the layer's end", format!("{}{}u\n{sq}{END7}{}U\nMB\n{END7}", begin7("A", 1), mask_start(), begin7("B", 1))),
|
||||
("the end of the file inside the mask", format!("{}{}{sq}{END7}", begin7("A", 1), mask_start())),
|
||||
];
|
||||
for (why, body) in layered {
|
||||
let e = read(mask_stream7(&body).as_bytes()).unwrap_err();
|
||||
assert!(e.contains("mask"), "{why}: {e}");
|
||||
}
|
||||
// Outside the layers, `Md` has nowhere to take its path from.
|
||||
let outside = format!("Mb\nMd\n{}{path}{sq}MB\n{END7}", begin7("A", 1));
|
||||
let e = read(mask_stream7(&outside).as_bytes()).unwrap_err();
|
||||
assert!(e.contains("mask"), "{e}");
|
||||
}
|
||||
|
||||
/// A clipping path painted among the masked objects clips its whole layer, as outside a mask.
|
||||
#[test]
|
||||
fn a_layers_clipping_path_in_a_multi_layer_mask_clips_the_layer() {
|
||||
let path = format!("{}h\nW\nn\n", rect_path(10.0, 10.0, 190.0, 190.0));
|
||||
let body = format!("{}{}{}{path}{}MB\n{END7}", begin7("A", 1), mask_start(), masked(15.0), masked(30.0));
|
||||
assert_eq!(layer_trees(&read7(&body).doc), [("A".to_string(), "c k[c p p]".to_string(), true)]);
|
||||
}
|
||||
|
||||
/// `Mb` before the first layer it covers and `MB` after the last one's `LB`.
|
||||
#[test]
|
||||
fn a_multi_layer_mask_begun_or_ended_between_layers() {
|
||||
let body = format!(
|
||||
"Mb\n{}{}h\nW\nn\nMd\n{}{END7}{}{}{END7}MB\n{}{}{END7}",
|
||||
begin7("A", 1),
|
||||
rect_path(40.0, 40.0, 120.0, 120.0),
|
||||
masked(15.0),
|
||||
begin7("B", 1),
|
||||
masked(30.0),
|
||||
begin7("C", 1),
|
||||
masked(150.0)
|
||||
);
|
||||
let trees: Vec<_> = layer_trees(&read7(&body).doc).into_iter().map(|(_, t, _)| t).collect();
|
||||
assert_eq!(trees, ["k[c p]", "k[c p]", "p"]);
|
||||
}
|
||||
|
||||
/// Each copy of the mask counts toward the most objects read, with its points.
|
||||
#[test]
|
||||
fn copies_of_a_multi_layer_mask_count_toward_the_limit() {
|
||||
let points: String = (0..2_000_001).map(|i| format!("{} 40 L\n", 40 + i % 80)).collect();
|
||||
let mask = format!("Mb\n40 40 m\n{points}h\nW\nn\nMd\n");
|
||||
let one = format!("{}{mask}{}MB\n{END7}", begin7("A", 1), masked(15.0));
|
||||
assert_eq!(layer_trees(&read7(&one).doc)[0].1, "k[c p]");
|
||||
let two = format!("{}{mask}{}{END7}{}{}MB\n{END7}", begin7("A", 1), masked(15.0), begin7("B", 1), masked(30.0));
|
||||
let e = read(mask_stream7(&two).as_bytes()).unwrap_err();
|
||||
assert!(e.contains("objects"), "{e}");
|
||||
}
|
||||
|
||||
@@ -163,6 +163,25 @@ fn a_postscript_ai_whose_layers_cant_be_read_says_why() {
|
||||
assert!(e.contains("`Adobe_packedarray`") && e.contains("its layers couldn't be read either") && e.contains("`frobnicate`"), "{e}");
|
||||
}
|
||||
|
||||
/// A `.ai` in PostScript form with a multi-layer mask (`Mb`, its path, `Md`, objects in both
|
||||
/// layers, `MB`) opens through its layers: a clipping group in each, and what follows `MB` unclipped.
|
||||
#[test]
|
||||
fn a_postscript_ai_with_a_multi_layer_mask_opens_with_its_layers() {
|
||||
let src = NAMED_PROLOG
|
||||
.replace("0 D\n10 10 m", "0 D\nMb\n20 20 m\n180 20 L\n180 80 L\n20 80 L\nh\nW\nn\nMd\n10 10 m")
|
||||
.replace("190 90 L\nS\nLB", "190 90 L\nS\nMB\n150 50 m\n195 95 L\nS\nLB");
|
||||
let r = import(src.as_bytes()).unwrap();
|
||||
assert!(!r.preview, "read through the layers, not a fallback preview");
|
||||
let d = &r.document;
|
||||
let names: Vec<_> = d.layers.iter().map(|l| l.name.clone().unwrap_or_default()).collect();
|
||||
assert_eq!(names, ["SECTION::Cut", "SECTION::Hatch"]);
|
||||
assert_eq!(tree(d.layers[0].children().unwrap()), "k[c p]");
|
||||
assert_eq!(tree(d.layers[1].children().unwrap()), "k[c p] p");
|
||||
let mask = d.layers[1].children().unwrap()[0].children().unwrap()[0].clone();
|
||||
assert_eq!(mask.geometric_bounds(), Some(Rect::new(20.0, 20.0, 180.0, 80.0)));
|
||||
assert!(r.warnings.iter().any(|w| w.contains("clipping group in each layer")), "{:?}", r.warnings);
|
||||
}
|
||||
|
||||
/// A `.ai` in PostScript form (read through its layers) whose text carries hyphenation and
|
||||
/// tab-ruler attributes: `XL` (hyphenation language), `Xb`/`XB` (a tab definition) and `Th`
|
||||
/// (hyphen control). These keep no geometry, so the reader drops them rather than failing the
|
||||
|
||||
@@ -4814,6 +4814,7 @@ digits Malayalam Malaiàlam
|
||||
@msg `{to}` is not an available name `{to}` no és un nom disponible
|
||||
@msg `{what}` closes nothing `{what}` no tanca res
|
||||
@msg `{what}` closes something it didn't open `{what}` tanca una cosa que no havia obert
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers una màscara que cobreix diverses capes entra com un grup de retall a cada capa que cobreix
|
||||
@msg a graph's records don't end where they should: its art was read as it is els registres d’un gràfic no acaben on haurien: la seva il·lustració s’ha llegit tal com és
|
||||
@msg `{w}` takes no operands `{w}` no admet operands
|
||||
@msg a wraparound group is inside a compound path un grup d’ajustament del text és dins d’un traçat compost
|
||||
@@ -5050,6 +5051,10 @@ digits Malayalam Malaiàlam
|
||||
@msg is not an image VectorCraft reads no és una imatge que VectorCraft pugui llegir
|
||||
@msg it decompresses to more than {_1} MB es descomprimeix fins a més de {_1} MB
|
||||
@msg it ends inside a layer acaba dins d’una capa
|
||||
@msg it ends inside a multi-layer mask acaba dins d’una màscara multicapa
|
||||
@msg a multi-layer mask's operators are out of order els operadors d’una màscara multicapa estan desordenats
|
||||
@msg a multi-layer mask needs one clipping path una màscara multicapa necessita un traçat de retall
|
||||
@msg a group crosses a multi-layer mask un grup travessa una màscara multicapa
|
||||
@msg it has art outside its layers té art fora de les seves capes
|
||||
@msg it has more than one artboard té més d’un tauler
|
||||
@msg it has more than {MAX_NODES} objects té més de {MAX_NODES} objectes
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4872,11 +4872,16 @@ imageTrace Outline Obrys
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead nejde o logo s plnými barvami ({_1} % jeho plných ploch odpovídá několika plným barvám), takže režim Ploché logo by z jeho přechodů udělal skvrny: použijte místo toho režim Barva
|
||||
@msg `{what}` closes nothing `{what}` nic neuzavírá
|
||||
@msg `{what}` closes something it didn't open `{what}` uzavírá něco, co neotevřel
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers maska, která pokrývá několik vrstev, se načte jako ořezová skupina v každé vrstvě, kterou pokrývá
|
||||
@msg a graph's records don't end where they should: its art was read as it is záznamy grafu nekončí tam, kde mají: jeho kresba byla načtena tak, jak je
|
||||
@msg `{w}` takes no operands `{w}` nepřijímá žádné operandy
|
||||
@msg a wraparound group is inside a compound path skupina obtékání textu je uvnitř složené cesty
|
||||
@msg a path has too many points cesta má příliš mnoho bodů
|
||||
@msg it ends inside a layer končí uvnitř vrstvy
|
||||
@msg it ends inside a multi-layer mask končí uvnitř masky přes více vrstev
|
||||
@msg a multi-layer mask's operators are out of order operátory masky přes více vrstev jsou ve špatném pořadí
|
||||
@msg a multi-layer mask needs one clipping path maska přes více vrstev potřebuje jednu ořezovou cestu
|
||||
@msg a group crosses a multi-layer mask skupina přesahuje masku přes více vrstev
|
||||
@msg it has art outside its layers má kresbu mimo své vrstvy
|
||||
@msg it has more than {MAX_NODES} objects má více než {MAX_NODES} objektů
|
||||
@msg it has no layers nemá žádné vrstvy
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4481,11 +4481,16 @@ theme Appearance Erscheinungsbild
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead dies ist kein Logo aus flächigen Farben ({_1} % seiner einfarbigen Bereiche entsprechen wenigen flächigen Farben), daher würde der Modus „Flaches Logo“ seine Verläufe in Flecken zerlegen: Verwenden Sie stattdessen den Modus „Farbe“
|
||||
@msg `{what}` closes nothing `{what}` schließt nichts
|
||||
@msg `{what}` closes something it didn't open `{what}` schließt etwas, das es nicht geöffnet hat
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers eine Maske über mehrere Ebenen wird in jeder Ebene, die sie abdeckt, zu einer Schnittgruppe
|
||||
@msg a graph's records don't end where they should: its art was read as it is die Datensätze eines Diagramms enden nicht dort, wo sie sollten: seine Grafik wurde so gelesen, wie sie ist
|
||||
@msg `{w}` takes no operands `{w}` nimmt keine Operanden
|
||||
@msg a wraparound group is inside a compound path eine Textumfluss-Gruppe liegt in einem zusammengesetzten Pfad
|
||||
@msg a path has too many points ein Pfad hat zu viele Punkte
|
||||
@msg it ends inside a layer es endet innerhalb einer Ebene
|
||||
@msg it ends inside a multi-layer mask es endet innerhalb einer ebenenübergreifenden Maske
|
||||
@msg a multi-layer mask's operators are out of order die Operatoren einer ebenenübergreifenden Maske stehen in falscher Reihenfolge
|
||||
@msg a multi-layer mask needs one clipping path eine ebenenübergreifende Maske braucht genau einen Schnittpfad
|
||||
@msg a group crosses a multi-layer mask eine Gruppe überschneidet eine ebenenübergreifende Maske
|
||||
@msg it has art outside its layers es enthält Grafik außerhalb seiner Ebenen
|
||||
@msg it has more than {MAX_NODES} objects es enthält mehr als {MAX_NODES} Objekte
|
||||
@msg it has no layers es enthält keine Ebenen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4514,11 +4514,16 @@ digits Malayalam Μαλαγιάλαμ
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead αυτό δεν είναι λογότυπο επίπεδων χρωμάτων ({_1}% των συμπαγών περιοχών του αντιστοιχούν σε λίγα χρώματα), επομένως η λειτουργία Επίπεδο λογότυπο θα μετατρέψει τα ντεγκραντέ σε κηλίδες: χρησιμοποιήστε τη λειτουργία Χρώμα
|
||||
@msg `{what}` closes nothing το `{what}` δεν κλείνει κανένα στοιχείο
|
||||
@msg `{what}` closes something it didn't open το `{what}` κλείνει στοιχείο που δεν άνοιξε
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers μια μάσκα που καλύπτει πολλά επίπεδα εισάγεται ως ομάδα αποκοπής σε κάθε επίπεδο που καλύπτει
|
||||
@msg a graph's records don't end where they should: its art was read as it is οι εγγραφές ενός γραφήματος δεν τελειώνουν εκεί που πρέπει: το έργο του διαβάστηκε όπως είναι
|
||||
@msg `{w}` takes no operands το `{w}` δεν δέχεται τελεστέους
|
||||
@msg a wraparound group is inside a compound path μια ομάδα αναδίπλωσης κειμένου βρίσκεται μέσα σε σύνθετη διαδρομή
|
||||
@msg a path has too many points η διαδρομή έχει υπερβολικά πολλά σημεία
|
||||
@msg it ends inside a layer τερματίζει μέσα σε επίπεδο
|
||||
@msg it ends inside a multi-layer mask τερματίζει μέσα σε μάσκα πολλών επιπέδων
|
||||
@msg a multi-layer mask's operators are out of order οι τελεστές μιας μάσκας πολλών επιπέδων είναι σε λάθος σειρά
|
||||
@msg a multi-layer mask needs one clipping path μια μάσκα πολλών επιπέδων χρειάζεται μία διαδρομή αποκοπής
|
||||
@msg a group crosses a multi-layer mask μια ομάδα διασχίζει μια μάσκα πολλών επιπέδων
|
||||
@msg it has art outside its layers περιέχει σχέδιο εκτός των επιπέδων του
|
||||
@msg it has more than {MAX_NODES} objects περιέχει περισσότερα από {MAX_NODES} αντικείμενα
|
||||
@msg it has no layers δεν περιέχει επίπεδα
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 164 and column 5.
|
@@ -4566,11 +4566,16 @@ axis Both Ambos
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead esto no es un logotipo de colores planos ({_1}% de sus zonas sólidas coinciden con unos pocos colores planos), así que el modo Logotipo plano convertiría sus degradados en manchas: usa el modo Color
|
||||
@msg `{what}` closes nothing `{what}` no cierra nada
|
||||
@msg `{what}` closes something it didn't open `{what}` cierra algo que no abrió
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers una máscara que cubre varias capas entra como un grupo de recorte en cada capa que cubre
|
||||
@msg a graph's records don't end where they should: its art was read as it is los registros de un gráfico no terminan donde deberían: su ilustración se leyó tal cual
|
||||
@msg `{w}` takes no operands `{w}` no admite operandos
|
||||
@msg a wraparound group is inside a compound path un grupo de ceñir texto está dentro de un trazado compuesto
|
||||
@msg a path has too many points un trazado tiene demasiados puntos
|
||||
@msg it ends inside a layer terminan dentro de una capa
|
||||
@msg it ends inside a multi-layer mask terminan dentro de una máscara de varias capas
|
||||
@msg a multi-layer mask's operators are out of order los operadores de una máscara de varias capas están desordenados
|
||||
@msg a multi-layer mask needs one clipping path una máscara de varias capas necesita un trazado de recorte
|
||||
@msg a group crosses a multi-layer mask un grupo atraviesa una máscara de varias capas
|
||||
@msg it has art outside its layers tienen ilustraciones fuera de sus capas
|
||||
@msg it has more than {MAX_NODES} objects tienen más de {MAX_NODES} objetos
|
||||
@msg it has no layers no tienen capas
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4774,11 +4774,16 @@ imageTrace Outline Ääriviiva
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead tämä ei ole tasavärinen logo ({_1} % sen yhtenäisistä alueista vastaa muutamaa tasaväriä), joten Tasavärilogo-tila muuttaisi sen liukuvärit laikuiksi: käytä sen sijaan Väri-tilaa
|
||||
@msg `{what}` closes nothing `{what}` ei sulje mitään
|
||||
@msg `{what}` closes something it didn't open `{what}` sulkee jotain, mitä se ei avannut
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers useita tasoja peittävä maski tuodaan leikkausryhmänä jokaiseen tasoon, jonka se peittää
|
||||
@msg a graph's records don't end where they should: its art was read as it is kaavion tietueet eivät pääty siihen, mihin niiden pitäisi: sen piirros luettiin sellaisenaan
|
||||
@msg `{w}` takes no operands `{w}` ei ota operandeja
|
||||
@msg a wraparound group is inside a compound path tekstin rivitysryhmä on yhdistelmäpolun sisällä
|
||||
@msg a path has too many points polulla on liian monta pistettä
|
||||
@msg it ends inside a layer se päättyy tason sisään
|
||||
@msg it ends inside a multi-layer mask se päättyy monitasoisen maskin sisään
|
||||
@msg a multi-layer mask's operators are out of order monitasoisen maskin operaattorit ovat väärässä järjestyksessä
|
||||
@msg a multi-layer mask needs one clipping path monitasoinen maski tarvitsee yhden leikkauspolun
|
||||
@msg a group crosses a multi-layer mask ryhmä ylittää monitasoisen maskin rajan
|
||||
@msg it has art outside its layers siinä on kuvitusta tasojensa ulkopuolella
|
||||
@msg it has more than {MAX_NODES} objects siinä on yli {MAX_NODES} objektia
|
||||
@msg it has no layers siinä ei ole tasoja
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4556,11 +4556,16 @@ axis Both Les deux
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead ce n’est pas un logo en aplats ({_1} % de ses zones pleines correspondent à quelques couleurs unies), donc le mode Logo en aplats transformerait ses dégradés en taches : utilisez le mode Couleur
|
||||
@msg `{what}` closes nothing `{what}` ne ferme rien
|
||||
@msg `{what}` closes something it didn't open `{what}` ferme quelque chose qu’il n’a pas ouvert
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers un masque qui couvre plusieurs calques est importé comme un groupe de découpe dans chaque calque qu’il couvre
|
||||
@msg a graph's records don't end where they should: its art was read as it is les enregistrements d’un graphe ne se terminent pas là où ils le devraient : son illustration a été lue telle quelle
|
||||
@msg `{w}` takes no operands `{w}` n’accepte aucun opérande
|
||||
@msg a wraparound group is inside a compound path un groupe d’habillage de texte se trouve dans un tracé transparent
|
||||
@msg a path has too many points un tracé a trop de points
|
||||
@msg it ends inside a layer elles se terminent à l’intérieur d’un calque
|
||||
@msg it ends inside a multi-layer mask elles se terminent à l’intérieur d’un masque multicalque
|
||||
@msg a multi-layer mask's operators are out of order les opérateurs d’un masque multicalque sont dans le désordre
|
||||
@msg a multi-layer mask needs one clipping path un masque multicalque nécessite un seul tracé d’écrêtage
|
||||
@msg a group crosses a multi-layer mask un groupe chevauche un masque multicalque
|
||||
@msg it has art outside its layers elles contiennent des illustrations hors de leurs calques
|
||||
@msg it has more than {MAX_NODES} objects elles contiennent plus de {MAX_NODES} objets
|
||||
@msg it has no layers elles n’ont aucun calque
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4557,6 +4557,7 @@ imageTrace Outline Körvonal
|
||||
@msg `{to}` is not an available name ez a név nem használható: `{to}`
|
||||
@msg `{what}` closes nothing `{what}` semmit sem zár le
|
||||
@msg `{what}` closes something it didn't open `{what}` olyat zár le, amit nem nyitott meg
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers a több réteget lefedő maszk minden általa lefedett rétegben vágócsoportként jön be
|
||||
@msg a graph's records don't end where they should: its art was read as it is egy grafikon rekordjai nem ott érnek véget, ahol kellene: a grafikája úgy lett beolvasva, ahogy van
|
||||
@msg `{w}` takes no operands `{w}` nem fogad operandusokat
|
||||
@msg a wraparound group is inside a compound path egy szövegkörbefuttatási csoport összetett útvonalon belül van
|
||||
@@ -4772,6 +4773,10 @@ imageTrace Outline Körvonal
|
||||
@msg invalid restored panel group érvénytelen visszaállított panelcsoport
|
||||
@msg is not an image VectorCraft reads nem olyan kép, amelyet a VectorCraft olvas
|
||||
@msg it ends inside a layer egy rétegen belül ér véget
|
||||
@msg it ends inside a multi-layer mask egy többrétegű maszkon belül ér véget
|
||||
@msg a multi-layer mask's operators are out of order egy többrétegű maszk operátorai rossz sorrendben vannak
|
||||
@msg a multi-layer mask needs one clipping path egy többrétegű maszkhoz egy vágóútvonal kell
|
||||
@msg a group crosses a multi-layer mask egy csoport átnyúlik egy többrétegű maszkon
|
||||
@msg it has art outside its layers a rétegein kívül is van grafikája
|
||||
@msg it has more than one artboard egynél több rajztáblája van
|
||||
@msg it has more than {MAX_NODES} objects túl sok objektumot tartalmaz (legfeljebb {MAX_NODES})
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4607,11 +4607,16 @@ axis Both Entrambi
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead questo non è un logo a colori piatti ({_1}% delle sue aree piene corrisponde a pochi colori piatti), quindi la modalità Logo piatto trasformerebbe i suoi sfumati in macchie: usa la modalità Colore
|
||||
@msg `{what}` closes nothing `{what}` non chiude nulla
|
||||
@msg `{what}` closes something it didn't open `{what}` chiude qualcosa che non ha aperto
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers una maschera che copre più livelli viene importata come gruppo di ritaglio in ogni livello che copre
|
||||
@msg a graph's records don't end where they should: its art was read as it is i record di un grafico non finiscono dove dovrebbero: la sua grafica è stata letta così com’è
|
||||
@msg `{w}` takes no operands `{w}` non accetta operandi
|
||||
@msg a wraparound group is inside a compound path un gruppo di testo attorno si trova in un tracciato composto
|
||||
@msg a path has too many points un tracciato ha troppi punti
|
||||
@msg it ends inside a layer terminano all'interno di un livello
|
||||
@msg it ends inside a multi-layer mask terminano all'interno di una maschera multilivello
|
||||
@msg a multi-layer mask's operators are out of order gli operatori di una maschera multilivello non sono in ordine
|
||||
@msg a multi-layer mask needs one clipping path una maschera multilivello richiede un solo tracciato di ritaglio
|
||||
@msg a group crosses a multi-layer mask un gruppo attraversa una maschera multilivello
|
||||
@msg it has art outside its layers contengono grafica al di fuori dei loro livelli
|
||||
@msg it has more than {MAX_NODES} objects contengono più di {MAX_NODES} oggetti
|
||||
@msg it has no layers non hanno livelli
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4311,11 +4311,16 @@ swatch Bright Violet ビビッドバイオレット
|
||||
@msg unknown command `{0}`; did you mean `{1}`? `{0}` は不明なコマンドです。`{1}` のことですか?
|
||||
@msg `{what}` closes nothing `{what}` に対応する開始部分がありません
|
||||
@msg `{what}` closes something it didn't open `{what}` が対応しない開始部分を閉じています
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers 複数のレイヤーにまたがるマスクは、覆う各レイヤーでクリップグループとして読み込まれます
|
||||
@msg a graph's records don't end where they should: its art was read as it is グラフのレコードが正しい位置で終わっていません: アートはそのまま読み込まれました
|
||||
@msg `{w}` takes no operands `{w}` はオペランドを取りません
|
||||
@msg a wraparound group is inside a compound path テキストの回り込みグループが複合パスの中にあります
|
||||
@msg a path has too many points ポイントが多すぎるパスがあります
|
||||
@msg it ends inside a layer レイヤーの途中で終わっています
|
||||
@msg it ends inside a multi-layer mask 複数レイヤーにまたがるマスクの途中で終わっています
|
||||
@msg a multi-layer mask's operators are out of order 複数レイヤーにまたがるマスクの演算子の順序が正しくありません
|
||||
@msg a multi-layer mask needs one clipping path 複数レイヤーにまたがるマスクにはクリッピングパスが 1 つ必要です
|
||||
@msg a group crosses a multi-layer mask グループが複数レイヤーにまたがるマスクと交差しています
|
||||
@msg it has art outside its layers レイヤーの外にアートがあります
|
||||
@msg it has more than {MAX_NODES} objects オブジェクトが {MAX_NODES} 個を超えています
|
||||
@msg it has no layers レイヤーがありません
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4305,11 +4305,16 @@ font-technology Variable ცვლადი
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead ეს ერთფეროვანი ლოგო არ არის (მისი მყარი არეების {_1}% რამდენიმე ერთგვაროვან ფერს ემთხვევა), ამიტომ Flat Logo რეჟიმი მის გრადიენტებს ლაქებად აქცევდა: გამოიყენეთ Color რეჟიმი
|
||||
@msg `{what}` closes nothing `{what}` არაფერს ხურავს
|
||||
@msg `{what}` closes something it didn't open `{what}` ხურავს იმას, რაც არ გაუხსნია
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers რამდენიმე ფენის დამფარავი ნიღაბი შემოდის როგორც ჩამოჭრის ჯგუფი თითოეულ ფენაში, რომელსაც ფარავს
|
||||
@msg a graph's records don't end where they should: its art was read as it is დიაგრამის ჩანაწერები იქ არ მთავრდება, სადაც უნდა: მისი გრაფიკა წაკითხულია ისე, როგორც არის
|
||||
@msg `{w}` takes no operands `{w}` ოპერანდებს არ იღებს
|
||||
@msg a wraparound group is inside a compound path ტექსტის გარსშემოვლების ჯგუფი შედგენილი ტრაექტორიის შიგნითაა
|
||||
@msg a path has too many points ტრაექტორიას ზედმეტად ბევრი წერტილი აქვს
|
||||
@msg it ends inside a layer ის შრის შიგნით მთავრდება
|
||||
@msg it ends inside a multi-layer mask ის მრავალშრიანი ნიღბის შიგნით მთავრდება
|
||||
@msg a multi-layer mask's operators are out of order მრავალშრიანი ნიღბის ოპერატორები არასწორი თანმიმდევრობითაა
|
||||
@msg a multi-layer mask needs one clipping path მრავალშრიან ნიღაბს ერთი მომჭრელი ტრაექტორია სჭირდება
|
||||
@msg a group crosses a multi-layer mask ჯგუფი მრავალშრიან ნიღაბს კვეთს
|
||||
@msg it has art outside its layers მას შრეების გარეთ ნახატი აქვს
|
||||
@msg it has more than {MAX_NODES} objects მას {MAX_NODES}-ზე მეტი ობიექტი აქვს
|
||||
@msg it has no layers მას შრეები არ აქვს
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -4238,11 +4238,16 @@ theme Appearance 외관
|
||||
@msg unknown command `{0}`; did you mean `{1}`? 알 수 없는 명령 `{0}`: `{1}`을(를) 의미하셨습니까?
|
||||
@msg `{what}` closes nothing `{what}`이(가) 닫는 항목이 없습니다
|
||||
@msg `{what}` closes something it didn't open `{what}`이(가) 열지 않은 항목을 닫습니다
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers 여러 레이어에 걸친 마스크는 덮는 각 레이어에서 클리핑 그룹으로 들어옵니다
|
||||
@msg a graph's records don't end where they should: its art was read as it is 그래프의 레코드가 끝나야 할 곳에서 끝나지 않습니다: 아트는 있는 그대로 읽었습니다
|
||||
@msg `{w}` takes no operands `{w}`은(는) 피연산자를 받지 않습니다
|
||||
@msg a wraparound group is inside a compound path 문자 감싸기 그룹이 컴파운드 패스 안에 있습니다
|
||||
@msg a path has too many points 패스의 점이 너무 많습니다
|
||||
@msg it ends inside a layer 레이어 안에서 끝납니다
|
||||
@msg it ends inside a multi-layer mask 여러 레이어 마스크 안에서 끝납니다
|
||||
@msg a multi-layer mask's operators are out of order 여러 레이어 마스크의 연산자 순서가 잘못되었습니다
|
||||
@msg a multi-layer mask needs one clipping path 여러 레이어 마스크에는 클리핑 패스가 하나 필요합니다
|
||||
@msg a group crosses a multi-layer mask 그룹이 여러 레이어 마스크에 걸쳐 있습니다
|
||||
@msg it has art outside its layers 레이어 밖에 아트웍이 있습니다
|
||||
@msg it has more than {MAX_NODES} objects 개체가 {MAX_NODES}개를 넘습니다
|
||||
@msg it has no layers 레이어가 없습니다
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4698,11 +4698,16 @@ imageTrace Outline Kontur
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead to nie jest logo z płaskimi kolorami ({_1}% jego jednolitych obszarów pasuje do kilku płaskich kolorów), więc tryb Płaskie logo zamieniłby jego gradienty w plamy: użyj trybu Kolor
|
||||
@msg `{what}` closes nothing `{what}` niczego nie zamyka
|
||||
@msg `{what}` closes something it didn't open `{what}` zamyka coś, czego nie otworzył
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers maska obejmująca kilka warstw jest wczytywana jako grupa przycinająca w każdej obejmowanej warstwie
|
||||
@msg a graph's records don't end where they should: its art was read as it is rekordy wykresu nie kończą się tam, gdzie powinny: jego grafika została wczytana tak, jak jest
|
||||
@msg `{w}` takes no operands `{w}` nie przyjmuje operandów
|
||||
@msg a wraparound group is inside a compound path grupa oblewania tekstem jest wewnątrz ścieżki złożonej
|
||||
@msg a path has too many points ścieżka ma zbyt wiele punktów
|
||||
@msg it ends inside a layer kończy się wewnątrz warstwy
|
||||
@msg it ends inside a multi-layer mask kończy się wewnątrz maski wielowarstwowej
|
||||
@msg a multi-layer mask's operators are out of order operatory maski wielowarstwowej są w złej kolejności
|
||||
@msg a multi-layer mask needs one clipping path maska wielowarstwowa wymaga jednej ścieżki przycinającej
|
||||
@msg a group crosses a multi-layer mask grupa przecina maskę wielowarstwową
|
||||
@msg it has art outside its layers ma kompozycję poza warstwami
|
||||
@msg it has more than {MAX_NODES} objects ma ponad {MAX_NODES} obiektów
|
||||
@msg it has no layers nie ma warstw
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4148,11 +4148,16 @@ axis Both Ambos
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead este não é um logotipo de cores chapadas ({_1}% de suas áreas sólidas correspondem a poucas cores chapadas), então o modo Logotipo plano transformaria seus gradientes em manchas: use o modo Cor
|
||||
@msg `{what}` closes nothing `{what}` não fecha nada
|
||||
@msg `{what}` closes something it didn't open `{what}` fecha algo que não abriu
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers uma máscara que cobre várias camadas entra como um grupo de recorte em cada camada que cobre
|
||||
@msg a graph's records don't end where they should: its art was read as it is os registros de um gráfico não terminam onde deveriam: sua arte foi lida como está
|
||||
@msg `{w}` takes no operands `{w}` não aceita operandos
|
||||
@msg a wraparound group is inside a compound path um grupo de quebra de texto está dentro de um traçado composto
|
||||
@msg a path has too many points um traçado tem pontos demais
|
||||
@msg it ends inside a layer termina dentro de uma camada
|
||||
@msg it ends inside a multi-layer mask termina dentro de uma máscara de várias camadas
|
||||
@msg a multi-layer mask's operators are out of order os operadores de uma máscara de várias camadas estão fora de ordem
|
||||
@msg a multi-layer mask needs one clipping path uma máscara de várias camadas precisa de um caminho de recorte
|
||||
@msg a group crosses a multi-layer mask um grupo atravessa uma máscara de várias camadas
|
||||
@msg it has art outside its layers tem arte fora de suas camadas
|
||||
@msg it has more than {MAX_NODES} objects tem mais de {MAX_NODES} objetos
|
||||
@msg it has no layers não tem camadas
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4602,11 +4602,16 @@ axis Both Оба
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead это не логотип из плоских цветов ({_1}% его сплошных областей совпадает с несколькими плоскими цветами), поэтому режим «Плоский логотип» превратил бы градиенты в пятна: используйте режим «Цвет»
|
||||
@msg `{what}` closes nothing `{what}` ничего не закрывает
|
||||
@msg `{what}` closes something it didn't open `{what}` закрывает то, что не открывал
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers маска, охватывающая несколько слоёв, переносится как обтравочная группа в каждый слой, который она охватывает
|
||||
@msg a graph's records don't end where they should: its art was read as it is записи диаграммы не заканчиваются там, где должны: её графика прочитана как есть
|
||||
@msg `{w}` takes no operands `{w}` не принимает операндов
|
||||
@msg a wraparound group is inside a compound path группа обтекания текстом находится внутри составного контура
|
||||
@msg a path has too many points в контуре слишком много точек
|
||||
@msg it ends inside a layer они заканчиваются внутри слоя
|
||||
@msg it ends inside a multi-layer mask они заканчиваются внутри многослойной маски
|
||||
@msg a multi-layer mask's operators are out of order операторы многослойной маски идут в неправильном порядке
|
||||
@msg a multi-layer mask needs one clipping path многослойной маске нужен один контур обрезки
|
||||
@msg a group crosses a multi-layer mask группа пересекает многослойную маску
|
||||
@msg it has art outside its layers в них есть графика вне слоёв
|
||||
@msg it has more than {MAX_NODES} objects в них больше {MAX_NODES} объектов
|
||||
@msg it has no layers в них нет слоёв
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4465,11 +4465,16 @@ axis Both Båda
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead det här är ingen logotyp i platta färger ({_1} % av dess enfärgade ytor matchar några få platta färger), så läget Platt logotyp skulle göra om dess gradienter till fläckar: använd läget Färg i stället
|
||||
@msg `{what}` closes nothing `{what}` stänger ingenting
|
||||
@msg `{what}` closes something it didn't open `{what}` stänger något som den inte öppnade
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers en mask som täcker flera lager kommer in som en urklippsgrupp i varje lager den täcker
|
||||
@msg a graph's records don't end where they should: its art was read as it is ett diagrams poster slutar inte där de ska: dess grafik lästes som den är
|
||||
@msg `{w}` takes no operands `{w}` tar inga operander
|
||||
@msg a wraparound group is inside a compound path en textombrytningsgrupp ligger inuti en sammansatt bana
|
||||
@msg a path has too many points en bana har för många punkter
|
||||
@msg it ends inside a layer den slutar inuti ett lager
|
||||
@msg it ends inside a multi-layer mask den slutar inuti en flerlagersmask
|
||||
@msg a multi-layer mask's operators are out of order operatorerna för en flerlagersmask står i fel ordning
|
||||
@msg a multi-layer mask needs one clipping path en flerlagersmask behöver en klippbana
|
||||
@msg a group crosses a multi-layer mask en grupp korsar en flerlagersmask
|
||||
@msg it has art outside its layers den har grafik utanför sina lager
|
||||
@msg it has more than {MAX_NODES} objects den har fler än {MAX_NODES} objekt
|
||||
@msg it has no layers den har inga lager
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4303,11 +4303,16 @@ axis Both Her İkisi
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead bu düz renkli bir logo değildir (düz alanların %{_1}'si birkaç düz renkle eşleşir), dolayısıyla Düz Logo modu degradelerini yamalara dönüştürür: bunun yerine Renk modunu kullanın
|
||||
@msg `{what}` closes nothing `{what}` hiçbir şeyi kapatmaz
|
||||
@msg `{what}` closes something it didn't open `{what}` açmadığı bir şeyi kapatıyor
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers birkaç katmanı kaplayan bir maske, kapladığı her katmana bir kırpma grubu olarak gelir
|
||||
@msg a graph's records don't end where they should: its art was read as it is bir grafiğin kayıtları bitmesi gereken yerde bitmiyor: resmi olduğu gibi okundu
|
||||
@msg `{w}` takes no operands `{w}` işlenen almaz
|
||||
@msg a wraparound group is inside a compound path bir metin kaydırma grubu bileşik bir yolun içinde
|
||||
@msg a path has too many points bir yolun çok fazla noktası var
|
||||
@msg it ends inside a layer bir katmanın içinde bitiyor
|
||||
@msg it ends inside a multi-layer mask çok katmanlı bir maskenin içinde bitiyor
|
||||
@msg a multi-layer mask's operators are out of order çok katmanlı bir maskenin işleçleri yanlış sırada
|
||||
@msg a multi-layer mask needs one clipping path çok katmanlı bir maskenin bir kırpma yoluna ihtiyacı var
|
||||
@msg a group crosses a multi-layer mask bir grup çok katmanlı bir maskeyi kesiyor
|
||||
@msg it has art outside its layers katmanlarının dışında sanat var
|
||||
@msg it has more than {MAX_NODES} objects {MAX_NODES}'den daha fazla nesneye sahip
|
||||
@msg it has no layers katmanı yok
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4591,11 +4591,16 @@ axis Both Обидві
|
||||
@msg this isn't a flat-colour logo ({_1}% of its solid areas match a few flat colours), so Flat Logo mode would turn its gradients into patches: use Color mode instead це не логотип із плоских кольорів ({_1}% його суцільних областей збігається з кількома плоскими кольорами), тому режим «Плоский логотип» перетворив би градієнти на плями: використовуйте режим «Колір»
|
||||
@msg `{what}` closes nothing `{what}` нічого не закриває
|
||||
@msg `{what}` closes something it didn't open `{what}` закриває те, що не відкривав
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers маску, що охоплює кілька шарів, перенесено як групу відсікання в кожен шар, який вона охоплює
|
||||
@msg a graph's records don't end where they should: its art was read as it is записи діаграми не закінчуються там, де мають: її графіку прочитано як є
|
||||
@msg `{w}` takes no operands `{w}` не приймає операндів
|
||||
@msg a wraparound group is inside a compound path група обтікання текстом розташована всередині складеного контуру
|
||||
@msg a path has too many points у контурі занадто багато точок
|
||||
@msg it ends inside a layer вони закінчуються всередині шару
|
||||
@msg it ends inside a multi-layer mask вони закінчуються всередині багатошарової маски
|
||||
@msg a multi-layer mask's operators are out of order оператори багатошарової маски йдуть у неправильному порядку
|
||||
@msg a multi-layer mask needs one clipping path багатошаровій масці потрібен один відсічний контур
|
||||
@msg a group crosses a multi-layer mask група перетинає багатошарову маску
|
||||
@msg it has art outside its layers у них є графіка поза шарами
|
||||
@msg it has more than {MAX_NODES} objects в них більше {MAX_NODES} об’єктів
|
||||
@msg it has no layers у них немає шарів
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 178 and column 5.
|
@@ -4209,6 +4209,7 @@ theme Appearance Giao diện
|
||||
@msg `{to}` is not an available name `{to}` không phải là tên khả dụng
|
||||
@msg `{what}` closes nothing `{what}` không đóng gì
|
||||
@msg `{what}` closes something it didn't open `{what}` đóng thứ nó chưa mở
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers một mặt nạ phủ nhiều lớp được nhập thành một nhóm cắt xén trong mỗi lớp mà nó phủ
|
||||
@msg a graph's records don't end where they should: its art was read as it is các bản ghi của một biểu đồ không kết thúc đúng chỗ: hình vẽ của nó được đọc nguyên trạng
|
||||
@msg `{w}` takes no operands `{w}` không nhận toán hạng
|
||||
@msg a wraparound group is inside a compound path một nhóm bao văn bản nằm trong một đường dẫn phức
|
||||
@@ -4422,6 +4423,10 @@ theme Appearance Giao diện
|
||||
@msg invalid restored panel group nhóm bảng được phục hồi không hợp lệ
|
||||
@msg is not an image VectorCraft reads không phải ảnh mà VectorCraft đọc được
|
||||
@msg it ends inside a layer nó kết thúc bên trong một lớp
|
||||
@msg it ends inside a multi-layer mask nó kết thúc bên trong một mặt nạ nhiều lớp
|
||||
@msg a multi-layer mask's operators are out of order các toán tử của mặt nạ nhiều lớp không đúng thứ tự
|
||||
@msg a multi-layer mask needs one clipping path mặt nạ nhiều lớp cần một đường dẫn cắt
|
||||
@msg a group crosses a multi-layer mask một nhóm vắt ngang mặt nạ nhiều lớp
|
||||
@msg it has art outside its layers nó có tác phẩm ngoài các lớp
|
||||
@msg it has more than one artboard nó có nhiều hơn một bảng vẽ
|
||||
@msg it has more than {MAX_NODES} objects nó có hơn {MAX_NODES} đối tượng
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 200 and column 5.
|
@@ -4036,11 +4036,16 @@ imageTrace Outline 轮廓
|
||||
@msg unknown command `{0}`; did you mean `{1}`? 未知命令 `{0}`;您是否想输入 `{1}`?
|
||||
@msg `{what}` closes nothing `{what}` 没有可结束的内容
|
||||
@msg `{what}` closes something it didn't open `{what}` 结束了并非由它开始的内容
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers 覆盖多个图层的蒙版会在其覆盖的每个图层中作为剪切组导入
|
||||
@msg a graph's records don't end where they should: its art was read as it is 图表的记录没有在应有的位置结束:其图稿按原样读取
|
||||
@msg `{w}` takes no operands `{w}` 不接受操作数
|
||||
@msg a wraparound group is inside a compound path 文本绕排组位于复合路径内
|
||||
@msg a path has too many points 某条路径的点过多
|
||||
@msg it ends inside a layer 它在图层内部结束
|
||||
@msg it ends inside a multi-layer mask 它在跨图层蒙版内部结束
|
||||
@msg a multi-layer mask's operators are out of order 跨图层蒙版的运算符顺序错误
|
||||
@msg a multi-layer mask needs one clipping path 跨图层蒙版需要一条剪切路径
|
||||
@msg a group crosses a multi-layer mask 编组跨越了跨图层蒙版
|
||||
@msg it has art outside its layers 它有位于图层之外的图稿
|
||||
@msg it has more than {MAX_NODES} objects 它包含超过 {MAX_NODES} 个对象
|
||||
@msg it has no layers 它没有图层
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1958,11 +1958,16 @@ file-filter Templates 範本
|
||||
@msg unknown command `{0}`; did you mean `{1}`? 未知的指令 `{0}`;您是指 `{1}` 嗎?
|
||||
@msg `{what}` closes nothing `{what}` 沒有可結束的內容
|
||||
@msg `{what}` closes something it didn't open `{what}` 結束了並非由它開始的內容
|
||||
@msg a mask that covers several layers comes in as a clipping group in each layer it covers 覆蓋多個圖層的遮色片會在其覆蓋的每個圖層中作為剪裁群組匯入
|
||||
@msg a graph's records don't end where they should: its art was read as it is 圖表的記錄沒有在應有的位置結束:其圖稿按原樣讀取
|
||||
@msg `{w}` takes no operands `{w}` 不接受運算元
|
||||
@msg a wraparound group is inside a compound path 文字繞圖群組位於複合路徑內
|
||||
@msg a path has too many points 有一條路徑的點過多
|
||||
@msg it ends inside a layer 它在圖層內部結束
|
||||
@msg it ends inside a multi-layer mask 它在跨圖層遮色片內部結束
|
||||
@msg a multi-layer mask's operators are out of order 跨圖層遮色片的運算子順序錯誤
|
||||
@msg a multi-layer mask needs one clipping path 跨圖層遮色片需要一條剪裁路徑
|
||||
@msg a group crosses a multi-layer mask 群組跨越了跨圖層遮色片
|
||||
@msg it has art outside its layers 它有位於圖層之外的圖稿
|
||||
@msg it has more than {MAX_NODES} objects 它有超過 {MAX_NODES} 個物件
|
||||
@msg it has no layers 它沒有圖層
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -43,6 +43,8 @@ private editing data. VectorCraft:
|
||||
write) is its own editing data: it opens through the layers its program has, compared with its page
|
||||
when the program runs, from the layers alone when it names its prolog without including it (#1027), and with its art on one
|
||||
layer when it has no layers (Illustrator 3, and image editors' exported paths: storytold/photocraft#6036).
|
||||
A multi-layer mask (`Mb` … `Md` … `MB`) comes in as a clipping group in each layer it covers, each
|
||||
clipped by a copy of the mask's path.
|
||||
RGB in the PDF page's `ICCBased` spaces keeps the file's numbers in a `.ai` (the `uncalibrated_rgb`
|
||||
import option, on for editor documents, off for PDFs), so `.ai` files tagged with a non-sRGB RGB profile
|
||||
open with different, unconverted RGB colours than before.
|
||||
|
||||
Reference in New Issue
Block a user