mirror of
https://github.com/storytold/cadcraft.git
synced 2026-11-11 16:32:22 -06:00
fix(io): the embedded column object carries the column height like AutoCAD's (#2248)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
9ff37ba262
commit
c5d186ae92
@@ -115,11 +115,14 @@ fn read_embedded_columns(tags: &[Tag]) -> Option<(MTextColumns, f64)> {
|
||||
let heights: Vec<f64> = obj.iter().filter(|t| t.code == 46).take(MAX_COLUMNS).map(|t| finite(t.f64()).max(0.0)).collect();
|
||||
let auto_height = first(73).map(Tag::i64).unwrap_or(0) != 0;
|
||||
let manual = kind == MTextColumnType::Dynamic && !auto_height;
|
||||
// The column height: the entity's own 46 (defined height), else the object's 41 or first 46.
|
||||
let own_46 = own(tags).iter().find(|t| t.code == 46).map(|t| finite(t.f64()).max(0.0));
|
||||
let defined = [own_46, first(41).map(|t| finite(t.f64())), heights.first().copied()].into_iter().flatten().find(|h| *h > 0.0).unwrap_or(0.0);
|
||||
let c = MTextColumns {
|
||||
kind,
|
||||
count: u16::try_from(first(72).map(Tag::i64).unwrap_or(1).clamp(1, MAX_COLUMNS as i64)).unwrap_or(1),
|
||||
gutter: first(45).map(|t| finite(t.f64()).max(0.0)).unwrap_or(0.0),
|
||||
height: if manual { heights.iter().copied().fold(0.0, f64::max) } else { heights.first().copied().unwrap_or(0.0) },
|
||||
height: if manual { heights.iter().copied().fold(0.0, f64::max) } else { defined },
|
||||
auto_height,
|
||||
heights: if manual { heights } else { Vec::new() },
|
||||
flow_reversed: first(74).map(Tag::i64).unwrap_or(0) != 0,
|
||||
@@ -137,7 +140,10 @@ pub(crate) fn column_tags(t: &MText, embedded: bool) -> Vec<Tag> {
|
||||
if embedded {
|
||||
let (sin, cos) = t.rotation.sin_cos();
|
||||
let total_width = t.width * count as f64 + c.gutter * (count as f64 - 1.0);
|
||||
// The column height (static, and dynamic with auto height) is the entity's group 46.
|
||||
let height = if manual { heights.iter().copied().fold(0.0, f64::max) } else { c.height };
|
||||
let mut v = vec![
|
||||
Tag::f(46, height),
|
||||
Tag::s(101, "Embedded Object"),
|
||||
Tag::i(70, 1),
|
||||
Tag::f(10, cos),
|
||||
@@ -147,9 +153,9 @@ pub(crate) fn column_tags(t: &MText, embedded: bool) -> Vec<Tag> {
|
||||
Tag::f(21, t.insert.y),
|
||||
Tag::f(31, t.insert.z),
|
||||
Tag::f(40, t.width),
|
||||
Tag::f(41, 0.0),
|
||||
Tag::f(41, height),
|
||||
Tag::f(42, total_width),
|
||||
Tag::f(43, heights.iter().copied().fold(0.0, f64::max)),
|
||||
Tag::f(43, height),
|
||||
Tag::i(71, if c.kind == MTextColumnType::Dynamic { 2 } else { 1 }),
|
||||
Tag::i(72, count as i64),
|
||||
Tag::f(44, t.width),
|
||||
@@ -157,7 +163,9 @@ pub(crate) fn column_tags(t: &MText, embedded: bool) -> Vec<Tag> {
|
||||
Tag::i(73, i64::from(c.auto_height)),
|
||||
Tag::i(74, i64::from(c.flow_reversed)),
|
||||
];
|
||||
v.extend(heights.into_iter().map(|h| Tag::f(46, h)));
|
||||
if manual {
|
||||
v.extend(heights.into_iter().map(|h| Tag::f(46, h)));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
let mut v = vec![
|
||||
|
||||
@@ -165,6 +165,16 @@ fn embedded_static_columns_are_read() {
|
||||
assert_eq!(t.columns, Some(c));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_column_height_is_the_entitys_defined_height() {
|
||||
// As ezdxf and AutoCAD write static columns: the height in the entity's 46, none in the object.
|
||||
let mut tags = embedded_tags(3, 12.5, 2.5, &[]);
|
||||
let at = tags.iter().position(|t| t.code == 101).unwrap();
|
||||
tags.insert(at, cadcraft_dxf::Tag::f(46, 20.0));
|
||||
let (_, t) = mtext_from_groups(&tags);
|
||||
assert_eq!(t.columns.map(|c| c.height), Some(20.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn r2018_writes_the_embedded_object_and_older_versions_the_legacy_groups() {
|
||||
let (_, t) = mtext_from_groups(&embedded_tags(3, 12.5, 2.5, &[20.0, 20.0, 20.0]));
|
||||
|
||||
Reference in New Issue
Block a user