pavius.net

The Dot Factory: An LCD Font and Image Generator
Thursday, 23 July 2009 07:10

 

The Dot Factory is a small, GPL, open source tool intended to generate the required C language information to store many fonts and images, as efficiently as possible, on a microcontroller. These fonts are then uploaded via the LCD driver (see the Drivers and Modules page for a few) to the actual dot matrix LCD. It is written in C# for Visual Studio 2008 and has been tested on Windows XP, 2003, Vista and 7.

Working with dot matrix LCDs with microcontrollers, while not difficult, is tedious. The actual LCD controller allows us to upload simple visual data (dot on or dot off) into the LCD's dot matrix, but not much else. It is up to our software to decide what to upload when we want to draw lines, circles and more importantly - text. While there are software graphic libraries that allow us to generate a character "on the fly" using vector graphics (the character is described as a series of drawing commands that allow scaling and decoration) - these are much too complex and large to integrate in a microcontroller environment. Consequently, we must store the exact appearance of a character as a series of 1s and 0s, equivalent to a "dot on" "dot off" on the LCD, and upload this as a bitmap when we want to display text. While it is possible to generate this manually, it is desired to have a tool to do our grunt work by converting windows fonts (given a size and decoration) into a series of bitmaps.

Using The Dot Factory


main-screen005TDF is comprised of two panes - the input pane on the left (what you want to generate) and the output pane  on the right (the generated output, in C code). The input pane can accept either a font of your choice (for writing text to the LCD) or an image. When generating a font, you have the option of either generating all the available letters (by selecting "All" in the Insert Text box and clicking the plus button) or by typing in which letters, numbers or symbols you are actually using in your application (for example: 0123abcd). If you are writing a simple application that has only a few sentences, you can type them wholly in this box without fear of duplicating letters - TDF takes care of that by discarding any duplicates. This way only the letters you use will take up space.

Once you have completed setting up what it is you'd like to generate (be it an image or font), select the output method in the output pane. If you are using the LCD drivers on this website, you want it to generate an MSb first output, otherwise images will come out wrong. If you have a compiler that supports the "0b" binary specifier, you can select "binary" rather than "hex". This will allow you to visually see the pixels you will set and allow for manual touch up by the user without having to calculate hex and experimentation. Click generate and your C code will be outputted to the text box below. Copy paste this into your application (it is recommended to put this in a separate module, not your LCD driver module, for organizational reasons).

Note that 5x7 and 5x8 fonts cannot be generated using this tool. While some TTF fonts can render characters this small they are usually distorted to the point of uselessness. Head over the the drivers page and download the dedicated 5x7 font.

What does it generate?


For font generation, three entities are generated.
  • howtoThe character bitmap array: This holds the actual characters as a bitmap (only the characters selected in the input pane). Each byte represents a single vertical page sent to the LCD. All vertical padding is removed from the characters
  • The character descriptor array: Allows O(1) mapping between a character's ASCII value and required meta information about the character - namely its width in bits and its offset into the character bitmap array. When the LCD driver needs to find where character X is located in the bitmap array, it will jump to index [X - font.startCharacter] in the descriptor array. The startCharacter is the first character (that is, the character with the lowest ASCII value) used for this font. By defining a startCharacter we can reduce the number of elements in the descriptor array.
  • The font information: This element is essentially the font descriptor for this font. It holds information regarding this font like the name of the character bitmap and descriptor arrays, the font start character and how many pixels wide a space character is for this font. The LCD driver will replace the space character with empty pixels (this saves both processing time, space in the character bitmap array and space in the character descriptor array - since the space is the first ASCII character and is commonly used).

The generated structures are generated with documentation, but you may want to see the bitmapDb header file in the drivers page for detailed info on the character descriptor array and font information structures.

For image generation, only the image's bitmap array and size descriptors are generated. Note that the height value is pixels (bits) and width values are in pages.

Revision History


  • Version 0.0.9 (06jun10): Fixed a bug that prevents the space character from being generated (broken in 0.0.8 - thanks Thomas Kibalo)
  • Version 0.0.8 (29may10): Fixed two unreported crashes (clicking generate without entering any text and when a newline existed in generated text), added the ability to copy the outputted text by using a context menu
  • Version 0.0.7 (28may10): Added ability to select whether character descriptor array is to be created and which character will be used to visualize the font (thanks Christian Treczoks), syntax coloring automatically disabled when generating large amounts of text (will be fixed properly next version), properly handled bitmaps with no black pixels in them (displays error instead of a crash), some minor cosmetics
  • Version 0.0.6 (03mar10): Bug fix for image generation (tried to save a temporary file for debugging in a custom directory) - thanks to Nir Shemesh for pointhing this out!
  • Version 0.0.5 (23dec09): Added support for rotation (90 degree increments), space character generation, width (bit/byte) selection of character width and font height, optional generation of character height/width and font height, structures are now generated with documention, input text and font is persisted throughout invokations of the application, persistent preset management - add, edit, delete output configuration presets
  • Version 0.0.4 (31jul09): Added a space to end of comments in the char descriptor array to prevent preprocessor misinterpreting '\' as a newline
  • Version 0.0.3 (30jul09): Added output configuration: hex/binary, MSb First/LSb first, configurable padding removal, comment control, flip X/Y and more
  • Version 0.0.2 (28jul09): Vista support
  • Version 0.0.1 (25jul09): Initial release (flip not supported, output format not supported, not tested on Vista)

Future features


