cancel
Showing results for 
Search instead for 
Did you mean: 

File format of binary fonts

Bart1
Associate

We are investigating the use of TouchGFX on a new product, but one very important requirement for us is to be able to generate the font files from our own proprietary tool, without the end user having to install any TouchGFX-related software.

In our previous products, we used emWin, where the SIF-format was not documented, but could be quite easily dtermined from the generated C-code. For TouchGFX this seems more difficult. Is there any description of the font file format necessary for loading in a BinaryFont?

2 REPLIES 2
Martin KJELDSEN
Chief III
struct BinaryFontData
{
    uint32_t fontIndex;                // The font index (as used by TypedTextDatabase)
    uint32_t sizeOfFontData;           // Size of the complete BinaryFont
    uint32_t offsetToTable;            // GlyphNode[]
    uint32_t offsetToKerning;          // KerningNode[]
    uint32_t offsetToGlyphs;           // uint8_t[]
    uint32_t offsetToGSUB;             // uint16_t[]
    uint16_t numberOfGlyphs;           // Number of glyphs in Table and Glyphs
    uint16_t height;                   // Font height from base
    uint8_t  pixBelowBase;             // Max pixels below base
    uint8_t  bitsPerPixel: 7;          // Bpp
    uint8_t  dataFormatA4: 1;          // A4
    uint8_t  maxLeft;                  // The maximum a character extends to the left
    uint8_t  maxRight;                 // The maximum a character extends to the right
    Unicode::UnicodeChar fallbackChar; // Fallback Character for the font
    Unicode::UnicodeChar ellipsisChar; // Ellipsis Character for the font
};

Thanks for the answer.

I had already found this, however if I analyze the generated binary files, I see some discrepancies that I do not fully understand:

I have a character (0x0031) with a Kerning distance of -1. I would expect to see "31 00 FF" in the binary, however I see "31 00 FF FF" as the kerning distance is declared as an uint8_t. Could there be some padding going on there?

00 00 00 00 // Font index
8C 00 00 00 // Font size
24 00 00 00 // Offset to glyphnodes
5C 00 00 00 // Offset to kerning nodes
60 00 00 00 // Offset to glyphs
00 00 00 00 // Offset to gsub
04 00 // Number of glyphs
14 00 // Height
00 // Pix below base
01 // BBP / A4
00 // maxLeft
 
3F 00 // Fallback character
00 00 // Ellipsis character
 
00 00 00 00 // Offset
20 00 // Unicode
00 // Width
00 // Height
00 // Top
00 // Left
06 // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // Flags
 
00 00 00 00 // Offset
30 00 // Unicode
09 // Width
0F // Height
0F // Top
01 // Left
0B // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // flags
 
11 00 00 00 // Data offset
31 00 // Unicode
05 // Width
0F // Height
0F // Top
02 // Left
0B // Advance
00 // Kerningtable
01 // Kerningtable size
00 // Flags
 
1B 00 00 00 // Data offset
3F 00 // Unicode
09 // Width
0F // Height
0F // Top
01 // Left
0B // Advance
00 // Kerningtable
00 // Kerningtable size
00 // Flags
 
31 00 // Kerning character
FF // Kerning Distance
 
WHAT'S THIS -> FF // ?
 
// Glyphs
7C FC 19 1B 3C 78 F0 E0 C1 83 07 0F 1E 6C CC 1F
1F
 
18 F3 BF 31 C6 18 63 8C 31 06
 
7C FC 1D 1F 0C 18 18 38 38 38 30 60 00 00 00 03
06

I also see that the glyph data for a certain character (last one in the file) has an extra "00" at the end, compared to the original C-code, could this also be some padding?

00 00 00 00 // uint32_t fontIndex;                // The font index (as used by TypedTextDatabase)
18 01 00 00 // uint32_t sizeOfFontData;           // Size of the complete BinaryFont
24 00 00 00 // uint32_t offsetToTable;            // GlyphNode[]
86 00 00 00 // uint32_t offsetToKerning;          // KerningNode[]
86 00 00 00 // uint32_t offsetToGlyphs;           // uint8_t[]
00 00 00 00 // uint32_t offsetToGSUB;             // uint16_t[]
07 00 // uint16_t numberOfGlyphs;           // Number of glyphs in Table and Glyphs
14 00 // uint16_t height;                   // Font height from base
04 // uint8_t  pixBelowBase;             // Max pixels below base
01 // uint8_t  bitsPerPixel: 7;          // Bpp / A4 // uint8_t  dataFormatA4: 1;          // A4
00 // uint8_t  maxLeft;                  // The maximum a character extends to the left
00 // uint8_t  maxRight;                 // The maximum a character extends to the right
 
3F 00 // Unicode::UnicodeChar fallbackChar; // Fallback Character for the font
00 00 // Unicode::UnicodeChar ellipsisChar; // Ellipsis Character for the font
 
// Glyph nodes
 
00 00 00 00 // Data offset
30 00 // Unicode
09 // Width
0F // Height
0F // Top
01 // Left
0B // Advance
00 // Kerningtablepos
00 // kerningtable size 
00 // flags
 
11 00 00 00 // Data offset
3F 00 // Unicode
09 // Width
0F // Height
0F // Top
01 // Left
0B // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // flags
 
22 00 00 00 // Data offset
40 00 // Unicode
12 // Width
13 // Height
0F // Top
01 // Left
14 // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // Flags
 
4D 00 00 00 // Data offset
4D 00 // Unicode
0D // Width
0F // Height
0F // Top
02 // Left
11 // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // Flags
 
66 00 00 00 // Data offset
61 00 // Unicode
09 // Width
0B // Height
0B // Top
01 // Left
0B // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // Flags
 
73 00 00 00 // Offset
67 00 // Unicode
09 // Width
0F // Height
0B // Top
01 // Left
0B // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // Flags
 
84 00 00 00 // Offset
F8 00 // Unicode
08 // Width
0D // Height
0C // Top
01 // Left
0B // Advance
00 // Kerningtablepos
00 // Kerningtable size
00 // Flags
 
// 0x0030
7C FC 19 1B 3C 78 F0 E0 C1 83 07 0F 1E 6C CC 1F
1F
 
// 0x003f
7C FC 1D 1F 0C 18 18 38 38 38 30 60 00 00 00 03
06
 
// 0x0040
C0 1F C0 FF 81 07 0F 07 70 8E B3 19 DF 6C CE F1
18 C6 33 18 CF 60 3C 83 F8 0C 63 73 CE 98 FF 61
DC 33 03 60 3C E0 C0 FF 01 FC 01
 
// 0x004D
07 FC C1 3F F8 07 BF B1 37 F6 C6 DE D8 B3 79 36
CF E6 D9 3C 8E C7 F1 38 06
 
// 0x0061
7C FE 0D 03 06 CF DF B3 61 E3 FE 79 06
 
// 0x0067
BC FD 1B 1F 3C 78 F0 E0 C1 C6 FD F3 06 3C FC 1F
1F
 
// 0x00F8
C0 FC 7E 77 F3 DB DB CF CF E6 7E 3B 01
 
00 --> Unaccounted for in corresponding C++ code

Both examples are created with Arial 20, 1 BBP and no A4 mode.

Next to that: the glyphs are in "dense format" according to the docs, but I cannot find a description of this dense format and I don't "see" the logic behind it when analysins (I thought it was similar to emWin's extended proportional, but it still seems to be a bit different)