fontcreator GLCD font format seems really odd.

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I've been playing with various fonts on a ks0108 GLCD.
I've seen that font header files created by Fabien Maximilian Thiele's fontcreator are pretty popular/common but the data format chosen for font heights that are not multiples of 8 seems to be odd and suboptimal.

I'm wondering if there was some specific reasoning for using this format that I'm not seeing/understanding.

The ks0108 chip wants to write data in 8 bit pages with the bits starting at the top and
increasing vertically down.
i.e. bit 0 is above bit 1 and bit 7 is the bottom of the 8 bit page/column.

fontcreator creates a nice avr gcc style header file that can be used and does order the bits in the correct order for easy access when using vertical 8 bit pages - most of the time.

The issue I'm seeing is that when the font is not a multiple of 8 bits in height, the fractional left over bits are in the least significant bits rather than most significant bits.

While doing it this way can be made to work,
it greatly complicates and slows down the code.

For example, suppose you have a 6x10 font.
(6 wide by 10 tall)
Something like a which fills all 60 pixels would take 12 bytes.
2 rows of six bytes, where the top
row of six bytes would contain the upper 8 horizontal lines of pixels and the bottom row of six bytes would contain the 2 bottom horizontal lines of pixels with 5 unused bits of padding.
The top row of six bytes is all 0xff as expected, but lower row of six bytes is 0xc0 rather than 0x03

It is like font bits are pushed into the font data bytes from MSB to LSB rather than building the byte by dropping in the bits starting in bit 0 up to bit 7.

When you have fractional bytes being used,
essentially what happens is that all the unused bits are left down at the LSB end of the byte. i.e the pad/unused bits are down low instead of up high in the byte.

This really complicates writing the character font data to the LCD as it is not in "normal" bitmap format and you have to run-time calculate the amount of right shift needed on the font data.

If it were in normal bitmap format, you could simply use normal bitmap drawing routines to draw characters just like any other bitmap.

This can be worked around by having special character font drawing routines that account for this run-time detect how much to shift the data to the right as needed. All the sample libraries that I've seen (including Thiele's) have special code to deal with the bottom/last byte for partial bytes.

However, all of these special font drawing routines I've seen, have errors in them and don't work properly when the fonts are not multiples of 8 bits in height. They don't properly treat the character as a bitmap and end up improperly rounding vertical/Y addresses to page boundaries and stomp on pixel data beyond the lower edge of the font.

Yes, this too can also be fixed with additional code.

But if the font data bytes were created with the pad bits in the upper bits rather than the lower bits, things could be simpler, and the special font drawing and all the PITA code and exceptions for the padding bits could go away.

To me it seems odd to burden run-time code with additional calculations that could be eliminated by changing the format of the static data.

Maybe its the way I'm looking at things related to how the ks0108 works, but it would seem better if the pad bits were moved to the upper bits rather than the lower bits.

Has anyone else seen this, or am I the only "crazy" one?

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
To me it seems odd to burden run-time code with additional calculations that could be eliminated by changing the format of the static data.

Just write a little quick'n'dirty program on your PC to alter the static data into the static data format of your choice.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Definitely possible, but that's such a kludge and the "fixups" never end. It has to be done each and every time a new font header file is created.

So yes, I could whip up some awk or perl scripts and hack the fontcreator header files, but I was really kind of wondering what other folks are doing before I headed down that path.

If nobody has any better alternatives,
I'll probably end up delving into the actual fontcreator JAVA code to see if I can fix it to generate the better format, along with some options to add some alternate formats like having an offset table for each character so that you don't have to run-time search through the entire list of font sizes for all the preceding ascii characters, each time you print a character just to figure out where the font data for that character starts.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Honestly, I think that is your best option.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok,
So I decided to try to fix the java to eliminate the issue once and for all as my first experience with java.
Turns out to be a very quick patch - even for a guy with zero java experience.
A quick update to my linux box to get the development tools in place and its all working now.

