A way to support good looking outline fonts with the current PokittoLib API

There are more than one time that I would have liked Pokitto library to support outline fonts, to make the text distinguishable from whatever is behind it. Especially with a small screen like in Pokitto, where I would not like to waste screen space to a separate text bar or an area with a single color background.

The outline font looks like this:
image

I have tried to print first the text with a black color and then offset the position a bit and print again with a white color but the result has always been a bit messy.

Just now I realized what would be a good solution without really adding a support for 2-color fonts for PokittoLib:

  • For some or every current font, there should be an “outline font” counterpart. Then you just print each text 2-times in the same position, first with the “outline” font then with the real font. The nice thing is that you can choose the colors freely :slight_smile:

E.g. Like this:

6 Likes

Agreed! I’ve been thinking about this, recently, too. I usually do outlined text with the 4 offsets (2 vertical, 2 horizontal), but of course that’s quite inefficient. And of course, it doesn’t always play nice with the “kerning” on the pokitto.**

I also think that two color fonts would be nice because you could do near-shaded colors with pairs of fonts designed to provide anti-aliasing.

** Actually, I just realized, though; this solution wouldn’t fix that kerning issue, and in fact would make it worse. Right now, characters are printed and then it advances by their width+1 to get the letter gap. One solution could be to add an extra pixel on the right side of the non-outlined font file to make sure that it lines up correctly, and then reverse the print order so that the outline covers it up. Or maybe another solution would just be to change the adjustCharStep variable between the two printings to make up the extra 2 pixels.

Maybe a new font format is needed, perhaps 2bpp, giving 2 colours and 1 transparent.
I’ve almost always used my own fount and routine, which can easily use variable width fonts without trouble.
Joe 2 uses a 2bpp font…
image
In fact so did Joe 1
image

Simply draw your font, chop it up into a sprite sheet and bob’s your uncle.

Is there any particular reason it needs to be a modification of the PokittoLib rather than being implemented as part of a separate library?

I would have thought with the fully buffered modes at least it ought to be possible to implement the font rendering with a separate library rather than adding more complication to the main library.

That would be a “correct” solution, but unless no-one have time to implement new font drawing routines we could go with a more inefficient but less work solution I suggested. We could anyway add a new PokittoLib wrapper method which draws the text twice.

It is possible with any mode. It would just require using the library’s print function instead of PokittoLib’s.

1 Like

You are correct. I did not think about the char gap. That might cause problems.

I know it’s theoretically possible, but I was thinking more in terms of practicality - I wasn’t sure if there would be any necessary functions or variables marked private. (With the buffered modes, you only need access to the buffer itself.) I’m presuming from your comment that all necessary variables and functions are accessible.

Yes, that’s what I meant, everything that is needed is accessible. The only thing that can’t be done is redirecting the built-in print function to a custom text renderer, so there will be some redundancy.

For the record, here is what I use…

// print text
void myPrint(char x, char y, const char* text) {
	uint8_t numChars = strlen(text);
	uint8_t x1 = 0;
	for (uint8_t t = 0; t < numChars; t++) {
		uint8_t character = text[t] - 32;
        Pokiito::Display::drawBitmap(x+((x1++)*8), y, font8x8[character]);
	}
}

Mostly I use the following font…

image

Just convert it for whatever screen mode you use.

The routine is very easily adapted for other screen modes if required. For example, lately I’ve adapted it to TAS mode by using the sprite drawing routines.

For variable width fonts, it is as simple as creating an array of widths (by hand?) and adding it on, rather than multiply by 8.

1 Like

Yes, that looks very workable too. Especially, if you are not short of rom.

1 Like

Just to check, do you realise that by using both strlen and a for loop you’re actually looping through the string twice?

You could save processing time by fusing the loops like so:

void myPrint(char x, char y, const char* text)
{
	for (std::uint8_t index = 0, x1 = 0; index < 255; ++index, ++x1)
	{
		if(text[index] == '\0')
			break;
			
		std::size_t glyphIndex = text[index] - 32;
        Pokiito::Display::drawBitmap(x + (x1 * 8), y, font8x8[glyphIndex]);
	}
}

So instead of O(n*2) it becomes just O(n).

This is a common problem when using the C-style string functions like std::strlen and std::strcat. (See also: Shlemiel the painter’s algorithm.)

2 Likes

These links might be useful to everyone wanting to use custom fonts…

You can view these fonts as images with this link - Hoard of bitfonts

