Author Topic: Bitmap-Font Maker  (Read 16717 times)

0 Members and 1 Guest are viewing this topic.

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Bitmap-Font Maker
« on: December 22, 2009 »
As a friend of mine asked for a simple way to create bitmaps from true-type-fonts, I dug out an old tool of mine - maybe it's useful for someone else, too.

What it does is rendering each character into a bitmap and tries to place them all into one map.
It creates a list with information about
  x-position
  y-position,
  width,
  height,
  offset from base-column (this is useful for serif-fonts where characters partially overlap),
  offset from base-line
  actual width required by the character (that's where the next character starts)

An extreme example of a single character stored in the map looks like this:


You can specify font, size, bitmap, spacing, number of colours and color-encoding.
There are some additional options like creating a set of required characters from the actual text and exporting image-data as ready to include source-code.

A simple heuristic tries to avoid worst-case scenarios when assembling the different character-bitmaps into a single map - but it's yet far from optimal or even clever.

Download here (3.1mb due to Qt).

Feature requests are welcome.

A very simple example how to use this with OpenGL is attached below.

Have fun.
« Last Edit: April 18, 2012 by hellfire »
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Fontmaker
« Reply #1 on: December 22, 2009 »
Very useful stuff hellfire will definately be making some use of this in future

Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1382
  • Karma: 83
    • View Profile
Re: Fontmaker
« Reply #2 on: December 22, 2009 »
These kinds of tools always fill a need. Have some karma.
Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: Fontmaker
« Reply #3 on: December 22, 2009 »
Looks like a really useful tool, thanks for sharing.

Offline Voltage

  • Professor
  • Pentium
  • *****
  • Posts: 857
  • Karma: 53
    • View Profile
Re: Fontmaker
« Reply #4 on: December 23, 2009 »
Great tool hellfire.

It has some nice features.... Generate chars list (from sentence), texture size, and the very useful char location array that goes with it.

karma++
Challenge Trophies Won:

Offline Voltage

  • Professor
  • Pentium
  • *****
  • Posts: 857
  • Karma: 53
    • View Profile
Re: Fontmaker
« Reply #5 on: December 23, 2009 »
I was able to get this working with a simple opengl texture example.

2 things though:

1) The "Save As Array" option in fontmaker doesn't add commas to the end of each line.  I had to manually add these commas.

2) I had a little bit of trouble trying to figure out which OGL settings to use to import this data as a texture.  I used the following:

Code: [Select]
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, fontdata);
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Fontmaker
« Reply #6 on: December 23, 2009 »
I usually use
Code: [Select]
glTexImage2D(
  GL_TEXTURE_2D,
  0,
  GL_ALPHA,
  sizeX,
  sizeY,
  0,
  GL_ALPHA,
  GL_UNSIGNED_BYTE,
  data);
This way all information is inside the alpha-channel so you can use proper blending and specify the color using glcolor.

In your screenshot you need to take the "baseline" parameter into account (the 7th in each row).
Postive value means up, negative value means down.
See screenshot above.
« Last Edit: December 29, 2009 by hellfire »
Challenge Trophies Won:

Offline Voltage

  • Professor
  • Pentium
  • *****
  • Posts: 857
  • Karma: 53
    • View Profile
Re: Fontmaker
« Reply #7 on: December 23, 2009 »
ah that makes sense.  I did get alpha working, but I did it an ugly way.

I created a temp buffer twice the size of the texture and...

Code: [Select]
for (i=0;i<512*512;i++) {
  buffertmp[i*2]=buffer[i];
  buffertmp[i*2+1]=buffer[i];
}

Then I used GL_RGBA and GL_LUMINANCE_AND_ALPHA (or something similar).

The method shown above(yours) is obviously cleaner.  Thanks for pointing that out.
« Last Edit: December 23, 2009 by Voltage »
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Fontmaker
« Reply #8 on: December 23, 2009 »
Well, the goal for the array-export is to keep the data as compact as posibble but still uncompressed (because thats what the exe-packer likes), so I thought it's enough to store a single channel.
If you like to store other formats I could add a selector for that.
I plan to support syntax for different languages, too.
« Last Edit: December 23, 2009 by hellfire »
Challenge Trophies Won:

