From 1bab465956a058ff9d01af73a1939e4cc92bf41a Mon Sep 17 00:00:00 2001 From: Raphael Amorim Date: Mon, 27 Apr 2026 22:39:58 +0200 Subject: [PATCH] fix kip --- frontends/rioterm/src/grid_emit.rs | 35 ++++++++++++++++++++++++++---- sugarloaf/src/renderer/mod.rs | 9 +++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/frontends/rioterm/src/grid_emit.rs b/frontends/rioterm/src/grid_emit.rs index b13f155c..626d4941 100644 --- a/frontends/rioterm/src/grid_emit.rs +++ b/frontends/rioterm/src/grid_emit.rs @@ -1066,6 +1066,15 @@ impl GridGlyphRasterizer { style_flags: u8, font_library: &FontLibrary, ) -> (u32, bool) { + // Kitty Unicode placeholder cells (U+10EEEE) are rendered as + // image-overlay slices, not text. Resolve them to the primary + // font as if they were a space, so the run shapes them as an + // invisible space glyph instead of falling back to a notdef + // tofu box. Mirrors ghostty's `font/shaper/run.zig:328-335`. + if ch == rio_backend::ansi::kitty_virtual::PLACEHOLDER { + return (rio_backend::sugarloaf::font::FONT_ID_REGULAR as u32, false); + } + // ASCII printable + regular style → always primary font, never // emoji. Skips the FxHashMap lookup that dominates this fn's // cost on terminal-typical content. @@ -1372,6 +1381,17 @@ pub fn build_row_fg( rasterizer.resolve_font(ch, run_style_flags, font_library); let run_start = x; + // Kitty Unicode placeholder shapes as a space — the cell + // joins the run, the shaper emits an invisible space glyph + // (no notdef tofu), and the kitty image overlay is drawn on + // top to fill the cell. Mirrors ghostty's + // `font/shaper/run.zig:264-267`. + let shape_ch = if ch == rio_backend::ansi::kitty_virtual::PLACEHOLDER { + ' ' + } else { + ch + }; + #[cfg(target_os = "macos")] { rasterizer.run_utf16_scratch.clear(); @@ -1382,12 +1402,12 @@ pub fn build_row_fg( let mut buf = [0u16; 2]; rasterizer .run_utf16_scratch - .extend_from_slice(ch.encode_utf16(&mut buf)); + .extend_from_slice(shape_ch.encode_utf16(&mut buf)); } #[cfg(not(target_os = "macos"))] { rasterizer.run_str_scratch.clear(); - rasterizer.run_str_scratch.push(ch); + rasterizer.run_str_scratch.push(shape_ch); } // Extend the run while (font_id, style_flags) match. @@ -1407,6 +1427,13 @@ pub fn build_row_fg( if font_id2 != font_id { break; } + // Same placeholder→space substitution as the run-start + // path above. + let shape_ch2 = if ch2 == rio_backend::ansi::kitty_virtual::PLACEHOLDER { + ' ' + } else { + ch2 + }; #[cfg(target_os = "macos")] { rasterizer @@ -1415,11 +1442,11 @@ pub fn build_row_fg( let mut buf = [0u16; 2]; rasterizer .run_utf16_scratch - .extend_from_slice(ch2.encode_utf16(&mut buf)); + .extend_from_slice(shape_ch2.encode_utf16(&mut buf)); } #[cfg(not(target_os = "macos"))] { - rasterizer.run_str_scratch.push(ch2); + rasterizer.run_str_scratch.push(shape_ch2); } end += 1; } diff --git a/sugarloaf/src/renderer/mod.rs b/sugarloaf/src/renderer/mod.rs index 10032221..bfd7ea5d 100644 --- a/sugarloaf/src/renderer/mod.rs +++ b/sugarloaf/src/renderer/mod.rs @@ -1325,9 +1325,6 @@ impl Renderer { crate::context::ContextType::Cpu(_) => unreachable!(), #[cfg(target_os = "linux")] crate::context::ContextType::Vulkan(_) => unreachable!(), - #[cfg(not(feature = "wgpu"))] - #[allow(unreachable_patterns)] - _ => continue, #[cfg(feature = "wgpu")] crate::context::ContextType::Wgpu(ctx) => { let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { @@ -1402,6 +1399,12 @@ impl Renderer { ); ImageTexture::Metal(mtl_tex) } + // `_Phantom` and any future-added variants. Placed + // LAST so platform arms (Metal/Wgpu/Vulkan) match + // first; an earlier `_ => continue` was the cause of + // image overlays silently dropping. + #[allow(unreachable_patterns)] + _ => continue, }; self.image_textures.insert( -- 2.51.2