How to embed fonts into your Windows programs. Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Dark Alchemist
Super wx Problem Solver
Super wx Problem Solver
Posts: 347
Joined: Wed Nov 02, 2005 10:33 am

How to embed fonts into your Windows programs.

Post by Dark Alchemist »

Just thought I would let others know of this since I have seen a few questions asking about this over the years and having just figured this out myself.

First take a program that converts any binary to C (bin2c but I wrote my own for inhouse work) and write out your binary into C code (unsigned char).

Make sure you know the real font's name because Windows isn't going to let you write in the font if you don't know its real name.

Now with that done and having the info ready here is the magical Windows' code

Code: Select all

    DWORD nFonts;
    size_t len = sizeof(FONT_FROM_THE_C_FILE_WE_CONVERTED);
    void *data = NAME_OF_THE_FONT_FROM_THE_C_FILE_WE_CONVERTED;
    
    void *m_fonthandle = AddFontMemResourceEx(data, len, NULL, &nFonts);
    if(m_fonthandle==0)
	wxLogError("Font add failed.");
You should call RemoveFontMemResourceEx before the application exits to be on the safe side but the system should unload the font even if you don't call RemoveFontMemResourceEx but always better to be safe and just call it (it uses the same info we fed into the AddFontMemResourceEX).

Basically, I just write out the binary of the .ttf into an unsigned char that gets placed into a .cpp file then I include that inside my main .cpp so that my application will then have the font embedded into it and I don't need it on the end user's hard drive nor in a cumbersome resource.

I hope this helps someone out there. :)
Azagaros
Experienced Solver
Experienced Solver
Posts: 59
Joined: Sat Feb 20, 2010 6:26 pm

Post by Azagaros »

You can't embed a font in a app. You can link the file to a binary and have extraction routine in you app. However on windows installing the font with out user rights might be a little bit of a problem, and accessing it from the install directory might cause problems. Not to mention extracting it to fill might raise a few red flags on a virus scanner.

An easier solution would be to convert to bitmaps and embed in your app, it wouldn't cause the same issues on the user side but it makes programming a little harder.

The easiest solution is ship the font in installation packages and stop being so protective of your font. I download many freely out there.

food for thought
17+ years of c++, currently open watcom and wxWidgets, MFC experience. C::B user.
The world begins again. Are you going to be one of the 2 billion left?
Dark Alchemist
Super wx Problem Solver
Super wx Problem Solver
Posts: 347
Joined: Wed Nov 02, 2005 10:33 am

Post by Dark Alchemist »

Azagaros wrote:You can't embed a font in a app. You can link the file to a binary and have extraction routine in you app. However on windows installing the font with out user rights might be a little bit of a problem, and accessing it from the install directory might cause problems. Not to mention extracting it to fill might raise a few red flags on a virus scanner.

An easier solution would be to convert to bitmaps and embed in your app, it wouldn't cause the same issues on the user side but it makes programming a little harder.

The easiest solution is ship the font in installation packages and stop being so protective of your font. I download many freely out there.

food for thought
My application works on W7, Vista and XP and not a single user has said they even had a prompt complaining or that they can't see the font. I am installing nothing on their machine which is why I like doing it like this (I hate resources for the last 10 years I have been using MSVC) because I have some really idiotic users that will snap me in my butt due their own ineptness from saying no to copying anything. :/

Basically the font lives for as long as my program is running and (according to MSDN) it can't be used by any other applications.

To be honest I am doing absolutely nothing differently from using the resource (this is why the resource commands exists) except I am not using MSVC's resource I am using my code. It is done exactly as people do to load up built in bitmaps, jpgs, pngs, etc...

The thing is Microsoft put in the functionality with the LoadResource stuff, and I am doing nothing differently than they do except mine is more raw and because of that I eliminate one or two lines of code plus the headaches associated with resources in general.
User avatar
Deluge
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Apr 30, 2010 4:52 am
Location: USA
Contact:

Re: How to embed fonts into your Windows programs.

Post by Deluge »

Thank you Dark Alchemist. This worked for me. I had also tried using AddFontResource, but couldn't get that one to work. I like this better anyway because the font is actually embedded into the executable.