…But…
I have jiggered with that page a little, so that the image format is right for img2pok to be used in our own Pokitto projects easily.
Hoard of bitfonts.zip (10.0 KB)
It’s just the same HTML file with some of the values changed, also it still pulls the font files from the above github, so as long as they stay there, this should work.
Here is an example of one of the fonts…
image
and
image

2 Likes

This is how the outline font looks like in Pokitto. It is not very useful in the lowres mode because of the long distance between chars but works better in the highres mode.
image

The code is like this:

        // Draw the outline
        PD::adjustCharStep = 1;
        PD::setColor(1);
        PD::setFont(fontTinyOutlineOnly);
        PD::print(x,y, "This is Pokitto outline font !!!");

        // Draw the normal font inside.
        PD::adjustCharStep = 3;
        PD::setColor(10);
        PD::setFont(fontTiny);
        PD::print(x+1,y+1, "This is Pokitto outline font !!!");

The "fontTinyOutlineOnly" array

You can use the normal “fontTiny” but you need the outline font below in addition.

const unsigned char fontTinyOutlineOnly[] = {
    8, 10, 32, 0, // width, height, start char, caps only
    0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 32: ' '
    0x03, 0xFE, 0x00, 0xA2, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 33: '!'
    0x05, 0x0F, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 34: '"'
    0x07, 0x7C, 0x00, 0xD6, 0x00, 0x82, 0x00, 0xD6, 0x00, 0x82, 0x00, 0xD6, 0x00, 0x7C, 0x00, 0x00, 0x00,       // 35: '#'
    0x07, 0xFC, 0x00, 0xB6, 0x00, 0xAB, 0x01, 0x01, 0x01, 0xAB, 0x01, 0xDA, 0x00, 0x7E, 0x00, 0x00, 0x00,       // 36: '$'
    0x05, 0xFE, 0x00, 0x9A, 0x00, 0xEE, 0x00, 0xB2, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 37: '%'
    0x06, 0x7C, 0x00, 0xD6, 0x00, 0xAA, 0x00, 0x8A, 0x00, 0xAE, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,       // 38: '&'
    0x03, 0x0F, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 39: '''
    0x04, 0xFE, 0x00, 0x83, 0x01, 0x7D, 0x01, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 40: '('
    0x04, 0xC7, 0x01, 0x7D, 0x01, 0x83, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 41: ')'
    0x06, 0x3E, 0x00, 0x2A, 0x00, 0x36, 0x00, 0x36, 0x00, 0x2A, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 42: '*'
    0x05, 0x38, 0x00, 0x6C, 0x00, 0x44, 0x00, 0x6C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 43: '+'
    0x04, 0xC0, 0x01, 0x60, 0x01, 0xA0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 44: ','
    0x05, 0x38, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 45: '-'
    0x03, 0xE0, 0x00, 0xA0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 46: '.'
    0x05, 0xF0, 0x00, 0x98, 0x00, 0xEE, 0x00, 0x32, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 47: '/'
    0x06, 0x7C, 0x00, 0xC6, 0x00, 0xBA, 0x00, 0xBA, 0x00, 0xC6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 48: '0'
    0x04, 0x1C, 0x00, 0xF6, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 49: '1'
    0x06, 0xFC, 0x00, 0xB6, 0x00, 0x9A, 0x00, 0xAA, 0x00, 0xB6, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 50: '2'
    0x06, 0xEE, 0x00, 0xBA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xD6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 51: '3'
    0x06, 0x78, 0x00, 0x4C, 0x00, 0xD6, 0x00, 0x82, 0x00, 0xDE, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,       // 52: '4'
    0x06, 0xFE, 0x00, 0xA2, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xDA, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 53: '5'
    0x06, 0x7C, 0x00, 0xC6, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xDE, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,       // 54: '6'
    0x06, 0x0E, 0x00, 0xFA, 0x00, 0x9A, 0x00, 0xEA, 0x00, 0x32, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 55: '7'
    0x06, 0x7C, 0x00, 0xD6, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xD6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 56: '8'
    0x06, 0x1C, 0x00, 0xF6, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xC6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 57: '9'
    0x03, 0xF8, 0x00, 0xA8, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 58: ':'
    0x05, 0xC0, 0x01, 0x78, 0x01, 0xA8, 0x01, 0xA8, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 59: ';'
    0x04, 0x38, 0x00, 0x6C, 0x00, 0x54, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 60: '<'
    0x05, 0x7C, 0x00, 0x54, 0x00, 0x54, 0x00, 0x54, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 61: '='
    0x04, 0x7C, 0x00, 0x54, 0x00, 0x6C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 62: '>'
    0x06, 0x0E, 0x00, 0xFA, 0x00, 0xAA, 0x00, 0xEA, 0x00, 0x36, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 63: '?'
    0x06, 0xFC, 0x00, 0x86, 0x01, 0x7A, 0x01, 0x4A, 0x01, 0x46, 0x01, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00,       // 64: '@'
    0x06, 0xFC, 0x00, 0x86, 0x00, 0xEA, 0x00, 0xEA, 0x00, 0x86, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 65: 'A'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xD6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 66: 'B'
    0x05, 0x7C, 0x00, 0xC6, 0x00, 0xBA, 0x00, 0xAA, 0x00, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 67: 'C'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xBA, 0x00, 0xBA, 0x00, 0xC6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 68: 'D'
    0x05, 0xFE, 0x00, 0x82, 0x00, 0xAA, 0x00, 0xBA, 0x00, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 69: 'E'
    0x05, 0xFE, 0x00, 0x82, 0x00, 0xEA, 0x00, 0x2A, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 70: 'F'
    0x06, 0x7C, 0x00, 0xC6, 0x00, 0xBA, 0x00, 0xAA, 0x00, 0x8A, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,       // 71: 'G'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xEE, 0x00, 0xEE, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,       // 72: 'H'
    0x05, 0xEE, 0x00, 0xBA, 0x00, 0x82, 0x00, 0xBA, 0x00, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 73: 'I'
    0x06, 0x70, 0x00, 0xDE, 0x00, 0xBA, 0x00, 0xBA, 0x00, 0xC2, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 74: 'J'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xEE, 0x00, 0xD6, 0x00, 0xBA, 0x00, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00,       // 75: 'K'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xBE, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,       // 76: 'L'
    0x07, 0xFE, 0x00, 0x82, 0x00, 0xF6, 0x00, 0x2C, 0x00, 0xF6, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00,       // 77: 'M'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xF6, 0x00, 0xEE, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,       // 78: 'N'
    0x06, 0x7C, 0x00, 0xC6, 0x00, 0xBA, 0x00, 0xBA, 0x00, 0xC6, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 79: 'O'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xEA, 0x00, 0x2A, 0x00, 0x36, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 80: 'P'
    0x06, 0x7C, 0x00, 0xC6, 0x00, 0xBA, 0x00, 0xBA, 0x01, 0x46, 0x01, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00,       // 81: 'Q'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xDA, 0x00, 0xDA, 0x00, 0xA6, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 82: 'R'
    0x06, 0xFC, 0x00, 0xB6, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xDA, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 83: 'S'
    0x05, 0x0E, 0x00, 0xFA, 0x00, 0x82, 0x00, 0xFA, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 84: 'T'
    0x06, 0x7E, 0x00, 0xC2, 0x00, 0xBE, 0x00, 0xBE, 0x00, 0xC2, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 85: 'U'
    0x06, 0x7E, 0x00, 0xC2, 0x00, 0xBE, 0x00, 0xCE, 0x00, 0x72, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 86: 'V'
    0x07, 0x7E, 0x00, 0xC2, 0x00, 0xBE, 0x00, 0xC8, 0x00, 0xBE, 0x00, 0xC2, 0x00, 0x7E, 0x00, 0x00, 0x00,       // 87: 'W'
    0x06, 0xFE, 0x00, 0x92, 0x00, 0xEE, 0x00, 0xEE, 0x00, 0x92, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,       // 88: 'X'
    0x06, 0x1E, 0x00, 0xF2, 0x00, 0xAE, 0x00, 0xAE, 0x00, 0xC2, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,       // 89: 'Y'
    0x05, 0xFE, 0x00, 0x9A, 0x00, 0xAA, 0x00, 0xB2, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 90: 'Z'
    0x04, 0xFE, 0x01, 0x02, 0x01, 0x7A, 0x01, 0xCE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 91: '['
    0x06, 0x1E, 0x00, 0x32, 0x00, 0x2E, 0x00, 0xE8, 0x00, 0x98, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,       // 92: '\'
    0x04, 0xCE, 0x01, 0x7A, 0x01, 0x02, 0x01, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 93: ']'
    0x05, 0x1C, 0x00, 0x16, 0x00, 0x1A, 0x00, 0x16, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 94: '^'
    0x07, 0xC0, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0xC0, 0x01, 0x00, 0x00,       // 95: '_'
    0x04, 0x0E, 0x00, 0x1A, 0x00, 0x16, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 96: '`'
    0x06, 0x78, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xD4, 0x00, 0x84, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 97: 'a'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xB6, 0x00, 0xB4, 0x00, 0xCC, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,       // 98: 'b'
    0x06, 0x78, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xB4, 0x00, 0xB4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 99: 'c'
    0x06, 0x78, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xB6, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,       // 100: 'd'
    0x06, 0x78, 0x00, 0xCC, 0x00, 0x94, 0x00, 0xA4, 0x00, 0xEC, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,       // 101: 'e'
    0x05, 0x38, 0x00, 0xEC, 0x00, 0x86, 0x00, 0xEA, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 102: 'f'
    0x06, 0x78, 0x00, 0xCC, 0x03, 0xB4, 0x02, 0xB4, 0x02, 0x04, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00,       // 103: 'g'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xF6, 0x00, 0xF4, 0x00, 0x8C, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,       // 104: 'h'
    0x03, 0xFE, 0x00, 0x8A, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 105: 'i'
    0x04, 0x80, 0x03, 0xFE, 0x02, 0x0A, 0x03, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 106: 'j'
    0x06, 0xFE, 0x00, 0x82, 0x00, 0xDE, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 107: 'k'
    0x03, 0xFE, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 108: 'l'
    0x07, 0xFC, 0x00, 0x84, 0x00, 0xF4, 0x00, 0x8C, 0x00, 0xF4, 0x00, 0x8C, 0x00, 0xF8, 0x00, 0x00, 0x00,       // 109: 'm'
    0x06, 0xFC, 0x00, 0x84, 0x00, 0xEC, 0x00, 0xF4, 0x00, 0x8C, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,       // 110: 'n'
    0x06, 0x78, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xB4, 0x00, 0xCC, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,       // 111: 'o'
    0x06, 0xFC, 0x01, 0x04, 0x01, 0xB4, 0x01, 0xB4, 0x00, 0xCC, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,       // 112: 'p'
    0x06, 0x78, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xB4, 0x01, 0x04, 0x01, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00,       // 113: 'q'
    0x05, 0xFC, 0x00, 0x84, 0x00, 0xEC, 0x00, 0x34, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 114: 'r'
    0x06, 0xF8, 0x00, 0xAC, 0x00, 0xA4, 0x00, 0x94, 0x00, 0xD4, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 115: 's'
    0x05, 0x1C, 0x00, 0x76, 0x00, 0xC2, 0x00, 0xB6, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 116: 't'
    0x06, 0x7C, 0x00, 0xC4, 0x00, 0xBC, 0x00, 0xBC, 0x00, 0xC4, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 117: 'u'
    0x06, 0x7C, 0x00, 0xC4, 0x00, 0xBC, 0x00, 0xDC, 0x00, 0x64, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,       // 118: 'v'
    0x07, 0x7C, 0x00, 0xC4, 0x00, 0xBC, 0x00, 0xC8, 0x00, 0xBC, 0x00, 0xC4, 0x00, 0x7C, 0x00, 0x00, 0x00,       // 119: 'w'
    0x05, 0xFC, 0x00, 0xB4, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 120: 'x'
    0x06, 0x7C, 0x00, 0xC4, 0x03, 0xBC, 0x02, 0xBC, 0x02, 0x04, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00,       // 121: 'y'
    0x06, 0xFC, 0x00, 0xB4, 0x00, 0x94, 0x00, 0xA4, 0x00, 0xB4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,       // 122: 'z'
    0x05, 0x38, 0x00, 0xEF, 0x01, 0x11, 0x01, 0x7D, 0x01, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 123: '{'
    0x03, 0xFE, 0x00, 0x82, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 124: '|'
    0x05, 0xC7, 0x01, 0x7D, 0x01, 0x11, 0x01, 0xEF, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // 125: '}'
    0x07, 0x78, 0x00, 0x4C, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x5C, 0x00, 0x64, 0x00, 0x3C, 0x00, 0x00, 0x00        // 126: '~'
    };
2 Likes

Just a thought, but you might also consider trying (if you haven’t already) a cross instead of a square as your… uh… “convolution kernel.” Could make the outline feel a little tighter and have a more distinct silhouette. Maybe enough to let the char step come in by one and retain readability. Though you might be able to do that, anyways; it just depends on the use case.

1 Like

I thought about that but it did not look good to my eyes.

Yes, for lowres at least i will try to decrease the char step.

1 Like

I love it!! not sure if that’s the choice of colors but this got a neon / old display mood

1 Like

Those colors just came out from rand() :wink:

1 Like

rand() has good tastes in colors :stuck_out_tongue:

2 Likes

Paul Rand() was a famous designer, for example the IBM and UPS logotypes