forked from 1b-agent/opencadstudio-upstream
feat(text): parse TEXT via acadrust + extend SDF text to MTEXT
Two related steps for the text pipeline: - TEXT parsing now goes through acadrust's parse_plain_text (like MTEXT uses parse_mtext). text::acad_text_encode parses the value's %% codes — including %%u/%%o underline/overline and %%nnn — and re-encodes to the stroke tessellator's \L/\O + resolved-Unicode grammar, so OCS no longer tokenizes TEXT %% codes itself. (ATTRIB/TOLERANCE/DIMENSION still use the local tokenizer for now.) Bumps the acadrust pin to the commit that completes the TEXT/MTEXT control-code set. - SDF text (OCS_TEXT_SDF) now covers MTEXT and every text-producing entity, not just top-level TEXT. TextStroke carries a GlyphRun (layout params); the collector walks convert()'s TruckObject::Text runs and applies annotation scale exactly as tessellate does for strokes. layout_glyph_quads shares lff::tokenize_run so %% specials resolve and \L/\O decorations are skipped (decoration LINES in SDF are still TODO). Verified: stroke rendering unchanged with the flag off; SDF glyphs render correctly for TEXT and MTEXT with OCS_TEXT_SDF=1. 154 lib tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
b88e5e4ad5
commit
d528a3e2a5
9 files changed
+149
-28
No files matched your search
@@ -70,11 +70,22 @@ pub fn layout_glyph_quads(
|
||||
let mut cursor_x = 0.0f32;
|
||||
let mut quads = Vec::new();
|
||||
|
||||
for ch in text.chars() {
|
||||
if ch == ' ' {
|
||||
cursor_x += face.word_spacing();
|
||||
continue;
|
||||
}
|
||||
// Same token walk as `tessellate_text_run` (LFF branch): DXF `%%` specials
|
||||
// resolve to glyphs, spaces/missing advance the pen, decoration toggles emit
|
||||
// no glyph (they render as lines on the stroke path).
|
||||
for tok in crate::scene::text::lff::tokenize_run(text) {
|
||||
let ch = match tok {
|
||||
crate::scene::text::lff::Tok::Glyph(c) => c,
|
||||
crate::scene::text::lff::Tok::Space => {
|
||||
cursor_x += face.word_spacing();
|
||||
continue;
|
||||
}
|
||||
crate::scene::text::lff::Tok::Missing => {
|
||||
cursor_x += 6.0 + face.letter_spacing() * tracking;
|
||||
continue;
|
||||
}
|
||||
crate::scene::text::lff::Tok::Deco(..) => continue,
|
||||
};
|
||||
match atlas.get_or_insert(font_name, ch) {
|
||||
Some(e) => {
|
||||
let (lo, hi) = (e.plane_min, e.plane_max);
|
||||
@@ -91,8 +102,7 @@ pub fn layout_glyph_quads(
|
||||
cursor_x += e.advance + face.letter_spacing() * tracking;
|
||||
}
|
||||
None => {
|
||||
// No ink (whitespace glyph) or atlas full: advance only, using
|
||||
// the glyph's own advance when the font knows it.
|
||||
// No ink (whitespace glyph) or atlas full: advance only.
|
||||
let adv = face.glyph(ch).map(|g| g.advance).unwrap_or(6.0);
|
||||
cursor_x += adv + face.letter_spacing() * tracking;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user