forked from 1b-agent/opencadstudio-upstream
ATTDEF: Fit/Align attribute text, TEXTSIZE, single-line restart
Align and Fit attributes run their text between the two baseline points, an ATTDEF height becomes the next text height, and Multiple lines is not carried to the next definition (measured). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
c5790c74a9
commit
c992b73cdf
3 files changed
+41
-2
No files matched your search
@@ -220,6 +220,12 @@ impl OpenCADStudio {
|
||||
// Record where this draw ended so ARC_CONT can continue from it
|
||||
// (before `entity` is moved into commit_entity).
|
||||
self.update_cont_anchor(&entity);
|
||||
// ATTDEF's height becomes the next text height (TEXTSIZE), as TEXT's does.
|
||||
if let codec::EntityType::AttributeDefinition(attribute) = &entity {
|
||||
if self.tabs[i].active_cmd.as_ref().is_some_and(|cmd| cmd.name().ends_with("ATTDEF")) {
|
||||
self.tabs[i].scene.document.header.text_height = attribute.height;
|
||||
}
|
||||
}
|
||||
let label = self.history_label_from_active_cmd(i, "ENTITY");
|
||||
let delta_safe = self.delta_add_safe(i, &entity);
|
||||
let pending = self.begin_undo(i, label, 1, delta_safe);
|
||||
|
||||
@@ -101,7 +101,7 @@ fn mtext_flag_str(f: MTextFlag) -> &'static str {
|
||||
/// Render text strokes for an attribute, honouring alignment, oblique angle,
|
||||
/// width factor, generation flags (backward / upside-down), text-style
|
||||
/// resolution, and basic multiline splitting on `\n` / `\\P`.
|
||||
fn build_attr_render(input: AttrTextInputs<'_>, document: &codec::CadDocument) -> RenderEntity {
|
||||
fn build_attr_render(mut input: AttrTextInputs<'_>, document: &codec::CadDocument) -> RenderEntity {
|
||||
let normal = (input.normal.x, input.normal.y, input.normal.z);
|
||||
let (wsx, wsy, wsz) = transform::ocs_point_to_wcs(
|
||||
(
|
||||
@@ -147,6 +147,37 @@ fn build_attr_render(input: AttrTextInputs<'_>, document: &codec::CadDocument) -
|
||||
resolved.oblique_angle
|
||||
};
|
||||
|
||||
// Align / Fit run the text along the baseline between the two points:
|
||||
// Fit stretches its width, Align scales its height too.
|
||||
let (mut rotation, mut width_factor) = (rotation, width_factor);
|
||||
let span = (
|
||||
input.alignment_point.x - input.insertion_point.x,
|
||||
input.alignment_point.y - input.insertion_point.y,
|
||||
);
|
||||
let length = span.0.hypot(span.1);
|
||||
if matches!(input.horizontal_alignment, AHA::Aligned | AHA::Fit)
|
||||
&& length > 1.0e-9
|
||||
&& !input.value.contains("\\P")
|
||||
{
|
||||
if let Some(b) = text_local_bounds(
|
||||
&resolved.font_name,
|
||||
&resolve_dxf_special_chars(input.value),
|
||||
input.height as f32,
|
||||
width_factor.abs(),
|
||||
oblique_angle,
|
||||
)
|
||||
.filter(|b| b.advance > 1.0e-6)
|
||||
{
|
||||
let scale = length / b.advance as f64;
|
||||
rotation = span.1.atan2(span.0) as f32;
|
||||
if matches!(input.horizontal_alignment, AHA::Aligned) {
|
||||
input.height *= scale;
|
||||
} else {
|
||||
width_factor *= scale as f32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Anchor selection mirrors Text: only Left/Baseline uses insertion_point;
|
||||
// every other alignment uses alignment_point.
|
||||
let needs_align_pt = !(matches!(input.horizontal_alignment, AHA::Left)
|
||||
|
||||
@@ -498,9 +498,11 @@ impl AttdefCommand {
|
||||
}
|
||||
|
||||
/// Keep AFLAGS / Annotative and the placed definition for the next ATTDEF.
|
||||
/// Multiple lines is not kept: the reference starts the next definition
|
||||
/// single-line again.
|
||||
pub fn remember(spec: &AttdefSpec, entity: &EntityType) {
|
||||
let mut s = session();
|
||||
s.aflags = spec.aflags;
|
||||
s.aflags = spec.aflags & !AFLAG_MULTILINE;
|
||||
s.annotative = spec.annotative;
|
||||
if let EntityType::AttributeDefinition(a) = entity {
|
||||
s.last = Some(a.clone());
|
||||
|
||||
Reference in new issue
Block a user