param([string]$In, [string]$Out, [double]$Pad = 200) $enc = [System.Text.Encoding]::GetEncoding(949) $lines = New-Object 'System.Collections.Generic.List[string]' $lines.AddRange([System.IO.File]::ReadAllLines($In, $enc)) $inv = [System.Globalization.CultureInfo]::InvariantCulture # locate ENTITIES section $start = -1 for ($i = 0; $i -lt $lines.Count - 1; $i++) { if ($lines[$i].Trim() -eq '2' -and $lines[$i + 1].Trim() -eq 'ENTITIES') { $start = $i + 2; break } } if ($start -lt 0) { throw 'no ENTITIES' } $ents = New-Object System.Collections.ArrayList $cur = $null for ($i = $start; $i -lt $lines.Count - 1; $i += 2) { $c = $lines[$i].Trim() $v = $lines[$i + 1] if ($c -eq '0') { if ($cur -ne $null) { [void]$ents.Add($cur) } if ($v.Trim() -eq 'ENDSEC') { $cur = $null; break } $cur = @{ type = $v.Trim(); idx = @{}; val = @{} } continue } if ($cur -ne $null) { $cur.idx[$c] = $i + 1; $cur.val[$c] = $v.Trim() } } # vertical cell-border lines: x, ymin, ymax $vx = New-Object System.Collections.ArrayList foreach ($e in $ents) { if ($e.type -ne 'LINE') { continue } $x1 = [double]::Parse($e.val['10'], $inv); $x2 = [double]::Parse($e.val['11'], $inv) $y1 = [double]::Parse($e.val['20'], $inv); $y2 = [double]::Parse($e.val['21'], $inv) if ([math]::Abs($x1 - $x2) -lt 0.01) { [void]$vx.Add([pscustomobject]@{ x = $x1; y0 = [math]::Min($y1, $y2); y1 = [math]::Max($y1, $y2) }) } } $changed = 0; $skipped = 0; $overflow = @() foreach ($e in $ents) { if ($e.type -ne 'TEXT') { continue } $layer = $e.val['8'] if ($layer -eq 'TITLE' -or $layer -eq 'NOTE') { $skipped++; continue } $has72 = $e.val.ContainsKey('72') -and $e.val['72'] -ne '0' $has73 = $e.val.ContainsKey('73') -and $e.val['73'] -ne '0' if ($has72 -or $has73) { $cx = [double]::Parse($e.val['11'], $inv); $cy = [double]::Parse($e.val['21'], $inv) } else { $cx = [double]::Parse($e.val['10'], $inv); $cy = [double]::Parse($e.val['20'], $inv) } $h = [double]::Parse($e.val['40'], $inv) # for left-baseline text (no alignment) test the vertical mid of the glyph row if (-not ($has72 -or $has73)) { $cy = $cy + $h / 2 } $left = $null; $right = $null foreach ($ln in $vx) { if ($cy -lt $ln.y0 - 0.5 -or $cy -gt $ln.y1 + 0.5) { continue } if ($ln.x -le $cx + 0.5) { if ($left -eq $null -or $ln.x -gt $left) { $left = $ln.x } } else { if ($right -eq $null -or $ln.x -lt $right) { $right = $ln.x } } } if ($left -eq $null) { $skipped++; continue } # not inside a table box $nx = $left + $Pad $s = $nx.ToString('0.000', $inv) # TEXT: 72 -> 0 (left), keep 73 (vertical middle); 10 and 11 x -> new left $lines[$e.idx['10']] = $s if ($e.idx.ContainsKey('11')) { $lines[$e.idx['11']] = $s } if ($e.idx.ContainsKey('72')) { $lines[$e.idx['72']] = '0' } $changed++ # rough overflow estimate (hangul ~1.0h, others ~0.6h) $txt = $lines[$e.idx['1']] $t = $enc.GetString([byte[]]$enc.GetBytes($txt)) $w = 0.0 foreach ($ch in $t.ToCharArray()) { if ([int]$ch -gt 255) { $w += $h * 1.0 } else { $w += $h * 0.6 } } if ($right -ne $null -and ($nx + $w) -gt ($right - 50)) { $overflow += ("{0}: '{1}' est.width {2:N0} room {3:N0}" -f $layer, $t, $w, ($right - $nx)) } } [System.IO.File]::WriteAllLines($Out, $lines, $enc) "changed=$changed skipped=$skipped" "possible overflow: " + $overflow.Count $overflow