forked from 1b-agent/opencadstudio-upstream
fix(mleader): repair creation and editing
This commit is contained in:
commit
ff1f873633
40 files changed
+4504
-1754
No files matched your search
@@ -403,8 +403,8 @@ pub fn set_property(
|
||||
let size = current.abs().max(0.01);
|
||||
let value = match trimmed.to_ascii_lowercase().as_str() {
|
||||
"none" => 0.0,
|
||||
"center marks" => size,
|
||||
"centerlines" => -size,
|
||||
"mark" | "center marks" => size,
|
||||
"line" | "centerlines" => -size,
|
||||
_ => return false,
|
||||
};
|
||||
set(doc, handle, DIMCEN, Some(XDataValue::Real(value)));
|
||||
@@ -423,6 +423,7 @@ pub fn set_property(
|
||||
return true;
|
||||
}
|
||||
let handle_field = match field {
|
||||
"dim_radial_arrow" => Some(DIMLDRBLK),
|
||||
"dim_arrowhead_1" => Some(DIMBLK1),
|
||||
"dim_arrowhead_2" => Some(DIMBLK2),
|
||||
"dim_linetype" => Some(DIMLTYPE),
|
||||
@@ -433,7 +434,7 @@ pub fn set_property(
|
||||
};
|
||||
if let Some(code) = handle_field {
|
||||
let resolved = match field {
|
||||
"dim_arrowhead_1" | "dim_arrowhead_2" => {
|
||||
"dim_radial_arrow" | "dim_arrowhead_1" | "dim_arrowhead_2" => {
|
||||
if trimmed == "Closed filled" {
|
||||
Some(Handle::NULL)
|
||||
} else {
|
||||
@@ -638,6 +639,10 @@ pub fn set_property(
|
||||
"dim_line_lineweight" | "dim_ext_line_lineweight" => {
|
||||
parse_lineweight_label(trimmed)
|
||||
}
|
||||
"dim_precision"
|
||||
| "dim_alt_precision"
|
||||
| "dim_tolerance_precision"
|
||||
| "dim_alt_tolerance_precision" => parse_precision_label(trimmed),
|
||||
"dim_ext_line_fixed"
|
||||
| "dim_text_outside_align"
|
||||
| "dim_text_inside_align"
|
||||
@@ -729,8 +734,8 @@ pub fn set_property(
|
||||
_ => trimmed.parse().ok(),
|
||||
},
|
||||
"dim_tolerance_alignment" => match trimmed.to_ascii_lowercase().as_str() {
|
||||
"align decimal separators" => Some(0),
|
||||
"align operational symbols" => Some(1),
|
||||
"decimal separator" | "align decimal separators" => Some(0),
|
||||
"operational symbols" | "align operational symbols" => Some(1),
|
||||
_ => trimmed.parse().ok(),
|
||||
},
|
||||
_ => trimmed.parse().ok(),
|
||||
@@ -744,6 +749,16 @@ pub fn set_property(
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_precision_label(value: &str) -> Option<i16> {
|
||||
if let Some(decimals) = value.strip_prefix("0.") {
|
||||
return (!decimals.is_empty()
|
||||
&& decimals.len() <= 8
|
||||
&& decimals.bytes().all(|digit| digit == b'0'))
|
||||
.then_some(decimals.len() as i16);
|
||||
}
|
||||
value.parse().ok()
|
||||
}
|
||||
|
||||
fn parse_lineweight_label(value: &str) -> Option<i16> {
|
||||
match value.trim() {
|
||||
"ByLayer" => Some(-1),
|
||||
|
||||
+982
-396
File diff suppressed because it is too large.
Load diff
+22
-14
@@ -3,6 +3,7 @@ use acadrust::entities::{
|
||||
MultiLeader, MultiLeaderPathType, MultiLeaderPropertyOverrideFlags, TextAlignmentType,
|
||||
TextAttachmentDirectionType, TextAttachmentType,
|
||||
};
|
||||
use cadkernel::geom2d::Transform;
|
||||
|
||||
use crate::entities::text_support::{
|
||||
layout_mtext, resolve_text_style, MTextRenderOpts, MTextVAnchor, ResolvedTextStyle,
|
||||
@@ -1120,7 +1121,9 @@ fn apply_geom_prop(ml: &mut MultiLeader, field: &str, value: &str) {
|
||||
!ml.text_frame
|
||||
} else {
|
||||
value == "true"
|
||||
}
|
||||
};
|
||||
ml.property_override_flags
|
||||
.insert(MultiLeaderPropertyOverrideFlags::TEXT_FRAME);
|
||||
}
|
||||
"path_type" => {
|
||||
ml.path_type = match value {
|
||||
@@ -1200,6 +1203,8 @@ fn apply_geom_prop(ml: &mut MultiLeader, field: &str, value: &str) {
|
||||
"dogleg_length" => {
|
||||
if let Some(v) = f64(value) {
|
||||
ml.dogleg_length = v;
|
||||
ml.property_override_flags
|
||||
.insert(MultiLeaderPropertyOverrideFlags::LANDING_DISTANCE);
|
||||
}
|
||||
}
|
||||
"arrowhead_size" => {
|
||||
@@ -1395,6 +1400,8 @@ fn apply_geom_prop(ml: &mut MultiLeader, field: &str, value: &str) {
|
||||
ml.context.text_rotation.sin(),
|
||||
0.0,
|
||||
);
|
||||
ml.property_override_flags
|
||||
.insert(MultiLeaderPropertyOverrideFlags::TEXT_ANGLE);
|
||||
}
|
||||
}
|
||||
"line_spacing" => {
|
||||
@@ -1941,9 +1948,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
}
|
||||
}
|
||||
|
||||
// Vertically-attached leaders (text above/below) have no dogleg:
|
||||
// the leader meets the text edge directly, so the short horizontal
|
||||
// dash would be a stray mark AutoCAD never draws.
|
||||
// Vertically attached leaders meet the text edge directly.
|
||||
let vertical_attach = matches!(
|
||||
ml.text_attachment_direction,
|
||||
acadrust::entities::multileader::TextAttachmentDirectionType::Vertical
|
||||
@@ -2074,20 +2079,28 @@ impl MultiLeaderTess for MultiLeader {
|
||||
}
|
||||
}
|
||||
if bounds[0] <= bounds[2] && bounds[1] <= bounds[3] {
|
||||
let to_block = Transform::rotation(-ml.block_rotation);
|
||||
let from_left = ml
|
||||
.context
|
||||
.leader_roots
|
||||
.first()
|
||||
.map_or(true, |root| root.direction.x >= 0.0);
|
||||
.map_or(true, |root| {
|
||||
to_block.apply_vector([
|
||||
root.direction.x,
|
||||
root.direction.y,
|
||||
])[0]
|
||||
>= 0.0
|
||||
});
|
||||
let anchor_x = if from_left { bounds[0] } else { bounds[2] } as f64;
|
||||
let anchor_y = ((bounds[1] + bounds[3]) * 0.5) as f64;
|
||||
let local_x =
|
||||
(anchor_x - block_record.base_point.x) * ml.block_scale.x;
|
||||
let local_y =
|
||||
(anchor_y - block_record.base_point.y) * ml.block_scale.y;
|
||||
let (sin_r, cos_r) = ml.block_rotation.sin_cos();
|
||||
insertion.x -= local_x * cos_r - local_y * sin_r;
|
||||
insertion.y -= local_x * sin_r + local_y * cos_r;
|
||||
let rotated = Transform::rotation(ml.block_rotation)
|
||||
.apply_vector([local_x, local_y]);
|
||||
insertion.x -= rotated[0];
|
||||
insertion.y -= rotated[1];
|
||||
}
|
||||
}
|
||||
let mut synth_ins = acadrust::entities::Insert::new(block_name, insertion);
|
||||
@@ -2171,12 +2184,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
let local_ins_x = (ins.x) as f32;
|
||||
let z = (ins.z) as f32;
|
||||
|
||||
// Rotation: the annotation context is AutoCAD's BAKED display
|
||||
// state — text_direction / text_rotation already reflect whatever
|
||||
// the style's angle setting produced at edit time. Re-deriving
|
||||
// from ml.text_angle_type here (e.g. forcing Horizontal to 0)
|
||||
// un-rotated leaders whose stored context is angled; the angle
|
||||
// type only guides recomputation during edits, not display.
|
||||
// The context stores the resolved display rotation.
|
||||
let td = ctx.text_direction;
|
||||
let mut rot = if td.x.abs() > 1e-9 || td.y.abs() > 1e-9 {
|
||||
(td.y as f32).atan2(td.x as f32)
|
||||
|
||||
Reference in new issue
Block a user