Trying to understand ProffieOS text font making (like our display\StarJedi10Font.h)

Hello friends,

I would like to understand the code from StarJedi10Font.h because I would like to make the smallest possible font where typing ‘a’ or ‘A’ will display/
010
101
111
101
101
where 1 in full pixel and 0 is empty. 5 tall x 3 wide but since our text fonts are coded side-ways, this would be:
11110
00101
11110

I will use “A” as an example to understand:

const uint16_t Starjedi10pt7bChar65[] = {
  0b10000000000000UL,
  0b11110000000000UL,
  0b11111110000000UL,
  0b11111111110000UL,
  0b11111111111110UL,
  0b01111111111111UL,
  0b00111011111111UL,
  0b00111000111111UL,
  0b00111000001111UL,
  0b00111001111111UL,
  0b01111111111111UL,
  0b11111111111111UL,
  0b11111111111000UL,
  0b11111111000000UL,
  0b11111000000000UL,
  0b11000000000000UL,
};

&

const Glyph Starjedi10pt7bGlyphs[] = {
...
  {  14,   -1,  -13, GLYPHDATA(Starjedi10pt7bChar33) },   // 0x41 'A'
...
};
  1. Why is the text bitmap side ways ?
  2. What is 0b at the beginning and UL at the end for ? (in 0b10000000000000UL,
    ) ?
  3. What is ‘10pt7b’ in const uint16_t Starjedi10pt7bChar65[] = { or is it just a name ? Shouldn’t it be named 14pt (14 pixels tall) I understand that in ‘Char65’, 65 is the ASCII code for “A” but why is GLYPHDATA using ‘Char33’ (ASCII code for “!”) and ‘Char65’ is commented // 0x61 'a' ? Are you confused yet, because I certainly am. I feel that it’s a miss-matched “mishmash” ?
  4. What are ‘14, -1, -13’ (ok, 14 is the character hight in pixels, but what about -1 & -13)

As always, thank you for any help.

Best regards,

  1. Efficiency, it makes it easier to draw the pixels onto the OLED. It also means that we can have characters of arbitrary length, but not arbitrary height.
  2. 0bXXXXXXX means “binary” (ones and zeroes) UL means “unsigned long”, which only really matters for very large characters.
  3. 10pt7b comes from the font conversion program, 10pt means “10 points”, which is a way to specify font sizes, not sure what the 7b means. The Char65 == ‘a’ is confusing, because it’s dumb luck. Char0, Char1 are simply numbered. It’s their location in the array that matters.
  4. The answer can be found here:
    ProffieOS/display/monoframe.h at db1b38254a040c0bb2aa30e1ab4f5edeebe7de14 · profezzorn/ProffieOS · GitHub
    basically, it’s basically character width (including space before and after character), x offset, y offset, number integers in the bitfield, and width of bitfield (1,2,4 or 8 bytes)

All of this data is auto-generated by the font dumping program. It’s possible to write it by hand, but it’s very tedious.

  1. That makes perfect sense.
  2. Can I drop the UL for very small characters ? And can I use const uint8_t since my characters are all max 5x5 ?
  3. [quote=“profezzorn, post:2, topic:6580”]
    It’s their location in the array that matters.
    [/quote]
    Does that mean I can “re-order” them:
  • Char0 to Char9 for digits from ‘0’ to ‘9’
  • Char10 to Char35 for ‘A’ to ‘Z’
  • Char36 to Char?? for punctuation & special characters (just the basic ones like ‘.’, ‘,’, ‘:’, ‘-’, ’ ’ (space), ‘<’, ‘>’, ‘/’, '', ‘+’, maybe ‘&’ (if can make it look good on 5x5) but certainly no ‘@’ (because it would be taller than 5)
  1. That is 5 digits but in the font file, there are only 3, for example with ‘A’:
    { 14, -1, -13, GLYPHDATA(Starjedi10pt7bChar33) }, // 0x41 'A'
  • 14 is the height
  • -1 I don’t understand (I thought that was width, so with my logic it should be 16 ?
  • -13 is the y-offset and in my font case it would be -4 for 5 pixels tall character and -3 for ‘+’, ‘:’, ‘=’ and -2 for ‘-’

For what is worth, here is my Basic5ptFontOli.h so far:
Basic5FontOli_rev04-1.h (7.8 KB)

Am I on the right track or way off ?

Edit: I found several errors already. I will correct it and repost version 4

  1. If you look carefully, you’ll find that small font characters already use uint8_t in the StarJedi font.
  2. You can rename them any way you want to. Why not CharA CharB, etc. ?
  3. GLYPHDATA is a macro that expands to three arguments:
    ProffieOS/display/monoframe.h at db1b38254a040c0bb2aa30e1ab4f5edeebe7de14 · profezzorn/ProffieOS · GitHub
    14 is not the height. It’s the width. The next number is the position within that width.
  1. I did figure that out in the mean time but thanks for the confirmation. I believe that several characters in Aurebesh10Font.h & StarJedi10Font.h could be declared with uint8_t instead of uint16_t and probably none needs uint32_t (maybe one exception). I don’t mind to check them all by hand one by one.
  • Has this been checked before?
  • Would it reduce flash memory usage if I just even find one ?
  • I am pretty sure it would help “RAM memory” (sorry, I forgot how you call it?) usage and processor overhead if I found a few, correct ?
    Does ‘0b’, ‘UL’ and the end of line comma(s) ‘,’ in the 0 to 255 range (or 0 to 65,535 range for uint16_t) count ?
  1. Cool. I didn’t know I could do that. So how does ProffieOS match ‘A’ to ‘Char65’ or ‘CharA’ or ‘CharXX’ ?
    Is there a “master mapping” somewhere ? I would prefer to “re-use” what already exists rather than creating my own (and not adding to memory (flash or Ram) usage.

  2. [quote=“profezzorn, post:4, topic:6580”]
    14 is not the height. It’s the width.
    [/quote]
    That is an easy (but tedious - I don’t mind) fix.

I can’t visualize what that means ? Can you give me the answer for “my” ‘A’:

...
 const uint8_t Basic5pt7bCharA[] = {   // 0x41 'A', 0x61 'a'
  0b11110UL,
  0b00101UL,
  0b11110UL,
};
...
const Glyph Basic5pt7bGlyphs[] = {
...
  { 3, ?? what should come here ??, -4, GLYPHDATA(Basic5pt7bCharA) },  // 0x41 'A', 0x61 'a'
...
};
  1. New question: how to draw a “good-looking” hampers-hand ‘&’ sign on a 5 pixels tall x 5 (or 6) pixels wide image ? This is what I got but I think none are “worthy”:
    Hampers-hand
    The left one is too fat. The right one is 6 pixels tall (one too much - but much better looking?)

Thank you @profezzorn for all the help you provide to all of us.

The font conversion program should do this automatically, so if you find any it means there is a bug in the font conversion program.

Yes, a little.

No, just flash memory.

No. It doesn’t matter how you write a number, what matters is how it is stored in memory.

That’s what the table is for.
If you call it CharA, then you have to use GLYPHDATA(…CharA) and that’s it.

The first value specifies how much space to reserve for your character.
The second specifies where within the space to draw the character.
In your case you probably want the xoffset to be 1 in almost all cases, unless you want more than one pixel between characters.

Note that some characters in the StarJedi font are confusing, because some of them are meant to draw things over the previous character.

Good luck with that.

1 Like

Thanks for the laugh. I know hampers-hand ‘&’ is a though one to display in 5x5 (or 5x6). Tomorrow, the kids don’t have school here, so I will ask them for help. I drew a few more examples, they will pick and choose or “tell me” how to do it (I will allow it, this time!) :wink:

1 Like

What is that font conversion program you speak of ?

I will check and report if I find something worth amending.

What about special characters ? I doubt it’s ok to name them ‘Char(’ or ‘Char[’, right ?

Here is the update on my tiny font:
Minimalist5FontOli_rev05-1.h (11.9 KB)

I know, it is getting bigger, but I also added more comments.

Did I miss any ‘important’ special characters for a menu ?

They have to be valid C++ identifiers.

You seem to be missing characters that I can read without a magnifying glass. :slight_smile:

I know it is small, but all the characters are in the comments. :stuck_out_tongue_winking_eye:

Latest version as decided by my kids:
Minimalist5FontOli_rev06-1.h (11.7 KB)