$ErrorActionPreference = 'Stop' function R16([byte[]]$b, [int]$p) { return [int]($b[$p]) -shl 8 -bor [int]$b[$p+1] } function R32([byte[]]$b, [int]$p) { return ([int]$b[$p] -shl 24) -bor ([int]$b[$p+1] -shl 16) -bor ([int]$b[$p+2] -shl 8) -bor [int]$b[$p+3] } function HexStr([string]$s) { if (-not $s) { return '' } $bytes = [Text.Encoding]::ASCII.GetBytes($s) $sb = New-Object Text.StringBuilder for ($i = 0; $i -lt $bytes.Length; $i++) { [void]$sb.Append('{0:x2} ' -f $bytes[$i]) } return $sb.ToString().TrimEnd() } function Get-Names([byte[]]$b) { $numTables = R16 $b 4 $nameOff = -1 for ($i = 0; $i -lt $numTables; $i++) { $rec = 12 + $i * 16 $tag = [Text.Encoding]::ASCII.GetString($b, $rec, 4) if ($tag -eq 'name') { $nameOff = R32 $b ($rec + 8) } } if ($nameOff -lt 0) { return $null } $base = $nameOff $count = R16 $b ($base + 2) $recordsEnd = 6 + $count * 12 $strOff32 = R32 $b ($base + 4) if ($strOff32 -ge $recordsEnd -and ($base + $strOff32) -le $b.Length) { $strOff = $strOff32 } else { $strOff = R16 $b ($base + 4) } $strBase = $base + $strOff $win = @{}; $mac = @{} for ($i = 0; $i -lt $count; $i++) { $r = $base + 6 + $i * 12 $plat = R16 $b $r $lang = R16 $b ($r + 4) $id = R16 $b ($r + 6) $len = R16 $b ($r + 8) $off = R16 $b ($r + 10) if ($len -eq 0 -or ($strBase + $off + $len) -gt $b.Length) { continue } $b2 = New-Object byte[] $len [Array]::Copy($b, $strBase + $off, $b2, 0, $len) if ($plat -eq 3 -and $lang -eq 0x0409) { if (-not $win.ContainsKey($id)) { $win[$id] = [Text.Encoding]::Unicode.GetString($b2) } } elseif ($plat -eq 1) { if (-not $mac.ContainsKey($id)) { $mac[$id] = [Text.Encoding]::ASCII.GetString($b2) } } } return @{ win = $win; mac = $mac } } $dir = "c:\Users\fdavalos\OneDrive - up.edu.mx\microtracking\MicrotrackingFer\tools\fonts\lm\fonts\opentype\public\lm" $out = New-Object Text.StringBuilder foreach ($f in (Get-ChildItem $dir -Filter *.otf | Sort-Object Name)) { $b = [IO.File]::ReadAllBytes($f.FullName) $n = Get-Names $b if (-not $n) { [void]$out.AppendLine(("{0} : NO name table" -f $f.Name)); continue } $fam = $n.win[16]; if (-not $fam) { $fam = $n.mac[16] }; if (-not $fam) { $fam = $n.win[1] }; if (-not $fam) { $fam = $n.mac[1] } $sub = $n.win[17]; if (-not $sub) { $sub = $n.mac[17] }; if (-not $sub) { $sub = $n.win[2] }; if (-not $sub) { $sub = $n.mac[2] } $psname = $n.win[6]; if (-not $psname) { $psname = $n.mac[6] } [void]$out.AppendLine(("{0} | f16=[{1}] s17=[{2}] ps6=[{3}]" -f $f.Name, (HexStr $fam), (HexStr $sub), (HexStr $psname))) } $wdir = $env:windir foreach ($f in @('times.ttf','timesbd.ttf','timesi.ttf','timesbi.ttf','arial.ttf','arialbd.ttf','ariali.ttf','arialbi.ttf','courier.ttf')) { $p = Join-Path $wdir "Fonts\$f" if (Test-Path $p) { $b = [IO.File]::ReadAllBytes($p) $n = Get-Names $b if ($n) { $fam = $n.win[16]; if (-not $fam) { $fam = $n.win[1] } $sub = $n.win[17]; if (-not $sub) { $sub = $n.win[2] } $psname = $n.win[6] [void]$out.AppendLine(("WIN: {0} | family=[{1}] sub=[{2}] psname=[{3}]" -f $f, (HexStr $fam), (HexStr $sub), (HexStr $psname))) } } } $dst = "c:\Users\fdavalos\OneDrive - up.edu.mx\microtracking\MicrotrackingFer\tools\fontnames.txt" [IO.File]::WriteAllText($dst, $out.ToString(), [Text.UTF8Encoding]::new($false)) Write-Output ("wrote {0}" -f $dst)