|
|
Comments and Discussions
|
|
 |

|
If you are only interested in the general name of the font (typeface name, font family) like "Arial" and not "Arial Bold Italic" you can use the following code:
Imports System.Drawing.Text
Imports Microsoft.VisualBasic
Module StartUp
Sub Main(ByVal args As String())
MsgBox(GetFontName("C:\Temp\palabi.ttf"))
End Sub
Public Function GetFontName(ByVal aFileName As String) As String
Dim myFC As New PrivateFontCollection
Try
myFC.AddFontFile(aFileName)
Return myFC.Families(0).Name
Finally
myFC.Dispose()
End Try
End Function
End Module
But there still remains the question how to get the exact name, eg. "Palatino Linotype Bold Italic"...
Best regards
chha
|
|
|
|

|
Hi Thanks a lot for this information, it works for most of the files, when i tried for FREE3OF9.TTF it gives name as "New" when i look into fontview.exe it shows "Free 3 of 9" any idea ?
If you can post updated c# version will be very very helpful to me.
Also there is API GetFontResourceInfoW in GDI32.DLL, i am not sure how to use and what are all parameters.
Thanks in advance.
|
|
|
|

|
Hi,
For C# Solution, see one of the posts below, someone has already ported this to C#.
Not sure what is the problem with that TTF file, as I do not have it - you will have to debug it yourself
And finally for GetFontResourceInfo function - this is undocumented method. So it really depends on where you are trying to use it, because remember, any undocumented function may change at any given time, without backward compatibility. Sure this doesn't happen a lot though For example, the same FontView uses this function. If you want to use it, below is its declaration. But remember, this declaration several years old - when I was interested in it. I do not know if it has been changed or not.
DWORD GetFontResourceInfoW(
LPCWCHAR wzFontName,
DWORD dwBufSize,
LPWCHAR wzBuffer,
DWORD dwInfo);
Neither I do no recall how to use it - you will have to find out this yourself, sorry
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|
|

|
You can find the csharp implementation in the below link
http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/d3ec5763-b7e8-4a29-9c50-1d6576ae6eae
|
|
|
|

|
Hi,
I have some query related to fonts. It would be very helpful if you give me some pointers for
the fallowing querries.
1.Is there any way to check for typeface such as symbol typeface/serif/sans serif etc.
2.How to calculate baseline/baselineoffset, charwidth/MaxCharWidth?
3.How to get the font attributes such as font style, ascent, descent etc.
I tried by using WIN32 GDI API's, but not able to get the info.
--
Ganesh
|
|
|
|

|
I want to see the old comments!
Thanks.
|
|
|
|

|
With the source code you provide, is this an MFC code? Or ATL code?
I've been trying to get it to work as a basic command line application but can't get it to compile no matter which headers I include.
Any tips would be great.
|
|
|
|

|
The application is MFC based. You should replace all CFile and CString, etc., with alternatives or include MFC headers and libs in your command line application
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|

|
Thank you very, very, very much!!! it's just what I needed.
There is just a little problem... it seems that some truetype fonts store the name in unicode or some other 2 bytes per character encoding; but I think I read somewhere in the specifications that the names should be exactly the same in unicode and ansi, so it was a matter of checking and eliminate the interleaved (zero) bytes to get an ansi compatible string. There is probably some place in the file where it states the character encoding convension, but I was to lazy to check, since this little trick worked for every font file I have.
Jihodg
|
|
|
|

|
I tried to save integer 1 to the UTF16 LE file and UTF16 BE file.
UTF16 LE file shows "FF FE 00 01 00 00" as you said upper... it's okay.
But UTF16 BE file shows like below.
"FE FF 00 01 00 00"
What's wrong?
|
|
|
|

|
Can we use the GetFontData for this task. If so please help me.
Pls check the below links
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cdc.3a3a.getfontdata.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_8d7l.asp
Thanks In Advance
Rangashan
|
|
|
|

|
GetFontData works with DC, which means font has to be already installed in the system and applied to target DC, which, in turns, means you cannot use it get information about font that has not been yet installed
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|

