fix(text): clip SDF text to xclip boundary; stop debug-assert crash on block fills

Two fixes for opening drawings with XCLIP'd blocks (crashed / mis-rendered
since SDF text became the default).

- block_cache emit_wire: the fill_tris/fill_tris_low length debug_assert
  panicked in debug builds on a legitimate case — a Leader/dimension arrowhead
  fill nested in a block carries fill_tris with an empty fill_tris_low (the
  WireModel contract's "all-zero low" form, which the code already handles via
  get().unwrap_or). Relax the assert to permit the empty case; a *partial* low
  half is still caught.
- xclip clip_wires: also clip the SDF glyph quads. Block-internal text was
  bleeding past the clip boundary (mixed batch) or vanishing (the tail retain
  dropped empty-points wires). Now each glyph quad is kept/dropped by its
  centroid vs the boundary (whole-glyph granularity), text_verts-carrying wires
  survive the retain, and the pick-box AABB is recomputed from the surviving
  glyphs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-07 21:32:17 +03:00
1 parent 5c15091e74
commit fa322991c6
2 files changed
+53 -3

No files matched your search

+11 -1
View File
@@ -1187,7 +1187,17 @@ fn emit_wire(
.tangent_geoms
.push(transform_tangent(tg, accum_xform));
}
debug_assert_eq!(lw.fill_tris.len(), lw.fill_tris_low.len());
// Per the WireModel contract an empty `fill_tris_low` means "all-zero low
// half" (e.g. a Leader / dimension arrowhead fill, which the tessellator
// emits without a low half). Only a *partially* populated low half is a
// real bug — keep the tripwire for that, but permit the empty case so debug
// builds don't panic on legitimate geometry.
debug_assert!(
lw.fill_tris_low.is_empty() || lw.fill_tris.len() == lw.fill_tris_low.len(),
"fill_tris_low must be empty or the same length as fill_tris (got {} vs {})",
lw.fill_tris.len(),
lw.fill_tris_low.len(),
);
for (idx, p) in lw.fill_tris.iter().enumerate() {
// Empty/short fill_tris_low means "no low half" (all-zero), per the
// WireModel contract — same panic-safe access the other fill consumers