forked from 1b-agent/opencadstudio-upstream
refactor(text): SDF for all text kinds; remove the legacy stroke text path
SDF is the only text renderer now — the stroke path and its LOD ladder are gone, and the remaining text kinds render as SDF glyph quads too. - ATTDEF / ATTRIB: carry a GlyphRun so single-line attribute text renders as SDF (multi-line already did via layout_mtext). Tolerance / complex-linetype text already SDF. - Remove `sdf_text_enabled()` (the OCS_TEXT_SDF flag / kill switch) and take the SDF path unconditionally everywhere: tessellate Text arm (per-group by GlyphRun presence), hit_test fallbacks, render gather, complex_lt, table, mleader. - Delete the text LOD ladder: tess.rs baseline/greek block and the block_cache greek/baseline path (emit_greeked_text / emit_text_baseline), plus the now-dead helpers text_baseline_points / text_greek_obb_tris / text_obb_corners_native / mtext_line_count and the LocalWire text_height_local / text_obb_local fields. All text is crisp at every zoom; text entities are exempt from the sub-pixel stub cull. - Fix a latent bug: block-internal SDF text was culled because its LocalWire aabb_local was [0,0,0,0] (no points) — fold the glyph-quad extent into aabb_local and exempt text_verts-carrying wires from the sub-pixel cull. - Clear the pre-existing dead-code warnings (TextPlacement.elevation, TabKind, MTextRunKind::Tab). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
67ce45d40b
commit
5c15091e74
12 files changed
+145
-1238
No files matched your search
+23
-59
@@ -492,10 +492,8 @@ pub fn tessellate_table(
|
||||
|
||||
// Accumulators keyed by quantised colour (+ weight for borders).
|
||||
let mut fills: HashMap<[u8; 4], ([f32; 4], Vec<[f32; 3]>)> = HashMap::default();
|
||||
let mut texts: HashMap<[u8; 4], ([f32; 4], Vec<[f32; 3]>, Vec<[f32; 3]>)> = HashMap::default();
|
||||
// SDF cell text: glyph quads (per-vertex coloured) collected across all
|
||||
// cells; emitted as one text-carrying wire at the end. Empty when SDF off.
|
||||
let sdf_on = crate::scene::text::sdf_atlas::sdf_text_enabled();
|
||||
// cells; emitted as one text-carrying wire at the end.
|
||||
let mut text_verts: Vec<crate::scene::pipeline::text_gpu::TextVertex> = Vec::new();
|
||||
let mut borders: HashMap<([u8; 4], u32), ([f32; 4], f32, Vec<[f32; 3]>)> = HashMap::default();
|
||||
let mut emitted: rustc_hash::FxHashSet<(i32, i32, i32, i32)> = rustc_hash::FxHashSet::default();
|
||||
@@ -713,55 +711,29 @@ pub fn tessellate_table(
|
||||
} else {
|
||||
entity_color
|
||||
};
|
||||
if sdf_on {
|
||||
// SDF: glyph quads per run at its placed origin (rotation baked
|
||||
// in by layout_glyph_quads), coloured by the cell's text colour.
|
||||
if let Ok(mut atlas) = crate::scene::text::sdf_atlas::text_atlas().lock() {
|
||||
for ts in &layout.strokes {
|
||||
let Some(run) = &ts.run else { continue };
|
||||
let quads = crate::scene::text::glyph_quads::layout_glyph_quads(
|
||||
&mut atlas,
|
||||
run.height,
|
||||
run.rotation,
|
||||
run.width_factor,
|
||||
run.oblique,
|
||||
run.tracking,
|
||||
&run.font,
|
||||
&run.text,
|
||||
);
|
||||
crate::scene::pipeline::text_gpu::push_glyph_vertices(
|
||||
&mut text_verts,
|
||||
&quads,
|
||||
[ts.origin[0], ts.origin[1], to.z as f64],
|
||||
1.0,
|
||||
tcol,
|
||||
0.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let entry = texts
|
||||
.entry(key4(tcol))
|
||||
.or_insert_with(|| (tcol, Vec::new(), Vec::new()));
|
||||
let buf = &mut entry.1;
|
||||
let tris_buf = &mut entry.2;
|
||||
// SDF glyph quads per run at its placed origin (rotation baked in by
|
||||
// layout_glyph_quads), coloured by the cell's text colour.
|
||||
if let Ok(mut atlas) = crate::scene::text::sdf_atlas::text_atlas().lock() {
|
||||
for ts in &layout.strokes {
|
||||
let sx = ts.origin[0] as f32;
|
||||
let sy = ts.origin[1] as f32;
|
||||
for stroke in &ts.strokes {
|
||||
if stroke.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
if !buf.is_empty() {
|
||||
buf.push([f32::NAN; 3]);
|
||||
}
|
||||
for &[x, y] in stroke {
|
||||
buf.push([x + sx, y + sy, (to.z as f64) as f32]);
|
||||
}
|
||||
}
|
||||
for &[x, y] in &ts.fill_tris {
|
||||
tris_buf.push([x + sx, y + sy, (to.z as f64) as f32]);
|
||||
}
|
||||
let Some(run) = &ts.run else { continue };
|
||||
let quads = crate::scene::text::glyph_quads::layout_glyph_quads(
|
||||
&mut atlas,
|
||||
run.height,
|
||||
run.rotation,
|
||||
run.width_factor,
|
||||
run.oblique,
|
||||
run.tracking,
|
||||
&run.font,
|
||||
&run.text,
|
||||
);
|
||||
crate::scene::pipeline::text_gpu::push_glyph_vertices(
|
||||
&mut text_verts,
|
||||
&quads,
|
||||
[ts.origin[0], ts.origin[1], to.z as f64],
|
||||
1.0,
|
||||
tcol,
|
||||
0.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,14 +781,6 @@ pub fn tessellate_table(
|
||||
out.push(mk(color, pts, vec![], lw));
|
||||
}
|
||||
}
|
||||
for (_, (color, pts, tris)) in texts {
|
||||
if !pts.is_empty() {
|
||||
out.push(mk(color, pts, vec![], line_weight_px));
|
||||
}
|
||||
if !tris.is_empty() {
|
||||
out.push(mk(color, vec![], tris, line_weight_px));
|
||||
}
|
||||
}
|
||||
// SDF cell text: one wire carrying the glyph quads (per-vertex coloured) +
|
||||
// a glyph-bounds AABB (f64 accumulate → f32) so the text draws + picks;
|
||||
// empty points so it adds no stroke geometry.
|
||||
|
||||
Reference in new issue
Block a user