Align MText properties and column layout
This commit is contained in:
parent
4be01774e1
commit
96ca741f35
6 changed files with 214 additions and 34 deletions
|
|
@ -200,6 +200,7 @@ fn build_attr_render(input: AttrTextInputs<'_>, document: &acadrust::CadDocument
|
|||
oblique_angle,
|
||||
is_backward: width_factor < 0.0,
|
||||
is_upside_down: false,
|
||||
is_vertical: false,
|
||||
};
|
||||
let layout = layout_mtext(&MTextRenderOpts {
|
||||
// Not an MTEXT: text in a fixed box, never columnar.
|
||||
|
|
@ -213,6 +214,8 @@ fn build_attr_render(input: AttrTextInputs<'_>, document: &acadrust::CadDocument
|
|||
attach_h_anchor,
|
||||
v_anchor,
|
||||
line_spacing_factor: 1.0,
|
||||
exact_line_spacing: false,
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ fn columns_of(t: &MText) -> MTextColumns {
|
|||
count: c.column_count.max(0) as usize,
|
||||
width: c.width as f32,
|
||||
gutter: c.gutter as f32,
|
||||
flow_reversed: c.flow_reversed,
|
||||
auto_height: c.auto_height,
|
||||
heights: c.heights.iter().map(|height| *height as f32).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +123,14 @@ pub fn glyph_boxes(t: &MText, document: &acadrust::CadDocument) -> Vec<GlyphBox>
|
|||
attach_h_anchor,
|
||||
v_anchor,
|
||||
line_spacing_factor: t.line_spacing_factor as f32,
|
||||
vertical_text: matches!(t.drawing_direction, DrawingDirection::TopToBottom),
|
||||
exact_line_spacing: matches!(
|
||||
t.line_spacing_style,
|
||||
acadrust::entities::LineSpacingStyle::Exactly
|
||||
),
|
||||
rectangle_height: t.rectangle_height.unwrap_or(0.0) as f32,
|
||||
vertical_text: matches!(t.drawing_direction, DrawingDirection::TopToBottom)
|
||||
|| matches!(t.drawing_direction, DrawingDirection::ByStyle)
|
||||
&& resolved_style.is_vertical,
|
||||
want_glyph_boxes: true,
|
||||
columns: columns_of(t),
|
||||
});
|
||||
|
|
@ -169,7 +179,14 @@ fn to_render(t: &MText, document: &acadrust::CadDocument) -> RenderEntity {
|
|||
attach_h_anchor,
|
||||
v_anchor,
|
||||
line_spacing_factor: t.line_spacing_factor as f32,
|
||||
vertical_text: matches!(t.drawing_direction, DrawingDirection::TopToBottom),
|
||||
exact_line_spacing: matches!(
|
||||
t.line_spacing_style,
|
||||
acadrust::entities::LineSpacingStyle::Exactly
|
||||
),
|
||||
rectangle_height: t.rectangle_height.unwrap_or(0.0) as f32,
|
||||
vertical_text: matches!(t.drawing_direction, DrawingDirection::TopToBottom)
|
||||
|| matches!(t.drawing_direction, DrawingDirection::ByStyle)
|
||||
&& resolved_style.is_vertical,
|
||||
want_glyph_boxes: false,
|
||||
columns: columns_of(t),
|
||||
});
|
||||
|
|
@ -231,8 +248,43 @@ fn grips(t: &MText) -> Vec<GripDef> {
|
|||
t.insertion_point.z,
|
||||
);
|
||||
let (dir, k) = width_grip_axis(t);
|
||||
let width_grip = p + dir * (k * t.rectangle_width.max(0.0));
|
||||
vec![square_grip(0, p), triangle_grip(1, width_grip)]
|
||||
let columns_active = t.column_data.column_type != 0
|
||||
&& t.column_data.column_count > 1
|
||||
&& t.column_data.width > 0.0;
|
||||
let block_width = if columns_active {
|
||||
t.column_data.width * t.column_data.column_count as f64
|
||||
+ t.column_data.gutter * (t.column_data.column_count - 1) as f64
|
||||
} else {
|
||||
t.rectangle_width.max(0.0)
|
||||
};
|
||||
let width_grip = p + dir * (k * block_width);
|
||||
let mut result = vec![square_grip(0, p), triangle_grip(1, width_grip)];
|
||||
|
||||
let height = t
|
||||
.rectangle_height
|
||||
.or_else(|| t.column_data.heights.first().copied())
|
||||
.unwrap_or(0.0);
|
||||
if height > 0.0 && !(columns_active && t.column_data.auto_height) {
|
||||
let (sin, cos) = t.rotation.sin_cos();
|
||||
let down = glam::DVec3::new(sin, -cos, 0.0);
|
||||
let (_, vertical) = attach_anchors(t);
|
||||
let factor = match vertical {
|
||||
MTextVAnchor::Top
|
||||
| MTextVAnchor::MiddleOfTopLine
|
||||
| MTextVAnchor::BottomOfTopLine => 1.0,
|
||||
MTextVAnchor::Middle => 0.5,
|
||||
MTextVAnchor::Bottom | MTextVAnchor::MiddleOfBottomLine => -1.0,
|
||||
};
|
||||
result.push(triangle_grip(2, p + down * (factor * height)));
|
||||
}
|
||||
if columns_active {
|
||||
result.push(triangle_grip(3, p + dir * (k * t.column_data.width)));
|
||||
result.push(triangle_grip(
|
||||
4,
|
||||
p + dir * (k * (t.column_data.width + t.column_data.gutter)),
|
||||
));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn columns_str(c: &acadrust::entities::MTextColumnData) -> &'static str {
|
||||
|
|
@ -371,20 +423,6 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec<PropSection> {
|
|||
.collect(),
|
||||
},
|
||||
},
|
||||
// Count / width / gutter are live only when columns are on.
|
||||
num_row(
|
||||
t!("Column count").as_ref(),
|
||||
"col_count",
|
||||
t.column_data.column_count as f64,
|
||||
col_type != 0,
|
||||
),
|
||||
num_row(t!("Column width").as_ref(), "col_width", t.column_data.width, col_type != 0),
|
||||
num_row(
|
||||
t!("Column gutter").as_ref(),
|
||||
"col_gutter",
|
||||
t.column_data.gutter,
|
||||
col_type != 0,
|
||||
),
|
||||
Property {
|
||||
label: t!("Text frame").into_owned(),
|
||||
field: "text_frame",
|
||||
|
|
@ -502,21 +540,21 @@ fn apply_geom_prop(t: &mut MText, field: &str, value: &str) {
|
|||
"ins_y" => t.insertion_point.y = v,
|
||||
"ins_z" => t.insertion_point.z = v,
|
||||
"height" if v > 0.0 => t.height = v,
|
||||
"rect_w" if v > 0.0 => t.rectangle_width = v,
|
||||
"rect_h" if v > 0.0 => t.rectangle_height = Some(v),
|
||||
"rect_w" if v >= 0.0 => t.rectangle_width = v,
|
||||
"rect_h" if v >= 0.0 => t.rectangle_height = (v > 0.0).then_some(v),
|
||||
"rotation" => t.rotation = v.to_radians(),
|
||||
"line_spacing" if v > 0.0 => t.line_spacing_factor = v,
|
||||
"line_spacing" if (0.25..=4.0).contains(&v) => t.line_spacing_factor = v,
|
||||
// Editing the absolute distance back-solves the line-spacing factor so
|
||||
// the two stay consistent (distance = height × 5/3 × factor).
|
||||
"line_space_distance" if v > 0.0 => {
|
||||
let denom = t.height * 1.666_666_666_666_667;
|
||||
if denom > 0.0 {
|
||||
t.line_spacing_factor = v / denom;
|
||||
let factor = v / denom;
|
||||
if (0.25..=4.0).contains(&factor) {
|
||||
t.line_spacing_factor = factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
"col_count" if v >= 1.0 => t.column_data.column_count = v.round() as i32,
|
||||
"col_width" if v > 0.0 => t.column_data.width = v,
|
||||
"col_gutter" if v >= 0.0 => t.column_data.gutter = v,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -541,7 +579,57 @@ fn apply_grip(t: &mut MText, grip_id: usize, apply: GripApply) {
|
|||
let dx = p.x as f64 - t.insertion_point.x;
|
||||
let dy = p.y as f64 - t.insertion_point.y;
|
||||
let projected = dx * dir.x + dy * dir.y;
|
||||
t.rectangle_width = (projected / k).max(0.01);
|
||||
let width = (projected / k).max(0.0);
|
||||
if t.column_data.column_type != 0 && t.column_data.column_count > 1 {
|
||||
let gaps = (t.column_data.column_count - 1) as f64;
|
||||
t.column_data.width =
|
||||
((width - t.column_data.gutter * gaps) / t.column_data.column_count as f64)
|
||||
.max(0.01);
|
||||
} else {
|
||||
t.rectangle_width = width;
|
||||
}
|
||||
}
|
||||
(2, GripApply::Absolute(p)) => {
|
||||
let (sin, cos) = t.rotation.sin_cos();
|
||||
let down = glam::DVec3::new(sin, -cos, 0.0);
|
||||
let delta = glam::DVec3::new(
|
||||
p.x as f64 - t.insertion_point.x,
|
||||
p.y as f64 - t.insertion_point.y,
|
||||
p.z as f64 - t.insertion_point.z,
|
||||
);
|
||||
let (_, vertical) = attach_anchors(t);
|
||||
let factor = match vertical {
|
||||
MTextVAnchor::Top
|
||||
| MTextVAnchor::MiddleOfTopLine
|
||||
| MTextVAnchor::BottomOfTopLine => 1.0,
|
||||
MTextVAnchor::Middle => 0.5,
|
||||
MTextVAnchor::Bottom | MTextVAnchor::MiddleOfBottomLine => -1.0,
|
||||
};
|
||||
let height = (delta.dot(down) / factor).max(0.01);
|
||||
t.rectangle_height = Some(height);
|
||||
if t.column_data.column_type != 0 && !t.column_data.auto_height {
|
||||
t.column_data.heights =
|
||||
vec![height; t.column_data.column_count.max(1) as usize];
|
||||
}
|
||||
}
|
||||
(3, GripApply::Absolute(p)) => {
|
||||
let (dir, k) = width_grip_axis(t);
|
||||
let delta = glam::DVec3::new(
|
||||
p.x as f64 - t.insertion_point.x,
|
||||
p.y as f64 - t.insertion_point.y,
|
||||
0.0,
|
||||
);
|
||||
t.column_data.width = (delta.dot(dir) / k).max(0.01);
|
||||
}
|
||||
(4, GripApply::Absolute(p)) => {
|
||||
let (dir, k) = width_grip_axis(t);
|
||||
let delta = glam::DVec3::new(
|
||||
p.x as f64 - t.insertion_point.x,
|
||||
p.y as f64 - t.insertion_point.y,
|
||||
0.0,
|
||||
);
|
||||
t.column_data.gutter =
|
||||
(delta.dot(dir) / k - t.column_data.width).max(0.0);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,6 +195,11 @@ fn to_render(ml: &MultiLeader, document: &acadrust::CadDocument) -> Option<Rende
|
|||
},
|
||||
),
|
||||
line_spacing_factor: ctx.line_spacing_factor as f32,
|
||||
exact_line_spacing: matches!(
|
||||
ctx.line_spacing_style,
|
||||
acadrust::entities::LineSpacingStyle::Exactly
|
||||
),
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: false,
|
||||
}))
|
||||
|
|
@ -412,6 +417,7 @@ fn text_box_geom(ml: &MultiLeader) -> ([f64; 2], [f64; 3]) {
|
|||
oblique_angle: 0.0,
|
||||
is_backward: false,
|
||||
is_upside_down: false,
|
||||
is_vertical: false,
|
||||
};
|
||||
let layout = layout_mtext(&MTextRenderOpts {
|
||||
columns: Default::default(),
|
||||
|
|
@ -424,6 +430,11 @@ fn text_box_geom(ml: &MultiLeader) -> ([f64; 2], [f64; 3]) {
|
|||
attach_h_anchor: 0.0,
|
||||
v_anchor: MTextVAnchor::Top,
|
||||
line_spacing_factor: ctx.line_spacing_factor as f32,
|
||||
exact_line_spacing: matches!(
|
||||
ctx.line_spacing_style,
|
||||
acadrust::entities::LineSpacingStyle::Exactly
|
||||
),
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: vertical,
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
|
|
@ -2039,6 +2050,11 @@ impl MultiLeaderTess for MultiLeader {
|
|||
attach_h_anchor: h_anchor,
|
||||
v_anchor,
|
||||
line_spacing_factor: ctx.line_spacing_factor as f32,
|
||||
exact_line_spacing: matches!(
|
||||
ctx.line_spacing_style,
|
||||
acadrust::entities::LineSpacingStyle::Exactly
|
||||
),
|
||||
rectangle_height: 0.0,
|
||||
// Vertical flow (top-to-bottom) is stored per-context.
|
||||
vertical_text: matches!(
|
||||
ctx.text_flow_direction,
|
||||
|
|
|
|||
|
|
@ -1187,6 +1187,7 @@ impl RenderConvertible for Table {
|
|||
oblique_angle: style.map(|s| s.oblique_angle as f32).unwrap_or(0.0),
|
||||
is_backward: style.map(|s| s.is_backward()).unwrap_or(false),
|
||||
is_upside_down: style.map(|s| s.is_upside_down()).unwrap_or(false),
|
||||
is_vertical: style.map(|s| s.is_vertical).unwrap_or(false),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1287,6 +1288,8 @@ impl RenderConvertible for Table {
|
|||
attach_h_anchor,
|
||||
v_anchor,
|
||||
line_spacing_factor: 1.0,
|
||||
exact_line_spacing: false,
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
|
|
@ -1453,6 +1456,7 @@ pub fn tessellate_table(
|
|||
oblique_angle: style.map(|s| s.oblique_angle as f32).unwrap_or(0.0),
|
||||
is_backward: style.map(|s| s.is_backward()).unwrap_or(false),
|
||||
is_upside_down: style.map(|s| s.is_upside_down()).unwrap_or(false),
|
||||
is_vertical: style.map(|s| s.is_vertical).unwrap_or(false),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1920,6 +1924,8 @@ pub fn tessellate_table(
|
|||
attach_h_anchor,
|
||||
v_anchor,
|
||||
line_spacing_factor: 1.0,
|
||||
exact_line_spacing: false,
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ pub struct ResolvedTextStyle {
|
|||
pub oblique_angle: f32,
|
||||
pub is_backward: bool,
|
||||
pub is_upside_down: bool,
|
||||
pub is_vertical: bool,
|
||||
}
|
||||
|
||||
pub fn resolve_text_style(style_name: &str, document: &CadDocument) -> ResolvedTextStyle {
|
||||
|
|
@ -76,6 +77,7 @@ pub fn resolve_text_style(style_name: &str, document: &CadDocument) -> ResolvedT
|
|||
oblique_angle: style.map(|s| s.oblique_angle as f32).unwrap_or(0.0),
|
||||
is_backward: style.map(|s| s.is_backward()).unwrap_or(false),
|
||||
is_upside_down: style.map(|s| s.is_upside_down()).unwrap_or(false),
|
||||
is_vertical: style.map(|s| s.is_vertical).unwrap_or(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1012,6 +1014,11 @@ pub struct MTextRenderOpts<'a> {
|
|||
pub v_anchor: MTextVAnchor,
|
||||
/// DXF code 44 — multiplier on the default 5/3-em baseline gap.
|
||||
pub line_spacing_factor: f32,
|
||||
/// `true` fixes every baseline advance to the entity spacing. `false`
|
||||
/// treats it as a minimum and expands for taller inline runs.
|
||||
pub exact_line_spacing: bool,
|
||||
/// User-defined text-box/column height. Zero means content-driven.
|
||||
pub rectangle_height: f32,
|
||||
/// `true` when the entity is laid out top-to-bottom (DXF code 71 = 2).
|
||||
pub vertical_text: bool,
|
||||
/// When true, `layout_mtext` also fills `MTextLayout::glyph_boxes` with
|
||||
|
|
@ -1025,10 +1032,9 @@ pub struct MTextRenderOpts<'a> {
|
|||
|
||||
/// An MTEXT's column layout, flattened from its `column_data`.
|
||||
///
|
||||
/// Content moves to the next column at a `\N` break. Filling a column and
|
||||
/// spilling into the next on its own is not modelled: `heights` / `auto_height`
|
||||
/// are not read, so a column runs as long as its content does.
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
/// Content moves to the next column at an explicit `\N` break or when the
|
||||
/// configured manual/automatic column height is exhausted.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct MTextColumns {
|
||||
/// Column count. 0 or 1 both mean "no column layout".
|
||||
pub count: usize,
|
||||
|
|
@ -1036,6 +1042,12 @@ pub struct MTextColumns {
|
|||
pub width: f32,
|
||||
/// Gap between two adjacent columns, world units.
|
||||
pub gutter: f32,
|
||||
/// Whether logical column flow starts at the opposite side.
|
||||
pub flow_reversed: bool,
|
||||
/// Dynamic-column height is balanced from content when true.
|
||||
pub auto_height: bool,
|
||||
/// Optional manual height for each logical column.
|
||||
pub heights: Vec<f32>,
|
||||
}
|
||||
|
||||
impl MTextColumns {
|
||||
|
|
@ -1046,7 +1058,12 @@ impl MTextColumns {
|
|||
|
||||
/// Left edge of column `i`, relative to the text block's own left edge.
|
||||
pub fn offset_of(&self, i: usize) -> f32 {
|
||||
i as f32 * (self.width + self.gutter)
|
||||
let physical = if self.flow_reversed {
|
||||
self.count.saturating_sub(1).saturating_sub(i)
|
||||
} else {
|
||||
i
|
||||
};
|
||||
physical as f32 * (self.width + self.gutter)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1128,7 +1145,7 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout {
|
|||
line_spacing: Option<ParaLineSpacing>,
|
||||
}
|
||||
|
||||
let cols = opts.columns;
|
||||
let cols = opts.columns.clone();
|
||||
// A `\N` past the last column has nowhere to go — keep those lines in the
|
||||
// last one rather than laying them out beyond the block.
|
||||
let last_col = cols.count.saturating_sub(1);
|
||||
|
|
@ -1366,15 +1383,55 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout {
|
|||
};
|
||||
// A paragraph's own `\psm#`/`\pse#` overrides the entity factor for
|
||||
// its lines; `Exact` fixes the baseline gap outright.
|
||||
let entity_gap = entity_h * ls_factor * (5.0 / 3.0) * base_font.line_spacing();
|
||||
match s.line_spacing {
|
||||
Some(ParaLineSpacing::Exact(e)) if e > 0.0 => e,
|
||||
Some(ParaLineSpacing::Multiple(m)) if m > 0.0 => {
|
||||
mh * m * (5.0 / 3.0) * base_font.line_spacing()
|
||||
}
|
||||
_ => mh * ls_factor * (5.0 / 3.0) * base_font.line_spacing(),
|
||||
_ if opts.exact_line_spacing => entity_gap,
|
||||
_ => (mh * ls_factor * (5.0 / 3.0) * base_font.line_spacing())
|
||||
.max(entity_gap),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Flow lines into the next column when the active column's configured
|
||||
// height is exhausted. Explicit `\N` breaks remain authoritative. Dynamic
|
||||
// auto-height balances the content; static/manual columns use their stored
|
||||
// height (falling back to the entity rectangle height).
|
||||
if cols.active() {
|
||||
let total_advance: f32 = per_line_h.iter().sum();
|
||||
let balanced = (total_advance / cols.count.max(1) as f32).max(entity_h);
|
||||
let mut current_column = 0usize;
|
||||
let mut used = 0.0_f32;
|
||||
for (index, line) in sub_lines.iter_mut().enumerate() {
|
||||
if line.column > current_column {
|
||||
current_column = line.column.min(cols.count - 1);
|
||||
used = 0.0;
|
||||
}
|
||||
let limit = if cols.auto_height {
|
||||
balanced
|
||||
} else {
|
||||
cols.heights
|
||||
.get(current_column)
|
||||
.copied()
|
||||
.filter(|height| *height > 0.0)
|
||||
.unwrap_or(opts.rectangle_height)
|
||||
};
|
||||
let advance = per_line_h.get(index).copied().unwrap_or(entity_h);
|
||||
if limit > 0.0
|
||||
&& used > 0.0
|
||||
&& used + advance > limit
|
||||
&& current_column + 1 < cols.count
|
||||
{
|
||||
current_column += 1;
|
||||
used = 0.0;
|
||||
}
|
||||
line.column = current_column;
|
||||
used += advance;
|
||||
}
|
||||
}
|
||||
// Per-line text height — the tallest Word on the line, an empty line
|
||||
// inheriting the previous line's height (same rule as `per_line_h`). Unlike
|
||||
// `line_max_h` it has no `entity_h` floor, so it reflects the ACTUAL text
|
||||
|
|
@ -2169,6 +2226,7 @@ mod tests {
|
|||
oblique_angle: 0.0,
|
||||
is_backward: false,
|
||||
is_upside_down: false,
|
||||
is_vertical: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2199,6 +2257,8 @@ mod tests {
|
|||
attach_h_anchor: 0.0,
|
||||
v_anchor: MTextVAnchor::Top,
|
||||
line_spacing_factor: 1.0,
|
||||
exact_line_spacing: false,
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
|
|
@ -2222,6 +2282,8 @@ mod tests {
|
|||
attach_h_anchor: 0.0,
|
||||
v_anchor: MTextVAnchor::Top,
|
||||
line_spacing_factor: 1.0,
|
||||
exact_line_spacing: false,
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: false,
|
||||
});
|
||||
|
|
@ -2378,6 +2440,7 @@ mod v_anchor_tests {
|
|||
oblique_angle: 0.0,
|
||||
is_backward: false,
|
||||
is_upside_down: false,
|
||||
is_vertical: false,
|
||||
};
|
||||
layout_mtext(&MTextRenderOpts {
|
||||
columns: Default::default(),
|
||||
|
|
@ -2390,6 +2453,8 @@ mod v_anchor_tests {
|
|||
attach_h_anchor: 0.0,
|
||||
v_anchor: MTextVAnchor::Top,
|
||||
line_spacing_factor: 1.0,
|
||||
exact_line_spacing: false,
|
||||
rectangle_height: 0.0,
|
||||
vertical_text: false,
|
||||
want_glyph_boxes: true,
|
||||
})
|
||||
|
|
|
|||
4
src/scene/cache/properties.rs
vendored
4
src/scene/cache/properties.rs
vendored
|
|
@ -94,7 +94,9 @@ pub fn general_section(entity: &EntityType) -> PropSection {
|
|||
],
|
||||
};
|
||||
|
||||
if matches!(entity, EntityType::LwPolyline(polyline) if crate::entities::lwpolyline::is_rectangle(polyline)) {
|
||||
if matches!(entity, EntityType::LwPolyline(polyline) if crate::entities::lwpolyline::is_rectangle(polyline))
|
||||
|| matches!(entity, EntityType::MText(_))
|
||||
{
|
||||
section.props.retain(|prop| prop.field != "handle");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue