Files
cadcraft/crates/doc/src/foreign.rs
T

80 lines
3.4 KiB
Rust

//! Data from a drawing file that CADCraft does not model, kept so that saving the drawing writes
//! it back: other programs' objects, extension dictionaries, xdata and properties (#528).
//!
//! It is kept as the file's own DXF groups, with the file's handles. The file reader fills it and
//! the writer puts it back, pointing references at whatever now has the referenced role (the
//! named object dictionary, a table record, a block, an entity); references to objects that are
//! gone are dropped. Commands don't edit it.
use std::collections::BTreeMap;
use crate::{Handle, RawTag};
/// What a file handle stood for when the object it named is one CADCraft writes itself (under a
/// new handle on save): a kind and an upper-case name, e.g. `("LAYER", "WALLS")`,
/// `("TABLE", "LAYER")`, `("BLOCK", "DOOR")`, `("NOD", "")` for the named object dictionary and
/// `("NOD", "ACAD_GROUP")` for one of its entries.
pub type ForeignKey = (String, String);
/// A non-graphical object of a type or role CADCraft does not model.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ForeignObject {
/// Its handle in the file it came from (kept on save).
pub handle: Handle,
/// Its DXF type (group 0), e.g. `XRECORD`.
pub kind: String,
/// Its groups after the type, as read.
pub tags: Vec<RawTag>,
}
/// What an entity, table record or block carries beyond what CADCraft models.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ForeignExtra {
/// Its extension dictionary (one of [`Foreign::objects`]).
pub xdict: Option<Handle>,
/// Objects of [`Foreign::objects`] that react to it (persistent reactors).
pub reactors: Vec<Handle>,
/// Other applications' extended data: groups from `1001` on.
pub xdata: Vec<RawTag>,
/// The colour book colour (group 430) and the true colour (group 420) it was read with: it is
/// written back while the colour is unchanged.
pub color_book: Option<(String, String)>,
/// Other unmodelled property groups (material 347, shadow mode 284).
pub props: Vec<RawTag>,
}
impl ForeignExtra {
pub fn is_empty(&self) -> bool {
self.xdict.is_none() && self.reactors.is_empty() && self.xdata.is_empty() && self.color_book.is_none() && self.props.is_empty()
}
}
/// Everything of a file CADCraft keeps without modelling it.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Foreign {
/// CLASS records (groups after `0 CLASS`) of the kept objects' and entities' types.
pub classes: Vec<Vec<RawTag>>,
/// Kept objects, in file order.
pub objects: Vec<ForeignObject>,
/// Entries of the named object dictionary that CADCraft doesn't write itself: (key, object).
pub dictionary: Vec<(String, Handle)>,
/// Extras of entities, by handle.
pub entities: BTreeMap<Handle, ForeignExtra>,
/// Extras of table records (`("LAYER", "WALLS")`), tables (`("TABLE", "LAYER")`) and blocks
/// (`("BLOCK", "DOOR")`), by [`ForeignKey`].
pub records: BTreeMap<ForeignKey, ForeignExtra>,
/// The roles of the file handles the kept data refers to, for objects CADCraft rewrites.
pub targets: BTreeMap<Handle, ForeignKey>,
}
impl Foreign {
pub fn is_empty(&self) -> bool {
self.objects.is_empty()
&& self.dictionary.is_empty()
&& self.entities.is_empty()
&& self.records.is_empty()
&& self.classes.is_empty()
&& self.targets.is_empty()
}
}