MonoGlyph project - monospaced bitmap fonts for C!

I'm working on this project, and I needed an scalable method for including bitmap fonts in the future, for any language that I might need. Then I started this project "MonoGlyph" (like, 2 hours ago).

In short words, it's a Lua script, that you provide a PNG file containing the characters, and a text file containing the same characters. The script converts everything to a C header file, which contains the RGBA pixels of the image, the glyphs (with Unicode codepoint, and location on the image).

Project link: https://github.com/ferreiradaselva/monoglyph

"But, there's only one font in the repository!" The objective is: if more people contribute, that could be a big database of monospaced bitmap fonts, easily accessible from C.

Example

This image:


This text file:
1
2
3
4
5
6
 !"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]_a
bcdefghijklmnopq
rstuvwxyz{|}


And this command:
1
2
3
4
5
lua generate.lua /absolute/path/monoglyph/fonts/simple1_5x8x8
    /absolute/path/monoglyph/fonts/simple1_5x8x8.png
    128 48 // image size
    simple1_5x8x8 5 8 8 // font name, baseline, glyph width, glyph height
    /absolute/path/monoglyph/fonts/simple1_5x8x8.h


Will generate a header like this:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef SIMPLE1_5X8X8_GLYPHS_H
#define SIMPLE1_5X8X8_GLYPHS_H

#include "monoglyph.h"

static uint8_t simple1_5x8x8_rgba[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	...
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

static struct glyph simple1_5x8x8_glyphs[] = {
	{
		/* " " */
		.codepoint = 32,
		.col = 0,
		.row = 0
	},
        ...
};

static struct glyph_set simple1_5x8x8_glyph_set = {
	.count = 0,
	.glyph_baseline = 5,
	.glyph_width = 8,
	.glyph_height = 8,
	.image_width = 128,
	.image_height = 48,
	.rgba = simple1_5x8x8_rgba,
	.glyphs = simple1_5x8x8_glyphs
};

Edited by Pengo on
Hey good idea! Only downside will be useability. The steps to iterate on a font, or get a new font in: write down the font mapping in a text file, associate it with a font file, run lua command, modify build script and or adjust code as necessary to include the new C code, recompile. That's a lot of steps. Your solution would be ideal for a finalized font, but might be a little more cumbersome for during development.

For example, say there were a font loading function like:

1
font_t* load_font_cp1252(image_path);


This could load a western font for codepage 1252 (ascii-extended for 32-255). Assuming the image is formatted in a way glyphs can be scanned (like using a fixed width, or height, or border pixels) then the workflow to add a new font would look like: place new font image into directory, call the load function, recompile. Modifying and existing font requires no extra steps at all. In this way iteration times are much simpler and faster.

Also you might consider making a web page. If we look at glad as the shining example, glad has this great webpage tool. It is actually incredibly annoying to use glad from the command line. For example a lot of machines I use don't have python installed, or pip, or other random tools. These dependencies are incredibly annoying for users and will deter them from using your code. The webpage alleviates this, since webpages are very accessible.
Hey Randy!

I like that website idea! For now, I reduced the verbosity of the command line:

1
lua generate.lua /absolute/path/ "font_name"


Now, it just needs the absolute path and the font name. The generator assumes that the image is named font name + ".png", and generates a header named font name + ".h".

All the other information now goes in the text file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
128                <--- image width
48                 <--- image height
5                  <--- glyph baseline
8                  <--- glyph width
8                  <--- glyph height
 !"#$%&'()*+,-./   <--- start of the character set
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]_a
bcdefghijklmnopq
rstuvwxyz{|}


As for iteration time, I'm thinking of a solution, I currently have this in mind:

- The generator parse the text file:
- find the lowest codepoint value (let's say it's 32)
- find the highest codepoint (let's say it's 255)
- Generate the array of glyphs with size 255 - 32
- The codepoint inside `struct glyph` will match the index in the array
- Depending on the font that someone created, there might be "holes" in the array (some wasted bytes), because they didn't include an specific character. Not really a problem, it's all a matter of what font you want to use and what that font offers

So, it will be possible get a glyph with codepoint-lowest_codepoint as index:

1
struct glyph *myglyph = &myfont_glyph_set.glyphs[codepoint - myfont_glyph_set.lowest_codepoint];


P.S.: Thanks for the tweet, admin!

Edited by Pengo on
Started working on a hiragana set:



Github issues will be a good way to record progress: https://github.com/ferreiradaselva/monoglyph/issues/1

Also, I should've stated before: anti-aliased fonts are OK to be submitted.

Edited by Pengo on
What all left is there to finish up on this project? It looks mostly completed.

Also, would it be possible to include in the repository something to package up the lua dependency? Maybe throw up a Windows executable or something similar, that runs the generate.lua? Right now if I want to try out MonoGlyph I have to somehow setup lua, which is a little too consuming for me. I imagine you don't want this kind of roadblock in the way of people interested in using your code.
Randy Gaul
What all left is there to finish up on this project? It looks mostly completed.


I need only to test with some more complicated languages, like Arabic, to check if needs something more.

Randy Gaul
Also, would it be possible to include in the repository something to package up the lua dependency? Maybe throw up a Windows executable or something similar, that runs the generate.lua? Right now if I want to try out MonoGlyph I have to somehow setup lua, which is a little too consuming for me. I imagine you don't want this kind of roadblock in the way of people interested in using your code.


I'm rewriting the generator in C, then I will distribute the generator precompiled in the "Releases" tab. That will remove the Lua dependency (binaries of the Lua interpreter can be downloaded here, btw: http://luabinaries.sourceforge.net/download.html) and I will use your "cute_png.h" header to remove the ImageMagick dependency.

Lua was my first choice, because it has a very nice utf8 module. But, I was finally able to make the UTF8 functions that I needed in C.

Edited by Pengo on