Offline combatking0

  • JavaScript lives!
  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4569
  • Karma: 235
  • Retroman!
    • View Profile
    • Combat King's Barcode Battler Home
Re: Fontmaker
« Reply #9 on: December 26, 2009 »
Very nice - finally a feature-rich font editor without ads/fees/viruses. K++
You are our 9001st visitor.
Challenge Trophies Won:

Offline Voltage

  • Professor
  • Pentium
  • *****
  • Posts: 857
  • Karma: 53
    • View Profile
Re: Fontmaker
« Reply #10 on: December 27, 2009 »
ok, I got the alpha channel working as per hellfire's instructions.  And the character positions also.

thanks again hellfire. 

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Fontmaker
« Reply #11 on: December 28, 2009 »
The "l" in "reload" isn't properly centered between the "e" and the "o".
So either you didn't take the offset from the base-column into account or I didn't calculate the character-width correctly (haven't tried any font in italics so that's quite possible).
I'll have a look at that later.
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: Fontmaker
« Reply #12 on: December 28, 2009 »
^^also the m.

Cool, will give this a whirl.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Voltage

  • Professor
  • Pentium
  • *****
  • Posts: 857
  • Karma: 53
    • View Profile
Re: Fontmaker
« Reply #13 on: December 29, 2009 »
I hadn't included the column adjustments.  I have now.

I'm not using italics, the letters are spinning.  See the attached exe.

The source is a dog's breakfast at the moment.  I'll clean it up a little and post it soon.
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Fontmaker
« Reply #14 on: December 29, 2009 »
I'm not using italics, the letters are spinning.  See the attached exe.
Cool :)

Noticed that I didn't reserve enough spare-pixels when rendering fonts with extreme amount of serifs, so I added an option to select it manually - cut regions are marked with a white line.
« Last Edit: December 29, 2009 by hellfire »
Challenge Trophies Won:

Offline energy

  • Amiga 1200
  • ****
  • Posts: 280
  • Karma: 25
    • View Profile
Re: Bitmap-Font Maker
« Reply #15 on: December 30, 2009 »
Great tool ,Hellfire....
 :goodpost:
Possible to get output format for MASM???
coding: jwasm,masm
hobby: www.scd2003.de

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Bitmap-Font Maker
« Reply #16 on: December 30, 2009 »
Sure. I don't use MASM, though. So please post a syntax-example.
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Bitmap-Font Maker
« Reply #17 on: April 16, 2012 »
Added a distance field rendering option for completeness (updated download link is in post #1).
More about distance field font rendering can be found here and here.
The distance is computed on a sub-pixel-level from the anti-aliased text, so the "supersampling" should be set to 1 (otherwise it takes literally ages to compute).
The interior threshold level is 128.
« Last Edit: April 20, 2012 by hellfire »
Challenge Trophies Won:

Offline Raizor

  • Founder Member
  • Pentium
  • ********
  • Posts: 1154
  • Karma: 175
    • View Profile
Re: Bitmap-Font Maker
« Reply #18 on: April 17, 2012 »
Interesting stuff Hellfire. I've come across this concept before, but this is the first time it's actually made sense to me.

Would it be possible to generate the distance fields at runtime for use in 64k intros or suchlike? I'm just curious as to whether the code to generate the data would be significantly smaller than a 256x256 or 512x512 texture.
raizor

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Bitmap-Font Maker
« Reply #19 on: April 17, 2012 »
Would it be possible to generate the distance fields at runtime for use in 64k intros or suchlike?
The code to generate the distance field is trivial and pretty compact.
It just does a spiraling search around each pixel to find the smallest distance to the neighbouring points.
To get some better precision I do a re-vectorization of the anti-aliased bitmap using marching squares.
Otherwise (when working with whole pixel distances only) you would need to increase the rendering size drastically (which makes the search incredibly slow).
But that's because the distance-search is just a naive add-on to the regular text-rendering function of this tool.

If you'd want to create a distance texture in a 64k-intro you'd probably store your font in some vectorized format anyway.
So you can simply test each pixels distance against the surrounding edges.
Since such vector-data is probably optimized (using as few points as possible to save space), the distance check should be pretty much faster than the pixel-based approach and certainly fits into a few hundred bytes of code.

Challenge Trophies Won: