Skip to content

fix(ui): render workspace terminal with Canvas + CJK fonts#253

Open
maxx-masa wants to merge 1 commit into
TraderAlice:masterfrom
maxx-masa:feat/terminal-cjk-canvas-pr
Open

fix(ui): render workspace terminal with Canvas + CJK fonts#253
maxx-masa wants to merge 1 commit into
TraderAlice:masterfrom
maxx-masa:feat/terminal-cjk-canvas-pr

Conversation

@maxx-masa

Copy link
Copy Markdown

Summary

  • Switch the workspace terminal's xterm renderer from WebGL to Canvas (@xterm/addon-canvas) and add Noto Sans Mono CJK JP / Noto Sans CJK JP to the font stack.
  • The WebGL glyph atlas drew any styled CJK cell it couldn't rasterize (notably italic Japanese — Noto Sans Mono CJK JP has no italic face) as a solid black box. Canvas rasterizes each cell via 2D fillText, falling back through the browser font stack and synthesizing obliques, so bold/italic Japanese renders correctly — while staying much faster than the DOM renderer.

Test plan

  • Japanese text renders correctly (incl. bold/italic) in the workspace terminal — verified in the running app.
  • cd ui && npx tsc -b — not run locally: node_modules is out of sync with this branch's base (fork base = current upstream), and a full install would disrupt the local dev environment. The change is a minimal, standard renderer swap.

Boundary touch

None.

🤖 Generated with Claude Code

Switch the xterm renderer from WebGL to Canvas (@xterm/addon-canvas) and
add "Noto Sans Mono CJK JP" / "Noto Sans CJK JP" to the terminal font
stack so Japanese text renders correctly in workspace sessions.

The WebGL glyph atlas drew any styled CJK cell it could not rasterize
(notably italic Japanese — Noto Sans Mono CJK JP has no italic face) as a
solid black box. The Canvas renderer rasterizes each cell via 2D
fillText, falling back through the browser font stack and synthesizing
obliques, so bold/italic Japanese renders correctly — while staying much
faster than the DOM renderer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 2, 2026

Copy link
Copy Markdown

@maxx-masa is attempting to deploy a commit to the luokerenx4's Team Team on Vercel.

A member of the Team first needs to authorize it.

@luokerenx4

Copy link
Copy Markdown
Contributor

Thanks for the report. We tried hard to reproduce this and couldn't, on two platforms with the exact production config (same @xterm/xterm 5.5 + WebGL addon + font stack):

  • macOS + Chromium: regular / bold / italic / bold-italic Japanese and Chinese all render correctly (italics as synthesized obliques) — no black boxes.
  • Linux + Chromium + Noto Sans CJK (your stated trigger: no italic face) with a real WebGL context: same result, no black boxes.

One correction to the diagnosis: the WebGL renderer's glyph rasterization is the same Canvas2D fillText path the Canvas renderer uses — browser font fallback and synthetic obliques apply to both (our WebGL-side screenshots show synthesized italic CJK drawn by the atlas itself). What differs is everything after rasterization: texture upload, WebGL context, driver compositing. That GPU pipeline has a known family of environment-specific corruption bugs in this exact stack (VS Code's terminal — same atlas — e.g. microsoft/vscode#137047, #163936, #288682), and VS Code's mitigation is a renderer escape hatch rather than dropping WebGL. Swapping to the Canvas renderer "fixes" it by routing around the broken GPU path on the affected machine.

So instead of a blanket renderer swap, master now ships an escape hatch (#305):

localStorage.setItem('openalice.terminal.renderer', 'dom') // then reload

Could you try current master on the machine that showed black boxes and report:

  1. Does the default (WebGL) still show black boxes there?
  2. Does setting the flag above fix it?
  3. Your environment: OS, browser vs Electron desktop shell, GPU model/driver, and the summary block of chrome://gpu.

If (1) yes + (2) yes, that confirms the GPU-pipeline diagnosis and we can talk about auto-detection or surfacing the toggle in settings. Leaving this PR open while we wait for your results.

pull Bot pushed a commit to dubbypanda/OpenAlice that referenced this pull request Jun 10, 2026
The WebGL renderer's glyph rasterization is plain Canvas2D (shared with
the DOM renderer), but the rasterized glyphs then ride a GPU pipeline
with a known family of environment-specific corruption bugs (black
boxes over CJK, garbled cells — same xterm atlas as VS Code's terminal,
see microsoft/vscode#137047/#163936/#288682). None of them throw, so
they can't be auto-detected; VS Code's answer is the gpuAcceleration
setting. Ours:

- `localStorage['openalice.terminal.renderer'] = 'dom'` forces the DOM
  renderer (unset/anything else keeps WebGL).
- Shared `attachWebglRenderer` loader: addon-throw and context-loss
  both degrade to the DOM renderer; the demo replay previously had no
  context-loss handling at all.

Investigated from external PR TraderAlice#253's black-box report — not
reproducible on macOS nor Linux+Noto CJK with identical config, so the
fix is an escape hatch rather than a blanket renderer swap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants