mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 04:07:12 -06:00
Merge pull request #3613 from Taha-Mahmoodi/fix/3544-svg-title-artboard
Fix #3544: an SVG of one artboard on its own has the artboard's name as its title
This commit is contained in:
@@ -800,10 +800,12 @@ fn items(
|
||||
};
|
||||
if o.full_document {
|
||||
// The bounds of all visible art, as the one artboard of the files that aren't PDFs (a PDF
|
||||
// row writes every artboard of the document itself).
|
||||
// row writes every artboard of the document itself). It is named after the document: an
|
||||
// SVG of one artboard takes the artboard's name as its title (#3544), and this one stands
|
||||
// for the whole document.
|
||||
let (whole, region) = if crop {
|
||||
let bounds = vectorcraft_render::encode::art_bounds(doc).ok_or_else(|| bad(C, "nothing to export: the document has no visible art"))?;
|
||||
(Arc::new(single_artboard(doc, bounds, "Document")), bounds)
|
||||
(Arc::new(single_artboard(doc, bounds, &doc.title)), bounds)
|
||||
} else {
|
||||
(doc.clone(), Rect::ZERO)
|
||||
};
|
||||
|
||||
@@ -179,9 +179,10 @@ pub(super) fn encode(doc: &Document, p: &Value, compressed: bool) -> Result<Enco
|
||||
let doc = flat.as_ref().unwrap_or(doc);
|
||||
let mut enc = Encoded { warnings, ..Encoded::default() };
|
||||
for artboard in boards {
|
||||
// A chosen artboard's file holds the art over it (#550).
|
||||
// A chosen artboard's file holds the art over it (#550) and is named after it (#3544).
|
||||
let over = artboard.filter(|_| chosen).and_then(|b| doc.artboards.get(b)).map(|a| super::export::art_over(doc, a.rect));
|
||||
let mut out = vectorcraft_svg::export_full(over.as_ref().unwrap_or(doc), &ExportOptions { artboard, ..opts.clone() }, native.as_deref());
|
||||
let file = ExportOptions { artboard, artboard_title: chosen, ..opts.clone() };
|
||||
let mut out = vectorcraft_svg::export_full(over.as_ref().unwrap_or(doc), &file, native.as_deref());
|
||||
let bytes = out.take_bytes();
|
||||
for l in out.linked {
|
||||
if !enc.linked.iter().any(|e| e.name == l.name) {
|
||||
|
||||
@@ -108,3 +108,39 @@ fn a_chosen_artboard_s_svg_keeps_an_object_whose_shadow_reaches_it() {
|
||||
s.execute("effect.apply", &json!({"effect": "stylize.dropShadow", "ids": [id], "params": {"x": 20, "y": 0, "blur": 0}})).unwrap();
|
||||
assert_eq!(paths(&mut s), 1, "its shadow reaches 10 pt onto the artboard");
|
||||
}
|
||||
|
||||
/// #3544: an SVG of one artboard on its own (an `artboard` or `range`, Export for Screens, an asset)
|
||||
/// has the artboard's (or asset's) name as `<title>`; Save's SVG and Export for Screens' Full
|
||||
/// Document keep the document's.
|
||||
#[test]
|
||||
fn an_svg_of_one_artboard_is_titled_after_it() {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"name": "Icons", "width": 24, "height": 24, "artboards": 2})).unwrap();
|
||||
for (index, name) in [(0, "arrow-left"), (1, "arrow-right")] {
|
||||
s.execute("artboard.setProps", &json!({"index": index, "name": name})).unwrap();
|
||||
}
|
||||
let square = s.execute("shape.rectangle", &json!({"x": 4, "y": 4, "width": 16, "height": 16})).unwrap()["id"].clone();
|
||||
let title = |svg: &str| svg.lines().find_map(|l| l.trim().strip_prefix("<title>")?.strip_suffix("</title>")).map(str::to_string);
|
||||
let serialize = |s: &mut Session, p: serde_json::Value| s.execute("document.serialize", &p).unwrap()["text"].as_str().unwrap().to_string();
|
||||
assert_eq!(title(&serialize(&mut s, json!({"format": "svg", "artboard": 1}))).as_deref(), Some("arrow-right"));
|
||||
assert_eq!(title(&serialize(&mut s, json!({"format": "svg", "artboard": 0}))).as_deref(), Some("arrow-left"));
|
||||
assert_eq!(title(&serialize(&mut s, json!({"format": "svg"}))).as_deref(), Some("Icons"), "Save's SVG");
|
||||
let all = s.execute("document.serialize", &json!({"format": "svg", "useArtboards": true, "range": "all"})).unwrap();
|
||||
let titles: Vec<_> = all["files"].as_array().unwrap().iter().map(|f| title(f["text"].as_str().unwrap())).collect();
|
||||
assert_eq!(titles, [Some("arrow-left".into()), Some("arrow-right".into())]);
|
||||
// Export for Screens: each artboard, an asset, and the Full Document.
|
||||
let screens = |s: &mut Session, p: serde_json::Value| -> Vec<Option<String>> {
|
||||
let r = s.execute("document.exportForScreens", &p).unwrap();
|
||||
r["files"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|f| title(&String::from_utf8(vectorcraft_format::base64_decode(f["dataBase64"].as_str().unwrap()).unwrap()).unwrap()))
|
||||
.collect()
|
||||
};
|
||||
let svg = json!([{"format": "svg"}]);
|
||||
assert_eq!(screens(&mut s, json!({"formats": svg})), [Some("arrow-left".into()), Some("arrow-right".into())]);
|
||||
let asset = s.execute("assets.add", &json!({"ids": [square], "name": "Square"})).unwrap()["assets"][0].clone();
|
||||
assert_eq!(screens(&mut s, json!({"assets": [asset], "formats": svg})), [Some("Square".into())]);
|
||||
assert_eq!(screens(&mut s, json!({"fullDocument": true, "formats": svg})), [Some("Icons".into())]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user