M7.6: Character and Paragraph Styles — partial named styles in the document, apply to objects or a Type tool range, Clear Overrides, override-preserving redefine, duplicate/rename/delete; panels with override markers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Thomas
2026-10-01 09:55:01 -04:00
co-authored by Claude Opus 5.5
parent 2dafc7634b
commit 48a4720ece
9 changed files with 768 additions and 4 deletions
+9 -1
View File
@@ -37,7 +37,7 @@ pub use live::{BlendOrientation, BlendSpacing, BlendSpec, EnvelopeKind, Gradient
pub use node::{ImageObject, LAYER_COLORS, LayerColor, LiveShape, Node, NodeId, NodeKind, OpacityMask};
pub use pattern::{Overlap, PatternDef, PatternEdit, RepeatKind, RepeatSpec, TileType};
pub use selection::{AnchorRef, Selection};
pub use text::{CharStyle, Justify, ParaStyle, TextKind, TextObject, TextRun};
pub use text::{CharStyle, Justify, ParaStyle, TextKind, TextObject, TextRun, TextStyleDef};
use drawcraft_color::{Swatch, SwatchGroup};
use drawcraft_geom::{Point, Rect};
@@ -268,6 +268,12 @@ pub struct Document {
pub swatch_groups: Vec<SwatchGroup>,
#[serde(default)]
pub graphic_styles: Vec<GraphicStyle>,
/// Character styles (besides the built-in [Normal Character Style], which may be redefined here).
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub char_styles: Vec<TextStyleDef>,
/// Paragraph styles (besides the built-in [Normal Paragraph Style]).
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub para_styles: Vec<TextStyleDef>,
#[serde(default)]
pub symbols: Vec<Symbol>,
#[serde(default)]
@@ -316,6 +322,8 @@ impl Document {
swatches,
swatch_groups,
graphic_styles: default_graphic_styles(),
char_styles: vec![],
para_styles: vec![],
symbols: vec![],
guides: vec![],
grid: GridPrefs::default(),
+16
View File
@@ -52,6 +52,9 @@ pub struct CharStyle {
pub strikethrough: bool,
#[serde(default)]
pub all_caps: bool,
/// Character style (Character Styles panel) these attributes come from; None = Normal.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub style_name: Option<String>,
}
fn regular() -> String {
@@ -80,6 +83,7 @@ impl Default for CharStyle {
underline: false,
strikethrough: false,
all_caps: false,
style_name: None,
}
}
}
@@ -107,6 +111,18 @@ pub struct ParaStyle {
pub space_after: f64,
#[serde(default)]
pub hyphenate: bool,
/// Paragraph style (Paragraph Styles panel) these attributes come from; None = Normal.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub style_name: Option<String>,
}
/// A named character or paragraph style: the attributes it sets (a subset of [`CharStyle`] or
/// [`ParaStyle`] fields, by their serialized names). Text using it records the name.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TextStyleDef {
pub name: String,
#[serde(default)]
pub attrs: serde_json::Map<String, serde_json::Value>,
}
/// A run of text sharing one character style.