home *** CD-ROM | disk | FTP | other *** search
- Attribute VB_Name = "FONTINFO1"
- Option Explicit
-
- #If Win32 Then
- Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
- Declare Function GetVersion Lib "kernel32" () As Long
- #Else
- Declare Function GetVersion& Lib "Kernel" ()
- Declare Function GetWindowsDirectory% Lib "Kernel" (ByVal lpBuffer$, ByVal nSize%)
- #End If
-
- Type OffsetTable
- sfntVersionA As Integer
- sfntVersionB As Integer
- numTables As Integer
- searchRange As Integer
- entrySelector As Integer
- rangeShift As Integer
- End Type
-
- Type TableDirectoryEntry
- tag(3) As Byte ' Was String * 4 in VB 3.0 - But chars are 2 bytes in Win32, hence the change
- checkSum As Long
- offset As Long
- length As Long
- End Type
-
- Type NamingTable
- FormatSelector As Integer
- NameRecords As Integer
- offsStrings As Integer
- End Type
-
- Type NameRecord
- PlatformID As Integer
- PlatformSpecific As Integer
- LanguageID As Integer
- NameID As Integer
- StringLength As Integer
- StringOffset As Integer
- End Type
-
- Global OT As OffsetTable
-
-
- Function GetNameForID(ByVal id As Long) As String
- Dim s$
- Select Case id
- Case 0
- s$ = "Copyright"
- Case 1
- s$ = "Font Family"
- Case 2
- s$ = "Font subfamily"
- Case 3
- s$ = "Font Identifier"
- Case 4
- s$ = "Full Font Name"
- Case 5
- s$ = "Version"
- Case 6
- s$ = "Postscript name"
- Case 7
- s$ = "Trademark"
- Case Else
- s$ = "Unknown"
- End Select
-
- GetNameForID = s$
- End Function
-
- Function GetPlatformForID(ByVal id As Long) As String
- Dim s$
- Select Case id
- Case 0
- s$ = "Apple Unicode"
- Case 1
- s$ = "Macintosh"
- Case 2
- s$ = "ISO"
- Case 3
- s$ = "Microsoft"
- End Select
- GetPlatformForID = s$
-
- End Function
-
- Sub LoadFontInfo(filename$, List1 As ListBox, mode%)
- Dim fileid%
- Dim TD As TableDirectoryEntry
- Dim NT As NamingTable
- Dim NR As NameRecord
- Dim n&
- Dim NTStart& ' Start of naming table
- Dim CurrentLoc& ' Current location in file
- Dim nrnum&
- Dim nameinfo() As Byte
- Dim nPlatformID&
- Dim stroffset&
-
- List1.Clear
- fileid% = FreeFile ' Get a file ID
-
- Open filename$ For Binary Access Read As #fileid%
- Get #fileid%, , OT ' Retrieve the offset table
- List1.AddItem "Version " & SwapInteger(OT.sfntVersionA) & "." & SwapInteger(OT.sfntVersionB)
- List1.AddItem "Tables " & SwapInteger(OT.numTables)
-
- Select Case mode%
- Case 0 ' List all tables
- For n& = 1 To SwapInteger(OT.numTables)
- Get #fileid%, , TD
- ' We used to be able to add the string directly (Win16), but
- ' Using a byte array requires a conversion
- List1.AddItem TagToString(TD)
- Next n&
- Case 1 ' Name Information
- For n& = 1 To SwapInteger(OT.numTables)
- Get #fileid%, , TD
- If TagToString(TD) = "name" Then
- ' Seek to the specified location in the file
- NTStart& = SwapLong(TD.offset) + 1
- Seek #fileid%, NTStart&
- Get #fileid%, , NT
- List1.AddItem "NumRecords " & SwapInteger(NT.NameRecords)
- For nrnum& = 1 To SwapInteger(NT.NameRecords)
- Get #fileid%, , NR
- List1.AddItem "NameRecord # " & nrnum&
- List1.AddItem " Platform ID: " & GetPlatformForID(SwapInteger(NR.PlatformID))
- List1.AddItem " NameID: " & GetNameForID$(SwapInteger(NR.NameID))
- nPlatformID = SwapInteger(NR.PlatformID)
- If (nPlatformID = 1 Or nPlatformID = 3) And NR.StringLength <> 0 Then
- ' Mark the current location in the file
- CurrentLoc& = Seek(fileid%)
- ' Calculate the length of the string
- ReDim nameinfo(SwapInteger(NR.StringLength) - 1)
- ' Calculate the location of the string
- ' It should be possible to use the NT.offsStrings field to determine the
- ' start location of the string table, but it turns out some fonts get this
- ' wrong, so we calculate it based on the number of NameRecord structures
- ' and the size of the structures.
- stroffset = 6 + SwapInteger(NT.NameRecords) * 12
- ' Get #fileid%, NTStart& + SwapInteger(NT.offsStrings) + SwapInteger(NR.StringOffset), nameinfo
- Get #fileid%, NTStart& + stroffset + SwapInteger(NR.StringOffset), nameinfo
- Select Case nPlatformID
- Case 1 ' Macintosh (ANSI)
- #If Win32 Then
- List1.AddItem " " & StrConv(nameinfo, vbUnicode)
- #Else
- List1.AddItem " " & CStr(nameinfo)
- #End If
- Case 3 ' Microsoft (Unicode)
- #If Win32 Then
- SwapArray nameinfo()
- List1.AddItem " " & CStr(nameinfo)
- #Else
- List1.AddItem " " & "Not supported in 16 bit environments"
- #End If
- End Select
- ' Restore the previous location
- Seek #fileid%, CurrentLoc&
- Else
- List1.AddItem " - This program only diplays Macintosh and Microsoft strings"
- End If
- Next nrnum&
-
- Exit For
- End If
- Next n&
- End Select
-
-
- Close #fileid%
-
- End Sub
-
- '
- ' Note that we swap the low order bytes in a long so that
- ' we don't have to worry about overflow problems
- '
- Function SwapInteger(ByVal i As Long) As Long
- SwapInteger = ((i \ &H100) And &HFF) Or ((i And &HFF) * &H100&)
-
- End Function
-
- '
- ' Swap a long value from Motorola to Intel format or vice versa
- '
- Function SwapLong(ByVal l As Long) As Long
- Dim addbit%
- Dim newlow&, newhigh&
-
- newlow& = l \ &H10000
- newlow& = SwapInteger(newlow& And &HFFFF&)
-
- newhigh& = SwapInteger(l And &HFFFF&)
- If newhigh& And &H8000& Then
- ' This would overflow
- newhigh& = newhigh And &H7FFF
- addbit% = True
- End If
- newhigh& = (newhigh& * &H10000) Or newlow&
- If addbit% Then newhigh = newhigh Or &H80000000
- SwapLong = newhigh&
-
- End Function
-
- ' Swap every other byte in a Unicode string
- Sub SwapArray(namearray() As Byte)
- Dim u%, p%
- Dim b As Byte
- u% = UBound(namearray)
- For p = 0 To u - 1 Step 2
- b = namearray(p)
- namearray(p) = namearray(p + 1)
- namearray(p + 1) = b
- Next p
- End Sub
- '
- ' Converts the byte array to a 4 character tag name
- '
- Public Function TagToString(TD As TableDirectoryEntry)
- Dim tagstr As String * 4
- Dim x%
- For x% = 1 To 4
- Mid(tagstr, x%, 1) = Chr$(TD.tag(x% - 1))
- Next x%
- TagToString = tagstr
- End Function
-