Sources/OrgCore/Semantic/DisplayWidth.swift
17 lines · 733 bytes
1/// Columns a string occupies in a monospaced table: East Asian wide and fullwidth characters
2/// and emoji take two, everything else one. Combining marks belong to their Character.
3public func displayWidth(_ text: some StringProtocol) -> Int {
4 text.reduce(0) { $0 + displayWidth(of: $1) }
5}
6
7func displayWidth(of character: Character) -> Int {
8 guard let scalar = character.unicodeScalars.first else { return 0 }
9 if scalar.properties.isEmojiPresentation { return 2 }
10 switch scalar.value {
11 case 0x1100...0x115F, 0x2E80...0x303E, 0x3041...0xA4CF, 0xAC00...0xD7A3, 0xF900...0xFAFF,
12 0xFE30...0xFE4F, 0xFF00...0xFF60, 0xFFE0...0xFFE6, 0x20000...0x3FFFD:
13 return 2
14 default:
15 return 1
16 }
17}