mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-30 04:37:29 -06:00
Fix #3544: an SVG of one artboard on its own has the artboard's name as its title
The SVG writer always wrote the document's title in <title>
(crates/svg/src/export.rs), so every file of Export As with Use
Artboards, Export for Screens or an `artboard`/`range` export was titled
after the document ("Icons"), whatever its artboard was called. The
writer's `artboard` option can't tell those apart from Save: Save writes
the first artboard too, standing for the whole document.
ExportOptions has a new `artboard_title` (set by the caller, as
`artboard` is, not deserialized): the file is that one artboard, exported
on its own, and its <title> is the artboard's name (XML-escaped as
before), or the document's title when the artboard has no name. The
engine's SVG encoder (fileio/svg.rs) sets it exactly when the export
names its artboards, which is also when a file holds only that
artboard's art (#550): Export As per artboard, document.export /
serialize with `artboard` or `range`, MCP export, and Export for Screens'
artboards, assets, layers and selections (each written as an artboard
named after it). Save and Save As keep the document's title. Export for
Screens' Full Document draws the art bounds as one artboard, which is now
named after the document, so its SVG keeps the document's title too.
docs/file-format-parity.md's SVG row says so.
Tests: title_control_chars::an_artboard_exported_alone_is_titled_after_it
(crates/svg: two named artboards, the second named with markup;
exporting either alone gives its escaped name, the default and an
artboard without artboard_title give the document's title, an unnamed
artboard falls back to it) and
tests_svgenc::an_svg_of_one_artboard_is_titled_after_it (the engine:
`artboard` 0 and 1, useArtboards range all, Save's SVG, Export for
Screens per artboard, an asset and Full Document). Both fail without the
change (the title was "Icons") and pass with it.
This commit is contained in:
committed by
bflatastic
parent
cc499d7e8e
commit
439d32fcf8
@@ -133,9 +133,12 @@ fn write(doc: &Document, opts: &ExportOptions, native: Option<&[u8]>, id_prefix:
|
||||
out.push_str(&w.indent(1));
|
||||
out.push_str(&format!("</defs>{nl}"));
|
||||
}
|
||||
if !doc.title.is_empty() {
|
||||
// An artboard exported on its own is named after it (#3544), else after the document.
|
||||
let board = opts.artboard.filter(|_| opts.artboard_title).and_then(|i| doc.artboards.get(i)).map(|a| a.name.as_str());
|
||||
let title = board.filter(|n| !n.trim().is_empty()).unwrap_or(&doc.title);
|
||||
if !title.is_empty() {
|
||||
out.push_str(&w.indent(1));
|
||||
out.push_str(&format!("<title>{}</title>{nl}", xml_text(&doc.title)));
|
||||
out.push_str(&format!("<title>{}</title>{nl}", xml_text(title)));
|
||||
}
|
||||
// File Info's description.
|
||||
if !doc.metadata.description.trim().is_empty() {
|
||||
|
||||
@@ -190,6 +190,13 @@ pub struct ExportOptions {
|
||||
/// it (the engine's `artboard`/`range`/`useArtboards` params), so it is not deserialized.
|
||||
#[serde(skip)]
|
||||
pub artboard: Option<usize>,
|
||||
/// The file is the one artboard `artboard` names, exported on its own (Export As with Use
|
||||
/// Artboards, Export for Screens, Asset Export, an `artboard`/`range` param): its `<title>` is
|
||||
/// the artboard's name, else (unnamed) the document's title (#3544). Off, the file stands for
|
||||
/// the document (Save, Save As) and has the document's title. Callers set it with `artboard`,
|
||||
/// so it is not deserialized either.
|
||||
#[serde(skip)]
|
||||
pub artboard_title: bool,
|
||||
pub styling: Styling,
|
||||
/// Decimal places for coordinates (1–7 in the dialog; default 3).
|
||||
pub decimals: u8,
|
||||
@@ -225,6 +232,7 @@ impl Default for ExportOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
artboard: Some(0),
|
||||
artboard_title: false,
|
||||
styling: Styling::PresentationAttributes,
|
||||
decimals: 3,
|
||||
object_ids: ObjectIds::LayerNames,
|
||||
|
||||
Reference in New Issue
Block a user