mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-14 22:35:26 +00:00
Delegate Graphic.xml writing to craft-idml
This commit is contained in:
3 files changed
+84
-133
No files matched your search
Generated
+9
-9
@@ -1242,10 +1242,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-idml"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=9eec083e9#9eec083e9f0355841784b54952a6f01f3b7f2dbe"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=99113d82a#99113d82a16bd25b791d682b2b70807ac12fe9e9"
|
||||
dependencies = [
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=9eec083e9)",
|
||||
"craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=9eec083e9)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=99113d82a)",
|
||||
"craft-zip 0.1.0 (git+https://github.com/storytold/craft-libs?rev=99113d82a)",
|
||||
"thiserror 2.0.21",
|
||||
]
|
||||
|
||||
@@ -1665,7 +1665,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-xml"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=9eec083e9#9eec083e9f0355841784b54952a6f01f3b7f2dbe"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=99113d82a#99113d82a16bd25b791d682b2b70807ac12fe9e9"
|
||||
dependencies = [
|
||||
"quick-xml 0.41.0",
|
||||
"thiserror 2.0.21",
|
||||
@@ -1740,7 +1740,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-zip"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=9eec083e9#9eec083e9f0355841784b54952a6f01f3b7f2dbe"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=99113d82a#99113d82a16bd25b791d682b2b70807ac12fe9e9"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"thiserror 2.0.21",
|
||||
@@ -2021,7 +2021,7 @@ dependencies = [
|
||||
"craft-prepress",
|
||||
"craft-print",
|
||||
"craft-svg 0.1.0 (git+https://github.com/storytold/craft-libs?rev=cc23ffd4d26f3074808e2187d332564817624f8f)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=9eec083e9)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=99113d82a)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=f23b0f33f0d00b157476533a43cbbcfd901aa1f1)",
|
||||
"designcraft-color",
|
||||
"designcraft-compose",
|
||||
@@ -2103,9 +2103,9 @@ name = "designcraft-idml"
|
||||
version = "0.20.1"
|
||||
dependencies = [
|
||||
"craft-file-formats",
|
||||
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=9eec083e9)",
|
||||
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=99113d82a)",
|
||||
"craft-svg 0.1.0 (git+https://github.com/storytold/craft-libs?rev=cc23ffd4d26f3074808e2187d332564817624f8f)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=9eec083e9)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=99113d82a)",
|
||||
"designcraft-color",
|
||||
"designcraft-compose",
|
||||
"designcraft-doc",
|
||||
@@ -2222,7 +2222,7 @@ version = "0.20.1"
|
||||
dependencies = [
|
||||
"craft-docx",
|
||||
"craft-file-formats",
|
||||
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=9eec083e9)",
|
||||
"craft-idml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=99113d82a)",
|
||||
"craft-rtf",
|
||||
"craft-wordmodel",
|
||||
"craft-xlsx",
|
||||
|
||||
+2
-2
@@ -16,10 +16,10 @@ craft-pdf = { git = "https://github.com/storytold/craft-libs", rev = "4052591363
|
||||
craft-designcraft-format = { git = "https://github.com/storytold/craft-libs", rev = "19692b6190465671e41967c75d0cd4c439d0c84c", version = "=0.1.0" }
|
||||
craft-eps = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
|
||||
craft-epub = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
|
||||
craft-idml = { git = "https://github.com/storytold/craft-libs", rev = "9eec083e9", version = "=0.1.0" }
|
||||
craft-idml = { git = "https://github.com/storytold/craft-libs", rev = "99113d82a", version = "=0.1.0" }
|
||||
craft-indd = { git = "https://github.com/storytold/craft-libs", rev = "47bf5650b0d503b97bfb5e841746c4957897d11f", version = "=0.1.0" }
|
||||
craft-svg = { git = "https://github.com/storytold/craft-libs", rev = "cc23ffd4d26f3074808e2187d332564817624f8f", version = "=0.1.0", features = ["tree-render", "tree-text"] }
|
||||
craft-xml = { git = "https://github.com/storytold/craft-libs", rev = "9eec083e9", version = "=0.1.0" }
|
||||
craft-xml = { git = "https://github.com/storytold/craft-libs", rev = "99113d82a", version = "=0.1.0" }
|
||||
craft-xml-dtd = { package = "craft-xml", git = "https://github.com/storytold/craft-libs", rev = "f23b0f33f0d00b157476533a43cbbcfd901aa1f1", version = "=0.1.0" }
|
||||
craft-rtf = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
|
||||
craft-xlsx = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use super::common::{bool_s, color_value, pct, pkg_root};
|
||||
use super::{Color, ColorType, El, Ex, GradientKind, SwatchValue, document, escape_id, num, swatch};
|
||||
use super::common::{color_value, pct};
|
||||
use super::{Color, ColorType, Ex, GradientKind, SwatchValue, escape_id, num, swatch};
|
||||
use craft_idml::model::{
|
||||
ColorDefinition, ColorGroupDefinition, ColorGroupMember, GradientDefinition, GradientStopDefinition, GraphicPart, InkDefinition,
|
||||
StrokeDefinition, TintDefinition,
|
||||
};
|
||||
|
||||
// Retained IDML attributes have unprefixed ASCII names. Native JSON can be
|
||||
// edited independently: never let its map keys become XML syntax or Self IDs.
|
||||
@@ -16,18 +20,11 @@ impl<'a> Ex<'a> {
|
||||
&mut self,
|
||||
s: &designcraft_color::Swatch,
|
||||
gradient: &designcraft_color::Gradient,
|
||||
colors: &mut Vec<El>,
|
||||
colors: &mut Vec<ColorDefinition>,
|
||||
by_value: &mut Vec<(Color, String)>,
|
||||
) -> El {
|
||||
) -> GradientDefinition {
|
||||
let id = self.sw(&s.name);
|
||||
let mut g = El::new("Gradient")
|
||||
.attr("Self", &id)
|
||||
.attr("Type", if gradient.kind == GradientKind::Radial { "Radial" } else { "Linear" })
|
||||
.attr("Name", &s.name)
|
||||
.attr("ColorEditable", "true")
|
||||
.attr("ColorRemovable", "true")
|
||||
.attr("Visible", "true")
|
||||
.attr("SwatchCreatorID", "7937");
|
||||
let mut stops = Vec::new();
|
||||
let d = self.d;
|
||||
for (i, stop) in gradient.stops.iter().enumerate() {
|
||||
// A stop on a swatch names it; a plain color names an equal color swatch or
|
||||
@@ -44,36 +41,30 @@ impl<'a> Ex<'a> {
|
||||
cid
|
||||
}
|
||||
};
|
||||
let mut e = El::new("GradientStop")
|
||||
.attr("Self", format!("{}GradientStop{i}", id.replace(['/', ' '], "_")))
|
||||
.attr("StopColor", cid)
|
||||
.attr("Location", pct(stop.offset as f64));
|
||||
if i > 0 {
|
||||
e.set("Midpoint", pct(gradient.stops[i - 1].midpoint as f64));
|
||||
}
|
||||
g.push(e);
|
||||
stops.push(GradientStopDefinition {
|
||||
self_id: format!("{}GradientStop{i}", id.replace(['/', ' '], "_")),
|
||||
color_id: cid,
|
||||
location: pct(stop.offset as f64),
|
||||
midpoint: (i > 0).then(|| pct(gradient.stops[i - 1].midpoint as f64)),
|
||||
});
|
||||
}
|
||||
g
|
||||
GradientDefinition { self_id: id, name: s.name.clone(), radial: gradient.kind == GradientKind::Radial, stops }
|
||||
}
|
||||
|
||||
// ---------- Graphic.xml ----------
|
||||
|
||||
pub(super) fn graphic_part(&mut self) -> Vec<u8> {
|
||||
let d = self.d;
|
||||
let mut root = pkg_root("Graphic");
|
||||
let mut colors: Vec<El> = Vec::new();
|
||||
let mut tints: Vec<El> = Vec::new();
|
||||
let mut gradients: Vec<El> = Vec::new();
|
||||
let mut inks: Vec<El> = Vec::new();
|
||||
let mut graphic = GraphicPart::default();
|
||||
// Specials (always present).
|
||||
colors.push(color_el("Color/Black", "Black", "Process", &Color::cmyk(0.0, 0.0, 0.0, 1.0), "Specialblack", (false, false, true)));
|
||||
graphic.colors.push(color_el("Color/Black", "Black", "Process", &Color::cmyk(0.0, 0.0, 0.0, 1.0), "Specialblack", (false, false, true)));
|
||||
let paper = match d.swatch(swatch::PAPER).map(|s| &s.value) {
|
||||
Some(SwatchValue::Paper { color }) => *color,
|
||||
_ => Color::cmyk(0.0, 0.0, 0.0, 0.0),
|
||||
};
|
||||
let paper = if paper == Color::WHITE { Color::cmyk(0.0, 0.0, 0.0, 0.0) } else { paper };
|
||||
colors.push(color_el("Color/Paper", "Paper", "Process", &paper, "Specialpaper", (true, false, true)));
|
||||
colors.push(color_el(
|
||||
graphic.colors.push(color_el("Color/Paper", "Paper", "Process", &paper, "Specialpaper", (true, false, true)));
|
||||
graphic.colors.push(color_el(
|
||||
"Color/Registration",
|
||||
"Registration",
|
||||
"Registration",
|
||||
@@ -84,18 +75,17 @@ impl<'a> Ex<'a> {
|
||||
for (i, ink) in
|
||||
[("Process Cyan", 75, 0.61), ("Process Magenta", 15, 0.76), ("Process Yellow", 0, 0.16), ("Process Black", 45, 1.7)].iter().enumerate()
|
||||
{
|
||||
inks.push(
|
||||
El::new("Ink")
|
||||
.attr("Self", format!("Ink/$ID/{}", ink.0))
|
||||
.attr("Name", format!("$ID/{}", ink.0))
|
||||
.attr("Angle", ink.1)
|
||||
.attr("ConvertToProcess", "false")
|
||||
.attr("Frequency", "70")
|
||||
.attr("NeutralDensity", num(ink.2))
|
||||
.attr("PrintInk", "true")
|
||||
.attr("TrapOrder", i + 1)
|
||||
.attr("InkType", "Normal"),
|
||||
);
|
||||
graphic.inks.push(InkDefinition {
|
||||
self_id: format!("Ink/$ID/{}", ink.0),
|
||||
name: format!("$ID/{}", ink.0),
|
||||
alias: None,
|
||||
angle: ink.1.to_string(),
|
||||
convert_to_process: false,
|
||||
frequency: "70".to_string(),
|
||||
neutral_density: num(ink.2),
|
||||
trap_order: i + 1,
|
||||
ink_type: "Normal".to_string(),
|
||||
});
|
||||
}
|
||||
// Colour swatches, by value, for gradient stop lookup.
|
||||
let mut by_value: Vec<(Color, String)> = Vec::new();
|
||||
@@ -107,82 +97,42 @@ impl<'a> Ex<'a> {
|
||||
match &s.value {
|
||||
SwatchValue::Color { color, color_type } => {
|
||||
let model = if *color_type == ColorType::Spot { "Spot" } else { "Process" };
|
||||
colors.push(color_el(&id, &s.name, model, color, "Normal", (true, true, true)));
|
||||
graphic.colors.push(color_el(&id, &s.name, model, color, "Normal", (true, true, true)));
|
||||
by_value.push((*color, id.clone()));
|
||||
if *color_type == ColorType::Spot {
|
||||
let mut ink = El::new("Ink");
|
||||
if let Some((_, to)) = d.inks.aliases.iter().find(|(a, _)| *a == s.name) {
|
||||
ink.set("AliasInkName", to);
|
||||
}
|
||||
let alias = d.inks.aliases.iter().find(|(a, _)| *a == s.name).map(|(_, to)| to.clone());
|
||||
let convert = d.inks.all_to_process || d.inks.to_process.contains(&s.name);
|
||||
inks.push(
|
||||
ink.attr("Self", format!("Ink/{}", escape_id(&s.name)))
|
||||
.attr("Name", &s.name)
|
||||
.attr("Angle", "45")
|
||||
.attr("ConvertToProcess", bool_s(convert))
|
||||
.attr("Frequency", "70")
|
||||
.attr("NeutralDensity", "0.5")
|
||||
.attr("PrintInk", "true")
|
||||
.attr("TrapOrder", inks.len() + 1)
|
||||
.attr("InkType", "Normal"),
|
||||
);
|
||||
graphic.inks.push(InkDefinition {
|
||||
self_id: format!("Ink/{}", escape_id(&s.name)),
|
||||
name: s.name.clone(),
|
||||
alias,
|
||||
angle: "45".to_string(),
|
||||
convert_to_process: convert,
|
||||
frequency: "70".to_string(),
|
||||
neutral_density: "0.5".to_string(),
|
||||
trap_order: graphic.inks.len() + 1,
|
||||
ink_type: "Normal".to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
SwatchValue::Tint { base, tint } => {
|
||||
tints.push(
|
||||
El::new("Tint")
|
||||
.attr("Self", &id)
|
||||
.attr("TintValue", pct(*tint as f64))
|
||||
.attr("BaseColor", self.sw(base))
|
||||
.attr("Name", &s.name)
|
||||
.attr("ColorOverride", "Normal")
|
||||
.attr("AlternateSpace", "NoAlternateColor")
|
||||
.attr("AlternateColorValue", "")
|
||||
.attr("ColorEditable", "true")
|
||||
.attr("ColorRemovable", "true")
|
||||
.attr("Visible", "true")
|
||||
.attr("SwatchCreatorID", "7937"),
|
||||
);
|
||||
graphic.tints.push(TintDefinition { self_id: id, value: pct(*tint as f64), base_color: self.sw(base), name: s.name.clone() });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
for s in &d.swatches {
|
||||
let SwatchValue::Gradient { gradient } = &s.value else { continue };
|
||||
gradients.push(self.gradient_el(s, gradient, &mut colors, &mut by_value));
|
||||
}
|
||||
for c in colors {
|
||||
root.push(c);
|
||||
}
|
||||
for i in inks {
|
||||
root.push(i);
|
||||
}
|
||||
for t in tints {
|
||||
root.push(t);
|
||||
}
|
||||
root.push(
|
||||
El::new("Swatch")
|
||||
.attr("Self", "Swatch/None")
|
||||
.attr("Name", "None")
|
||||
.attr("ColorEditable", "false")
|
||||
.attr("ColorRemovable", "false")
|
||||
.attr("Visible", "true")
|
||||
.attr("SwatchCreatorID", "7937"),
|
||||
);
|
||||
for g in gradients {
|
||||
root.push(g);
|
||||
graphic.gradients.push(self.gradient_el(s, gradient, &mut graphic.colors, &mut by_value));
|
||||
}
|
||||
for (gi, g) in d.color_groups.iter().enumerate() {
|
||||
let mut el = El::new("ColorGroup")
|
||||
.attr("Self", format!("ColorGroup/{}", escape_id(&g.name)))
|
||||
.attr("Name", &g.name)
|
||||
.attr("IsRootColorGroup", "false");
|
||||
let mut members = Vec::new();
|
||||
for (k, n) in g.swatches.iter().enumerate() {
|
||||
if let Some(id) = self.swatch_ids.get(n) {
|
||||
el.push(El::new("ColorGroupSwatch").attr("Self", format!("u{gi}ColorGroupSwatch{k}")).attr("SwatchItemRef", id));
|
||||
members.push(ColorGroupMember { self_id: format!("u{gi}ColorGroupSwatch{k}"), swatch_id: id.clone() });
|
||||
}
|
||||
}
|
||||
root.push(el);
|
||||
graphic.color_groups.push(ColorGroupDefinition { self_id: format!("ColorGroup/{}", escape_id(&g.name)), name: g.name.clone(), members });
|
||||
}
|
||||
for st in &d.stroke_styles {
|
||||
let id = format!("CustomStrokeStyle/{}", st.name);
|
||||
@@ -190,22 +140,26 @@ impl<'a> Ex<'a> {
|
||||
let el = match &st.kind {
|
||||
designcraft_doc::StrokeType::Stripes { bands } => {
|
||||
let flat: Vec<f64> = bands.iter().flat_map(|(a, w)| [*a, a + w]).collect();
|
||||
Some(El::new("StripedStrokeStyle").attr("StripeArray", pcts(&flat)))
|
||||
Some(StrokeDefinition::Striped { self_id: id.clone(), name: st.name.clone(), array: pcts(&flat) })
|
||||
}
|
||||
designcraft_doc::StrokeType::Dashed { pattern } => {
|
||||
Some(El::new("DashedStrokeStyle").attr("DashArray", pattern.iter().map(|x| num(*x)).collect::<Vec<_>>().join(" ")))
|
||||
designcraft_doc::StrokeType::Dashed { pattern } => Some(StrokeDefinition::Dashed {
|
||||
self_id: id.clone(),
|
||||
name: st.name.clone(),
|
||||
array: pattern.iter().map(|x| num(*x)).collect::<Vec<_>>().join(" "),
|
||||
}),
|
||||
designcraft_doc::StrokeType::Dotted => {
|
||||
Some(StrokeDefinition::Dotted { self_id: id.clone(), name: st.name.clone(), array: "0 200".to_string() })
|
||||
}
|
||||
designcraft_doc::StrokeType::Dotted => Some(El::new("DottedStrokeStyle").attr("DotArray", "0 200")),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(el) = el {
|
||||
root.push(el.attr("Self", id).attr("Name", &st.name));
|
||||
if let Some(style) = el {
|
||||
graphic.stroke_styles.push(style);
|
||||
}
|
||||
}
|
||||
for s in STROKE_STYLES {
|
||||
root.push(El::new("StrokeStyle").attr("Self", format!("StrokeStyle/$ID/{s}")).attr("Name", format!("$ID/{s}")));
|
||||
graphic.stroke_styles.push(StrokeDefinition::Named { self_id: format!("StrokeStyle/$ID/{s}"), name: format!("$ID/{s}") });
|
||||
}
|
||||
document(&root)
|
||||
craft_idml::part_xml(&graphic.to_el())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,20 +185,17 @@ const STROKE_STYLES: &[&str] = &[
|
||||
];
|
||||
|
||||
/// A `Color` element. `flags` is (editable, removable, visible).
|
||||
fn color_el(self_id: &str, name: &str, model: &str, c: &Color, over: &str, (editable, removable, visible): (bool, bool, bool)) -> El {
|
||||
fn color_el(self_id: &str, name: &str, model: &str, c: &Color, over: &str, (editable, removable, visible): (bool, bool, bool)) -> ColorDefinition {
|
||||
let (space, val) = color_value(c);
|
||||
crate::xml::from_craft(
|
||||
craft_idml::model::ColorDefinition {
|
||||
self_id: self_id.to_string(),
|
||||
name: name.to_string(),
|
||||
model: model.to_string(),
|
||||
space: space.to_string(),
|
||||
value: val,
|
||||
override_kind: over.to_string(),
|
||||
editable,
|
||||
removable,
|
||||
visible,
|
||||
}
|
||||
.to_el(),
|
||||
)
|
||||
ColorDefinition {
|
||||
self_id: self_id.to_string(),
|
||||
name: name.to_string(),
|
||||
model: model.to_string(),
|
||||
space: space.to_string(),
|
||||
value: val,
|
||||
override_kind: over.to_string(),
|
||||
editable,
|
||||
removable,
|
||||
visible,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user