|
Hi,
Where can i find the sample code for GetfontData?
I see the prototype in MSDN @ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_8d7l.asp
but I don't not know anything other then the first parameter,
How am i suppose to extract
the Font Face, Font Style, Font size, Font Color,Font Bck color from the 'lpvBuffer'
When I do not know the format/structure of 'lpvBuffer' .
Any help on this will be appreciated.
-Arif
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
FROM MSDN
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GetFontData
The GetFontData function retrieves font metric data for a TrueType font.
DWORD GetFontData(
HDC hdc, // handle to DC
DWORD dwTable, // metric table name
DWORD dwOffset, // offset into table
LPVOID lpvBuffer, // buffer for returned data
DWORD cbData // length of data
);
Parameters
hdc
[in] Handle to the device context.
dwTable
[in] Specifies the name of a font metric table from which the font data is to be retrieved. This parameter can identify one of the metric tables documented in the TrueType Font Files specification published by Microsoft Corporation. If this parameter is zero, the information is retrieved starting at the beginning of the file for TrueType font files or from the beginning of the data for the currently selected font for TrueType Collection files. To retrieve the data from the beginning of the file for TrueType Collection files specify 'ttcf' (0x66637474).
dwOffset
[in] Specifies the offset from the beginning of the font metric table to the location where the function should begin retrieving information. If this parameter is zero, the information is retrieved starting at the beginning of the table specified by the dwTable parameter. If this value is greater than or equal to the size of the table, an error occurs.
lpvBuffer
[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.
cbData
[in] Specifies the length, in bytes, of the information to be retrieved. If this parameter is zero, GetFontData returns the size of the data specified in the dwTable parameter.
Return Values
If the function succeeds, the return value is the number of bytes returned.
If the function fails, the return value is GDI_ERROR.
http://groups.yahoo.com/group/programmers-town/
|
|
|
|

|
Please give me some example on using GetFontData API.
|
|
|
|

|
Without reading the ttf file is there any windows API to get the Font Face name from a TTF file.
Rangashan
|
|
|
|

|
Not that I know, otherwise I wouldn't post this article
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|

|
Use undocumented font resource api which is GetFontResourceInfoW in gdi32.dll
|
|
|
|

|
Hello!
This article is very helpful! Thank you.
I've got a problem with OpenType (*.ttf). They have information at ttRecord.uNameID > 0 and <= 20 (First 7 or 8 are similar to TrueType and they can easyly be read). But I need to read information when ttRecord.uNameID is more than 7. How can I do that.
Thank you in advance.
|
|
|
|

|
I really need help in that... Does anyone know how i can use a .otf file from inside c# in order to view the font inside the application. I know that GDI+ does not support otf files, but if anyone knows a method to be called or something, that would be great. Thanks alot in advance
H Adel
|
|
|
|
|

|
This immensely helpful article insprired me to do the C# version. Not a 100% match (c++ to c#), but I am able to get a font name. For this code to work, you'll need to change where I have "C:\\jami.ttf" to a font file on your system. Thanks again Philip. #region Using directives using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO;
#endregion namespace FontNameGetter { [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_OFFSET_TABLE { public ushort uMajorVersion; public ushort uMinorVersion; public ushort uNumOfTables; public ushort uSearchRange; public ushort uEntrySelector; public ushort uRangeShift; } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_TABLE_DIRECTORY { public char szTag1; public char szTag2; public char szTag3; public char szTag4; public uint uCheckSum; //Check sum public uint uOffset; //Offset from beginning of file public uint uLength; //length of the table in bytes } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_NAME_TABLE_HEADER { public ushort uFSelector; public ushort uNRCount; public ushort uStorageOffset; } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_NAME_RECORD { public ushort uPlatformID; public ushort uEncodingID; public ushort uLanguageID; public ushort uNameID; public ushort uStringLength; public ushort uStringOffset; } partial class Form1 : Form { public Form1() { InitializeComponent(); } private TT_OFFSET_TABLE ttOffsetTable; private TT_TABLE_DIRECTORY tblDir; private TT_NAME_TABLE_HEADER ttNTHeader; private TT_NAME_RECORD ttNMRecord; private void button1_Click(object sender, EventArgs e) { FileStream fs = new FileStream("c:\\jami.ttf", FileMode.Open, FileAccess.Read); BinaryReader r = new BinaryReader(fs); byte[] buff = r.ReadBytes(Marshal.SizeOf(ttOffsetTable)); buff = BigEndian(buff); IntPtr ptr = Marshal.AllocHGlobal(buff.Length); Marshal.Copy(buff, 0x0, ptr, buff.Length); TT_OFFSET_TABLE ttResult = (TT_OFFSET_TABLE)Marshal.PtrToStructure(ptr, typeof(TT_OFFSET_TABLE)); Marshal.FreeHGlobal(ptr); //Must be maj =1 minor = 0 if (ttResult.uMajorVersion != 1 || ttResult.uMinorVersion != 0) return; bool bFound = false; TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY(); for (int i = 0; i < ttResult.uNumOfTables; i++) { byte[] bNameTable = r.ReadBytes(Marshal.SizeOf(tblDir)); IntPtr ptrName = Marshal.AllocHGlobal(bNameTable.Length); Marshal.Copy(bNameTable, 0x0, ptrName, bNameTable.Length); tbName = (TT_TABLE_DIRECTORY)Marshal.PtrToStructure(ptrName, typeof(TT_TABLE_DIRECTORY)); Marshal.FreeHGlobal(ptrName); string szName = tbName.szTag1.ToString() + tbName.szTag2.ToString() + tbName.szTag3.ToString() + tbName.szTag4.ToString(); if (szName != null) { if (szName.ToString() == "name") { bFound = true; byte [] btLength = BitConverter.GetBytes(tbName.uLength); byte [] btOffset = BitConverter.GetBytes(tbName.uOffset); Array.Reverse(btLength); Array.Reverse(btOffset); tbName.uLength = BitConverter.ToUInt32(btLength, 0); tbName.uOffset = BitConverter.ToUInt32(btOffset, 0); break; } } } if (bFound) { fs.Position = tbName.uOffset; byte[] btNTHeader = r.ReadBytes(Marshal.SizeOf(ttNTHeader)); btNTHeader = BigEndian(btNTHeader); IntPtr ptrNTHeader = Marshal.AllocHGlobal(btNTHeader.Length); Marshal.Copy(btNTHeader, 0x0, ptrNTHeader, btNTHeader.Length); TT_NAME_TABLE_HEADER ttNTResult = (TT_NAME_TABLE_HEADER)Marshal.PtrToStructure(ptrNTHeader, typeof(TT_NAME_TABLE_HEADER)); Marshal.FreeHGlobal(ptrNTHeader); bFound = false; for (int i = 0; i < ttNTResult.uNRCount; i++) { byte[] btNMRecord = r.ReadBytes(Marshal.SizeOf(ttNMRecord)); btNMRecord = BigEndian(btNMRecord); IntPtr ptrNMRecord = Marshal.AllocHGlobal(btNMRecord.Length); Marshal.Copy(btNMRecord, 0x0, ptrNMRecord, btNMRecord.Length); TT_NAME_RECORD ttNMResult = (TT_NAME_RECORD)Marshal.PtrToStructure(ptrNMRecord, typeof(TT_NAME_RECORD)); Marshal.FreeHGlobal(ptrNMRecord); if (ttNMResult.uNameID == 1) { long fPos = fs.Position; fs.Position = tbName.uOffset + ttNMResult.uStringOffset + ttNTResult.uStorageOffset; char[] szResult = r.ReadChars(ttNMResult.uStringLength); if (szResult.Length != 0) { int y = 0;//szResult now contains the font name. } } } } } private byte[] BigEndian(byte[] bLittle) { byte[] bBig = new byte[bLittle.Length]; for (int y = 0; y < (bLittle.Length-1); y += 2) { byte b1, b2; b1 = bLittle[y]; b2 = bLittle[y + 1]; bBig[y] = b2; bBig[y + 1] = b1; } return bBig; } } }
|
|
|
|

|
thank you for the information. i have a requirement of displaying all the glphys in a selected font file. Please suggest on how i could do that.
Thanks in advance
|
|
|
|

|
Thanks for the excellent work. But I have noted that it can get the font family name only. For example, it gets the same name "Arial" from arial.ttf and arialbd.ttf. How can I get the bold and italic info?
tommy
|
|
|
|

|
You must read record with uNameID=1.
Read Microsoft documentation.
Rimuk
|
|
|
|

|
Sorry,
You must read record with uNameID=2.
Read Microsoft documentation.
Rimuk
|
|
|
|

|
your article is very good. May I ask a question? I want to outline text charecters after choosing a font from the fonts common dialog; that is to have a border surronding text characters in different color ? the border of each character can be changed. How can i implement this function. Would you like helping me?
|
|
|
|

|
how to know a particular font file is a unicode font file like japanese, chinese or korean font file
|
|
|
|

|
You don't know how long I have needed this snipped of code. It seems like a terrible hole in the Windows API, considering they have functions to install a font based on its filename, but no way to determine the face name of the font you just installed.
I have hit a small snag with the code, however. Specifically, when you are reading the face name from the file, sometimes an extra character is appended to the name of the face. The problem lies with this code here:
f.Read(csTemp.GetBuffer(ttRecord.uStringLength + 1), ttRecord.uStringLength);
I was able to correct this problem as follows:
char *buf = csTemp.GetBuffer(ttRecord.uStringLength + 1);
ZeroMemory(buf, ttRecord.uStringLength + 1);
f.Read(buf, ttRecord.uStringLength);
I am sure that there is a more elegant solution, but it worked for me. Hopefully this helps you. And again, I really appreciate this code!!!!
|
|
|
|
|

|
The error is, in fact, very simple.
The string in the file isn't null-terminated. All you have to do is to insert a '\0' at the end of csTemp after reading from the file.
Therefore, a slightly simpler solution would be:
char *buf = csTemp.GetBuffer(ttRecord.uStringLength + 1);
f.Read(buf, ttRecord.uStringLength);
buf[ttRecord.uStringLength] = '\0';
though the actual perf gain is neglectible, but at least we now know what went wrong.
|
|
|
|

|
I really appreciate to you and this article author. Thank you!
|
|
|
|

|
Thanks for the good article
Samy Abdul-Rahman
Development Manager
Harf Informatiom Technology
|
|
|
|

|
You are always welcome
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|

|
This was very useful to me, I'd been staring at the Windows API trying to work out if it was possible and I was just about to resort to disecting the TTF header myself but you've saved me the bother. Yay!
|
|
|
|

|
The code was very useful ....
I have a particular application where I have to read the sample text provided with the TTF. As per the documentation i figure that this to be the string when the Name ID is 19. But when i used the code that was provided here, I saw that the Name ID contains value only up to 12.
Can you please throw some light on this subject.
|
|
|
|

|
Jiju wrote:
Name ID contains value only up to 12
You mean the length of the string is only 12? Or what? Have you tried to read the text stored in offset specified? What you get in such case?
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
|
|
|
|

|
I wanted to search this information for a long time, but didn't found the time.
You made the work for me
I immediately converted it to pure API (no MFC) and included it (the code from demo, a bit more complete) in a new FileTip module, it works perfectly!
FYI, FileTip is a useful shell extension: when the cursor hover on a file in Explorer, a tooltip appears giving informations on the file (image size, uncompressed Zip size, version information, etc.
An interesting feature is that this program accepts DLLs as plug-ins, ie. you can write your own file handler.
You can find it on the PCMag site, at http://www.pcmag.com/article/0,2997,a=12518,00.asp but you need to register ([non longer] free [alas]) to download it.
For this TTF module, I actually copied the FTI_ZipInfo module, renamed everywhere Zip to Ttf, changed a bit the resource and replaced the core code with my API version of Philip's code. And it works!
Thank you for the useful code.
--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--=#=--
Philippe Lhoste (Paris -- France)
Professional programmer and amateur artist
http://Phi.Lho.free.fr
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Explains how to retrieve a font name from TrueType or OpenType files (.ttf)
| Type | Article |
| Licence | CPOL |
| First Posted | 16 May 2002 |
| Views | 155,280 |
| Bookmarked | 30 times |
|
|