Get name of a font from the file without installing it

For the Windows version of Fonts Manager, I need to find the name of a font from the font file.

On Mac, there is an MBS plugin, but unfortunately nothing for Windows.

Scouring the Internet, I found the function GetFontResourceInfo at http://www.undocprint.org/winspool/getfontresourceinfo

It seems simple enough, but I am at a loss about how to get the return information :

BOOL GetFontResourceInfo( LPCTSTR lpszFilename, // font file name LPDWORD cbBuffer, // size of buffer for resource information LPVOID lpBuffer, // buffer for returned resource information DWORD dwQueryType, // resource information query type );

[code]Parameters

lpszFilename

[in] Pointer to a null-terminated character string that contains a valid font file name. This parameter can specify any of the following files. File extension Description .fon Font resource file. .fnt Raw bitmap font file. .ttf Raw TrueType file. .ttc East Asian Windows: TrueType font collection. .fot TrueType resource file. .otf PostScript OpenType font. .mmm multiple master Type1 font resource file. It must be used with .pfm and .pfb files. .pfb Type 1 font bits file. It is used with a .pfm file. .pfm Type 1 font metrics file. It is used with a .pfb file.

To add a font whose information comes from several resource files, point lpszFileName to a string with the file names separated by a | –for example, abcxxxxx.pfm | abcxxxxx.pfb.

cbBuffer

[in,out] Specifies the length, in bytes, of the information to be retrieved. If this parameter is zero, GetFontResourceInfo returns the size of the data specified in the dwQueryType parameter.

lpBuffer

[out] Pointer to a buffer that receives the font information. If this parameter is NULL, the function returns the size of the buffer required for the font data.

dwQueryType

Specifies the type of resouce information to return. This parameter can be one of the following values.

Value Meaning
QFR_0
0 DWORD or LPVOID
unknown
QFR_DESCRIPTION
1 The function provides a string that an NT-based operating system will use to describe the font file. A null-terminated Unicode string is written to the buffer pointed to by lpBuffer.
QFR_LOGFONT
2 Array of LOGFONT
QFR_PDEV
3 PDEV ?
QFR_FONTFILE
4 scalable font file name
QFR_5
5 DWORD
Windows XP: Always returns 0[/code]

How do I get the value back ?

I started writing this and got stuck with lpbuffer :

Soft Declare Function GetFontResourceInfo Lib "User32" (lpzfilename as WString, byref cbBuffer as Uint32, byref lpBuffer as Ptr ? ?

I realize I simply don’t know how to get the information back in a MemoryBlock, maybe a string ?

Will very much appreciate assistance.

TIA

you get a ptr back and can create a memoryblock from a ptr but you can also just use references from the ptr itself

http://developer.xojo.com/ptr

Well, you could first create a big memoryblock and pass its pointer.
And use maybe QFR_LOGFONT.

Memoryblock should be big enough for LOGFONT structure from Windows.
And that one may contain your font name.

OK. FunctionNotFound Exception… That is what I get for using an undocumented call :frowning:

Back to the drawing board.

Thank you, Norman, thank you Christian.

you’d think something on here would be useful
https://msdn.microsoft.com/en-us/library/windows/desktop/dd144821(v=vs.85).aspx

Well, I have been through it but there is nothing which can return the font name from the file.

I have found this
http://www.codeguru.com/cpp/g-m/gdi/fonthandlinganddetection/article.php/c3659/Retrieving-the-Font-Name-from-a-TTF-File.htm
where the author shows how to get each table and offset from the font data, in order to fetch the name.

I guess that is so far my best bet.

Please see this, in that code I get fonName and fontNameFamily in pure xojo code, not declares nor plugins.

Thank you Bernardo,

but your code as it stands contains references to many other classes and structures which makes it very difficult to understand.

I found a decent description of the tables inside a TTF font here
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6.html#Directory

How many bytes does an Uint16 and Uint32 represent ? 2 and 4, respectively like Int16 and Int32 ?

Well, if you have a license of DynaPDF plugin, you could tell it to ignore system fonts and load only the font you want to check.
Than ask DynaPDF about all fonts and you get only yours. With all the details.

http://developer.xojo.com/integer-size-specific (at the bottom of the page)

[quote=311080:@Christian Schmitz]Well, if you have a license of DynaPDF plugin, you could tell it to ignore system fonts and load only the font you want to check.
Than ask DynaPDF about all fonts and you get only yours. With all the details.[/quote]

Christian, I would prefer having a simple plugin that gives me the name of the font from the file as you have for Mac, than to buy a huge anvil like DynaPDF in order to swat such a minuscule fly.

I like you, but with this one, you are pushing it a tad too far :stuck_out_tongue:

Thank you Julian.

If you know a WIn32 function to do it, let me know and I add it to the plugin.

I just know that parsing font files is not trivial and hoped you got a DynaPDF starter via OmegaBundle the last years.

Well, I don’t have DynaPDF, and without a real reason to buy it, I think I am going to take my chances trying to find my way in the font table.

Thanks anyway.

This is the best resource I could find on the matter:

https://www.codeproject.com/Articles/42041/How-to-Use-a-Font-Without-Installing-it

It has source code (C++) that could assist you including functions to read TTF and TTC.

Here’s some more information:

https://www.microsoft.com/typography/otspec/otff.htm
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6.html

GetFontResourceInfo is an undocumented function. Should never use it. It also does not exist on my Windows 7. I found GetFontResourceInfoW in GDI.DLL but don’t know whether undocumented or not.

I have reference to this old solid workhorse code. I tested it after making sure that TTFontFile is assigned a valid filename in Command1_Click event.

Maybe you can find some use from this converting to Xojo.

Here you go, sorry, I’m not very good with memory blocks or pointers yet so it might need a little clean up:

[code]Public Function GetFontName(FontPath As String) as String
'http://www.undocprint.org/winspool/getfontresourceinfo
Soft Declare Function GetFontResourceInfoW Lib “gdi32.dll” (lpszFilename As WString, byref cbBuffer As UInt32, lpBuffer As Ptr, dwQueryType As UInt32) as Boolean

dim pL as UInt32 = 0
dim mb as MemoryBlock
dim mbP as Ptr

dim result as Boolean

result = GetFontResourceInfoW(FontPath, pL, Nil, 1)

if NOT result then
return “There was a problem reading the length of the name”
end if

mb = New MemoryBlock(pL)
mbP = mb

result = GetFontResourceInfoW(FontPath, pL, mbP, 1)

if NOT result then
return “There was a problem reading the name”
end if

Return mb.WString(0)
End Function[/code]

Thank you, Cho and Julian.

No problemo, I hope it works for you.

I just noticed you can actually remove all references to mbP and change mbP to mb on the 2nd call to GetFontResourceInfoW as

“A MemoryBlock can be passed in place of a Ptr when used in a Declare call.”

[quote=311133:@]No problemo, I hope it works for you.

I just noticed you can actually remove all references to mbP and change mbP to mb on the 2nd call to GetFontResourceInfoW as

“A MemoryBlock can be passed in place of a Ptr when used in a Declare call.”[/quote]

Excellent. Thank you.