For anyone using wxWidgets 3.1.1, the static method wxFont::AddPrivateFont has been added. Unfortunately, I don't think it allows loading embedded fonts from memory. It has to be an external file. And I think it only supports TrueType fonts.

At the time of writing this, 3.1 isn't considered the stable branch. My system (Windows w/ MSYS2/MinGW) only has 3.0.4 available.

--- Edit ---

FYI, I used Binary to Header to create the resource (plugging my own little app ;)).
Projects:
Debreate
MyABCs
Stendhal

OSes:
Windows 10 Home (missing my Linux & Freebsd :()
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: How to embed fonts into your Windows programs.

Post by ONEEYEMAN »

Hi,
If you use latest release of wxWidgets you can add the user defined font to your program by loading it.

There was a very old thread which was updated yesterday.

I'm not sure whether this functionality is cross-platform or not.

Thank you.
User avatar
Asimov
Earned some good credits
Earned some good credits
Posts: 146
Joined: Tue Nov 17, 2020 6:43 pm

Re: How to embed fonts into your Windows programs.

Post by Asimov »

Hi all,

Just want to add my little it to this as I just got it working with bin2c.
Just thought I would mention a couple of things that happened while I was using this method.
So in bin2c you just run the command
bin2c.exe -o "font.h" font.ttf
and it makes a header file which you can include.

Because I used bin2c you don't need to check for size, as it has it in the header. The only problem I had was that after converting using bin2c you get this.

Code: Select all

const long int font_ttf_size = 77832;
const unsigned char font_ttf[77832] = {
    0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70, 0x44, 0x53, 0x49, 0x47,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4F, 0x53, 0x2F, 0x32,
So when you run the code above you get an error cannot convert from const to void.

So all I did was to remove the const

Code: Select all

const long int font_ttf_size = 77832;
unsigned char font_ttf[77832] = {
    0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70, 0x44, 0x53, 0x49, 0x47,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4F, 0x53, 0x2F, 0x32,
like this, and because the filesize is already in a variable I run the above code like this, after including it. It also works static so you only have to include it in main.

Code: Select all

size_t len = font_ttf_size;
void *data = font_ttf;
void *m_fonthandle = AddFontMemResourceEx(data, len, NULL, &nFonts);
if(m_fonthandle==0)
        wxLogError("Font add failed.");
Thankyou Dark Alchemist.

regards
Asimov
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to embed fonts into your Windows programs.

Post by doublemax »

bin2c is not necessary. You can put the font file as binary into the resource and use it from there.

https://docs.wxwidgets.org/trunk/group_ ... 60741476bb
Use the source, Luke!
User avatar
Asimov
Earned some good credits
Earned some good credits
Posts: 146
Joined: Tue Nov 17, 2020 6:43 pm

Re: How to embed fonts into your Windows programs.

Post by Asimov »

Hi doublemax,

Tried it that way, but doesn't seem to work.
Added the font to my resource file like this

Code: Select all

MYFONT RCDATA "rc/Key.ttf"
Then I run the new line like this.

Code: Select all

void *m_fonthandle = wxLoadUserResource(wxT("MYFONT"),wxT("TEXT"),0);
    if(m_fonthandle==0)
        wxLogError("Font add failed.");
However I got an error that the font was not found, and at that point I gave up LOL

regards
Asimov
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to embed fonts into your Windows programs.

Post by doublemax »

However I got an error that the font was not found
At runtime or at compile time? Was the path to the font file correct?

This worked for me.

Code: Select all

MYFONT BINARY "Key.ttf"

Code: Select all

void *fontmem = wxLoadUserResource(wxT("MYFONT"), wxT("BINARY"), 0);
wxLogMessage("font %p", fontmem);
delete [] fontmem;
Use the source, Luke!
User avatar
Asimov
Earned some good credits
Earned some good credits
Posts: 146
Joined: Tue Nov 17, 2020 6:43 pm

Re: How to embed fonts into your Windows programs.

Post by Asimov »

Hi doublemax,

Well I should have had a lowercase K, but put it right and tried your code, however I get this.
fonty.png
fonty.png (3.22 KiB) Viewed 3080 times
I am using the very latest wxWidgets 3.1.4

I know the path is correct because I have a folder called rc where I put all my resource files.

PS.so after trying it and failing I also stuck the font in resource hacker and output a bin file, which is what I do with all my files, and it still won't work. For instance this is my resource file.
aaaaab ICON "rc/rs.ico"
#include "wx/msw/wx.rc"
ARROW-DOWN RCDATA "rc/ARROW-DOWN.bin"
aaaaab ICON "rc/rs.ico"
#include "wx/msw/wx.rc"

ARROW-DOWN RCDATA "rc/ARROW-DOWN.bin"
ARROW-UP RCDATA "rc/ARROW-UP.bin"
CREATE RCDATA "rc/CREATE.bin"
DELETE RCDATA "rc/DELETE.bin"
UPDATE RCDATA "rc/UPDATE.bin"
HELPIC RCDATA "rc/HELP.bin"
EXIT RCDATA "rc/EXIT.bin"
INSTRUCTION RCDATA "rc/INSTRUCTION.bin"
INSMENU RCDATA "rc/INSMENU.bin"
ASITRON RCDATA "rc/ASITRON.bin"
MYFONT BINARY "rc/KEY.bin"
So I have tried it with MYFONT BINARY "rc/key.ttf" which is the original font, and I have also tried it from resource hacker which is what I use to build all my resource files, and it doesn't work for me so far

regards
Asimov
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to embed fonts into your Windows programs.

Post by doublemax »

I had a typo in my code where it said "MYFONT " (trailing space) instead of ""MYFONT". Did you fix that?

If that's not it, i don't know why it doesn't work for you.
Use the source, Luke!
User avatar
Asimov
Earned some good credits
Earned some good credits
Posts: 146
Joined: Tue Nov 17, 2020 6:43 pm

Re: How to embed fonts into your Windows programs.

Post by Asimov »

Hi doublemax,

Now it seems to be working but my font is not showing
Now I get font 034b5588 and I tried it with key.ttf and my KEY.bin

So I get the same code coming up,but my font does not show.

Code: Select all

void *fontmem = wxLoadUserResource(wxT("MYFONT"), wxT("BINARY"), 0);
wxLogMessage("font %p", fontmem);
delete [] fontmem;
You were right about the space.

So I set up my font with

Code: Select all

wxFont myFont;
and then I load my font in my constructor.

Code: Select all

 myFont = wxFont(wxFontInfo(20).FaceName("Keystroke"));
So it looks like it is workng,cos I get a hex code coming back,but my font doesn't show up.
Never mind, I can still get it working the other way for now.

It is a shame, but it is just one more step to convert it to a header file

Ps. Also tried removing the delete line in case it was deleting my font too..

regards
Asimov
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to embed fonts into your Windows programs.

Post by doublemax »

That code was only to demonstrate how to access the font data from a resource. It did not install the font. You still need the code part with AddFontMemResourceEx from further above.
Use the source, Luke!
User avatar
Asimov
Earned some good credits
Earned some good credits
Posts: 146
Joined: Tue Nov 17, 2020 6:43 pm

Re: How to embed fonts into your Windows programs.

Post by Asimov »

Hi doublemax,

Obviously I am doing something wrong, cos I still get font not found.

Code: Select all

void *fontmem = wxLoadUserResource(wxT("MYFONT"), wxT("BINARY"), 0);
wxLogMessage("font %p", fontmem);
//delete [] fontmem;
DWORD nFonts;
size_t len = sizeof(fontmem);
void *data = fontmem;
void *m_fonthandle = AddFontMemResourceEx(data, len, NULL, &nFonts);
if(m_fonthandle==0)
	wxLogError("Font add failed.");
I am beginning to wonder if the header file method was easier LOL.

regards
Asimov
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to embed fonts into your Windows programs.

Post by doublemax »

Code: Select all

size_t len = sizeof(fontmem);
That of course can't work.

Code: Select all

int size;
void *fontmem = wxLoadUserResource(wxT("MYFONT"), wxT("BINARY"), &size);
Try with the size filled in by the wxLoadUserResource call.
Use the source, Luke!
Post Reply