@@ -6,6 +6,7 @@ function Draw-AsciiBanner {
66 Draws a decorative ASCII banner box with rounded corners around one or more lines of text.
77 Uses Unicode box-drawing characters for a clean, modern appearance in the console.
88 Supports customizable text and border colors, and adjustable padding.
9+ Properly handles double-width characters (CJK, emoji, etc.) for correct alignment.
910 . PARAMETER Lines
1011 An array of strings to display inside the banner. Each string will be centered on its own line.
1112 . PARAMETER TextColor
@@ -26,6 +27,7 @@ function Draw-AsciiBanner {
2627 . NOTES
2728 This is a private function used internally by the AsBuiltReport.Core module.
2829 Uses Unicode box-drawing characters (U+256D, U+256E, U+2570, U+256F, U+2500, U+2502) for PS 5.1 compatibility.
30+ Calculates display width accounting for double-width characters (CJK ideographs, full-width forms, etc.).
2931 #>
3032 param (
3133 [string []]$Lines ,
@@ -34,8 +36,46 @@ function Draw-AsciiBanner {
3436 [int ]$ExtraPadding = 2
3537 )
3638
37- $maxLen = ($Lines | Measure-Object Length - Maximum).Maximum
38- $contentWidth = $maxLen + ($ExtraPadding * 2 )
39+ # Helper function to calculate display width of a string
40+ # Accounts for double-width characters (CJK, emoji, etc.)
41+ function Get-DisplayWidth {
42+ param ([string ]$Text )
43+
44+ $width = 0
45+ foreach ($char in $Text.ToCharArray ()) {
46+ $codePoint = [int ][char ]$char
47+
48+ # Check if character is double-width
49+ # CJK Unified Ideographs: U+4E00-U+9FFF
50+ # CJK Extension A: U+3400-U+4DBF
51+ # Hangul Syllables: U+AC00-U+D7AF
52+ # Hiragana/Katakana: U+3040-U+30FF
53+ # Full-width Forms: U+FF00-U+FFEF
54+ # CJK Symbols and Punctuation: U+3000-U+303F
55+ if (($codePoint -ge 0x4E00 -and $codePoint -le 0x9FFF ) -or
56+ ($codePoint -ge 0x3400 -and $codePoint -le 0x4DBF ) -or
57+ ($codePoint -ge 0xAC00 -and $codePoint -le 0xD7AF ) -or
58+ ($codePoint -ge 0x3040 -and $codePoint -le 0x30FF ) -or
59+ ($codePoint -ge 0xFF00 -and $codePoint -le 0xFFEF ) -or
60+ ($codePoint -ge 0x3000 -and $codePoint -le 0x303F )) {
61+ $width += 2
62+ } else {
63+ $width += 1
64+ }
65+ }
66+ return $width
67+ }
68+
69+ # Calculate max display width across all lines
70+ $maxDisplayWidth = 0
71+ foreach ($line in $Lines ) {
72+ $displayWidth = Get-DisplayWidth - Text $line
73+ if ($displayWidth -gt $maxDisplayWidth ) {
74+ $maxDisplayWidth = $displayWidth
75+ }
76+ }
77+
78+ $contentWidth = $maxDisplayWidth + ($ExtraPadding * 2 )
3979
4080 # Top and bottom borders - use Unicode code points for PS 5.1 compatibility
4181 $topLeft = [char ]0x256D # ╭
@@ -50,7 +90,8 @@ function Draw-AsciiBanner {
5090
5191 Write-Host $top - ForegroundColor $BorderColor
5292 foreach ($line in $Lines ) {
53- $totalPadding = $contentWidth - $line.Length
93+ $lineDisplayWidth = Get-DisplayWidth - Text $line
94+ $totalPadding = $contentWidth - $lineDisplayWidth
5495 $leftPad = [math ]::Floor($totalPadding / 2 )
5596 $rightPad = $totalPadding - $leftPad
5697 $padded = (' ' * $leftPad ) + $line + (' ' * $rightPad )
0 commit comments