Private/AnsiWidth.ps1

function Get-InTUIConsoleInnerWidth {
    <#
    .SYNOPSIS
        Returns usable inner width for content rendering, minimum 48.
    #>

    [CmdletBinding()]
    param()

    $width = 80
    try {
        $width = [Console]::WindowWidth - 4
    }
    catch {
        $width = 80
    }

    return [Math]::Max(48, $width)
}

function Measure-InTUIDisplayWidth {
    <#
    .SYNOPSIS
        Returns the visual column width of a string, accounting for characters
        that render as 2 columns in terminal emulators (East Asian Wide,
        Fullwidth, and common ambiguous-width symbols).
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [AllowEmptyString()]
        [string]$Text
    )

    if ([string]::IsNullOrEmpty($Text)) { return 0 }

    $width = 0
    for ($i = 0; $i -lt $Text.Length; $i++) {
        $cp = [int]$Text[$i]

        # Handle surrogate pairs (emoji, CJK Extension B+)
        if ($cp -ge 0xD800 -and $cp -le 0xDBFF -and ($i + 1) -lt $Text.Length) {
            $low = [int]$Text[$i + 1]
            if ($low -ge 0xDC00 -and $low -le 0xDFFF) {
                $cp = 0x10000 + (($cp - 0xD800) -shl 10) + ($low - 0xDC00)
                $i++
            }
        }

        # Control characters and ANSI escape components: 0 width
        if ($cp -lt 0x20 -or ($cp -ge 0x7F -and $cp -lt 0xA0)) {
            continue
        }

        # 2-column ranges
        if (
            # East Asian Wide / Fullwidth
            ($cp -ge 0x1100 -and $cp -le 0x115F) -or   # Hangul Jamo
            ($cp -ge 0x2E80 -and $cp -le 0x303E) -or   # CJK Radicals, Ideographic, Symbols
            ($cp -ge 0x3041 -and $cp -le 0x33BF) -or   # Hiragana, Katakana, Bopomofo, CJK Compat
            ($cp -ge 0x3400 -and $cp -le 0x4DBF) -or   # CJK Unified Ext A
            ($cp -ge 0x4E00 -and $cp -le 0x9FFF) -or   # CJK Unified Ideographs
            ($cp -ge 0xAC00 -and $cp -le 0xD7AF) -or   # Hangul Syllables
            ($cp -ge 0xF900 -and $cp -le 0xFAFF) -or   # CJK Compatibility Ideographs
            ($cp -ge 0xFE30 -and $cp -le 0xFE6F) -or   # CJK Compatibility Forms
            ($cp -ge 0xFF01 -and $cp -le 0xFF60) -or   # Fullwidth Forms
            ($cp -ge 0xFFE0 -and $cp -le 0xFFE6) -or   # Fullwidth Signs
            ($cp -ge 0x20000 -and $cp -le 0x2FFFF) -or # CJK Extension B+
            ($cp -ge 0x30000 -and $cp -le 0x3FFFF) -or # CJK Extension G+
            # Supplemental emoji (actual pictographic emoji)
            ($cp -ge 0x1F000 -and $cp -le 0x1FAFF)     # Emoji & Symbols
        ) {
            $width += 2
        }
        else {
            $width += 1
        }
    }

    return $width
}