6.3 KiB
Diff hatching: two-column diagonal feasibility
Finding
Yes: Unicode has the exact two line segments needed. Repeat the following pair, in this order, with each character occupying one terminal column:
| Position | Character | Code point | Official Unicode name |
|---|---|---|---|
| Left cell | | U+1FBD0 | BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER LEFT |
| Right cell | | U+1FBD1 | BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT |
These are listed under Character cell diagonals on page 6 of the official Unicode 17.0 Symbols for Legacy Computing chart; the exact names are also in UnicodeData.txt. They were introduced in Unicode 16.0 (1FBCB..1FBEF in DerivedAge.txt). The names specify endpoints, not a drawing direction: together they join the pair's bottom-left corner to the shared edge's midpoint, then to the pair's top-right corner.
Sample (glyphs may be missing or differently rendered in the Markdown viewer):
Equivalent escaped sequence: \u{1FBD0}\u{1FBD1}. This is two separate characters/cells, not one double-width character.
Geometry
For physical cell width W and height H, the ideal joined stroke has horizontal run 2W and vertical rise H, so its angle above horizontal is:
θ = atan(H / (2W))
This is 45° iff H = 2W. The current full-cell ╱ has ideal angle atan(H / W); at H = 2W, that is approximately 63.4°. Thus the pair is shallower, but the actual angle depends on the terminal's cell dimensions, including line spacing. These are geometric deductions from the chart's endpoints, not measured rendering results.
Do not substitute U+1FBA0–U+1FBAE: their centre/cell-edge endpoints describe different segments (see page 5 of the same chart). In particular, a side midpoint to top/bottom centre has run W/2 and rise H/2, preserving the full-cell diagonal's slope rather than halving it.
Line segments, not filled mosaics
U+1FBD0/U+1FBD1 are light box-drawing strokes. The chart separately labels U+1FB3C–U+1FB6F as Smooth mosaic terminal graphic characters: their BLOCK DIAGONAL names describe filled regions bounded by diagonals, not thin lines. For example, U+1FB48 is LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO LOWER MIDDLE RIGHT and U+1FB42 is LOWER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER RIGHT (chart, pages 3–4, UnicodeData.txt). Those are not equivalent replacements for light hatching.
Support limits and current code
- Unicode 16.0 repertoire support is a prerequisite; the existence of these characters does not establish coverage in the selected terminal/font. Missing glyphs or fallback glyphs remain possible, and fallback geometry must be checked in the intended renderer. Unicode explicitly says its chart glyph shapes are not prescriptive and actual fonts may vary (chart, page 1). Pixel-perfect joins or 45° rendering cannot be promised.
- The pair has East Asian Width Neutral (
N), from1FB94..1FBEFin EastAsianWidth.txt. This is not a terminal-width guarantee: UAX #11, §2 and §4 explicitly requires terminal-specific tailoring and distinguishes font/layout width from the property. Both the application and terminal must agree on one column per glyph. - Current rendering writes one
╱per column withDarkGrayforeground and reset background in src/tui.rs:3308–3316; the documented behavior is docs/editing.md:426. This note proposes no implementation change. Any later cutover would need a defined pair phase and odd-width clipping behavior, plus terminal/font evidence.
Terminal support
- Ghostty 1.3.1: The released drawing source explicitly implements both segments with the required endpoints. Ghostty's codepoint resolver normally selects procedural sprite rendering before ordinary font lookup, so this does not require font coverage; explicit codepoint font overrides take precedence.
- Kitty: Current font dispatch routes this range to native box drawing, and drawing source explicitly implements the two segments. This establishes support in inspected upstream source, not a minimum released version.
- The local environment reported Herdr 0.9.3; installed binaries reported Ghostty 1.3.1 and Kitty 0.45.0. Herdr runs inside an outer terminal, so its presence and these installations do not prove which renderer displays this session. Visual verification through the actual terminal/multiplexer remains necessary.
Recommendation: Use the two-character text tile if it looks correct in the target terminal. No image protocol or new dependency is needed. Older/other terminals may lack glyph coverage; exact 45° remains conditional on cell geometry.
Runtime evidence
An executed disposable rustc smoke program used the repository's actual compiled ratatui and unicode-width dependencies, a fixed viewport, Terminal<CrosstermBackend<Vec<u8>>>, and the same per-cell set_symbol/style logic as the current renderer. Both U+1FBD0 and U+1FBD1 returned width Some(1). At three rows high, widths 1, 2, 3, and 12 emitted exactly 3, 6, 9, and 36 glyphs respectively: no dropped or double-width cells. This establishes application-side width/emission behavior, not actual terminal glyph coverage, pixel joins, or the visible angle; those were not visually verified. The disposable program and binary were removed.
Investigation only: no production code changed and no TODO marked complete.