forked from 1b-agent/opencadstudio-upstream
style: apply cargo fmt across workspace
This commit is contained in:
1 parent
85710e5454
commit
9cf9ff2c5c
531 files changed
+57740
-33906
No files matched your search
+191
-261
@@ -57,7 +57,8 @@ pub(crate) fn active_vertical_attachment(ml: &MultiLeader) -> TextAttachmentType
|
||||
|
||||
use crate::command::EntityTransform;
|
||||
use crate::entities::common::{
|
||||
center_grip, edit_angle_prop as edit_angle, edit_prop as edit, num_prop as num_row, ro_prop as ro, square_grip, triangle_grip,
|
||||
center_grip, edit_angle_prop as edit_angle, edit_prop as edit, num_prop as num_row,
|
||||
ro_prop as ro, square_grip, triangle_grip,
|
||||
};
|
||||
use crate::entities::traits::RenderConvertible;
|
||||
use crate::scene::convert::acad_to_render::{RenderEntity, RenderObject};
|
||||
@@ -189,13 +190,11 @@ fn to_render(ml: &MultiLeader, document: &codec::CadDocument) -> Option<RenderEn
|
||||
codec::entities::multileader::TextAttachmentPointType::Center => 0.5,
|
||||
codec::entities::multileader::TextAttachmentPointType::Right => 1.0,
|
||||
},
|
||||
v_anchor: mleader_v_anchor(
|
||||
if text_sign >= 0.0 {
|
||||
ctx.text_left_attachment
|
||||
} else {
|
||||
ctx.text_right_attachment
|
||||
},
|
||||
),
|
||||
v_anchor: mleader_v_anchor(if text_sign >= 0.0 {
|
||||
ctx.text_left_attachment
|
||||
} else {
|
||||
ctx.text_right_attachment
|
||||
}),
|
||||
line_spacing_factor: ctx.line_spacing_factor as f32,
|
||||
exact_line_spacing: matches!(
|
||||
ctx.line_spacing_style,
|
||||
@@ -250,14 +249,12 @@ fn to_render(ml: &MultiLeader, document: &codec::CadDocument) -> Option<RenderEn
|
||||
first = false;
|
||||
|
||||
// Build the full control-point list: line.points + landing point
|
||||
let mut ctrl: Vec<[f64; 3]> =
|
||||
line.points.iter().map(|p| p3(p)).collect();
|
||||
let mut ctrl: Vec<[f64; 3]> = line.points.iter().map(|p| p3(p)).collect();
|
||||
|
||||
let last_f = *ctrl.last().unwrap_or(&elbow_pt);
|
||||
|
||||
let dist = ((last_f[0] - elbow_pt[0]).powi(2)
|
||||
+ (last_f[1] - elbow_pt[1]).powi(2))
|
||||
.sqrt();
|
||||
let dist =
|
||||
((last_f[0] - elbow_pt[0]).powi(2) + (last_f[1] - elbow_pt[1]).powi(2)).sqrt();
|
||||
|
||||
if dist > 1e-9 {
|
||||
ctrl.push(elbow_pt);
|
||||
@@ -454,20 +451,11 @@ fn text_box_geom(ml: &MultiLeader) -> ([f64; 2], [f64; 3]) {
|
||||
};
|
||||
(
|
||||
[dir[0] * k, dir[1] * k],
|
||||
[
|
||||
tl.x + dir[0] * k * extent,
|
||||
tl.y + dir[1] * k * extent,
|
||||
tl.z,
|
||||
],
|
||||
[tl.x + dir[0] * k * extent, tl.y + dir[1] * k * extent, tl.z],
|
||||
)
|
||||
}
|
||||
fn mleader_landing_geom(
|
||||
ml: &MultiLeader,
|
||||
) -> Option<(DVec3, DVec3, f64, f64, f64)> {
|
||||
if ml.content_type != LeaderContentType::MText
|
||||
|| !ml.enable_landing
|
||||
|| !ml.enable_dogleg
|
||||
{
|
||||
fn mleader_landing_geom(ml: &MultiLeader) -> Option<(DVec3, DVec3, f64, f64, f64)> {
|
||||
if ml.content_type != LeaderContentType::MText || !ml.enable_landing || !ml.enable_dogleg {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -546,10 +534,7 @@ fn grips(ml: &MultiLeader) -> Vec<GripDef> {
|
||||
for root in &ml.context.leader_roots {
|
||||
for line in &root.lines {
|
||||
for p in &line.points {
|
||||
result.push(square_grip(
|
||||
id,
|
||||
DVec3::new(p.x, p.y, p.z),
|
||||
));
|
||||
result.push(square_grip(id, DVec3::new(p.x, p.y, p.z)));
|
||||
|
||||
id += 1;
|
||||
}
|
||||
@@ -557,35 +542,21 @@ fn grips(ml: &MultiLeader) -> Vec<GripDef> {
|
||||
}
|
||||
|
||||
if ml.content_type == LeaderContentType::MText {
|
||||
if let Some((elbow, _, _, _, _)) = mleader_landing_geom(ml)
|
||||
{
|
||||
result.push(square_grip(
|
||||
id,
|
||||
elbow,
|
||||
));
|
||||
if let Some((elbow, _, _, _, _)) = mleader_landing_geom(ml) {
|
||||
result.push(square_grip(id, elbow));
|
||||
|
||||
id += 1;
|
||||
}
|
||||
|
||||
let tl = &ml.context.text_location;
|
||||
|
||||
result.push(center_grip(
|
||||
id,
|
||||
DVec3::new(tl.x, tl.y, tl.z),
|
||||
));
|
||||
result.push(center_grip(id, DVec3::new(tl.x, tl.y, tl.z)));
|
||||
|
||||
id += 1;
|
||||
|
||||
let (_, far) = text_box_geom(ml);
|
||||
|
||||
result.push(triangle_grip(
|
||||
id,
|
||||
DVec3::new(
|
||||
far[0],
|
||||
far[1],
|
||||
far[2],
|
||||
),
|
||||
));
|
||||
result.push(triangle_grip(id, DVec3::new(far[0], far[1], far[2])));
|
||||
}
|
||||
|
||||
result
|
||||
@@ -595,26 +566,15 @@ fn grips(ml: &MultiLeader) -> Vec<GripDef> {
|
||||
/// text grip's "Move with Leader" action so the leader follows the text.
|
||||
pub(crate) const MOVE_ALL_GRIP: usize = usize::MAX;
|
||||
|
||||
fn apply_grip(
|
||||
ml: &mut MultiLeader,
|
||||
grip_id: usize,
|
||||
apply: GripApply,
|
||||
) {
|
||||
fn apply_grip(ml: &mut MultiLeader, grip_id: usize, apply: GripApply) {
|
||||
if grip_id == MOVE_ALL_GRIP {
|
||||
let (dx, dy, dz) = match apply {
|
||||
GripApply::Translate(d) => (
|
||||
d.x as f64,
|
||||
d.y as f64,
|
||||
d.z as f64,
|
||||
),
|
||||
GripApply::Translate(d) => (d.x as f64, d.y as f64, d.z as f64),
|
||||
|
||||
GripApply::Absolute(a) => (
|
||||
a.x as f64
|
||||
- ml.context.text_location.x,
|
||||
a.y as f64
|
||||
- ml.context.text_location.y,
|
||||
a.z as f64
|
||||
- ml.context.text_location.z,
|
||||
a.x as f64 - ml.context.text_location.x,
|
||||
a.y as f64 - ml.context.text_location.y,
|
||||
a.z as f64 - ml.context.text_location.z,
|
||||
),
|
||||
};
|
||||
|
||||
@@ -728,18 +688,13 @@ fn apply_grip(
|
||||
);
|
||||
let target = match apply {
|
||||
GripApply::Absolute(a) => DVec3::new(a.x as f64, a.y as f64, a.z as f64),
|
||||
GripApply::Translate(d) => {
|
||||
old_end + DVec3::new(d.x as f64, d.y as f64, d.z as f64)
|
||||
}
|
||||
GripApply::Translate(d) => old_end + DVec3::new(d.x as f64, d.y as f64, d.z as f64),
|
||||
};
|
||||
|
||||
if let Some((elbow, axis, sign, _, gap)) = landing {
|
||||
let requested_total = (target - elbow).dot(axis) * sign;
|
||||
let new_length = (requested_total - gap).max(1.0e-6);
|
||||
set_mleader_text_location(
|
||||
ml,
|
||||
elbow + axis * (sign * (new_length + gap)),
|
||||
);
|
||||
set_mleader_text_location(ml, elbow + axis * (sign * (new_length + gap)));
|
||||
ml.dogleg_length = new_length;
|
||||
for root in &mut ml.context.leader_roots {
|
||||
root.landing_distance = new_length;
|
||||
@@ -756,15 +711,9 @@ fn apply_grip(
|
||||
let (dir, far) = text_box_geom(ml);
|
||||
|
||||
let (nx, ny) = match apply {
|
||||
GripApply::Absolute(a) => (
|
||||
a.x as f64,
|
||||
a.y as f64,
|
||||
),
|
||||
GripApply::Absolute(a) => (a.x as f64, a.y as f64),
|
||||
|
||||
GripApply::Translate(d) => (
|
||||
far[0] + d.x as f64,
|
||||
far[1] + d.y as f64,
|
||||
),
|
||||
GripApply::Translate(d) => (far[0] + d.x as f64, far[1] + d.y as f64),
|
||||
};
|
||||
|
||||
let tl = &ml.context.text_location;
|
||||
@@ -890,7 +839,11 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
||||
!ml.enable_annotation_scale,
|
||||
),
|
||||
// Style name is resolved from style_handle by the panel builder (needs doc).
|
||||
ro(t!("Multileader style").as_ref(), "mleader_style", "Standard"),
|
||||
ro(
|
||||
t!("Multileader style").as_ref(),
|
||||
"mleader_style",
|
||||
"Standard",
|
||||
),
|
||||
bool_toggle(
|
||||
t!("Annotative").as_ref(),
|
||||
"enable_annotation_scale",
|
||||
@@ -903,46 +856,66 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
||||
// Landing rows are folded in here: the standalone "Leader Structure" group
|
||||
// is a style-dialog tab, not a palette group.
|
||||
let mut leader_props = vec![
|
||||
choice(
|
||||
t!("Leader type").as_ref(),
|
||||
"path_type",
|
||||
leader_type_str(&ml.path_type),
|
||||
&["Straight", "Spline", "None"],
|
||||
),
|
||||
Property {
|
||||
label: t!("Leader color").into_owned(),
|
||||
field: "line_color",
|
||||
value: PropValue::ColorChoice(ml.line_color),
|
||||
},
|
||||
// Linetype name resolved from line_type_handle by the panel builder.
|
||||
ro(t!("Leader linetype").as_ref(), "line_type_handle", "ByBlock"),
|
||||
Property {
|
||||
label: t!("Leader lineweight").into_owned(),
|
||||
choice(
|
||||
t!("Leader type").as_ref(),
|
||||
"path_type",
|
||||
leader_type_str(&ml.path_type),
|
||||
&["Straight", "Spline", "None"],
|
||||
),
|
||||
Property {
|
||||
label: t!("Leader color").into_owned(),
|
||||
field: "line_color",
|
||||
value: PropValue::ColorChoice(ml.line_color),
|
||||
},
|
||||
// Linetype name resolved from line_type_handle by the panel builder.
|
||||
ro(
|
||||
t!("Leader linetype").as_ref(),
|
||||
"line_type_handle",
|
||||
"ByBlock",
|
||||
),
|
||||
Property {
|
||||
label: t!("Leader lineweight").into_owned(),
|
||||
field: "line_weight",
|
||||
value: PropValue::FieldLwChoice {
|
||||
field: "line_weight",
|
||||
value: PropValue::FieldLwChoice {
|
||||
field: "line_weight",
|
||||
value: ml.line_weight,
|
||||
},
|
||||
value: ml.line_weight,
|
||||
},
|
||||
// Arrowhead block name resolved by the panel builder (default "Closed filled").
|
||||
ro(t!("Arrowhead").as_ref(), "arrowhead_handle", "Closed filled"),
|
||||
edit(t!("Arrowhead Size").as_ref(), "arrowhead_size", ml.arrowhead_size),
|
||||
bool_toggle(t!("Horizontal Landing").as_ref(), "enable_dogleg", ml.enable_dogleg),
|
||||
num_row(
|
||||
t!("Landing distance").as_ref(),
|
||||
"landing_distance",
|
||||
if ml.enable_dogleg { ml.dogleg_length } else { 0.0 },
|
||||
ml.enable_dogleg,
|
||||
),
|
||||
];
|
||||
},
|
||||
// Arrowhead block name resolved by the panel builder (default "Closed filled").
|
||||
ro(
|
||||
t!("Arrowhead").as_ref(),
|
||||
"arrowhead_handle",
|
||||
"Closed filled",
|
||||
),
|
||||
edit(
|
||||
t!("Arrowhead Size").as_ref(),
|
||||
"arrowhead_size",
|
||||
ml.arrowhead_size,
|
||||
),
|
||||
bool_toggle(
|
||||
t!("Horizontal Landing").as_ref(),
|
||||
"enable_dogleg",
|
||||
ml.enable_dogleg,
|
||||
),
|
||||
num_row(
|
||||
t!("Landing distance").as_ref(),
|
||||
"landing_distance",
|
||||
if ml.enable_dogleg {
|
||||
ml.dogleg_length
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
ml.enable_dogleg,
|
||||
),
|
||||
];
|
||||
// The extension is an MText-only landing option. It is absent for block
|
||||
// content and whenever the horizontal landing itself is disabled.
|
||||
if ml.content_type == LeaderContentType::MText && ml.enable_dogleg {
|
||||
leader_props.push(bool_toggle(
|
||||
t!("Leader extension").as_ref(),
|
||||
"extend_leader_to_text",
|
||||
ml.extend_leader_to_text,
|
||||
));
|
||||
t!("Leader extension").as_ref(),
|
||||
"extend_leader_to_text",
|
||||
ml.extend_leader_to_text,
|
||||
));
|
||||
}
|
||||
let leaders = PropSection {
|
||||
title: t!("Leaders").into_owned(),
|
||||
@@ -974,8 +947,16 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
||||
),
|
||||
edit(t!("Width").as_ref(), "text_width", ctx.text_width),
|
||||
edit(t!("Height").as_ref(), "text_height", ml.text_height),
|
||||
edit_angle(t!("Rotation").as_ref(), "text_rotation", ctx.text_rotation.to_degrees()),
|
||||
edit(t!("Line space factor").as_ref(), "line_spacing", ctx.line_spacing_factor),
|
||||
edit_angle(
|
||||
t!("Rotation").as_ref(),
|
||||
"text_rotation",
|
||||
ctx.text_rotation.to_degrees(),
|
||||
),
|
||||
edit(
|
||||
t!("Line space factor").as_ref(),
|
||||
"line_spacing",
|
||||
ctx.line_spacing_factor,
|
||||
),
|
||||
edit(
|
||||
t!("Line space distance").as_ref(),
|
||||
"line_space_distance",
|
||||
@@ -1038,7 +1019,8 @@ fn properties(ml: &MultiLeader) -> Vec<PropSection> {
|
||||
),
|
||||
],
|
||||
};
|
||||
text.props.splice(attachment_insert..attachment_insert, attachment_rows);
|
||||
text.props
|
||||
.splice(attachment_insert..attachment_insert, attachment_rows);
|
||||
|
||||
// ── Block ────────────────────────────────────────────────────────────
|
||||
let block = PropSection {
|
||||
@@ -1130,9 +1112,8 @@ fn apply_geom_prop(ml: &mut MultiLeader, field: &str, value: &str) {
|
||||
for root in &mut ml.context.leader_roots {
|
||||
for line in &mut root.lines {
|
||||
line.path_type = ml.path_type;
|
||||
line.override_flags.insert(
|
||||
codec::entities::LeaderLinePropertyOverrideFlags::PATH_TYPE,
|
||||
);
|
||||
line.override_flags
|
||||
.insert(codec::entities::LeaderLinePropertyOverrideFlags::PATH_TYPE);
|
||||
}
|
||||
}
|
||||
ml.property_override_flags
|
||||
@@ -1554,14 +1535,8 @@ impl crate::entities::traits::Grippable for MultiLeader {
|
||||
fn apply_grip(&mut self, grip_id: usize, apply: GripApply) {
|
||||
apply_grip(self, grip_id, apply);
|
||||
}
|
||||
fn grip_menu(
|
||||
&self,
|
||||
grip_id: usize,
|
||||
) -> Vec<crate::scene::model::object::GripMenuItem> {
|
||||
use crate::scene::model::object::{
|
||||
GripMenuAction,
|
||||
GripMenuItem,
|
||||
};
|
||||
fn grip_menu(&self, grip_id: usize) -> Vec<crate::scene::model::object::GripMenuItem> {
|
||||
use crate::scene::model::object::{GripMenuAction, GripMenuItem};
|
||||
|
||||
let n_vertices: usize = self
|
||||
.context
|
||||
@@ -1571,42 +1546,27 @@ impl crate::entities::traits::Grippable for MultiLeader {
|
||||
.map(|line| line.points.len())
|
||||
.sum();
|
||||
|
||||
if self.content_type
|
||||
== LeaderContentType::MText
|
||||
{
|
||||
let has_elbow =
|
||||
mleader_landing_geom(self).is_some();
|
||||
if self.content_type == LeaderContentType::MText {
|
||||
let has_elbow = mleader_landing_geom(self).is_some();
|
||||
|
||||
let elbow_id =
|
||||
n_vertices;
|
||||
let elbow_id = n_vertices;
|
||||
|
||||
let landing_id =
|
||||
n_vertices
|
||||
+ usize::from(has_elbow);
|
||||
let landing_id = n_vertices + usize::from(has_elbow);
|
||||
|
||||
let width_id =
|
||||
landing_id + 1;
|
||||
let width_id = landing_id + 1;
|
||||
|
||||
if has_elbow
|
||||
&& grip_id == elbow_id
|
||||
{
|
||||
return vec![
|
||||
GripMenuItem {
|
||||
label: "Stretch",
|
||||
action:
|
||||
GripMenuAction::Stretch,
|
||||
},
|
||||
];
|
||||
if has_elbow && grip_id == elbow_id {
|
||||
return vec![GripMenuItem {
|
||||
label: "Stretch",
|
||||
action: GripMenuAction::Stretch,
|
||||
}];
|
||||
}
|
||||
|
||||
if grip_id == landing_id {
|
||||
return vec![
|
||||
GripMenuItem {
|
||||
label: "Stretch",
|
||||
action:
|
||||
GripMenuAction::Stretch,
|
||||
},
|
||||
];
|
||||
return vec![GripMenuItem {
|
||||
label: "Stretch",
|
||||
action: GripMenuAction::Stretch,
|
||||
}];
|
||||
}
|
||||
|
||||
if grip_id == width_id {
|
||||
@@ -1617,22 +1577,23 @@ impl crate::entities::traits::Grippable for MultiLeader {
|
||||
vec![
|
||||
GripMenuItem {
|
||||
label: "Stretch",
|
||||
action:
|
||||
GripMenuAction::Stretch,
|
||||
action: GripMenuAction::Stretch,
|
||||
},
|
||||
GripMenuItem {
|
||||
label: "Add Leader",
|
||||
action:
|
||||
GripMenuAction::AddLeader,
|
||||
action: GripMenuAction::AddLeader,
|
||||
},
|
||||
GripMenuItem {
|
||||
label: "Remove Leader",
|
||||
action:
|
||||
GripMenuAction::RemoveLeader,
|
||||
action: GripMenuAction::RemoveLeader,
|
||||
},
|
||||
]
|
||||
}
|
||||
fn apply_grip_menu(&mut self, grip_id: usize, action: crate::scene::model::object::GripMenuAction) {
|
||||
fn apply_grip_menu(
|
||||
&mut self,
|
||||
grip_id: usize,
|
||||
action: crate::scene::model::object::GripMenuAction,
|
||||
) {
|
||||
use crate::scene::model::object::GripMenuAction as A;
|
||||
// Locate the (root, line) and vertex position owning this grip id.
|
||||
let mut idx = 0usize;
|
||||
@@ -1732,8 +1693,7 @@ pub(crate) fn block_content_insert(
|
||||
let anchor_y = ((bounds[1] + bounds[3]) * 0.5) as f64;
|
||||
let local_x = (anchor_x - record.base_point.x) * ml.block_scale.x;
|
||||
let local_y = (anchor_y - record.base_point.y) * ml.block_scale.y;
|
||||
let rotated =
|
||||
Transform::rotation(ml.block_rotation).apply_vector([local_x, local_y]);
|
||||
let rotated = Transform::rotation(ml.block_rotation).apply_vector([local_x, local_y]);
|
||||
insertion.x -= rotated[0];
|
||||
insertion.y -= rotated[1];
|
||||
}
|
||||
@@ -1820,9 +1780,11 @@ impl MultiLeaderTess for MultiLeader {
|
||||
.find(|lt| lt.handle == h)
|
||||
.map(|lt| lt.name.clone());
|
||||
match name {
|
||||
Some(n) => {
|
||||
crate::scene::view::render::resolve_pattern(&document.line_types, &n, lt_scale)
|
||||
}
|
||||
Some(n) => crate::scene::view::render::resolve_pattern(
|
||||
&document.line_types,
|
||||
&n,
|
||||
lt_scale,
|
||||
),
|
||||
None => (0.0, [0.0; 8]),
|
||||
}
|
||||
}
|
||||
@@ -1831,14 +1793,12 @@ impl MultiLeaderTess for MultiLeader {
|
||||
|
||||
let name = handle.value().to_string();
|
||||
let nan = [f32::NAN; 3];
|
||||
let p3 = |v: &codec::types::Vector3| -> [f32; 3] {
|
||||
[(v.x) as f32, (v.y) as f32, (v.z) as f32]
|
||||
};
|
||||
let p3 =
|
||||
|v: &codec::types::Vector3| -> [f32; 3] { [(v.x) as f32, (v.y) as f32, (v.z) as f32] };
|
||||
|
||||
// ── Scaling ──────────────────────────────────────────────────────────────
|
||||
// Used only when a context omits an already-resolved content size.
|
||||
let annotative =
|
||||
crate::scene::annotative::mleader_is_annotative(document, ml);
|
||||
let annotative = crate::scene::annotative::mleader_is_annotative(document, ml);
|
||||
|
||||
// Context sizes are resolved at their stored annotation scale.
|
||||
let base_scale = if ml.scale_factor.abs() > 1.0e-12 {
|
||||
@@ -1849,28 +1809,23 @@ impl MultiLeaderTess for MultiLeader {
|
||||
|
||||
let stored_context_scale = ml.context.scale_factor as f32;
|
||||
|
||||
let context_scale_correction =
|
||||
if annotative && stored_context_scale.abs() > 1.0e-12 {
|
||||
let correction =
|
||||
(base_scale * anno_scale) / stored_context_scale;
|
||||
let context_scale_correction = if annotative && stored_context_scale.abs() > 1.0e-12 {
|
||||
let correction = (base_scale * anno_scale) / stored_context_scale;
|
||||
|
||||
if correction.is_finite() && correction > 0.0 {
|
||||
correction
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
if correction.is_finite() && correction > 0.0 {
|
||||
correction
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
}
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
|
||||
let fallback_content_scale =
|
||||
base_scale * if annotative { anno_scale } else { 1.0 };
|
||||
let fallback_content_scale = base_scale * if annotative { anno_scale } else { 1.0 };
|
||||
|
||||
// The active context stores the resolved world-space arrow size.
|
||||
// Reapplying the entity scale here makes context-sized arrows grow twice.
|
||||
let arrow_size =
|
||||
ml.context.arrowhead_size as f32
|
||||
* context_scale_correction;
|
||||
let arrow_size = ml.context.arrowhead_size as f32 * context_scale_correction;
|
||||
let draw_arrow = arrow_size > 0.0;
|
||||
let invisible = ml.path_type == MultiLeaderPathType::Invisible;
|
||||
// arrowhead_handle resolves through the block records to a named arrow
|
||||
@@ -1898,18 +1853,14 @@ impl MultiLeaderTess for MultiLeader {
|
||||
let mut text_loc_w = ml.context.text_location;
|
||||
|
||||
// Scale the annotation-side offset around the fixed elbow.
|
||||
if annotative
|
||||
&& (context_scale_correction - 1.0).abs() > 1.0e-6
|
||||
{
|
||||
if annotative && (context_scale_correction - 1.0).abs() > 1.0e-6 {
|
||||
if let Some(root) = ml.context.leader_roots.first() {
|
||||
let anchor = root.connection_point;
|
||||
let k = context_scale_correction as f64;
|
||||
|
||||
text_loc_w = codec::types::Vector3::new(
|
||||
anchor.x
|
||||
+ (text_loc_w.x - anchor.x) * k,
|
||||
anchor.y
|
||||
+ (text_loc_w.y - anchor.y) * k,
|
||||
anchor.x + (text_loc_w.x - anchor.x) * k,
|
||||
anchor.y + (text_loc_w.y - anchor.y) * k,
|
||||
text_loc_w.z,
|
||||
);
|
||||
}
|
||||
@@ -2025,9 +1976,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
// stray line up the side of the text.
|
||||
// Landing distance belongs to the selected leader-root context
|
||||
// and is already resolved in world units.
|
||||
let d =
|
||||
root.landing_distance
|
||||
* context_scale_correction as f64;
|
||||
let d = root.landing_distance * context_scale_correction as f64;
|
||||
// The dogleg runs along the leader root's stored direction —
|
||||
// for a rotated leader that is the angled baseline, not world
|
||||
// X. Roots without a usable direction keep the legacy
|
||||
@@ -2039,17 +1988,12 @@ impl MultiLeaderTess for MultiLeader {
|
||||
(x / l, y / l)
|
||||
})
|
||||
.unwrap_or((text_sign_w, 0.0));
|
||||
let landing_end = [
|
||||
(cp.x + ux * d) as f32,
|
||||
(cp.y + uy * d) as f32,
|
||||
cp_f[2],
|
||||
];
|
||||
let landing_end = [(cp.x + ux * d) as f32, (cp.y + uy * d) as f32, cp_f[2]];
|
||||
points.push(nan);
|
||||
points.push(cp_f);
|
||||
points.push(landing_end);
|
||||
if ml.extend_leader_to_text {
|
||||
let gap = ml.context.landing_gap.max(0.0)
|
||||
* context_scale_correction as f64;
|
||||
let gap = ml.context.landing_gap.max(0.0) * context_scale_correction as f64;
|
||||
points.push([
|
||||
(text_loc_w.x - ux * gap) as f32,
|
||||
(text_loc_w.y - uy * gap) as f32,
|
||||
@@ -2102,17 +2046,16 @@ impl MultiLeaderTess for MultiLeader {
|
||||
// error at UTM scale) — not a crash. Follow-up: double-single-split
|
||||
// via points_to_ds to match emit_wire's paired fill path.
|
||||
fill_tris_low: Vec::new(),
|
||||
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
});
|
||||
|
||||
let host = codec::EntityType::MultiLeader(Box::new(ml.clone()));
|
||||
for block_use in crate::scene::render_graph::entity_render_block_uses(document, &host, 1.0)
|
||||
.into_iter()
|
||||
.filter(|block_use| {
|
||||
block_use.active
|
||||
&& block_use.role
|
||||
== crate::scene::render_graph::BlockRole::MultiLeaderContent
|
||||
&& block_use.role == crate::scene::render_graph::BlockRole::MultiLeaderContent
|
||||
})
|
||||
{
|
||||
wires.extend(
|
||||
@@ -2152,11 +2095,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
// Only the fallback path (file omits the context value) needs
|
||||
// scale_factor + annotation scale applied.
|
||||
let height = if ctx.text_height > 0.0 {
|
||||
ctx.text_height as f32
|
||||
* context_scale_correction
|
||||
ctx.text_height as f32 * context_scale_correction
|
||||
} else {
|
||||
ml.text_height as f32
|
||||
* fallback_content_scale
|
||||
ml.text_height as f32 * fallback_content_scale
|
||||
};
|
||||
|
||||
let ins = &text_loc_w;
|
||||
@@ -2217,9 +2158,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
// The stored text attachment point is the insertion's horizontal
|
||||
// anchor within the text block (Left/Center/Right) — honour it
|
||||
// instead of guessing from the leader side.
|
||||
use codec::entities::multileader::{
|
||||
TextAttachmentDirectionType,
|
||||
};
|
||||
use codec::entities::multileader::TextAttachmentDirectionType;
|
||||
// The context's attachment point exists in every DWG version;
|
||||
// the entity-level copy only exists from R2010 on.
|
||||
let h_anchor: f32 = match ctx.text_attachment_point {
|
||||
@@ -2247,9 +2186,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
value: &ctx.text_string,
|
||||
insertion: [local_ins_x as f64, local_ins_y as f64, z as f64],
|
||||
height,
|
||||
rect_w:
|
||||
ctx.text_width as f32
|
||||
* context_scale_correction,
|
||||
rect_w: ctx.text_width as f32 * context_scale_correction,
|
||||
rotation: rot,
|
||||
style: &style,
|
||||
attach_h_anchor: h_anchor,
|
||||
@@ -2301,10 +2238,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
Vec::new();
|
||||
if let Ok(mut atlas) = crate::scene::text::sdf_atlas::text_atlas().lock() {
|
||||
for ts in &layout.strokes {
|
||||
let is_shaped = ts
|
||||
.run
|
||||
.as_ref()
|
||||
.is_some_and(|r| crate::scene::text::web_font::requires_shaping(&r.text));
|
||||
let is_shaped = ts.run.as_ref().is_some_and(|r| {
|
||||
crate::scene::text::web_font::requires_shaping(&r.text)
|
||||
});
|
||||
if ts.run.is_none() || is_shaped {
|
||||
for stroke in &ts.strokes {
|
||||
if stroke.len() < 2 {
|
||||
@@ -2331,18 +2267,17 @@ impl MultiLeaderTess for MultiLeader {
|
||||
continue;
|
||||
}
|
||||
let run = ts.run.as_ref().unwrap();
|
||||
let (quads, pen_adv) =
|
||||
crate::scene::text::glyph_quads::layout_glyph_quads(
|
||||
&mut atlas,
|
||||
run.height,
|
||||
run.rotation,
|
||||
run.width_factor,
|
||||
run.oblique,
|
||||
run.tracking,
|
||||
&run.font,
|
||||
run.bold,
|
||||
&run.text,
|
||||
);
|
||||
let (quads, pen_adv) = crate::scene::text::glyph_quads::layout_glyph_quads(
|
||||
&mut atlas,
|
||||
run.height,
|
||||
run.rotation,
|
||||
run.width_factor,
|
||||
run.oblique,
|
||||
run.tracking,
|
||||
&run.font,
|
||||
run.bold,
|
||||
&run.text,
|
||||
);
|
||||
// Inline `\C` / `\c` colour wins over the entity text
|
||||
// colour, matching the top-level Text arm.
|
||||
let gcolor = ts
|
||||
@@ -2379,8 +2314,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
}
|
||||
if !sdf_verts.is_empty() || !deco_pts.is_empty() || !deco_fill.is_empty() {
|
||||
// Pick box from the glyph quads (f64 accumulate → f32).
|
||||
let (mut nx, mut ny, mut xx, mut xy) =
|
||||
(f64::MAX, f64::MAX, f64::MIN, f64::MIN);
|
||||
let (mut nx, mut ny, mut xx, mut xy) = (f64::MAX, f64::MAX, f64::MIN, f64::MIN);
|
||||
for v in &sdf_verts {
|
||||
let x = v.pos[0] as f64 + v.pos_low[0] as f64;
|
||||
let y = v.pos[1] as f64 + v.pos_low[1] as f64;
|
||||
@@ -2450,9 +2384,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
use codec::entities::multileader::TextAttachmentType as TA;
|
||||
let ul_lines: Option<Vec<usize>> = match vertical_attach {
|
||||
TA::BottomOfTopLineUnderlineTopLine => Some(vec![0]),
|
||||
TA::BottomOfTopLineUnderlineAll => {
|
||||
Some((0..layout.line_count).collect())
|
||||
}
|
||||
TA::BottomOfTopLineUnderlineAll => Some((0..layout.line_count).collect()),
|
||||
TA::BottomLine | TA::BottomOfTopLineUnderlineBottomLine => {
|
||||
Some(vec![layout.line_count.saturating_sub(1)])
|
||||
}
|
||||
@@ -2460,8 +2392,7 @@ impl MultiLeaderTess for MultiLeader {
|
||||
};
|
||||
if let Some(lines) = ul_lines {
|
||||
let mut pts: Vec<[f32; 3]> = Vec::new();
|
||||
let (x0, x1) =
|
||||
(-max_line_w * h_anchor, max_line_w * (1.0 - h_anchor));
|
||||
let (x0, x1) = (-max_line_w * h_anchor, max_line_w * (1.0 - h_anchor));
|
||||
for li in lines {
|
||||
let y = v_offset - li as f32 * line_h - height * 0.15;
|
||||
let (ax, ay) = (
|
||||
@@ -2512,17 +2443,16 @@ impl MultiLeaderTess for MultiLeader {
|
||||
plinegen: true,
|
||||
fill_tris: vec![],
|
||||
fill_tris_low: Vec::new(),
|
||||
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Text frame / background-fill rectangle in local frame, then rotated to WCS.
|
||||
if ml.text_frame || ctx.background_fill_enabled {
|
||||
// Border offset is a scale factor around the laid-out text box.
|
||||
let pad = height
|
||||
* ((ctx.background_scale_factor.max(1.0) as f32 - 1.0) * 0.5);
|
||||
let pad = height * ((ctx.background_scale_factor.max(1.0) as f32 - 1.0) * 0.5);
|
||||
// Box the glyphs that were actually laid out (valid for
|
||||
// vertical flow too); the metric-derived box is only the
|
||||
// no-glyph fallback.
|
||||
@@ -2560,9 +2490,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
} else {
|
||||
color_or_inherit(&ctx.background_fill_color, entity_color)
|
||||
};
|
||||
fill_color[3] *=
|
||||
(1.0 - ctx.background_transparency.clamp(0, 90) as f32 / 100.0)
|
||||
.clamp(0.1, 1.0);
|
||||
fill_color[3] *= (1.0
|
||||
- ctx.background_transparency.clamp(0, 90) as f32 / 100.0)
|
||||
.clamp(0.1, 1.0);
|
||||
let fill_tris: Vec<[f32; 3]> = vec![
|
||||
wcs_corners[0],
|
||||
wcs_corners[1],
|
||||
@@ -2586,9 +2516,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
render_instance: None,
|
||||
pick_tris: Vec::new(),
|
||||
pick_tris_low: Vec::new(),
|
||||
dash_from_start: false,
|
||||
dash_align_end: None,
|
||||
text_verts: Vec::new(),
|
||||
dash_from_start: false,
|
||||
dash_align_end: None,
|
||||
text_verts: Vec::new(),
|
||||
name: name.clone(),
|
||||
points: vec![],
|
||||
points_low: Vec::new(),
|
||||
@@ -2605,9 +2535,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
plinegen: true,
|
||||
fill_tris,
|
||||
fill_tris_low: Vec::new(),
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
// Text frame — closed rectangle, matches text color.
|
||||
@@ -2634,9 +2564,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
render_instance: None,
|
||||
pick_tris: Vec::new(),
|
||||
pick_tris_low: Vec::new(),
|
||||
dash_from_start: false,
|
||||
dash_align_end: None,
|
||||
text_verts: Vec::new(),
|
||||
dash_from_start: false,
|
||||
dash_align_end: None,
|
||||
text_verts: Vec::new(),
|
||||
name,
|
||||
points: frame_points,
|
||||
points_low: Vec::new(),
|
||||
@@ -2653,9 +2583,9 @@ impl MultiLeaderTess for MultiLeader {
|
||||
plinegen: true,
|
||||
fill_tris: vec![],
|
||||
fill_tris_low: Vec::new(),
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user