mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-28 21:06:56 -06:00
io: only the first CADCraft xdata string marks the PAPERVIEW viewport (#253)
dxf_ext::is_paper_view (#225) matched any 1000 string in the CADCraft xdata, but later strings are layer names (VPFROZEN, VPCOLORS). A real viewport with a frozen or recoloured layer named PAPERVIEW was therefore dropped on read. Only the first string, where the writer puts the marker, counts now. Regression test in tests/paperview_marker.rs. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3ef0edaed9
commit
1bd1c5cfa2
@@ -310,9 +310,11 @@ pub(crate) fn read_dstyle(tags: &[Tag], styles: &HashMap<String, String>, blocks
|
||||
/// CADCraft keeps that viewport implicit, so the reader drops it.
|
||||
pub(crate) const PAPER_VIEW: &str = "PAPERVIEW";
|
||||
|
||||
/// True for a VIEWPORT record carrying the [`PAPER_VIEW`] marker.
|
||||
/// True for a VIEWPORT record carrying the [`PAPER_VIEW`] marker as the first string of its CADCraft
|
||||
/// xdata, where the writer puts it. Later strings are layer names (VPFROZEN, VPCOLORS), so a layer
|
||||
/// called PAPERVIEW does not count.
|
||||
pub(crate) fn is_paper_view(tags: &[Tag]) -> bool {
|
||||
xdata(tags, APP).iter().any(|t| t.code == 1000 && t.str().trim().eq_ignore_ascii_case(PAPER_VIEW))
|
||||
xdata(tags, APP).iter().find(|t| t.code == 1000).is_some_and(|t| t.str().trim().eq_ignore_ascii_case(PAPER_VIEW))
|
||||
}
|
||||
|
||||
/// Snap kinds in CADCraft's ASSOC xdata.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//! The DXF reader drops the paper-space viewport the writer adds (marked `1000 PAPERVIEW` in
|
||||
//! CADCraft xdata) but keeps a real viewport whose frozen or recoloured layer is named PAPERVIEW.
|
||||
|
||||
use cadcraft_color::Color;
|
||||
use cadcraft_doc::*;
|
||||
use cadcraft_geom::{Vec2, Vec3};
|
||||
|
||||
fn viewport(id: u32, frozen_layers: Vec<String>, layer_colors: Vec<(String, Color)>) -> EntityKind {
|
||||
EntityKind::Viewport(Viewport {
|
||||
center: Vec3::new(50.0, 40.0, 0.0),
|
||||
width: 80.0,
|
||||
height: 60.0,
|
||||
view_center: Vec2::new(10.0, 10.0),
|
||||
view_height: 50.0,
|
||||
id,
|
||||
locked: false,
|
||||
frozen_layers,
|
||||
layer_colors,
|
||||
})
|
||||
}
|
||||
|
||||
fn viewports(l: &Layout) -> Vec<Viewport> {
|
||||
l.entities.iter().filter_map(|e| if let EntityKind::Viewport(v) = &e.kind { Some(v.clone()) } else { None }).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn viewport_with_a_layer_named_paperview_survives_dxf_roundtrip() {
|
||||
let mut d = Drawing::new_metric();
|
||||
d.ensure_layer("PAPERVIEW");
|
||||
let sheet = Space::Paper(d.layouts[0].name.clone());
|
||||
d.add(&sheet, Common::default(), viewport(2, vec!["PAPERVIEW".into()], vec![])).unwrap();
|
||||
d.add(&sheet, Common::default(), viewport(3, vec![], vec![("PAPERVIEW".into(), Color::Index(1))])).unwrap();
|
||||
|
||||
let text = cadcraft_io::write_dxf(&d);
|
||||
let back = cadcraft_io::read_dxf(text.as_bytes()).unwrap();
|
||||
let vps = viewports(&back.layouts[0]);
|
||||
assert_eq!(vps.iter().map(|v| v.id).collect::<Vec<_>>(), [2, 3], "only the added sheet viewport is dropped");
|
||||
assert_eq!(vps[0].frozen_layers, ["PAPERVIEW"]);
|
||||
assert_eq!(vps[1].layer_colors, [("PAPERVIEW".to_string(), Color::Index(1))]);
|
||||
}
|
||||
Reference in New Issue
Block a user