EPS: Save As options are menus with readable names, and Export As's Range shows an example

Save As to an EPS file showed Preview Format, Overprints and Flattener
Preset as text fields holding their ids (tiffColor, preserve, medium),
the PostScript level as a number field, and labeled every EPS option
except Use Artboards from its name ("Cmyk Post Script", "Thumbnails").

The dialog now shows the options Export's EPS Options shows. Preview,
Overprints, Flattener preset (the built-in presets, then saved ones) and
PostScript are menus of readable names. Transparent and Opaque apply to
the color TIFF preview only. Embed Fonts shows checked and disabled. The
PostScript level comes last. A pick writes the same values as before
(previewFormat "tiffColor", a built-in preset's id, a saved preset's
name, the level as a number). A value that the save would reject shows
as it is.

Every option the dialog shows has a written label. "Preview:" has a row
in every catalog, and the de, it, ja, ko, uk, vi and zh-hant catalogs
gain the menu names, which Export's EPS Options also showed in English.

Export As's Range field shows the "1-3, 5" example when emptied, as
Save As's does.
This commit is contained in:
dotCooCoo
2026-11-11 19:04:27 -08:00
parent 269a75c45c
commit 935ebccc25
33 changed files with 394 additions and 12 deletions
+2 -1
View File
@@ -103,7 +103,8 @@ fn body(_: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
d.fields.insert("all".into(), json!(all));
}
let mut range = d.str("range");
if ui.add_enabled(!all, egui::TextEdit::singleline(&mut range).align(egui::Align2::LEFT_CENTER).desired_width(90.0)).changed() {
let field = egui::TextEdit::singleline(&mut range).align(egui::Align2::LEFT_CENTER).desired_width(90.0).hint_text("1-3, 5");
if ui.add_enabled(!all, field).changed() {
d.fields.insert("range".into(), json!(range));
}
});
+126 -10
View File
@@ -9,7 +9,10 @@
//! artboard to a separate file, with `all` (true: every artboard) or `range`, Include Linked Files,
//! Embed ICC Profiles, Create PDF-Compatible File and Use Compression. EPS shows Use Artboards
//! (`useArtboards`, off by default: the bounding box fits the visible art) with the same `all` or
//! `range` under it. A native file's Version is a menu of the versions VectorCraft writes
//! `range` under it, then the options Export's EPS Options shows: Preview, Overprints, Flattener
//! preset and PostScript are menus that write the option's value (`previewFormat: "tiffColor"`,
//! `overprints: "preserve"`, `flattenerPreset: "medium"` or a saved preset's name, `level: 3`).
//! A native file's Version is a menu of the versions VectorCraft writes
//! (`version`, named by the releases that read each). A
//! `.ai` file's Version comes first: PDF-compatible, or legacy version 7 (`aiVersion: "7"`, a file
//! per artboard), which takes only Transparent Images (`transparentImages`), Hidden Objects
@@ -20,7 +23,9 @@
use std::sync::OnceLock;
use serde_json::{Map, Value, json};
use vectorcraft_engine::cmd::FlattenOptions;
use vectorcraft_engine::cmd::fileio::{self, ArtboardPick, Format, FormatOption, SAVE_FORMATS, SaveMode, TEMPLATE_FORMATS};
use vectorcraft_eps::{Level, Overprint, Preview};
use super::{DialogResult, DialogSpec, form};
use crate::state::Dialog;
@@ -109,19 +114,87 @@ fn shown(f: &Format) -> impl Iterator<Item = &'static FormatOption> {
})
}
/// An option's label: the save options as the reference app's options dialog names them, the
/// others from their names.
/// An option's label: its written label, or for an option without one, its name split into words.
fn label(o: &FormatOption) -> String {
match o.name {
written_label(o).unwrap_or_else(|| form::humanize(o.name))
}
/// The written label of option `o`, translated.
fn written_label(o: &FormatOption) -> Option<String> {
Some(match o.name {
"separateArtboards" => tl!("Save each artboard to a separate file").into(),
"useArtboards" => tl!("Use Artboards").into(),
"includeLinked" => tl!("Include Linked Files").into(),
"includeLinked" | "includeLinkedFiles" => tl!("Include Linked Files").into(),
"embedProfiles" => tl!("Embed ICC Profiles").into(),
"pdfCompatible" => tl!("Create PDF-Compatible File").into(),
"compress" => tl!("Use Compression").into(),
"editingData" => tl!("Include Editing Data for Other Apps").into(),
_ => form::humanize(o.name),
"version" | "aiVersion" => tl!("Version:").into(),
"transparentImages" => tl!("Transparent Images:").into(),
"hiddenObjects" => tl!("Hidden Objects:").into(),
"outlineText" => tl!("Text:").into(),
"preview" => tl!("Preview").into(),
"thumbnails" => tl!("Include Document Thumbnails").into(),
"previewFormat" => tl!("Preview:").into(),
"transparentPreview" => tl!("Transparent").into(),
"overprints" => tl!("Overprints:").into(),
"flattenerPreset" => tl!("Flattener preset:").into(),
"embedFonts" => tl!("Embed Fonts (for other applications)").into(),
"cmykPostScript" => tl!("Include CMYK PostScript in RGB Files").into(),
"compatibleGradients" => tl!("Compatible Gradient and Gradient Mesh Printing").into(),
"level" => tl!("PostScript:").into(),
_ => return None,
})
}
/// The values of an option that takes one of a fixed set, each with the name its menu shows, and
/// `at`, the entry the option's value picks as the save reads it (none when the save would reject
/// the value). The first `builtins` names are VectorCraft's own (translated where they are shown);
/// the others are names the user gave (saved flattener presets), shown as they are.
struct Choices {
values: Vec<Value>,
names: Vec<String>,
builtins: usize,
at: Option<usize>,
}
/// The choices of `f`'s option `o`, whose value is `value`, when it takes one of a fixed set of
/// values: EPS's preview format, overprints, PostScript level and flattener preset (the built-in
/// presets by id, then the saved ones by name).
fn choices(app: &VectorcraftApp, f: &Format, o: &FormatOption, value: &Value) -> Option<Choices> {
if f.id != "eps" {
return None;
}
let text = value.as_str().map_or_else(|| value.to_string(), str::to_string);
let (pairs, builtins, at): (Vec<(Value, String)>, Option<usize>, Option<usize>) = match o.name {
"previewFormat" => (
Preview::ALL.iter().map(|p| (json!(p.id()), p.label().to_string())).collect(),
None,
Preview::from_id(&text).and_then(|p| Preview::ALL.iter().position(|q| *q == p)),
),
"overprints" => (
Overprint::ALL.iter().map(|p| (json!(p.id()), p.label().to_string())).collect(),
None,
Overprint::from_id(&text).and_then(|p| Overprint::ALL.iter().position(|q| *q == p)),
),
// The level is a number in the save options.
"level" => (
Level::ALL.iter().filter_map(|l| Some((json!(l.id().parse::<u64>().ok()?), l.label().to_string()))).collect(),
None,
Level::from_id(&text).and_then(|l| Level::ALL.iter().position(|q| *q == l)),
),
"flattenerPreset" => {
let presets = app.session.flattener_presets();
let id = |name: &str| FlattenOptions::PRESETS.into_iter().find(|id| FlattenOptions::preset_label(id) == Some(name));
let pairs = presets.iter().map(|p| (id(&p.name).map_or_else(|| json!(p.name), |id| json!(id)), p.name.clone())).collect();
let at = app.session.flattener_preset(&text).and_then(|p| presets.iter().position(|q| q.name == p.name));
(pairs, Some(FlattenOptions::builtin_presets().len()), at)
}
_ => return None,
};
let builtins = builtins.unwrap_or(pairs.len());
let (values, names): (Vec<Value>, Vec<String>) = pairs.into_iter().unzip();
Some(Choices { values, names, builtins, at })
}
/// Every artboard (the All choice under Save each artboard to a separate file or Use Artboards):
@@ -181,9 +254,10 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
// Version first; the legacy version takes only its own options.
let legacy = legacy_ai(d);
let mut rows: Vec<&FormatOption> = shown(f).filter(|o| LEGACY_ONLY.contains(&o.name) == legacy || o.name == "aiVersion").collect();
rows.sort_by_key(|o| o.name != "aiVersion");
// EPS's PostScript level comes last, as in Export's EPS Options.
rows.sort_by_key(|o| (o.name != "aiVersion", f.id == "eps" && o.name == "level"));
for o in rows {
option_row(app, ui, d, o);
option_row(app, ui, d, f, o);
}
});
if legacy_ai(d) && app.session.active().is_some_and(|st| st.doc.artboards.len() > 1) {
@@ -344,8 +418,9 @@ fn artboard_picker(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog)
}
}
/// One option: a checkbox, an artboard menu, a version menu, a number or a text field.
fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, o: &FormatOption) {
/// One option of format `f`: a checkbox, an artboard menu, a version menu, a menu of its
/// [`choices`], a number or a text field.
fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, f: &Format, o: &FormatOption) {
let t = Tokens::get(ui.ctx());
let label = label(o);
let value = d.fields.get(o.name).cloned().unwrap_or(Value::Null);
@@ -397,6 +472,40 @@ fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, o: &Forma
ui.end_row();
return;
}
if let Some(c) = choices(app, f, o, &value) {
ui.label(egui::RichText::new(&label).color(t.text_dim)).on_hover_text(o.description);
// A value none of them names shows as it is.
let current = c.at.and_then(|i| c.names.get(i)).cloned().unwrap_or_else(|| value.as_str().map_or_else(|| value.to_string(), str::to_string));
let names: Vec<&str> = c.names.iter().map(String::as_str).collect();
if let Some(i) = super::mixed_dropdown(ui, ("save-option", o.name), &current, &names, 254.0, |k| k < c.builtins) {
choose(d, o, &c, i);
}
ui.end_row();
return;
}
if f.id == "eps" && o.name == "transparentPreview" {
// Only the color preview can keep transparency.
ui.label("");
let color = Preview::from_id(&d.str("previewFormat")) == Some(Preview::TiffColor);
let transparent = value.as_bool().unwrap_or(true);
ui.horizontal(|ui| {
for (name, on) in [(tl!("Transparent"), true), (tl!("Opaque"), false)] {
if widgets::radio(ui, name, color && transparent == on, color) {
d.fields.insert(o.name.into(), json!(on));
}
ui.add_space(12.0);
}
});
ui.end_row();
return;
}
if f.id == "eps" && o.name == "embedFonts" {
// Type is written as glyph outlines, which need no fonts.
ui.label("");
widgets::check_tip(ui, &label, true, false, o.description);
ui.end_row();
return;
}
if o.ty == "boolean" {
ui.label("");
let on = value.as_bool().unwrap_or(false);
@@ -435,6 +544,13 @@ fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, o: &Forma
ui.end_row();
}
/// Option `o` set to the value of entry `i` of its menu `c`.
fn choose(d: &mut Dialog, o: &FormatOption, c: &Choices, i: usize) {
if let Some(v) = c.values.get(i) {
d.fields.insert(o.name.into(), v.clone());
}
}
/// The native versions VectorCraft writes, newest first, each with the first release that reads
/// it (the format version each release tag writes: 2 in 0.1, 3 from 0.2, 4 from 0.8).
const NATIVE_VERSIONS: [(u32, &str); 4] = [(4, "0.8"), (3, "0.2"), (2, "0.1"), (1, "0.1")];
@@ -407,6 +407,154 @@ fn eps_save_as_shows_use_artboards_off_and_writes_the_art_or_the_artboard() {
assert_eq!(bounding_box(&saved[2].1), "%%BoundingBox: 0 0 100 80");
}
/// Save As › EPS shows the options of Export's EPS Options: Preview, Overprints, Flattener preset
/// and PostScript as menus of readable names (not fields holding `tiffColor`, `preserve` and
/// `medium`), the checkboxes under written labels, and the PostScript level last.
#[test]
fn eps_save_options_are_menus_with_readable_names() {
let (mut app, _, _) = desktop("art.eps");
app.run("file.saveAs", json!({})).unwrap();
let text = crate::tests_labels::painted_text(&mut app, |app, ui| super::super::show(app, ui.ctx()));
let lines: Vec<&str> = text.lines().collect();
for shown in [
"Preview:",
"TIFF (8-bit Color)",
"Transparent",
"Opaque",
"Overprints:",
"Preserve",
"Flattener preset:",
"Medium Resolution",
"Embed Fonts (for other applications)",
"Include Linked Files",
"Include Document Thumbnails",
"Include CMYK PostScript in RGB Files",
"Compatible Gradient and Gradient Mesh Printing",
"PostScript:",
"Language Level 3",
] {
assert!(lines.contains(&shown), "{shown:?} in {text}");
}
for id in ["tiffColor", "preserve", "medium", "Cmyk Post Script", "Preview Format:", "Level:", "Thumbnails"] {
assert!(!lines.contains(&id), "{id:?} in {text}");
}
let at = |s: &str| lines.iter().position(|l| *l == s).unwrap();
assert!(at("PostScript:") > at("Compatible Gradient and Gradient Mesh Printing"), "{text}");
}
/// Every option the save options dialog shows, in every format it serves, has a written label:
/// none is painted as its name split into words.
#[test]
fn save_options_have_written_labels() {
// The web's Save As and Save as Template dialogs show the options of every format they pick.
let formats = SAVE_FORMATS.iter().map(|id| (*id, "file.saveAs")).chain(TEMPLATE_FORMATS.iter().map(|id| (*id, "file.saveAsTemplate")));
for (id, command) in formats {
let (mut app, _) = web();
app.run(command, json!({})).unwrap();
let mut d = app.ui.dialog.take().unwrap();
switch_format(&mut app, &mut d, id);
app.ui.dialog = Some(d);
assert_eq!((dialog(&app).kind.as_str(), dialog(&app).str("format").as_str()), (KIND, id));
let text = crate::tests_labels::painted_text(&mut app, |app, ui| super::super::show(app, ui.ctx()));
let f = fileio::format(id).unwrap();
for o in shown(f) {
let written = written_label(o);
assert!(written.is_some(), "{id}: {} has no written label", o.name);
let split = form::humanize(o.name);
let split = split.trim_end_matches(':');
assert!(
written.as_deref().map(|w| w.trim_end_matches(':')) == Some(split) || !text.lines().any(|l| l == split),
"{id}: {split:?} in {text}"
);
}
}
}
/// A pick from an EPS menu saves the option's value: the id, the level as a number, a saved
/// flattener preset by its name. The file is written with them.
#[test]
fn picking_eps_menu_items_saves_their_values() {
let (mut app, written, _) = desktop("art.eps");
app.session.prefs.flattener_presets.push(vectorcraft_engine::cmd::FlattenerPreset {
name: "Mine".into(),
options: vectorcraft_engine::cmd::FlattenOptions::preset("low").unwrap(),
});
app.run("file.saveAs", json!({})).unwrap();
let f = fileio::format("eps").unwrap();
let mut d = app.ui.dialog.take().unwrap();
for (name, pick, value) in [
("previewFormat", "None", json!("none")),
("overprints", "Discard", json!("discard")),
("flattenerPreset", "Mine", json!("Mine")),
("level", "Language Level 2", json!(2)),
] {
let o = f.options.iter().find(|o| o.name == name).unwrap();
let c = choices(&app, f, o, &Value::Null).unwrap_or_else(|| panic!("{name} is a menu"));
let i = c.names.iter().position(|n| n == pick).unwrap_or_else(|| panic!("{pick} in {name}: {:?}", c.names));
choose(&mut d, o, &c, i);
assert_eq!(d.fields[name], value, "{name}");
assert_eq!(choices(&app, f, o, &value).unwrap().at, Some(i), "{name}: the menu shows the pick");
}
// The built-in presets come first, by id. A value picks the entry the save reads it as: a
// preset by id or name in any case, a level by its digits, a preview or overprint by id only.
let at = |name: &str, value: Value| {
let o = f.options.iter().find(|o| o.name == name).unwrap();
choices(&app, f, o, &value).unwrap().at
};
let o = f.options.iter().find(|o| o.name == "flattenerPreset").unwrap();
let c = choices(&app, f, o, &Value::Null).unwrap();
assert_eq!(c.values, [json!("high"), json!("medium"), json!("low"), json!("Mine")]);
assert_eq!((c.builtins, c.at), (3, None));
assert_eq!(
(at("flattenerPreset", json!("MEDIUM RESOLUTION")), at("flattenerPreset", json!("mine")), at("flattenerPreset", json!("Other"))),
(Some(1), Some(3), None)
);
assert_eq!((at("level", json!("level2")), at("level", json!(3)), at("level", json!(4))), (Some(0), Some(1), None));
assert_eq!((at("previewFormat", json!("TIFFBW")), at("previewFormat", json!("TIFF (8-bit Color)"))), (Some(1), None));
assert_eq!((at("overprints", json!("Discard")), at("overprints", json!("keep"))), (Some(1), None));
app.ui.dialog = Some(d);
super::super::confirm(&mut app).unwrap();
assert!(app.ui.dialog.is_none(), "saved: {}", app.ui.status);
let saved = &app.session.active().unwrap().save_options;
for (name, value) in [("previewFormat", json!("none")), ("overprints", json!("discard")), ("flattenerPreset", json!("Mine")), ("level", json!(2))]
{
assert_eq!(saved[name], value, "{name}");
}
let bytes = written.borrow()[0].1.clone();
let (ps, preview) = vectorcraft_eps::sections(&bytes).unwrap();
assert!(preview.is_none(), "no preview");
assert!(String::from_utf8_lossy(ps).contains("%%LanguageLevel: 2"));
}
/// Save As › EPS: Transparent and Opaque apply to the color TIFF preview only, and are disabled
/// with any other preview. Embed Fonts shows checked and disabled. A flattener preset that no
/// entry of the menu names shows as it is.
#[test]
fn eps_save_transparency_follows_the_color_preview() {
use crate::widgets::accessibility_tests::{named, role_and_state, tree};
use egui::accesskit::Toggled;
let (mut app, _, _) = desktop("art.eps");
app.run("file.saveAs", json!({})).unwrap();
let set = |app: &mut VectorcraftApp, k: &str, v: Value| {
app.ui.dialog.as_mut().unwrap().fields.insert(k.into(), v);
};
set(&mut app, "previewFormat", json!("tiffColor"));
set(&mut app, "transparentPreview", json!(false));
let t = tree(|ui| super::super::show(&mut app, ui.ctx()));
assert!(!named(&t, "Transparent").is_disabled() && !named(&t, "Opaque").is_disabled());
assert_eq!((role_and_state(&t, "Transparent").1, role_and_state(&t, "Opaque").1), (Some(Toggled::False), Some(Toggled::True)));
let fonts = named(&t, "Embed Fonts (for other applications)");
assert_eq!((fonts.is_disabled(), fonts.toggled()), (true, Some(Toggled::True)));
for preview in ["none", "tiffBw"] {
set(&mut app, "previewFormat", json!(preview));
let t = tree(|ui| super::super::show(&mut app, ui.ctx()));
assert!(named(&t, "Transparent").is_disabled() && named(&t, "Opaque").is_disabled(), "{preview}");
}
set(&mut app, "flattenerPreset", json!("Gone"));
let text = crate::tests_labels::painted_text(&mut app, |app, ui| super::super::show(app, ui.ctx()));
assert!(text.lines().any(|l| l == "Gone"), "{text}");
}
/// #4931: a native file's Version is a menu of the versions VectorCraft writes, the current one
/// first and chosen, each named by the releases that read it. An older version without
/// compression saves plain, whatever Use Compression held.
@@ -180,6 +180,15 @@ fn a_bad_range_keeps_export_as_open() {
assert!(written.borrow().is_empty());
}
/// An emptied Range field shows an example of the artboard numbers it takes, as Save As's does.
#[test]
fn an_empty_export_as_range_shows_an_example() {
let (mut app, _) = app(2);
app.run("file.exportAs", json!({"useArtboards": true, "range": ""})).unwrap();
let text = crate::tests_labels::painted_text(&mut app, |app, ui| show(app, ui.ctx()));
assert!(text.lines().any(|l| l == "1-3, 5"), "{text}");
}
#[test]
fn svg_continues_in_svg_options_and_pdf_art_is_written_directly() {
let (mut app, written) = app(2);
+1
View File
@@ -2461,6 +2461,7 @@ font-technology Variable Променливи
Presets: Предварителни настройки:
Press Натиснете
Preview Преглед
Preview: Преглед:
Preview All Layers Преглед на всички слоеве
Preview in Browser Преглед в браузър
Preview in Browser needs the desktop app (the web downloads files instead) Прегледът в браузър изисква настолното приложение (уеб версията изтегля файловете вместо това)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -544,6 +544,7 @@
Gaussian Blur… Gaussovo zamućenje…
View Prikaz
Preview Pregled
Preview: Pregled:
Overprint Preview Pregled pretiska
Pixel Preview Pregled piksela
Trim View Prikaz obrezivanja
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3194,6 +3194,7 @@ digits Malayalam Malaiàlam
Press Quality Qualitat d’impressió
Pressure Pressió
Preview Previsualització
Preview: Previsualització:
Preview (1 inch on the page) Previsualització (1 polzada a la pàgina)
Preview All Layers Previsualitza totes les capes
Preview in Browser Previsualitza al navegador
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -552,6 +552,7 @@
Gaussian Blur… Gaussovské rozostření…
View Zobrazení
Preview Náhled
Preview: Náhled:
Overprint Preview Náhled přetisků
Pixel Preview Náhled obrazových bodů
Trim View Oříznuté zobrazení
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -508,6 +508,7 @@
Gaussian Blur… Gaussisk sløring…
View Vis
Preview Forhåndsvisning
Preview: Forhåndsvisning:
Overprint Preview Overprint-forhåndsvisning
Pixel Preview Pixel-forhåndsvisning
Trim View Beskåret visning
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -798,6 +798,14 @@ font-technology Variable Variabel
Disable Auto Add/Delete Automatisches Hinzufügen/Löschen deaktivieren
Disable Opacity Mask Deckkraftmaske deaktivieren
Discard Verwerfen
Preserve Beibehalten
TIFF (Black & White) TIFF (Schwarzweiß)
TIFF (8-bit Color) TIFF (8-Bit-Farbe)
High Resolution Hohe Auflösung
Medium Resolution Mittlere Auflösung
Low Resolution Niedrige Auflösung
Language Level 2 Sprachebene 2
Language Level 3 Sprachebene 3
Discard Empty Type Leeren Text verwerfen
Discard Recovered Documents Wiederhergestellte Dokumente verwerfen
Discard White Overprint in Output Weißes Überdrucken in der Ausgabe verwerfen
@@ -2490,6 +2498,7 @@ diagnostics ui Oberfläche
Presets: Vorgaben:
Press Mit
Preview Vorschau
Preview: Vorschau:
Preview All Layers Vorschau aller Ebenen
Preview in Browser Vorschau im Browser
Preview in Browser needs the desktop app (the web downloads files instead) „Vorschau im Browser“ erfordert die Desktop-App (im Web werden stattdessen Dateien heruntergeladen)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1879,6 +1879,7 @@ font-technology Variable Μεταβλητές
Preset: Προεπιλογή:
Presets: Προεπιλογές:
Preview Προεπισκόπηση
Preview: Προεπισκόπηση:
Previous Προηγούμενο
Print Εκτύπωση
Printer Εκτυπωτής
Can't render this file because it is too large.
+1
View File
@@ -2534,6 +2534,7 @@ font-technology Variable Variables
Presets: Preajustes:
Press Presiona
Preview Vista previa
Preview: Vista previa:
Preview All Layers Previsualizar todas las capas
Preview in Browser Previsualizar en el navegador
Preview in Browser needs the desktop app (the web downloads files instead) Previsualizar en el navegador requiere la aplicación de escritorio (la versión web descarga los archivos)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -546,6 +546,7 @@
Gaussian Blur… Gaussin sumennus…
View Näytä
Preview Esikatselu
Preview: Esikatselu:
Overprint Preview Päällepainatuksen esikatselu
Pixel Preview Pikseliesikatselu
Trim View Rajattu näkymä
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2526,6 +2526,7 @@ font-technology Variable Variables
Presets: Paramètres prédéfinis :
Press Appuyez sur
Preview Aperçu
Preview: Aperçu :
Preview All Layers Aperçu de tous les calques
Preview in Browser Aperçu dans le navigateur
Preview in Browser needs the desktop app (the web downloads files instead) L’aperçu dans le navigateur nécessite l’application de bureau (la version web télécharge les fichiers à la place)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3487,6 +3487,7 @@ antiAlias Sharp शार्प
Press Quality प्रेस गुणवत्ता
Pressure दबाव
Preview प्रीव्यू
Preview: प्रीव्यू:
Preview (1 inch on the page) प्रीव्यू (1 इंच पृष्ठ पर)
Preview All Layers सभी लेयर्स का प्रीव्यू करें
Preview in Browser ब्राउज़र में प्रीव्यू
Can't render this file because it is too large.
+1
View File
@@ -3082,6 +3082,7 @@ diagnostics ui felület
Press keys… Nyomd le a billentyűket…
Pressure Nyomás
Preview Előnézet
Preview: Előnézet:
Preview All Layers Összes réteg előnézetben
Preview in Browser Előnézet böngészőben
Preview in Browser needs the desktop app (the web downloads files instead) Az Előnézet böngészőben az asztali alkalmazásban érhető el (a webes változat helyette letölti a fájlokat)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -508,6 +508,7 @@
Gaussian Blur… Kabur Gaussian…
View Tampilan
Preview Pratinjau
Preview: Pratinjau:
Overprint Preview Pratinjau overprint
Pixel Preview Pratinjau piksel
Trim View Tampilan terpangkas
1 # Indonesian (id) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation
508
509
510
511
512
513
514
+9
View File
@@ -819,6 +819,14 @@ font-technology Variable Variabili
Disable Auto Add/Delete Disattiva aggiunta/eliminazione automatica
Disable Opacity Mask Disattiva maschera di opacità
Discard Scarta
Preserve Mantieni
TIFF (Black & White) TIFF (bianco e nero)
TIFF (8-bit Color) TIFF (colore a 8 bit)
High Resolution Alta risoluzione
Medium Resolution Media risoluzione
Low Resolution Bassa risoluzione
Language Level 2 Livello di linguaggio 2
Language Level 3 Livello di linguaggio 3
Discard Empty Type Scarta testo vuoto
Discard Recovered Documents Scarta documenti recuperati
Discard White Overprint in Output Scarta sovrastampa del bianco nell'output
@@ -2566,6 +2574,7 @@ diagnostics ui interfaccia
Presets: Preset:
Press Premi
Preview Anteprima
Preview: Anteprima:
Preview All Layers Anteprima di tutti i livelli
Preview in Browser Anteprima nel browser
Preview in Browser needs the desktop app (the web downloads files instead) Anteprima nel browser richiede l'app desktop (la versione web scarica invece i file)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -848,6 +848,7 @@ digits Malayalam マラヤーラム数字
Search Commands… コマンドを検索…
VectorCraft Help… VectorCraft ヘルプ…
Preview プレビュー
Preview: プレビュー:
Show Edges エッジを表示
Show Corner Widget コーナーウィジェットを表示
Show Template テンプレートを表示
@@ -1437,6 +1438,14 @@ antiAlias Sharp シャープ
Disable Auto Add/Delete 自動追加/削除機能を使用しない
Disable Opacity Mask 不透明マスクを無効にする
Discard 破棄
Preserve 保持
TIFF (Black & White) TIFF (白黒)
TIFF (8-bit Color) TIFF (8 bit カラー)
High Resolution 高解像度
Medium Resolution 中解像度
Low Resolution 低解像度
Language Level 2 言語レベル 2
Language Level 3 言語レベル 3
Discard Empty Type 空のテキストを破棄
Discard Recovered Documents 復帰したドキュメントを破棄
Discard White Overprint in Output 出力時に白のオーバープリントを破棄
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -482,6 +482,7 @@
Gaussian Blur… გაუსის გაბუნდოვნება…
View ხედი
Preview წინასწარი ნახვა
Preview: წინასწარი ნახვა:
Overprint Preview ზედდაბეჭდვის წინასწარი ნახვა
Pixel Preview პიქსელების წინასწარი ნახვა
Trim View მოჭრილი ხედი
Can't render this file because it is too large.
+9
View File
@@ -841,6 +841,7 @@ digits Malayalam 말라얄람어
Search Commands… 명령 검색…
VectorCraft Help… VectorCraft 도움말…
Preview 미리 보기
Preview: 미리 보기:
Show Edges 가장자리 표시
Show Corner Widget 모퉁이 위젯 표시
Show Template 템플릿 표시
@@ -1427,6 +1428,14 @@ antiAlias Sharp 날카롭게
Disable Auto Add/Delete 자동 추가/삭제 사용 안 함
Disable Opacity Mask 불투명 마스크 사용 안 함
Discard 삭제
Preserve 보존
TIFF (Black & White) TIFF (흑백)
TIFF (8-bit Color) TIFF (8비트 색상)
High Resolution 고해상도
Medium Resolution 중간 해상도
Low Resolution 저해상도
Language Level 2 언어 수준 2
Language Level 3 언어 수준 3
Discard Empty Type 빈 문자 삭제
Discard Recovered Documents 복구된 문서 삭제
Discard White Overprint in Output 출력에서 흰색 오버프린트 삭제
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -522,6 +522,7 @@
Gaussian Blur… Gaussiaanse vervaging…
View Beeld
Preview Voorbeeld
Preview: Voorbeeld:
Overprint Preview Overprintvoorbeeld
Pixel Preview Pixelvoorbeeld
Trim View Bijsnijweergave
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -511,6 +511,7 @@
Gaussian Blur… Rozmycie gaussowskie…
View Widok
Preview Podgląd
Preview: Podgląd:
Overprint Preview Podgląd nadruku
Pixel Preview Podgląd pikseli
Trim View Widok przycięty
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2107,6 +2107,7 @@ antiAlias Sharp Nítido
Presets: Predefinidos:
Press Pressione
Preview Visualização
Preview: Visualização:
Preview Mode Modo de Visualização
Preview in Browser Visualizar no Navegador
Preview the document as it is now Visualizar o documento como está agora
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1
View File
@@ -2561,6 +2561,7 @@ diagnostics ui интерфейс
Presets: Наборы:
Press Нажмите
Preview Просмотр
Preview: Просмотр:
Preview All Layers Просмотреть все слои
Preview in Browser Просмотреть в браузере
Preview in Browser needs the desktop app (the web downloads files instead) Просмотр в браузере требует настольного приложения (web-версия скачивает файлы)
Can't render this file because it is too large.
+1
View File
@@ -2471,6 +2471,7 @@ font-technology Variable Variabla
Presets: Förinställningar:
Press Tryck på
Preview Förhandsgranskning
Preview: Förhandsgranskning:
Preview All Layers Förhandsgranska alla lager
Preview in Browser Förhandsgranska i webbläsare
Preview in Browser needs the desktop app (the web downloads files instead) Förhandsgranska i webbläsare kräver skrivbordsappen (webbversionen hämtar filerna i stället)
Can't render this file because it contains an unexpected character in line 5 and column 25.
+21
View File
@@ -238,6 +238,27 @@ fn anti_aliasing_method_labels_are_in_complete_catalogs() {
}
}
/// The names the EPS options' menus show (preview, overprints, flattener preset and PostScript
/// level), and Save As's Preview label.
#[test]
fn eps_option_menu_names_are_in_complete_catalogs() {
use vectorcraft_engine::cmd::FlattenOptions;
use vectorcraft_eps::{Level, Overprint, Preview};
let names: Vec<&str> = Preview::ALL
.map(Preview::label)
.into_iter()
.chain(Overprint::ALL.map(Overprint::label))
.chain(Level::ALL.map(Level::label))
.chain(FlattenOptions::PRESETS.into_iter().filter_map(FlattenOptions::preset_label))
.chain(["Preview:"])
.collect();
for lang in LANGUAGES.iter().filter(|lang| lang.complete_menus) {
for label in &names {
assert!(lang.catalog().plain(label).is_some(), "{} is missing {label}", lang.code);
}
}
}
/// Each language counts with its own plural rule: the form a count picks (`one`, then `few`, then
/// `other`/`many`).
#[test]
+1
View File
@@ -2344,6 +2344,7 @@ shape Open Açık
Presets: Ön ayarlar:
Press Basın
Preview Önizleme
Preview: Önizleme:
Preview All Layers Tüm Katmanları Önizle
Preview in Browser Tarayıcıda Önizleme
Preview in Browser needs the desktop app (the web downloads files instead) Tarayıcıdaki önizleme için masaüstü uygulaması gerekir (bunun yerine web, dosyaları indirir)
Can't render this file because it contains an unexpected character in line 5 and column 25.
+9
View File
@@ -813,6 +813,14 @@ font-technology Variable Варіативні
Disable Auto Add/Delete Вимкнути авто-додавання/видалення
Disable Opacity Mask Вимкнути маску непрозорості
Discard Відкинути
Preserve Зберігати
TIFF (Black & White) TIFF (чорно-білий)
TIFF (8-bit Color) TIFF (8-бітний колір)
High Resolution Висока роздільна здатність
Medium Resolution Середня роздільна здатність
Low Resolution Низька роздільна здатність
Language Level 2 Рівень мови 2
Language Level 3 Рівень мови 3
Discard Empty Type Видалити порожній текст
Discard Recovered Documents Відкинути відновлені документи
Discard White Overprint in Output Скасувати накладення білого під час виведення
@@ -2558,6 +2566,7 @@ diagnostics ui інтерфейс
Presets: Набори:
Press Натисніть
Preview Перегляд
Preview: Перегляд:
Preview All Layers Переглянути всі шари
Preview in Browser Переглянути у браузері
Preview in Browser needs the desktop app (the web downloads files instead) Перегляд у браузері вимагає настільної програми (web-версія завантажує файли)
Can't render this file because it contains an unexpected character in line 182 and column 5.
+9
View File
@@ -954,6 +954,14 @@ font-technology Variable Biến thiên
Disable Auto Add/Delete Tắt tự động thêm/xóa
Disable Opacity Mask Tắt mặt nạ độ mờ
Discard Loại bỏ
Preserve Bảo lưu
TIFF (Black & White) TIFF (Đen trắng)
TIFF (8-bit Color) TIFF (Màu 8 bit)
High Resolution Độ phân giải cao
Medium Resolution Độ phân giải vừa
Low Resolution Độ phân giải thấp
Language Level 2 Cấp ngôn ngữ 2
Language Level 3 Cấp ngôn ngữ 3
Discard Empty Type Loại bỏ chữ trống
Discard Recovered Documents Loại bỏ tài liệu đã phục hồi
Discard White Overprint in Output Loại bỏ in chồng màu trắng khi xuất
@@ -2867,6 +2875,7 @@ diagnostics ui giao diện
Press Nhấn
Pressure Áp lực
Preview Xem trước
Preview: Xem trước:
Preview All Layers Xem trước tất cả lớp
Preview in Browser Xem trước trong trình duyệt
Preview in Browser needs the desktop app (the web downloads files instead) Xem trước trong trình duyệt cần ứng dụng máy tính để bàn (web sẽ tải tệp xuống thay thế)
Can't render this file because it contains an unexpected character in line 204 and column 5.
+1
View File
@@ -2432,6 +2432,7 @@ diagnostics ui 界面
Presets: 预设:
Press 按
Preview 预览
Preview: 预览:
Preview in Browser 在浏览器中预览
Preview in Browser needs the desktop app (the web downloads files instead) 在浏览器中预览需要桌面版应用程序 (网页版会改为下载文件)
Preview Mode 预览模式
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -781,6 +781,14 @@ font-technology Variable 可變
Disable Auto Add/Delete 停用自動增加/刪除
Disable Opacity Mask 停用不透明度遮色片
Discard 捨棄
Preserve 保留
TIFF (Black & White) TIFF (黑白)
TIFF (8-bit Color) TIFF (8 位元色彩)
High Resolution 高解析度
Medium Resolution 中解析度
Low Resolution 低解析度
Language Level 2 語言層級 2
Language Level 3 語言層級 3
Discard Empty Type 捨棄空白文字
Discard Recovered Documents 捨棄已復原的文件
Discard White Overprint in Output 輸出時捨棄白色疊印
@@ -3515,6 +3523,7 @@ diagnostics ui 介面
Presets: 預設集:
Press 按下
Preview 預覽
Preview: 預覽:
Preview All Layers 預覽所有圖層
Preview in Browser 在瀏覽器中預覽
Preview in Browser needs the desktop app (the web downloads files instead) 在瀏覽器中預覽需要桌面版應用程式 (網頁版會改為下載檔案)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+5 -1
View File
@@ -787,7 +787,11 @@ artboards' files. A `.ai` file's `aiVersion` comes first: `"pdf"` (the default)
Options"), which takes only `transparentImages` (`"flatten"` or `"omit"`), `hiddenObjects` (`"layer"`, `"omit"` or
`"visible"`, the Hidden Objects menu), `outlineText` (the Text menu: false Editable, true Outlines) and, with several artboards, the artboard
picker: `boards`, one bool per artboard (default: those last saved, else all), saved as `range`, one file per checked
artboard. OK is disabled with none checked.
artboard. OK is disabled with none checked. Save As to an EPS file opens the same dialog after the save panel (heading
"EPS Options") with `useArtboards`, `all` and `range`, then the options Export's EPS Options shows. Preview
(`previewFormat`), Overprints (`overprints`), Flattener preset (`flattenerPreset`) and PostScript (`level`) are menus:
a pick writes the option's value (`"tiffColor"`, `"preserve"`, a built-in preset's id such as `"medium"` or a saved
preset's name, the level as a number), and a value none of them names shows as it is.
EMF and WMF: Export As… lists both formats (`file.exportAs {format: "emf"}` or `"wmf"`); they have no options
dialog, so `ui.dialog.confirm` asks for the path and writes the file (one per artboard with Use Artboards). Open and