Solved

Embedding and Extracting Fonts

Posted on 2000-03-17
13
403 Views
Last Modified: 2013-12-03

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
0
Comment
Question by:RoboRob
  • 4
  • 4
  • 3
  • +2
13 Comments
 
LVL 28

Expert Comment

by:AzraSound
ID: 2629540
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.
0
 
LVL 27

Expert Comment

by:Ark
ID: 2630156
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
0
 

Author Comment

by:RoboRob
ID: 2630277

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
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2630444
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.
0
 

Accepted Solution

by:
fmharr earned 200 total points
ID: 2630478
By using the AddFontResource WinAPI call.  Any font file on your harddrive can be added to windows (you don't have to add it to windows/font directory for this to work).

Once it is added, you access it just as you would any other font.

use RemoveFontResource to remove it from the system.  

AddFontResource is not permanent and does not survive a reboot!

The syntac for these commands are:

AddFontResourceA("c:\MyFont.tt")
RemoveFontResourceA("c:\MyFont.tt")

The declares are:

Public Declare Function AddFontResource Lib "gdi32" Alias "AddFontResourceA" (ByVal lpFileName As String) As Long

Public Declare Function RemoveFontResource Lib "gdi32" Alias "RemoveFontResourceA" (ByVal lpFileName As String) As Long

Hope this helps.  I have used these commands in VC++ but not in VB.

You can keep the font in the same directory as your exe, It does not even have to have the tt font extension to work!
0
 

Expert Comment

by:FONATURE
ID: 2630719
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
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Expert Comment

by:FONATURE
ID: 2630739
Heres the Project I did On this

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

0
 

Expert Comment

by:FONATURE
ID: 2632260
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
0
 

Author Comment

by:RoboRob
ID: 2632459
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?
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2632859
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

0
 

Author Comment

by:RoboRob
ID: 2632886
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.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2632963
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.
0
 

Author Comment

by:RoboRob
ID: 2632985
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
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now