Solved

Embedding and Extracting Fonts

Posted on 2000-03-17
13
411 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 28

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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 

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

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

749 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