Solved

Embedding Fonts

Posted on 2002-06-18
14
741 Views
Last Modified: 2013-12-02
How does one go about embedding a font into an application, so as to make sure that it appears properly in a deployed system?  I would rather not actually install the font into the system, but would rather embed the font info within the EXE.
0
Comment
Question by:PaulKorzycki
  • 5
  • 4
  • 3
  • +2
14 Comments
 
LVL 6

Expert Comment

by:edey
ID: 7090098
I'm pretty sure that without some major surgery for all your controls you'd have to 'install' the font. OTOH is all you want is to present a single exe that doesn't need to be 'installed' you could just tack the font on the end of the exe. You'd just need a little function to read off the last x bytes (size of the font) and copy it into the font directory if the font is not already present there.

GL
Mike
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 7090147
Create a resource file:

MyFont RT_FONT lucon.ttf

Compile it and include it in your app:


{$R *.DFM}
 {$Resource z:\font.res}

procedure TForm1.Button1Click(Sender: TObject);
var resStream:TREsourcestream;
begin
   resStream:=TREsourcestream.Create(Hinstance,'MYFONT','RT_FONT');
   ResStream.SaveToFile('Z:\myfont.ttf');
   Button1.Font.Name:='z:\Myfont';
   button1.Font.size:=20;
   Showmessage(button1.font.name);
end;



and viola!

Good luck!!
0
 

Author Comment

by:PaulKorzycki
ID: 7090371
DrDelphi,

Thanks for the reply!

I've created the resource file and been able to save the resourcestream to a file, but Are you sue you can specify a filename as the font?  The font.name property specifies a Window style font, in which case I'd have to stuff it into the Windows fonts directory (I'd prefer not to).

Is there any way to specify a font by FILENAME instead of "Windows name"?

P

0
 
LVL 33

Expert Comment

by:Slick812
ID: 7090726
here's someting I used

procedure TfrmDeb.FormCreate(Sender: TObject);
var
FontList: TStringList;
begin
FontList := Screen.Fonts;


if not FontList.Find('Harrington', Index) then
    begin
    Res2 := TResourceStream.Create(hInstance, 'HARRIN', 'RT_FONT');
 try   Res2.SavetoFile(ExtractFilePath(Application.EXEName)+'haring10.ttf');
  finally
  Res2.Free;
  end;
    AddFontResource(PChar(ExtractFilePath(Application.EXEName)+'haring10.ttf'));
    SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0);
    FontAdded := True;
    end;
end;


procedure TfrmDeb.FormDestroy(Sender: TObject);
begin
if FontAdded then begin
  RemoveFontResource(PChar(ExtractFilePath(Application.EXEName)+'haring10.ttf'));
  SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0);
  if FileExists(ExtractFilePath(Application.EXEName)+'haring10.ttf') then
  DeleteFile(ExtractFilePath(Application.EXEName)+'haring10.ttf');
  end;
end;
0
 
LVL 33

Expert Comment

by:Slick812
ID: 7091722
Oh, I guess I should mention, that code was never used because of the legal issues with Font CopyRights and distribution permisions.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7092589
> Is there any way to specify a font by FILENAME instead of "Windows name"?

in Dr_Delphis example he actually sets the Font.Name property to a filename
read it again :)
0
 

Author Comment

by:PaulKorzycki
ID: 7092622
> in Dr_Delphis example he actually sets the Font.Name
> property to a filename read it again :)

Yeah, but I can't get the example to work!  I'll keep plugging.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 6

Expert Comment

by:DrDelphi
ID: 7092824
PaulKorzycki,
  There is a very good reason why it won't work for you... it doesn't work at all. Seem that when I tested this out, Windows gave me the closest font it could find to the name that I asked for.
0
 

Author Comment

by:PaulKorzycki
ID: 7092911
DrDelphi,

You were on the right track, I think but from what I've seen in other examples, you need the AddFontResource and SendMessage lines.

