DIMTFILL and DIMTFILLCLR are written in DIMSTYLE only when set; COMPAREEXPORT redraws dimensions instead of copying their blocks, and gaps.md notes its groups

This commit is contained in:
aiongg
2026-10-25 03:43:34 +00:00
parent 429554b389
commit 8171c9be17
5 changed files with 52 additions and 4 deletions
@@ -371,6 +371,9 @@ fn paint(d: &mut Drawing, e: &mut Entity, color: Color, tinted: &mut Tinted, dep
}
}
EntityKind::Dimension(dm) => {
// Drawn again from its geometry in the object's color; a named copy of its `*D`
// block would stay behind in saved files.
dm.block = None;
if let Ok(by_block) = serde_json::to_value(Color::ByBlock) {
for var in ["DIMCLRD", "DIMCLRE", "DIMCLRT"] {
dm.overrides.retain(|k, _| DimStyle::field_name(k) != DimStyle::field_name(var));
+7
View File
@@ -351,6 +351,13 @@ fn a_named_block_whose_dimension_draws_another_block_shows_the_other_definition(
.unwrap_or_default();
assert_eq!(drawn, [Some("*D2".to_string())], "the other drawing's PART is copied with its dimension block");
assert_eq!(ends(&s, "*D2"), vec![5.0]);
// The colored copies redraw their dimensions instead of keeping colored copies of `*D` blocks.
let d = s.doc().unwrap();
let dim_copy = |n: &str| {
n.starts_with("COMPARE_")
&& n.rsplit('_').next().is_some_and(|t| t.len() > 1 && t.starts_with('D') && t[1..].bytes().all(|c| c.is_ascii_digit()))
};
assert!(!d.blocks.keys().any(|n| dim_copy(n)), "{:?}", d.blocks.keys().collect::<Vec<_>>());
}
#[test]
+6 -1
View File
@@ -2309,8 +2309,13 @@ fn tags_for(d: &Drawing, version: Version, target: Version) -> Vec<Tag> {
w.dimval(*code, enc, false);
continue;
}
// Table groups where the file version has them, else xdata.
// Table groups where the file version has them, else xdata. DIMTFILL and DIMTFILLCLR
// are written only when set, as other writers do, so a style without a text
// background has a single 70 (its flags).
if version >= dxf_ext::newer_since(*code) {
if matches!(*code, 69 | 70) && v.get(*field) == defaults.get(*field) {
continue;
}
w.dimval(*code, enc, false);
} else if v.get(*field) != defaults.get(*field) {
newer.i(1070, i64::from(*code));
+35 -2
View File
@@ -1,6 +1,6 @@
//! DIMTFILL (group 69) and DIMTFILLCLR (group 70) survive DXF: as DIMSTYLE groups from R2007,
//! after the record's own flags (also 70), and in the style's `CADCRAFT` "DIMVARS" xdata in older
//! files. The `*D` block of a dimension with DIMTFILL 2 holds the background as a SOLID.
//! after the record's own flags (also 70) and only when set, and in the style's `CADCRAFT`
//! "DIMVARS" xdata in older files. The `*D` block of a dimension with DIMTFILL 2 holds the background as a SOLID.
use cadcraft_color::Color;
use cadcraft_doc::{Common, DimKind, DimStyle, Dimension, Drawing, EntityKind, Space};
@@ -54,6 +54,39 @@ fn text_fill_roundtrips_in_the_dimstyle_table() {
}
}
#[test]
fn unset_text_fill_writes_no_groups() {
let mut d = Drawing::new_imperial();
d.dim_styles.push(DimStyle { name: "Plain".into(), ..DimStyle::default() });
d.dim_styles.push(DimStyle { name: "Canvas".into(), text_fill: 1, ..DimStyle::default() });
let text = dxf(&d, Version::R2018);
let groups = |name| -> Vec<(String, String)> {
record(&text, name).chunks(2).filter_map(|p| Some((p.first()?.to_string(), p.get(1)?.to_string()))).collect()
};
let plain = groups("Plain");
// The record's flags are its only 70.
assert_eq!(plain.iter().filter(|g| g.0 == "70").count(), 1, "{plain:?}");
assert!(!plain.iter().any(|g| g.0 == "69"), "{plain:?}");
let canvas = groups("Canvas");
assert!(canvas.contains(&("69".into(), "1".into())), "{canvas:?}");
assert_eq!(canvas.iter().filter(|g| g.0 == "70").count(), 1, "the default DIMTFILLCLR is not written: {canvas:?}");
let back = cadcraft_io::read_dxf(text.as_bytes()).unwrap();
assert_eq!(back.dim_style("Plain").unwrap().text_fill, 0);
assert_eq!(back.dim_style("Canvas").unwrap().text_fill, 1);
}
#[test]
fn hostile_text_fill_groups_fall_back_to_defaults() {
let text = dxf(&drawing(), Version::R2018);
for (fill, color) in [("99", "3"), ("-5", "3"), ("2", "40000"), ("2", "-7")] {
let edited = text.replacen(" 69\r\n2\r\n 70\r\n3\r\n", &format!(" 69\r\n{fill}\r\n 70\r\n{color}\r\n"), 1);
assert_ne!(edited, text, "groups replaced");
let back = cadcraft_io::read_dxf(edited.as_bytes()).unwrap();
let st = back.dim_style("Fill").unwrap();
assert!(st.text_fill <= 2, "{fill}/{color}: {}", st.text_fill);
}
}
#[test]
fn record_flags_are_not_read_as_dimtfillclr() {
let text = dxf(&drawing(), Version::R2018);
+1 -1
View File
@@ -43,7 +43,7 @@ do them first.
| F19 | MATCHPROP Settings is a keyword prompt (no dialog) and has no material, shadow or centre-object settings; TEXTTOFRONT and HATCHTOBACK act on the current space only; OVERKILL doesn't compare polyline segments with other objects (picker and Settings, DRAWORDER Above/Under, TEXTTOFRONT, HATCHTOBACK, OVERKILL tolerance/ignore/overlap/end-to-end options landed, #439) | `props/matchprop.rs`, `draworder.rs`, `overkill.rs` | Low | 2–4 |
| F20 | OPTIONS dialog done (#23): Display, Open and Save, Drafting, Selection, User Preferences and Profiles tabs, and the user profile (object snap modes, drafting toggles, Dynamic Input, PICKBOX, APERTURE, GRIPSIZE, CURSORSIZE, PICKFIRST, PICKADD, QPMODE, model and paper background, snap marker size, system cursor) survives restarts. Left: right-click customization, the autosave interval and default save version on Open and Save (the features themselves landed, #406, #421), AutoSnap magnet and tooltip toggles, colours of the other drawing-area elements, named profiles with import and export | `ui-egui/src/options/` | Low | 2–4 |
| F21 | MLINE, REGION and HELIX are objects since #510, with gaps: MLEDIT tees trim square; UNION/SUBTRACT/INTERSECT only combine regions whose boundaries don't meet; regions are saved as closed polylines (no ACIS data); PURGE skips multiline styles | `draw2/mline.rs`, `inquiry/regions.rs`, `dxf_region.rs` | Low | 6–10 |
| F22 | Inquiry leftovers (COUNT across spaces and nested blocks, the QuickCalc palette and COMPARE landed, #563; MASSPROP on regions, #510): COMPARE compares the tab shown, not every layout at once (COMPAREEXPORT, the comparison as a new drawing, landed); QuickCalc keeps its history and variables for the session only | `file/compare.rs`, `palettes/quickcalc.rs` | Low | 3–5 |
| F22 | Inquiry leftovers (COUNT across spaces and nested blocks, the QuickCalc palette and COMPARE landed, #563; MASSPROP on regions, #510): COMPARE compares the tab shown, not every layout at once (COMPAREEXPORT, the comparison as a new drawing, landed); COMPAREEXPORT puts the two sets of objects in model-space groups, where AutoCAD puts them in blocks; QuickCalc keeps its history and variables for the session only | `file/compare.rs`, `palettes/quickcalc.rs` | Low | 3–5 |
| F23 | No Sheet Set Manager, eTransmit, Share, Traces, Markup Import, Activity Insights | menu items uncovered | Low-medium (team workflows) | 40–70 |
| F24 | No 3D: UCS, 3D views, orbit, solids, surfaces, meshes, sections, visual styles, materials, lights, rendering (150 menu items) | [parity-checklist](parity-checklist.md) | Medium (3D users) | 300–450 |