A lightweight Python library for calculating visual width of text, especially designed for subtitle display.
- Accurate width calculation: Calculates visual width based on Unicode properties and character characteristics
- Multi-language support: Supports CJK (Chinese, Japanese, Korean), Latin, Arabic, Hebrew, and many other scripts
- Subtitle-optimized: Designed specifically for subtitle text width calculation
- CJK comprehensive: Full support for all CJK character ranges including extensions A-I
- Zero dependencies: Uses only Python standard library (
unicodedata,math,functools) - Type safety: Full type hints for better IDE support
- Performance: Uses LRU cache for efficient repeated calculations
pip install visual-widthfrom visual_width import VisualWidth
# Calculate width of English text
width = VisualWidth.calc("Hello, world!")
print(width) # 13.0
# Calculate width of Chinese text
width = VisualWidth.calc("你好,世界")
print(width) # 10.0 (5 characters × 2.0 width each)
# Calculate width of mixed text
width = VisualWidth.calc("Hello 世界")
print(width) # 12.0 (5 + 1 + 6)The library uses the following width mapping:
- CJK characters (Chinese, Japanese, Korean): 2.0
- Latin lowercase letters: ~1.0 (varies by character)
- Latin uppercase letters: ~1.15 (except I=0.4, M/W=1.3)
- Numbers: 0.9
- Space: 0.3
- Very narrow characters (i, l, I, etc.): 0.4
- Narrow characters (f, j, t, r, etc.): 0.6
- Wide characters (m, w, M, W, etc.): 1.3
The calc() method returns a float value rounded up to one decimal place (always rounds up).
Examples:
1.23→1.31.21→1.31.20→1.2
Main utility class for visual width calculation. All methods are static.
Calculate the visual width of text for subtitle display.
This method calculates the visual width of text (in character units), where 1.0 represents the width of a standard Latin lowercase letter.
Parameters:
text(str): Input text string.
Returns:
float: Visual width in character units, rounded up to one decimal place.
Examples:
from visual_width import VisualWidth
# English text
width = VisualWidth.calc("Hello")
print(width) # 5.0
# Chinese text
width = VisualWidth.calc("你好")
print(width) # 4.0
# Mixed text
width = VisualWidth.calc("Hello 世界")
print(width) # 12.0
# Text with numbers and punctuation
width = VisualWidth.calc("Price: $99.50")
print(width) # 13.0
# Empty string
width = VisualWidth.calc("")
print(width) # 0.0The VisualWidth class provides the following constants for character width categories:
VisualWidth.VERY_NARROW_CHARS: Set of very narrow characters (width 0.4)VisualWidth.NARROW_CHARS: Set of narrow characters (width 0.6)VisualWidth.WIDE_CHARS: Set of wide characters (width 1.3)
These constants can be accessed directly if needed for custom logic.
- CJK Unified Ideographs: 0x4E00-0x9FFF
- CJK Extension A-I: All extension blocks (0x3400-0x323AF, 0x2EBF0-0x2EE5F)
- CJK Compatibility Ideographs: 0xF900-0xFAFF, 0x2F800-0x2FA1F
- Hiragana: 0x3040-0x309F
- Katakana: 0x30A0-0x30FF
- Hangul Syllables: 0xAC00-0xD7AF (plus extensions)
- Bopomofo (Zhuyin): 0x3100-0x312F
- Latin: Standard and extended Latin characters
- Greek: Greek letters (uppercase: 1.1, lowercase: 1.0)
- Cyrillic: Cyrillic letters (uppercase: 1.15, lowercase: 1.0)
- Arabic: Arabic letters (0.8 width)
- Hebrew: Hebrew letters (0.9 width)
- Thai: Thai characters (0.9 width)
- Devanagari: Devanagari script (0.9 width)
- Emoji: Emoji and symbols (2.0 width)
- Python >= 3.10
No external dependencies required. This package uses only Python standard library modules (unicodedata, math, functools).
MIT License