Ok so here's how data is stored in these font files. Let's consider the font "bocdmonolightultcond.core".
Note that all the hex numbers are stored in little endian format, that is, they must be read right to left.
Let's start from the header:
F3 08 7B 7B 6C 8D E6 E0 is the file header, and is present in all of these font .core files.
31 10 00 00 = 4145 bytes is the file length in bytes.
A4 64 01 DC F5 D4 45 43 8E E7 6D CE 1F A7 EC DD is most probably a hash value used by the game to reference to this font. Indeed, it is present inside the file "ui_font_family.core" that it seems to contain information on which font
to use in the UI of the game.
18 00 00 00 = 24 bytes is the length of the font name, in bytes.
67 C5 E1 31 unknown, may be a date or a checksum.
42 4F 20 43 44 20 4D 6F 6E 6F 20 4C 69 67 68 74 20 55 6C 74 43 6F 6E 64 = "BO CD Mono Light UltCond" is of course the font name, composed of 24 bytes.
00 00 7A 44 = 1000. It is the "EM units" of the font.
00 00 48 44 = 800. It is the "ascent" of the font, that is, the positive height of characters with respect to the baseline.
00 00 48 43 = 200. It is the "descent" of the font, that is, the negative height of characters with respect to the baseline.
00 00 2F 44 = 700. It is the height of capital letters in the font.
Here is a picture to better clarify the meaning of those parameters:
Note that ascent + descent = EM.
0B 00 00 00 = 11. It is the number of characters stored in the font file (in this case 10 numbers + 1 for space).
Then, the next 4 bytes, right after 00 80 A5 43, are 20 00 00 00 = ' ' (it is the symbol of a space). Let's skip this one for a moment and consider the next glyph, which is easier to understand:
00 80 A5 43 = 331. It is the so called "advance" of the glyph.
30 00 00 00 = '0'. It is the symbol of the glyph: a zero.
00 00 34 42 00 00 00 00 = (45,0). They are the (x,y) coordinates of the lower left point of the glyph.
00 80 8E 43 00 00 2F 44 = (285,700). They are the (x,y) coordinates of the upper right point of the glyph.
To better understand the meaning of these values, refer to the following figure, where you can clearly see the "advance" and "min" and "max" coordinates:
In most fonts, glyph's data is stored as a sequence of coordinates of points that define its outlines. There may be more than one outline (this happens if the outlines need to be disjoint like in the symbols 'O', '=', etc.).
02 00 00 00 = 2. It is the number of outlines that define the borders of the glyph.
Now we enter in the #1 outline details:
0F 00 00 00 = 15 is the length of what I call "line data" of the outline, and define how the outline must be traced.
42 01 42 01 42 01 42 01 42 01 42 01 42 01 42 is the "line data" of this outline. In each byte,
if the bit #6 = 0, the number represent the number of points connected by straight lines (e.g. 01 = 1 straight line);
if the bit #6 = 1, the number subtracted by 64 represent the number of points connected by bezier curves (e.g. 42 -> 2 bezier curves).
18 00 00 00 = 24 is the number of coordinates (x,y) of points that define the outline.
So 24 x 2 coord. x 4 bytes = 192 bytes is the length of the following outline data:
00 00 65 43 00 80 2D 44
00 C0 5E 43 00 00 2F 44
00 00 57 43 00 00 2F 44
00 00 E6 42 00 00 2F 44
00 80 D6 42 00 00 2F 44
00 00 CA 42 00 80 2D 44
00 00 4C 42 00 00 21 44
00 00 34 42 00 70 1F 44
00 00 34 42 00 80 1D 44
00 00 34 42 00 00 8C 42
00 00 34 42 00 00 79 42
00 00 4C 42 00 00 60 42
00 00 CA 42 00 00 C0 40
00 80 D6 42 00 00 00 00
00 00 E6 42 00 00 00 00
00 00 57 43 00 00 00 00
00 C0 5E 43 00 00 00 00
00 00 65 43 00 00 C0 40
00 80 8B 43 00 00 60 42
00 80 8E 43 00 00 79 42
00 80 8E 43 00 00 8C 42
00 80 8E 43 00 80 1D 44
00 80 8E 43 00 70 1F 44
00 80 8B 43 00 00 21 44
is the sequence of points expressed as coordinates (x,y) that define the outline.
In this example there are indeed 24 points.
After this block of data you can see the "line data" of outline #2 followed by its sequence of points.
You should now be able to understand how the space ' ' glyph is stored. Note that no outlines have been defined for it, and (x,y) min and max are meaningless for it.
Using this information, I was able to write a small script using MATLAB. Here it is an example of the number '0' that was discussed above:
Note how the glyph is actually centred with an advance of 331 units. The lower left point is indeed (45,0) and the upper right is (285,700).
The numbers in red, from 1 to 24, represent the numbered sequence of points in the outline #1.
A note about those bezier curves used to join points: according to
this webpage (and also
this post), a quadratic bezier curve is used to join two adjacent points. In order to reduce the number of data stored in the font file, the virtual control point is not present among the sequence of points of the outline, and must be computed as the mean of the previous and the next points in the sequence.
Sorry for the long post, but I wanted to be as clear as possible. Let me know if you have any question or want to add more information about this topic.
Update:
I finally understood the meaning of the font values next to its name. They are indeed metrics used to define the font and are called "EM units", "ascent", "descent" and "cap height".
Then, I proceeded to generate a SVG font (which is a deprecated file format, but really easy to understand) using
this webpage as reference. This is done with the new script "generatesvgfont.m".
The last step to obtain a TrueType font is to convert it with a software. To do so, open FontForge, import the SVG font:
Then go to Element->Font Info.. and add a value in the "Version" field (you can digit whatever number you want). Finally, go to File->Generate Fonts.. and save the font as .TTF or whatever format you need. Ignore the errors that may pop up.
The MATLAB scripts are here attached and updated.
"demo.m" is indeed a demo script that prints the font table and then a sentence.
"generatesvgfont.m" is used to create a SVG font from the imported .core data.