Codebase I started with:
http://www.mikrocontroller.net/attachment/22095/GLCDFontCreator2.zip

Here is the patch. It was just as I had suspected.
The data bytes were shifted in starting at bit 7 rather then dropping them in starting at bit 0.

Change these lines in FontExport.java:

data = 0;
for(int l=0; l<8 && l+j*8>= 1;
    data |= p<<7;
}

with this code:

data = 0;
for(int l=0; l<8 && l+j*8

The choice of lower case "L" for a variable was unfortunate in this code as it makes it very confusing because it looks so similar to "1".

The upper code is shifting a data to the right "1" (one) time.
The lower code is shifting pixel bit to the left "L" times.

Now that the font data is in this format, lots of things get simpler and become possible. It does require changing the graphical "putchar()" function, but it reduces
to a draw bitmap function.

If anybody has current contact information for Fabian Thiele or where there is an "official" fontcreator repository. I'd be willing to generate formal patches.

I've also got a few changes planned to allow the tool to generate its structure declaration with ifdefs to allow the font header files to automatically detect different compilers.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hehehe, yep... one of the advantages of being well versed in C is that you can usually kludge your away around many other languages, as they tend to be based on C somewhat.

Great work!

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For those that are still interested
I've been digging a little deeper, and it appears that Thiele's data format was inspired by Adobe's BDF format:
http://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format

It defines how character glyph data is stored. It defines how to pad the pixel data bytes when font sizes are not multiples of 8.

The difference is that Adobe's rastor format paints pixels left to right horizontally msb to lsb.
Moving left to right, Bit 7 is the first bit painted followed by bit 6, .... to bit 0.
Because they paint msb to lsb if you have a glyph that isn't a width that is multiple of a byte you want the pad bits pushed to the lsb side of the byte.
This allows you to paint pixels on a line starting with bit 7 byte by byte and then simply stop when you reach the right most position.

ks0108 GLCD memory doesn't work this way.
A byte paints 8 pixels vertically.
However, the big difference is that ks0108 memory paints the dots from lsb to msb. i.e. bit 0 is above bit 1 and bit 7 is the bottom of the 8 dots. It also advances through memory addresses perpendicular to the direction that pixels are painted.
So the fastest way to paint memory is horizontally in 8 pixel "pages".

To account for this difference, the font data can easily be stored rotated to make painting characters easier/faster. Which is what fontcreator does.

However, there is still the difference of lsb to msb vs msb to lsb pixel ordering when padding bytes.

To keep things simpler and make character glyphs look like ordinary bitmaps, I believe that Pad bits should always be pushed toward the end of the byte that is painted with the highest pixel address.

Because of this, I believe that you really don't want to push the pad bits to the lsb end the way Adobe's BDF defines it when rotating font data for a ks0108.

The tiny patch I posted ealier puts the pad bits at the msb end of the data bytes.

--------------------------------------------
Another odd thing I noticed is that
the size field (first 2 bytes) of the data is obviously not being used by anyone as they are currently incorrect. The calculation for this value is incorrect. Part of the calculation is using bits and part is using bytes so the final number is not very useful.

Since it's not being used, a better use of the 2 bytes would be for a signature that indicates the format of the font data.

-------------------------------------------

I looked at the site where fontcreator2 was hosted for some fontcreator2 contact information.
http://www.mikrocontroller.net/

But I'm limited to the english portions of the sited and forums as I don't speak any german.

Maybe if someone else is able to locate an author or maintainer of the code, I could propose some updates/patches for it.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But I'm limited to the english portions of the sited and forums as I don't speak any german.

While not perfect - did you try Google?

http://translate.google.co.uk/tr...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Bill,

I am interested in following your progress with a ks0108 friendly version of FontCreator. I am using Maximilian Thiele's code in the KS0108 library I have published in the Arduino wiki and it would certainly make the font routines more robust if fontCreator produced headers that were easier to handle.

Have you published the patched fontCreator code?

Michael