feat(modify): TXTEXP turns text into its character outlines

TXTEXP replaces each selected TEXT and MTEXT with one polyline per
glyph contour, on the text's layer and with its properties: a
lightweight polyline for flat text, a 3D polyline for tilted text.
The outlines come from the same glyph tessellation the text renders
with, so stroke fonts give their strokes and outline fonts their
closed contours.

Refs D#1665

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-13 15:27:28 +03:00
1 parent 57eb7fe4db
commit dd45ac4039
28 files changed
+147 -1

No files matched your search

+32
View File
@@ -1303,6 +1303,38 @@ impl OpenCADStudio {
}
}
// TXTEXP — text becomes the polylines of its character outlines.
"TXTEXP" => {
let selected: Vec<_> = self.tabs[i]
.scene
.selected_entities()
.into_iter()
.filter(|(handle, _)| !self.tabs[i].scene.is_layer_locked(*handle))
.collect();
if selected.is_empty() {
use crate::modules::draw::select::SelectObjectsCommand;
let cmd = SelectObjectsCommand::new("TXTEXP");
self.command_line.push_info(&cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(cmd));
} else {
use crate::modules::draw::modify::explode::apply_explode_replacements;
use crate::modules::draw::modify::txtexp::plan_text_explode;
let replacements = plan_text_explode(&selected, &self.tabs[i].scene.document);
let exploded = replacements.len();
if exploded > 0 {
self.push_undo_snapshot(i, "TXTEXP");
apply_explode_replacements(&mut self.tabs[i].scene, replacements);
self.tabs[i].dirty = true;
self.refresh_properties();
self.command_line
.push_output(crate::tf!("{exploded} object(s) exploded.").as_ref());
} else {
self.command_line
.push_info(crate::t!("TXTEXP: no text selected.").as_ref());
}
}
}
"OFFSET" => {
use crate::modules::draw::modify::offset::{is_offsettable, OffsetCommand};
let all_entities: Vec<_> = self.tabs[i]
+2
View File
@@ -277,6 +277,7 @@ fn command_category(name: &str) -> &'static str {
"BREAK",
"JOIN",
"EXPLODE",
"TXTEXP",
"STRETCH",
"ARRAY",
"PEDIT",
@@ -349,6 +350,7 @@ fn command_selection_policy(name: &str) -> &'static str {
"CUTCLIP",
"ERASE",
"EXPLODE",
"TXTEXP",
"GROUP",
"LAYFRZ",
"LAYLCK",