mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-12 17:02:08 -06:00
WordArt xlsx: only the textNoShape marker reads as WordArt, an empty WordArt keeps its body
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
6a22a3b357
commit
2a9a21d41c
@@ -221,8 +221,9 @@ fn read_shape(obj: &El, anchor: Anchor) -> Option<Shape> {
|
||||
let tx_box = obj.path(&["nvSpPr", "cNvSpPr"]).is_some_and(|c| c.flag("txBox", false));
|
||||
let ln = sp.child("ln");
|
||||
let arrow = ln.is_some_and(|l| l.child("tailEnd").or_else(|| l.child("headEnd")).is_some_and(|t| t.attr("type").is_some_and(|v| v != "none")));
|
||||
// WordArt: a text body carrying a text warp (`a:bodyPr/a:prstTxWarp`).
|
||||
let word_art = obj.path(&["txBody", "bodyPr", "prstTxWarp"]).is_some();
|
||||
// WordArt: our marker, a text body with the non-warping text warp `textNoShape`. Any other warp
|
||||
// (Excel puts one on ordinary filled shapes too) leaves the shape what its geometry says.
|
||||
let word_art = obj.path(&["txBody", "bodyPr", "prstTxWarp"]).is_some_and(|w| w.attr("prst") == Some("textNoShape"));
|
||||
let kind = match prst {
|
||||
_ if word_art => ShapeKind::WordArt,
|
||||
_ if tx_box => ShapeKind::TextBox,
|
||||
@@ -554,7 +555,8 @@ pub fn write_drawing(sheet: &Sheet, theme: &Theme, objs: &[Obj<'_>]) -> String {
|
||||
s.push_str("</a:ln>");
|
||||
}
|
||||
s.push_str("</xdr:spPr>");
|
||||
if !sh.text.is_empty() {
|
||||
// A WordArt with no text still writes its body, which carries the WordArt marker.
|
||||
if !sh.text.is_empty() || sh.kind == ShapeKind::WordArt {
|
||||
let f = &sh.format;
|
||||
let anchor = match f.anchor {
|
||||
Some(ShapeTextAnchor::Top) => " anchor=\"t\"",
|
||||
|
||||
@@ -100,3 +100,24 @@ fn word_art_keeps_right_to_left_paragraphs() {
|
||||
assert_eq!(shape.format.align, Some(ShapeTextAlign::Right));
|
||||
assert_eq!(shape.text, "مرحبا\nبالعالم");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn word_art_with_empty_text_keeps_its_kind() {
|
||||
let mut wb = text_box("", ShapeFormat::default());
|
||||
wb.sheet_mut(0).unwrap().shapes[0].kind = ShapeKind::WordArt;
|
||||
let (reopened, _) = read_xlsx(&write_xlsx(&wb).unwrap()).unwrap();
|
||||
assert_eq!(reopened.sheet(0).unwrap().shapes[0].kind, ShapeKind::WordArt);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_text_warp_on_a_filled_ellipse_does_not_make_it_word_art() {
|
||||
let drawing = ARABIC_TEXT_BOX
|
||||
.replace(r#"<xdr:cNvSpPr txBox="1"/>"#, "<xdr:cNvSpPr/>")
|
||||
.replace(r#"prst="rect""#, r#"prst="ellipse""#)
|
||||
.replace(r#"anchor="t"/>"#, r#"anchor="t"><a:prstTxWarp prst="textTriangle"><a:avLst/></a:prstTxWarp></a:bodyPr>"#);
|
||||
let wb = read_drawing(&drawing);
|
||||
assert_eq!(wb.sheet(0).unwrap().shapes[0].kind, ShapeKind::Ellipse);
|
||||
// The marker the writer uses still reads back as WordArt.
|
||||
let marked = drawing.replace("textTriangle", "textNoShape");
|
||||
assert_eq!(read_drawing(&marked).sheet(0).unwrap().shapes[0].kind, ShapeKind::WordArt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user