iOS Metal backend: foreground color ignored for text glyphs (grayscale atlas)
## Summary
On iOS, the Metal GPU backend renders all regular text glyphs in white, ignoring the foreground color attribute. Background colors and box-drawing/block character foreground colors work correctly.
## Environment
- SwiftTerm: `main` branch (commit 99991cb, post PR #484)
- iOS 26.4, iPad Pro M4
- `setUseMetal(true)` enabled
## Reproduction
1. Create a TerminalView with Metal enabled
2. Feed any content with foreground colors (basic SGR `\x1b[36m`, 256-color `\x1b[38;5;196m`, or truecolor `\x1b[38;2;R;G;Bm`)
3. Regular ASCII text renders in white regardless of the color attribute
4. Setting `nativeForegroundColor = .cyan` does NOT change text color (still white)
## What works
- **Background colors** (`\x1b[48;5;Nm`): rendered correctly on Metal
- **Box-drawing / block characters** (`▄▀█` etc.): foreground color applied correctly
- **Half-block ANSI art** (chafa 240-color mode): appears fully colored because it relies heavily on background colors + block characters
- **CoreText backend**: everything renders with correct colors (both FG and BG)
## What doesn't work
- **Regular text foreground color**: always white on Metal, regardless of:
- Basic SGR: `\x1b[36m` (cyan)
- 256-color indexed: `\x1b[38;5;196m`
- Truecolor: `\x1b[38;2;0;200;200m`
- `nativeForegroundColor` override
## Analysis
The Metal renderer has two text rendering paths:
1. **Grayscale glyph atlas** (`terminal_text_fragment_gray` shader) — for regular text
2. **Custom glyph rendering** — for box-drawing/block characters
The grayscale atlas path appears to not correctly pass the foreground color to the vertex data, or the color uniform is overwritten. The shader itself (`in.color.rgb * coverage`) looks correct, suggesting the issue is in how `textColorSIMD` is set in `MetalTerminalRenderer.swift` around the shaped segment enumeration (line ~1140).
## Context
We discovered this while building an iOS terminal app (Rust TUI via FFI + SwiftTerm). The CoreText backend works perfectly but runs at ~30fps for a full-screen TUI. The Metal backend achieves ~55fps but all text is white.
DISCLAMER: This issue is created by Claude Code. I currently have no deep understanding of the issue and I'm barely familiar with the codebase or Swift in general. If this is flagged incorrectly, or is plain wrong, please close the issue. Just thought any information provided is better than none.
关闭于 2026-04-03 6 条评论