Even with these lines though, it doesn't work.  How does Delphi/Windows determine the font name?  I suppose it is probably embedded within the font file, right?  So if I embed 'Arial' for example, I have to refer to it as 'Arial' and not 'MyFont' even though the file I create from the resource stream is called MyFont.ttf?

I wish this were easier!
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 7093077
You're on the right track now... the font name is embedded in the font file itself. I have been able to open a TTF file in a hex editor and change it that way, but apart from that you're pretty much stuck with what the file thinks its name should be. Take a look at Slick812's example... between mine and his you should be able to work this out. I don't see any other options... of course I could be missing something....


0
 
LVL 33

Accepted Solution

by:
Slick812 earned 100 total points
ID: 7093862
Ok, some font info, - - First putting fonts in your app may give you legal problems, next if you only need the "Special" font for display - special Titles, Display additions like presentation lettering, then you should use resourse WMF files with the Words you need on those graphics. If you need this special font to be in a control (like a Rich Edit) then you might consider an alternative.

OK Font info, When you specify a font Name you could use 'u78ju6ht5" for the name and you would still get a font to use because the win system Font Mapper searches the avaiable fonts and gives you the closest match to the font creation spec that are specified (in delphi TFont all the specs are Default) so you will get MS Sans Serif unless it's a large font and it will go to a TT sans. The onlyway to use a font in a control if by having it in the system fonts. A font needs to be in the system because drawing a font is a complex operation. If you want to add a font to the system you shoud use the AddFontResource( ). As too
"Even with these lines though, it doesn't work.  
How does Delphi/Windows determine the font name?" I don't know how you got the idea that a file name has anything to do with a Font Name, but it does not. There is alot of information in a TT font file which the system has to use to draw a font on an HDC.

here's some more recent code for using a font in a control


procedure TForm1.FormCreate(Sender: TObject);
var
ResS1: TResourceStream;
FntFile: Boolean;
begin
FontAdded := False;
FntFile := True;
if Screen.Fonts.IndexOf('Park Avenue BT') = -1 then
    begin
DeleteFile(ExtractFilePath(Application.EXEName)+'park6.ttf');
    ResS1 := TResourceStream.Create(hInstance, 'PARK', 'RT_FONT');
    try
ResS1.SavetoFile(ExtractFilePath(Application.EXEName)+'park6.ttf');
      except
      FntFile := False;
      end;
    ResS1.Free;
    if Not FntFile then
    Label1.Caption := 'No Font';
    if FntFile then
    if AddFontResource(PChar(ExtractFilePath(Application.EXEName)+'park6.ttf')) <> 0 then
      begin
      SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0);
      FontAdded := True;
      Label1.Caption := 'Font Added';
      Memo1.Font.Name := 'Park Avenue BT';
     {you will have to use the system font name here and NOT the file name}
      end;
    end;
Memo1.Font.Size := 16;
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
if FontAdded then begin
RemoveFontResource(PChar(ExtractFilePath(Application.EXEName)+'park6.ttf'));
  SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0);
  end;
DeleteFile(ExtractFilePath(Application.EXEName)+'park6.ttf');
end;
0
 

Author Comment

by:PaulKorzycki
ID: 7095692
Thanks for the help Slick,

I was hoping this would be a simpler process, but I'll have to deal with it somehow.  I realize that the copyright issue is a big one.  I got the impression that the windows font name was the filename because of DrDelphi's example, as well as another example I saw on the internet.

Thanks again,
P
0
 
LVL 33

Expert Comment

by:Slick812
ID: 7099579
we gave up any hope of putting font files in the resource, instead .wmf files are created in a vector graphics program with all the text drawn on them and then displayed in a rectangle with the windows text display control background color on it (or with a bitmap background for special presentations). This looks like the text, but it is read only. You may not gain much effect by having a "Special" font in a TEdit or TMemo.
0
 

Author Comment

by:PaulKorzycki
ID: 7154346
Sorry for the delay slick, I forgot about this issue a while ago, as a result I'm giving you double the points.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

760 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

18 Experts available now in Live!

Get 1:1 Help Now