Font Editor (preview #5)
Rayman
Posts: 14,652
I'm working on this font editor. It's mostly for LCD screens and LED panels.
But, I've added some options to import the font from "VGA_HiRes_Text.spin".
You can then export it and paste it back in. Run the stock "VGA_HiRes_Text_Demo" to see your font on a VGA screen.
Fonts are saved as ".rfd" files.
This program is self-contained, so just extract it anywhere and run it:
RaysFontEditor_24Aug12.zip 'Updated version 0.5
But, I've added some options to import the font from "VGA_HiRes_Text.spin".
You can then export it and paste it back in. Run the stock "VGA_HiRes_Text_Demo" to see your font on a VGA screen.
Fonts are saved as ".rfd" files.
This program is self-contained, so just extract it anywhere and run it:
RaysFontEditor_24Aug12.zip 'Updated version 0.5
Comments
I've looked at a number of font solutions. I've ended up using a free program to create a bitmap of all the fonts, then a custom vb.net program to turn that into a file that can be loaded rapidly off an sd card. It is a solution that works for any font and means you can use any font editor out there to build a new .fon file, then convert it when it is done.
Hmm - that is a bit confusing to explain. At the end of the day, it is about a 30second process to create a font file.
However I've never been entirely happy with it being in vb.net as that is not a program that can be run on linux/mac etc. Maybe we can share some code here?
This is written in MFC, so there's no way it will work on Linux (well, at least not without VirtualBox).
If you tell me about your .fon format, I can try to include that for you though.
I have been using this free program to convert true type fonts into bitmaps http://www.angelcode.com/products/bmfont/
That generates two things, a bitmap picture, and a text file that tells you where each character is in the picture. That in itself could be decoded by a spin program. However, I process that a bit more and combine them into one file which has a jump table at the beginning and also changes the foreground and background color to whatever you want. That means that you can get the pixel data for a character quickly - take the ascii value which points to the jump location in the header and the width and height and number of pixels, jump to that location, and then read off the pixels. This preprocessing makes the retrieval fast. This is the spin code to print a character:
If this is helpful I can give you the vb.net code to produce these font files.
As for editing fonts, hmm, that is a separate issue. Truetype or bitmap fonts?
Sorry about the delay. The angelcode program takes a .ttf font file and produces two files - a text file and a png graphic. I save the text files with a .fnt extension.
The png file is white on black and you can use the grayscale to convert from any foreground and any background.
I'll post the full vb.net program below, but this is the routine to load up the .png and .fnt files and draw the png on a picturebox
Then you can use a color selection box to change the colors (eg white on black to black on white).
This is the code that does the conversion
Attached are the vb.net program (in ILI9325.zip) and three font files, the .png, .fnt and the output .ifn file. The .ifn one is the one that spin code in the previous post can decode.
The font is stored as one word per pixel suitable for touchscreens ie RRRRRGGG_GGGBBBBB
The catch here is that when you store fonts as raw pixels most fonts end up 30-60k in size, and if you want to read characters quickly then you need external ram rather than reading each one off the sd card. I think you have some external ram working, is that correct?
Reading your last post, I think you want 16 bpp, but that winds up bigger than what you can hold in the Propeller...
My font editor works in 24 bpp, so it can generate the 16 bpp you want.
But, personally, I think 1 bpp is the best way to go for LCD screens, at least initially.
Small size fonts really don't get anti-aliased anyway, so you don't really gain anything in 16 bpp, except for the ClearType effect.
I do actually have some code to send out the propeller font using the more traditional method and I use that for bootup messages, in particular messages related to starting up the SD card because if the SD card is not working you can't display a font off the SD card. The catch is that it is slower.
One thing that could be possible is to take that code and turn it into pasm and then it should be a lot faster and fonts will be a lot smaller.
The angelcode font program has a checkbox for outputting aliased or non aliased fonts so we could think about non aliased fonts with 32 pixels per long and which will be 1/16th of the size compared with aliased bitmap ones. An advantage is that you could change the foreground and background colors on the fly. A disadvantage will be that the code for variable width fonts will be more complex.
Your thoughts?
http://www.mikroe.com/eng/products/view/683/glcd-font-creator/
which works with a .LCD file, in ascii format, one example, snipped for size.
Looks to store 24bpp, but as just one of two values for a Monochrome Font.
This would be a good file format to support ?
53='5', and I think this stores left-column first (ie Top-Left, DecY ,DecX order) 0=ON ?
I think I have decided that the ROM font works well on this 5" Newhaven LCD, so it may be moot there.
Still, for large text, and for reading, the cleartype effect helps a lot. I think I can do it with 4 bpp though...
jmg, that program looks a lot like what I'm trying to do... Maybe I wouldn't have done this if I'd found that one... Still, I think mine is unique in capturing the Parallax font with it's code page (I'm hoping to make an on-Prop spin editor, so I'll want that...) and also outputting to VG_HiRes_Text . That format looks fine.
http://terminus-font.sourceforge.net/
The sizes present are 6x12, 8x14, 8x16, 10x18, 10x20, 11x22, 12x24, 14x28 and 16x32.
The styles are normal and bold (except for 6x12), plus EGA/VGA-bold for 8x14 and 8x16.
I see your Font Editor imports in Pixels, or Point, whilst the glcd-font-creator I linked above, imports in Point only, and so getting the wanted Pixel XY is more of a lottery.
glcd-font-creator does have a Export Range feature, but it annoyingly lacks a Raster-Order choice (and defaults to a dY scan).
The ideal is to
* Export each Char with the Char as a comment, (allows users to cut/paste/merge)
* Give users the choice of Mirror X, Mirror Y and dX or dY raster scan exports
Most assemblers I've used support DB and DW tables, but I cannot see that mentioned in the Prop Assembler reference, it would be a useful option.
Maybe we can think about a format for fonts for the propeller?
Good idea, see the example in #10.
That is ASCII, so is easy to parse, is text editor friendly, and it has the support of a free viewer.
hehe, I think that is targeting Fixed-width LCDs, but there is nothing preventing allowing an optional field of on a per-character basis (usually only one would vary, in the plot direction, if you expected both to vary, then the issue of handling offsets occurs.
You would need to scan the file and build a separate index table if you wanted to remove the dead-space, and the Free Viewer would likely break.....
On some instances, simpler indexing might be more important than smallest size (eg Font in QuadSPI ), but for RAM hosted fonts, smallest overall footprint would be the target.
I do like the idea of an ascii readable font. For speed of processing, would you make the text for something like "width" always a fixed number of characters? That might make the conversion quicker, eg if you had leading zeros then the position of the text describing the width is always in a fixed location so you can do a simple "ascii to value" conversion.
I built a jump table at the front of the font as it makes it quicker to send out the pixels. Still, it takes about one and a half seconds to dump out all the display in this photo. I have a vague feeling that if you gave up aliasing and just went for white and black, plus a pasm driver, plus smaller font files, this could be dumped to the display quicker.
I'm not completely following the question, but assuming too much about the format can be dangerous, as it may be Auto-created.
Taking the example above, of
WIDTH="6"
Usually you would 'key' off 'WIDTH=', or perhaps even 'WIDTH="', and then trim using the next ", which should leave a number string, which could be in any base.
The time needed to work on ASCII files is not important, as you usually finally create a Table, which is then assembled/compiled.
eg the glcd-font-creator above is somewhat sluggish in load/trim/export, but 10 seconds is not a big problem.
Byte alignment (none, 1, 2, 4)
Scan direction (8 different ways)
Bits per pixel (1,4,8,24)
This is for fixed-width. For variable width, I was thinking about having all characters still taking the same # of bytes to define plus 1 byte to say the width. That way, you can quickly index the characters... But, this takes up more space than necessary, so I'm still mulling it over...
If you are looking for suggestions for your font editor, these are the 'peeves' I found with glcd-font-creator
* It lacks raster order export choices, (seems to always TopLeft, dY then dX) - needs Mirror X, Mirror Y, Scan X.Y and Y.X choices.
* It can insert/delete rows, but ONLY on the edges, so (eg) making a taller variant is more work than it should be.
Insert row/column choices of Black/White/Clone Present row would almost eliminate pixel-clicking.
* It lacks a screen-preview mode, your's is way ahead there. Allows a screen capture font thumbnail record.
Pluses :
It has a simple ASCII file, so a user can always add external code to fix some of this.
Sounds great. When you say 'binary' do you mean ASM type source ?
There, I would add each Char value as a comment, and allow DB 12H,34H,... and DW 1234H,5678H, ... syntax.
I've struck some assemblers that choke above some line-length, so an ASM line length option would fix that.
ie if practical I prefer one line per char, but larger fonts, and Colour, will give long lines.
Perhaps an option ? As you say, Fixed is simpler and Serial flash is dirt cheap, but someone may want to target RAM use, and RAM is precious indeed on a Prop.
The most compact would be a separate byte-sized width table, and you simply run through that, adding the widths to find your packed Char index. Code to run-sum should be << the alternative N.Words index array.
Or maybe all 3 : Simple/Compact/Fast, but that may be over-doing a font editor... ?
One that you can include in Prop Tool like this:
I do like that XML output format, BTW. I also like the idea of defining a range of characters to output.
In some cases, you might only want to define the "normal" characters...
So that is an ASM source file ? - like you export now as :
So I would suggest also doing what we do here, which is Asm DB, with ASM comments like : The AsciiArt is what you expect to see, the DB may be bit-flipped
( with perhaps DW option, but then an endian choice may be needed...)
This would allow using almost any assembler to create large hex files for Font ROMs
Yes, and in other cases, you may wish to merge fonts from multiple archives/sources...
WIDTH=6
HEIGHT=12
then if you have a bigger font
WIDTH=15
HEIGHT=12
the position of "H" changes and then you have to search for a string which takes more time. I was thinking you write
WIDTH=06
HEIGHT=12
and then H is always in the same place in the file.
Another idea - instead of writing in longs, what about writing in binary. Assume all fonts will be less than 32 wide (probably true). Ok it wastes a bit of memory for small fonts but it very much simplifies both editing and processing. eg an A
binary output means that for, e.g., this 8x16 x 1bpp font, the first 16 bytes in the file represent the 1st character...
but why work in hard-to--check binary, given you import into a compiler, or assembler, anyway, to create the full run-time ?
( or assemble multiple files to a HEX file for loading a Font-rom).
I'm not following the issue here ?
On a PC, who cares how many microseconds a string search adds ?
On the target, you would not work with full ASCII-parser record files, you would use equates, or DB/long arrays, and even there
the source-file size is a total 'don't care' these days, so I create for clarity.
And for more efficiency regarding file size, maybe have two file types - one for "bytes" and one for "longs", ie ones that are 1-8 pixels wide and ones that are more than 8 pixels wide? Then you could display both in a way that you can edit easily as you can see the pixels.
ah - miscommunication there, I was thinking you wanted an ascii file on the target.
Many possibilities here. I wonder if one solution is to produce an ascii file that is actually code you can paste into the DAT section of code?
he he - how about a program you run on the PC that produces a spin/pasm program that contains not only the font data in a DAT section but also the code needed to process it? Then if the format of the file changes the code changes too. Crazy stuff. Quite doable of course.
I see three levels of choice :
Simplest : No tables, all chars are identical sizes and no 'gaps'. Suits serial FLASH fonts.
Compact : For variable width fonts, you need a width, but an Index table is not mandatory, you can quick-sum the width bytes.
Fastest: : Uses a Index table, and could pack Width into the Table-change, which needs a EOF entry.
This is larger, as the font index will be at least 16 bits, and could be 24 or 32 bits per character.
An index table has one other advantage, in that it allows sparse fonts - you can skip unused values, but still use an accepted/portable ASCII value index to the ones you do have. - eg A meter might support 0..9, and A,V,Hz (etc)
I'm going to have a go at writing a "True Type Font to Spin converter" when I get home. I've got this idea that the driver and the data get created at the same time. Later, if one lost the program to create the code, you could still edit a font as the code is human readable. And you could even automatically generate comments - eg your Simplest one is going to be fixed height and width so all the data is just one character after another. But if you had a variable width font, you could put in the dat section the width of the letter as a hex byte, but more importantly, you could put a comment in next to that to say what it is. So again, later you could edit this despite not having access to the code that made the program. Ditto you could edit the Spin - translate it to pasm if you wanted.
produced by this