M4: a wrap style per paragraph and in text styles, overriding the layer's (#1827)

"You can apply a wrap style at three levels: Text layer, Paragraph, Text style". The layer level was done in #1871; this adds the other two, following the per-paragraph text direction (#1830) and the list style in text styles (#1876).

ParaList::wrap (None follows the layer) with para_wrap_style, set_wrap_style (the layer level, clears overrides), set_para_wrap_styles and common_wrap_style; restyle_breaks takes a style per paragraph; ParagraphStyle::wrap_style; text.wrapStyle and node.set wrapStyle with start/end; inspect lineWrapStyles; CSS text-wrap only when the paragraphs agree; the Wrap style control follows the paragraph; a read-only row in the style editor. The .fig mapping is left for a later change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 briefed; Sonnet 5.5 wrote at medium
This commit is contained in:
Trevor BrownandClaude Sonnet 5.5 committed 2026-11-07 21:13:39 -05:00
1 parent 3635c23070
commit 136ca4cda7
15 files changed
+234 -29

No files matched your search

+6 -4
View File
@@ -302,10 +302,12 @@ fn text_decls(doc: &Document, n: &Node, tx: &figcraft_doc::TextData, t: &mut Tok
TextAlignH::Right => put("text-align", "right".into()),
TextAlignH::Justified => put("text-align", "justify".into()),
}
match tx.wrap_style {
figcraft_doc::WrapStyle::Auto => {}
figcraft_doc::WrapStyle::Balance => put("text-wrap", "balance".into()),
figcraft_doc::WrapStyle::Pretty => put("text-wrap", "pretty".into()),
// CSS has one `text-wrap` per element: written when every paragraph has the same one.
let wrap = (0..tx.paragraph_count()).map(|p| tx.para_wrap_style(p)).collect::<Vec<_>>();
match wrap.first().copied().filter(|w| wrap.iter().all(|x| x == w)) {
Some(figcraft_doc::WrapStyle::Balance) => put("text-wrap", "balance".into()),
Some(figcraft_doc::WrapStyle::Pretty) => put("text-wrap", "pretty".into()),
_ => {}
}
// A base direction forced on every paragraph (CSS has one per element).
let dir = tx.paragraphs.first().map(|p| p.direction).filter(|d| tx.paragraphs.iter().all(|p| p.direction == *d));