I'm trying to get TDF to a point where it will be flexible enough to generate most of the formats people need (this will, of course, take time). Since I am not familiar with all possible formats, I will need your help. If you'd like to suggest an output format, drop me a line and I will try to make sense of it.

  • Select between generating pages from rows or columns (to allow more efficient 0/180 degree encoding) - as suggested by Darcy
  • unicodeUnicode support (your input required!): Today TDF can generate unicode, but does not generate a proper lookup table in most cases. For example, if you would generate a few letters in hebrew everything would work fine. However, should you also like a character like "." (a dot) - the character descriptor array would become huge; mostly containing empty records but still allowing for direct lookup. This, of course, is bad. Since I haven't yet needed Unicode in my applications, I can only theorize what would be suitable and need your input on this. My idea is based on the assumption that when using Unicode you would use two or more ranges - the actual character range (the letters in your language's alphabet which usually have a very high 16 bit value) and special characters like dot, comma, etc which usually have a very low value. This means that in the real world you would have at least two consecutive blocks of characters - one for the "special" characters and one for each alphabet you use. Therefore, my suggestion for solving this is to create a character descriptor array for each consecutive block and have a new array generated that would allow you to first map the character to its character descriptor array. This means you have an O(N) lookup to find the descriptor array (where N equals the number of character descriptor blocks, usually 2 but probably not more than 10) and then an O(1) to find the descriptor for this character. Let me know what you think.

Downloads


To run this executable, you must have the .NET framework installed. The stable binary has been in the wild for a month at least with no major bugs reported. Non stable binary contains new features and bug fixes (see revision history). Please mail me with any bugs and feature requests via the contact page.
 

Comments 

 
# -jmg 2010-02-24 09:31
If you are looking for formats to support, I'd suggest BDF, as fontforge and others can read/write that, and it is also easy to script-massage to custom ASM formats.

[eg we are going to store Fonts as array-strips, for faster readout. Not as readable, but the same size tables, and smaller/faster runtime code ]

http://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format
Reply | Reply with quote | Quote
 
 
# BDFEran 2010-02-25 08:22
Seems like an interesting and easy to output format, but I am wondering who would use it and in which scenario? I'm guessing that most, if not all, use cases of TDF are to generate information so that text can be written on dot matrix LCDs with no second step or processing on the outputted data - just directly work on the outputted arrays in the LCD driver.

If TDF were to generate BDF, how would this contribute to said scenario? I would be happy to understand this further.

I also fixed the split links - thanks a bunch for the input and heads up!
Reply | Reply with quote | Quote
 
 
# RE: The Dot Factory: An LCD Font and Image Generatorjmg 2010-02-24 22:53
The link to source above, is strangely split.
Some places it is
http://www.pavius.net/bin/TheDotFactory-src-0.0.5.7z
but under 'stable' it says
http://www.pavius.net/bin/TheDotFactory-0.0.5.7z
Reply | Reply with quote | Quote
 
 
# Error creating imageJochem 2010-05-07 05:52
Crashes on certain JPG files, error is in dutch, sorry.. Basically it says the rectangle cannot have a width or height of 0. (And I guess the height can't be negative as well..)

System.ArgumentExcepti on: Rechthoek {X=0,Y=720,Width=0,Height=-720} kan geen breedte of hoogte van 0 hebben.
bij System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)
bij TheDotFactory.MainForm.manipulateBitma p(Bitmap bitmapOriginal, BitmapBorder tightestCommonB order, Bitmap& bitmapManipulat ed, Int32 minWidth, Int32 minHeight)
bij TheDotFactory.MainForm.generateOutputF orImage(Bitmap& bitmapOriginal, String& resultTextSourc e, String& resultTextHeade r)

[...] etcetera (comment too long for this box)
Reply | Reply with quote | Quote
 
 
# this imageJochem 2010-05-07 05:55
Among others, this jpeg generates the error:
http://www.broodjesexpress.nl/shop_2006/media/blikje-chocomel.jpg
Reply | Reply with quote | Quote
 
 
# Thanks for the reportEran 2010-05-10 06:08
I'll look at it once i return home in a few days [Update: fixed in 0.0.7]
Reply | Reply with quote | Quote
 
 
# Character descriptorscanosso 2010-05-16 16:05
Hello,
is it possible to switch of the Character descriptors?
If you want to convert single Chinese chars, the whole unicode table of chines chars will be loaded and the programm hangs up.
Reply | Reply with quote | Quote
 
 
# Syntax coloring issueEran 2010-05-16 18:36
This is a known issue with 0.0.6 and will be addressed in 0.0.7. The problem is with the syntax coloring (the lookup table is huge and takes time to color code the outputted text).

If you'd like, you can replace the call to outputSyntaxCol oredString to simply set the text directly to the text box; this overrides this issue
Reply | Reply with quote | Quote
 
 
# Sorry, the FONT_CHAR_INFO is a problemcanosso 2010-05-16 19:08
If I only input e.g. ?????? in the text field, the whole table of Cyrillic chars will be generated in FONT_CHAR_INFO. If is possible to generate only a table of the chars, it would be nice.

It is great piece of software you made. Thank you.
Reply | Reply with quote | Quote
 
 
# YepEran 2010-05-16 19:19
The "hanging" problem is the syntax coloring but there still remains an issue with what to generate in the FONT_CHAR_INFO lookup array.

I still need to look at what exactly can be generated to allow effective lookup for Unicode characters. Since they are not sequential in their value, an array is not acceptable.
Reply | Reply with quote | Quote
 
 
# Just Perfect.SpiralBrain 2010-08-18 08:04
Brilliant piece of software. Thanks Eran!
wonder if there is a way to add custom c syntax.


http://sunbizhosting.co.uk/~spiral/
Reply | Reply with quote | Quote
 

Add comment

Security code
Refresh