Description
All text width calculations in the layout engine use string.length * theme.averageCharWidth, which treats every character as a single-width glyph. CJK characters (Chinese, Japanese, Korean) are double-width in monospace fonts, so any component containing CJK text renders at roughly half the correct width.
This is a systemic issue — it affects every component that measures text via .length, not just chip.
Steps to Reproduce
Render a chip with Chinese text:
chip "已归档"
chip "已分享"
chip "收藏" icon="star"
The pill boxes are noticeably narrower than the text they contain. Compare with Latin text of the same character count (e.g. chip "abc") which renders correctly.
Root Cause
In src/renderer/layout.ts, every measurement function computes width as:
const labelW = node.label.length * theme.averageCharWidth;
With averageCharWidth = 7.2 and the string "已归档" (3 CJK chars):
- Current calculation:
3 × 7.2 = 21.6px
- Expected width (each CJK char is ~2× wide in monospace):
3 × 14.4 ≈ 43.2px
This pattern appears in 44+ locations across layout.ts and svg.ts (for chip, button, text, menu, breadcrumb, checkbox, radio, toggle, status, segmented, tree, menubar, kv, combo, stat, input placeholder, tabbar, and more).
Suggested Fix
Introduce a visualTextWidth(text, averageCharWidth) helper that detects CJK characters and applies a 2× multiplier per character:
const CJK_RANGE = /[\u2E80-\u9FFF\uF900-\uFAFF\uFE30-\uFE4F\u{20000}-\u{2FA1F}]/u;
function visualTextWidth(text: string, charWidth: number): number {
let w = 0;
for (const ch of text) {
w += CJK_RANGE.test(ch) ? charWidth * 2 : charWidth;
}
return w;
}
Then replace all node.label.length * theme.averageCharWidth calls with visualTextWidth(node.label, theme.averageCharWidth).
Environment
- Wireloom: latest
main branch
- Rendering: SVG output (terminal/SVG renderer)
- Font: monospace (CJK glyphs are full-width)
Description
All text width calculations in the layout engine use
string.length * theme.averageCharWidth, which treats every character as a single-width glyph. CJK characters (Chinese, Japanese, Korean) are double-width in monospace fonts, so any component containing CJK text renders at roughly half the correct width.This is a systemic issue — it affects every component that measures text via
.length, not just chip.Steps to Reproduce
Render a chip with Chinese text:
The pill boxes are noticeably narrower than the text they contain. Compare with Latin text of the same character count (e.g.
chip "abc") which renders correctly.Root Cause
In
src/renderer/layout.ts, every measurement function computes width as:With
averageCharWidth = 7.2and the string"已归档"(3 CJK chars):3 × 7.2 = 21.6px3 × 14.4 ≈ 43.2pxThis pattern appears in 44+ locations across
layout.tsandsvg.ts(for chip, button, text, menu, breadcrumb, checkbox, radio, toggle, status, segmented, tree, menubar, kv, combo, stat, input placeholder, tabbar, and more).Suggested Fix
Introduce a
visualTextWidth(text, averageCharWidth)helper that detects CJK characters and applies a 2× multiplier per character:Then replace all
node.label.length * theme.averageCharWidthcalls withvisualTextWidth(node.label, theme.averageCharWidth).Environment
mainbranch