mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-26 20:06:50 -06:00
This commit is contained in:
@@ -365,6 +365,25 @@ pub(crate) fn read_frozen(tags: &[Tag]) -> Vec<String> {
|
||||
list.iter().take(MAX_XDATA_ITEMS).filter(|t| t.code == 1000).map(Tag::str).collect()
|
||||
}
|
||||
|
||||
/// A viewport's layer colour overrides as CADCraft xdata: `1000 VPCOLORS`, `1002 {`, then per override
|
||||
/// `1000 layer` and `1000 colour` (the [`Color::name`] text, which keeps true colours), `1002 }`.
|
||||
pub(crate) fn layer_colors_xdata(colors: &[(String, Color)]) -> Vec<Tag> {
|
||||
let mut v = vec![Tag::s(1000, "VPCOLORS"), Tag::s(1002, "{")];
|
||||
for (layer, color) in colors {
|
||||
v.push(Tag::s(1000, layer.clone()));
|
||||
v.push(Tag::s(1000, color.name()));
|
||||
}
|
||||
v.push(Tag::s(1002, "}"));
|
||||
v
|
||||
}
|
||||
|
||||
/// The overrides written by [`layer_colors_xdata`]; empty for files from other writers, bad pairs are skipped.
|
||||
pub(crate) fn read_layer_colors(tags: &[Tag]) -> Vec<(String, Color)> {
|
||||
let list = xdata_list(xdata(tags, APP), "VPCOLORS");
|
||||
let names: Vec<String> = list.iter().take(MAX_XDATA_ITEMS * 2).filter(|t| t.code == 1000).map(Tag::str).collect();
|
||||
names.chunks_exact(2).filter_map(|p| Some((p.first()?.clone(), Color::parse(p.get(1)?)?))).collect()
|
||||
}
|
||||
|
||||
const POINT_NAMES: [&str; 5] = ["defpt", "p13", "p14", "p15", "p16"];
|
||||
|
||||
/// Associativity links from CADCraft xdata; malformed links are skipped.
|
||||
|
||||
@@ -307,7 +307,7 @@ fn entity(kind: &str, tags: &[Tag]) -> Option<(Common, EntityKind)> {
|
||||
id: t.i(69).unwrap_or(0) as u32,
|
||||
locked: t.i(90).unwrap_or(0) & 16384 != 0,
|
||||
frozen_layers: crate::dxf_ext::read_frozen(tags),
|
||||
layer_colors: Vec::new(),
|
||||
layer_colors: crate::dxf_ext::read_layer_colors(tags),
|
||||
}),
|
||||
"WIPEOUT" => {
|
||||
let o = t.p(10);
|
||||
|
||||
@@ -792,9 +792,15 @@ fn entity(w: &mut W, d: &Drawing, e: &Entity, owner: &str, paper: bool, cx: &Ctx
|
||||
w.f(45, v.view_height);
|
||||
// Status flags: 16384 = display locked.
|
||||
w.i(90, if v.locked { 16384 } else { 0 });
|
||||
if !v.frozen_layers.is_empty() {
|
||||
// One CADCraft xdata group holds both lists: readers stop at the first group of an app.
|
||||
if !v.frozen_layers.is_empty() || !v.layer_colors.is_empty() {
|
||||
w.s(1001, dxf_ext::APP);
|
||||
w.xdata(dxf_ext::frozen_xdata(&v.frozen_layers));
|
||||
if !v.frozen_layers.is_empty() {
|
||||
w.xdata(dxf_ext::frozen_xdata(&v.frozen_layers));
|
||||
}
|
||||
if !v.layer_colors.is_empty() {
|
||||
w.xdata(dxf_ext::layer_colors_xdata(&v.layer_colors));
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityKind::Wipeout(wo) => {
|
||||
|
||||
@@ -571,6 +571,43 @@ fn viewport_frozen_layers_roundtrip() {
|
||||
assert!(frozen.contains(&(3, Vec::new())), "{frozen:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn viewport_layer_colors_roundtrip() {
|
||||
let mut d = sample();
|
||||
let paper = Space::Paper("Layout1".into());
|
||||
let vp = |id: u32, frozen: Vec<String>, colors: Vec<(String, Color)>| {
|
||||
EntityKind::Viewport(Viewport {
|
||||
center: Vec3::new(5.0, 4.0, 0.0),
|
||||
width: 8.0,
|
||||
height: 6.0,
|
||||
view_center: Vec2::new(5.0, 2.5),
|
||||
view_height: 12.0,
|
||||
id,
|
||||
locked: false,
|
||||
frozen_layers: frozen,
|
||||
layer_colors: colors,
|
||||
})
|
||||
};
|
||||
let colors = vec![("Walls".to_string(), Color::Index(5)), ("A B".to_string(), Color::True(cadcraft_color::Rgb(255, 128, 0)))];
|
||||
d.add(&paper, Common::default(), vp(2, Vec::new(), colors.clone())).unwrap();
|
||||
d.add(&paper, Common::default(), vp(3, Vec::new(), Vec::new())).unwrap();
|
||||
// Frozen layers and colour overrides share one CADCraft xdata group.
|
||||
d.add(&paper, Common::default(), vp(4, vec!["Walls".into()], colors.clone())).unwrap();
|
||||
let back = roundtrip(&d);
|
||||
let found: Vec<(u32, Vec<String>, Vec<(String, Color)>)> = back
|
||||
.layouts
|
||||
.iter()
|
||||
.flat_map(|l| l.entities.iter())
|
||||
.filter_map(|e| match &e.kind {
|
||||
EntityKind::Viewport(v) => Some((v.id, v.frozen_layers.clone(), v.layer_colors.clone())),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
assert!(found.contains(&(2, Vec::new(), colors.clone())), "{found:?}");
|
||||
assert!(found.contains(&(3, Vec::new(), Vec::new())), "{found:?}");
|
||||
assert!(found.contains(&(4, vec!["Walls".to_string()], colors)), "{found:?}");
|
||||
}
|
||||
|
||||
fn full_dim_style() -> DimStyle {
|
||||
DimStyle {
|
||||
name: "Mech".into(),
|
||||
|
||||
Reference in New Issue
Block a user