fix(text): bake draw-order depth into glyphs so fills can't cover text

Fill triangles (DIMTFILL backgrounds, MLEADER masks, hatches) carry the
entity's draw-order rank, but SDF glyph quads were pushed at neutral 0.0
— any entity in the front half of the draw order had its own background
fill painted over its text. gather_text_verts now adds the host wire's
wire_draw_depth to each glyph: a text background lands at the same
biased depth (glyphs draw after fills and win the LessEqual test), and
text respects draw order against other entities' fills too.

The #403 glyph-reuse fast path gains a rank-stability gate: adding or
removing an entity shifts every sibling's bias (the rank denominator
changes), so reuse is only safe across all-Modified edits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Fable 5 committed 2026-07-23 01:13:33 +03:00
1 parent f407835543
commit 94609fc54a
2 files changed
+43 -4

No files matched your search

+11
View File
@@ -1416,6 +1416,17 @@ impl Scene {
/// references (their baked text moves with the instance) — an edit to any of
/// those, or any removal, invalidates it; a plain line / arc / polyline edit
/// does not.
/// Whether the per-entity draw-order ranks are unchanged since
/// `last_epoch`: every delta is a Modify (an Add / Remove changes the rank
/// denominator and shifts every sibling's bias — same rule as the
/// `draw_depth_map` cache).
pub(super) fn draw_ranks_stable(&self, last_epoch: u64) -> bool {
match self.replay_since(last_epoch) {
Some(deltas) => deltas.iter().all(|&(_, k)| k == ChangeKind::Modified),
None => false,
}
}
fn text_unchanged(&self, last_epoch: u64) -> bool {
match self.replay_since(last_epoch) {
Some(deltas) => deltas.iter().all(|&(h, k)| {