Link to home
Start Free TrialLog in
Avatar of RoboRob
RoboRob

asked on

Embedding and Extracting Fonts


I'd like to be able to embed a Windows TrueType font in a proprietary-format document. Therefore, I need to know the following:

(1) How to obtain the data for a font, given the name by which the font is registered in Windows. For example, if I specified the "Courier New" font, where would you obtain the appropriate data (as a string)? Is there a way to get the path and filename for each Windows TT font?

(2) Once the data has been stored (and later retrieved), how would you go about installing the font in Windows? The obvious idea would be to write the data to a file in the Windows font directory, then add the font programatically. However, I would prefer to create a "virtual" font that would be usable by my application only and would cease to exist once the application is finished with it.

To get a better idea of what I need to do, think about an Adobe Acrobat (PDF) file. If you create a PDF on another system and utilize a non-standard TrueType font, that font is embedded in the document. If you open (read) the PDF on another PC, it looks the same --even though you may not have that font --- because the font data is embedded within the document. I'm sure you get the idea.

What I'd really like to see is a simple application that writes a font's data to disk in a Binary file, then reads the file and creates the font on-the-fly without actually installing it in Windows.

Good luck, guys, and thanks for reading this far!

Rob Thayer
Avatar of AzraSound
AzraSound
Flag of United States of America image

I dont know about how to go about getting the structure of each TT font in Windows, but if you could get that info you might be able to implement what you are trying to achieve using the api call CreateFont or CreateFontIndirect.  Using these functions you can make a font pretty much any way you would like and use the font on your form. Just be sure to call the DeleteObject function before closing your form to free up the resources used to create the font.
Avatar of Ark
Hi
Acrobat file (PDF) is an array of pictures - ie every page is a picture. So (IMHO) the only way to create non-standart font is to draw an alphabet in .bmp format and then use ClipPicture control (or PatBlt API) to cut every letter and draw it on HDC, using BitBlt or StretchBlt if you need different font sizes.
Cheers
Avatar of RoboRob
RoboRob

ASKER


I'm not sure if I agree with you about the Acrobat files. Yes, they contain pictures, but the pages themselves are not raster images. They are a conglomeration of images, fonts, lines, etc. that are redrawn as necessary.

Also, I think you misunderstood my question about fonts. I'm not trying to create a font from scratch (I actually know how to do that). I'm trying to load and save the data for existing fonts so they can be reused on any PC without actually having to install them in Windows -- which, by the way, may lead to some licensing issues.

AzraSound had the right idea, though I was already aware of the API functions for fonts. I don't know enough about it to say for sure if that's the way to go or not, so I was hoping to see a concrete example. The Win32 API font functions are a bit confusing, no doubt about it!

Rob
it can be confusing but i think this is the way to go...there is another api call called EnumFontFamilies which used in correspondence with the CopyMemory function to store info about a font.  Perhaps by using this method you can achieve what you need.
ASKER CERTIFIED SOLUTION
Avatar of fmharr
fmharr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok I added A font to a res file Which I then added to a Project Then I used this to Make the font to my projects folder (You Can Make the Path anywhere you like)I named the Folder in the res file NEWFONT and I gave the Index number the value of 1.Now this did work for me.ANYNAMEFONT.ttf is the fonts name when your done.

In a Modual

Public Sub MakeFont(iIndex As Integer, Optional NEWFONT As String)
On Error Resume Next
Dim vAddress As String
vAddress = StrConv(LoadResData(iIndex, "NEWFONT"), vbUnicode)
Dim num%
num = FreeFile
Open App.Path & "\ANYNAMEFONT.ttf" For Binary As #num
Put #num, , vAddress
Close #num
End Sub


Ok To Call it just do this

Call Makefont (1)


I use res files to store all kinds of stuff it seems like a simple answer to your problem
Heres the Project I did On this

http://www.geocities.com/fonature1/font.zip

My Code does work the only problem is when i created the font ANYNAMEFONT.ttf
it shows up as the fonts name in the windows\font folder.so in my example project i used a existing font from my computer so when I added it to the fonts folder it showed up as the fonts name not "anynamefont" Kinda hard to explain.But what I did was get a font that wasnt on my comp and added that to the res file then when i created the font it showed up in the fonts folder.Ill upload the project to the web when i get home from work to night with the new font Called Zoomorphica.In the new project Ill put it in the      C:\windows\fonts folder.This is really easy to do.And Ill add the Kill command to kill the font when the program ends

Cheers Hope someones reading this LOL
Avatar of RoboRob

ASKER

While I do believe that FONATURE's solution would work, it requires the use of a .RES file -- something that I was trying to stay away from.

fmharr's response steered me in the right direction. The AddFontResource and RemoveFontResource are extremely easy to use, fast, and don't require the font to be "officially" added to Windows. Like he said, AddFontResource does not survive a reboot, so the font addition is temporary. Perfect!

There are only two minor downsides that I can see to this method. One is that it requires a temporary file to be created. Once the font data (basically, the contents of a .TTF file) has been extracted from the file in which it was embedded, it has to be written out to a temporary file that can be used with the two API functions. Not really a big deal, but disk access is always to be avoided if possible.

The second problem is that even once the font has been installed using the AddFontResource function, you don't know the actual name of the font (in the Windows font list). Of course, you can embed this information along with the font data, so this is also not a big deal.

The only question that remains from my original post is how to obtain the file name and path for an installed Windows font. For example, if you have a font called "OCR-A" in your font list, how would you determine the path and file name for that font?
Arent the font names generally the filename for that font as well? If so you could use this function to find the file:
http://www.vbsquare.com/tips/tip229.html

Avatar of RoboRob

ASKER

The file names CAN sometimes be similar, but not really. Consider that the Times New Roman font's file name is Times.ttf. It's all guesswork, especially when you're dealing with the billion or so non-standard fonts floating around out there.

Most font files are stored in the Windows Fonts directory, which is pretty easily figured out by using an API function to get the Windows path and appending "\Fonts\" plus the filename. It's figuring out the filename that's the hard part!

The FindFile routine mentioned by AzraSound is definitely worth noting, but (unfortunately) doesn't really apply to this situation.
i'm not sure about all fonts but i know the standard fonts have info about them stored in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts in Windows98 for example.  the names in the registry have the extension .fot but the names correspond to the actual names of the font as well as showing the values, or string, assigned to that font that users are accustomed to.  for example the registry will say something like:
Times New Roman (TrueType) TIMES.FOT
Times New Roman Bold (TrueType) TIMESBD.FOT
Times New Roman Bold Italic (TrueType) TIMESBI.FOT

Perhaps you can use the registry API calls to get this information.
Again, I dont know if every installed font is registered in this manner but it appears a great bulk of them are.
Avatar of RoboRob

ASKER

I've accepted fmharr's answer since it was the most practical to my situation and works so well. Good job!

Since AzraSound has answered the other part of my question, I'm posting a new question that will deal only with the font location issue. AzraSound, please submit an answer to that question and I'll accept it and give you 100 points.

Thanks to everyone who helped out in answering my question!

Rob