fix: resolve DXF %%x codes and render MText decoration strokes

Text/MText values now correctly handle DXF special-character sequences:
- %%d → °, %%p → ±, %%c → ⌀, %%nnn → Unicode scalar (resolved in tessellation)
- %%u / %%o toggle underline and overline strokes for TEXT entities

MText decoration codes (\L/\l, \O/\o, \K/\k) were previously consumed
as argument-bearing codes, silently eating the decorated text. Fixed
strip_mtext_codes to keep them as zero-width markers; tessellate_text_ex
now emits actual line strokes (underline, overline, strikethrough).
measure_mtext_chars and word_wrap skip markers so line widths are correct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-04-26 21:57:51 +03:00
commit 4504916f97
4 changed files with 222 additions and 37 deletions

View file

@ -4,7 +4,7 @@ use glam::Vec3;
use crate::command::EntityTransform;
use crate::entities::common::{edit_prop as edit, ro_prop as ro, square_grip, triangle_grip};
use crate::entities::text_support::{
resolve_text_style, split_mtext_lines, strip_mtext_codes, word_wrap,
measure_mtext_chars, resolve_text_style, split_mtext_lines, strip_mtext_codes, word_wrap,
};
use crate::entities::traits::{Grippable, PropertyEditable, Transformable, TruckConvertible};
use crate::scene::acad_to_truck::{TruckEntity, TruckObject};
@ -145,16 +145,7 @@ fn to_truck(t: &MText, document: &acadrust::CadDocument) -> TruckEntity {
};
let line_w = if h_anchor > 0.0 {
let scale = t.height as f32 / 9.0 * style_width_factor;
line.chars()
.map(|c| {
if c == ' ' {
return font.word_spacing * scale;
}
font.glyph(c)
.map(|g| (g.advance + font.letter_spacing) * scale)
.unwrap_or(t.height as f32 * 0.6)
})
.sum()
measure_mtext_chars(line, scale, font)
} else {
0.0
};