fix(io): resolve root named-objects dict robustly on foreign DWGs
Some DWGs written by other programs leave the root named-objects dictionary unrecoverable: the header pointer names a non-dictionary and the real NOD child dicts are owned by a table-control handle, so nothing has owner==NULL. Navigating the root then silently no-ops, and registering a new named-object entry (page setup, annotation scale, CTAB) against the missing root orphans it — it never round-trips. Add shared annotative::root_named_dict_handle(): resolve the header pointer, else adopt the richest owner==NULL dict, else synthesise a fresh root and write it back. Route ensure_plotsettings_dict, add_scale's scalelist-create branch, and set_saved_active_layout through it. Resolve the plot-settings dict via the PlotSettings owner when the header pointer is stale, mirroring scalelist_dict_handle. Verified page setups survive a DWG save/reload on the repro file with layouts intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0c4272fbb0
commit
04bd49c715
5 changed files with 227 additions and 32 deletions
|
|
@ -550,27 +550,11 @@ pub fn set_saved_active_layout(doc: &mut CadDocument, name: &str) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
// Attach a new CTAB entry to the root named-object dictionary. Prefer the
|
||||
// header handle; fall back to scanning for the root dict (the one holding
|
||||
// `ACAD_LAYOUT`) since a from-scratch document leaves the header handle null
|
||||
// until it is built. No root dict at all → `$TILEMODE` still records
|
||||
// model-vs-paper.
|
||||
let named = doc.header.named_objects_dict_handle;
|
||||
let root = if !named.is_null() && doc.objects.contains_key(&named) {
|
||||
named
|
||||
} else {
|
||||
match doc.objects.iter().find_map(|(h, o)| match o {
|
||||
ObjectType::Dictionary(d)
|
||||
if d.entries.iter().any(|(k, _)| k.eq_ignore_ascii_case("ACAD_LAYOUT")) =>
|
||||
{
|
||||
Some(*h)
|
||||
}
|
||||
_ => None,
|
||||
}) {
|
||||
Some(h) => h,
|
||||
None => return,
|
||||
}
|
||||
};
|
||||
// Attach a new CTAB entry to the root named-object dictionary. Resolve it
|
||||
// robustly (or synthesise one) so the current-tab record persists even on a
|
||||
// from-scratch document, or a foreign DWG whose header root pointer is
|
||||
// unresolvable. See `annotative::root_named_dict_handle`.
|
||||
let root = crate::scene::annotative::root_named_dict_handle(doc);
|
||||
let handle = doc.allocate_handle();
|
||||
let mut var = DictionaryVariable::new("CTAB", name);
|
||||
var.handle = handle;
|
||||
|
|
|
|||
Loading…
Reference in a new issue