fix(multileader): render text properly — strip MText codes, honor full layout

Multileader text was emitted as a single literal stroke pass with no MText
code handling, no rotation, no attachment, no line breaks, no per-piece
color and bad f32 precision under world_offset. Two separate render paths
both had the same bug, and one was masking the fix in the other.

This rewrite, applied to both paths:

- Strips MText format codes (`{\fArial Black|b0|i0|c162|p34;...}`) so the
  rendered text is the actual content, not the markup.
- Honors text_rotation (preferring text_direction so transforms survive),
  text_attachment_point (Left/Center/Right horizontal anchor), and
  text_left_attachment for vertical alignment via a shared
  v_offset_for_attachment helper.
- Splits on \P/\n/\N and word-wraps to text_width.
- Applies line_spacing_factor with the same 5/3 × height convention as
  MText.
- Resolves the text style via text_style_handle (fallback STANDARD).
- Applies ml.scale_factor everywhere (arrow size, dogleg length, text
  height, text width). anno_scale is now only applied when
  enable_annotation_scale is set.
- Splits the scene-level output into separate WireModels so leader,
  text, frame and background fill each carry their own colour
  (ctx.text_color, ml.text_frame, ctx.background_fill_color).
- Mirrors text_direction, base_direction and root.direction in
  apply_transform so a mirrored multileader's text follows the geometry
  instead of staying at its original rotation.
- Computes the text origin and frame corners in offset-relative f32
  space — drawings sit at large absolute coordinates and casting to f32
  before subtracting world_offset was wrecking the rotated sub-glyph
  precision.
This commit is contained in:
Hakan Seven 2026-05-12 23:27:53 +03:00
commit 8bfa5088c4
3 changed files with 495 additions and 80 deletions

View file

@ -3787,6 +3787,25 @@ fn tessellate_entity(
return wires;
}
if let EntityType::MultiLeader(ml) = e {
let aabb = entity_aabb(e, world_offset);
let mut wires = tessellate::tessellate_multileader(
document,
h,
ml,
sel,
entity_color,
line_weight_px,
world_offset,
anno_scale,
);
for w in &mut wires {
w.aci = aci;
w.aabb = aabb;
}
return wires;
}
if let EntityType::Insert(ins) = e {
// Resolve the INSERT's own style so ByBlock sub-entities can inherit it.
let (ins_color, ins_pat_len, ins_pat, ins_lw_px, _) = render::render_style_for(document, e);