A low resolution font for LED matrix displays e.g. neopixels

Dependents:   WS2812Text

A basic low resolution font

This font is intend for very low resolution display systems e.g. LED matrix displays. All characters are 5 pixels high and 5 or less pixels wide.

Data for a given character is returned as an array of 5 chars each char represents one row of the image reading from the top down. The least significant 5 bits of each char represent the pixels on that line.

e.g. For the letter X the returned data is { 0x11, 0x0a, 0x04, 0x0a, 0x11 } As bits this translates to

  • 10001
  • 01010
  • 00100
  • 01010
  • 10001

The following code will output the bit pattern for the selected character.

#include "miniFont.h"
miniFont myFont;

int main()
{

    const char **charData = NULL;
    char letter = 'x';

    if (myFont.getChar(letter,charData)) {
        for (int row = 0; row < myFont.getPixHeight(letter); row++) {
            for (int col = myFont.getPixWidth(letter) - 1; col >= 0; col--) { // start at the left not the right
                if ( *(*charData + row) & (0x01<<col))
                    printf("1");
                else
                    printf("0");
            }
            printf("\n");
        }
    }
}

Note - In order to avoid pointless copying of data getChar modifies the value in the supplied char to point to the start of the character array. However in some situations this means that the data will only be valid until the next time getChar is called. If you need to keep the data longer than that make a copy.

Characters are right justified, e.g. if getWidth() returns a value of 3 then only the 3 least significant bits of each row contain data. There are options to force fixed width characters (narrow characters will be shifted to the middle of a 5 pixel width) and to rotate characters 90 degrees Supported characters are A-Z 0-9 . ! ? <space> Any lower case letters are automatically capitalized. Not tested excessively, if you find any problems please let me know.

Committer:
AndyA
Date:
Fri Nov 07 09:38:54 2014 +0000
Revision:
1:46e0549c2bfb
Parent:
0:29155ff9313e
Documentation and example updated

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndyA 0:29155ff9313e 1 #include "miniFont.h"
AndyA 0:29155ff9313e 2
AndyA 0:29155ff9313e 3 const char miniFont::dot[5] = { 0x00,0x00,0x00,0x03,0x03};
AndyA 0:29155ff9313e 4 const char miniFont::space[5] = { 0x00,0x00,0x00,0x00,0x00};
AndyA 0:29155ff9313e 5 const char miniFont::exclam[5] = { 0x01,0x01,0x01,0x00,0x01};
AndyA 0:29155ff9313e 6 const char miniFont::quest[5] = { 0x0f,0x09,0x02,0x00,0x02};
AndyA 0:29155ff9313e 7
AndyA 0:29155ff9313e 8 const char miniFont::numbers[10][5] = {
AndyA 0:29155ff9313e 9 { 0x0e, 0x11, 0x11, 0x11, 0x08 }, // 0
AndyA 0:29155ff9313e 10 { 0x06, 0x02, 0x02, 0x02, 0x07 }, // 1
AndyA 0:29155ff9313e 11 { 0x1f, 0x01, 0x06, 0x18, 0x1f }, // 2
AndyA 0:29155ff9313e 12 { 0x1f, 0x01, 0x0f, 0x01, 0x1f }, // 3
AndyA 0:29155ff9313e 13 { 0x10, 0x10, 0x14, 0x1f, 0x04 }, // 4
AndyA 0:29155ff9313e 14 { 0x1f, 0x10, 0x1e, 0x01, 0x1e }, // 5
AndyA 0:29155ff9313e 15 { 0x1f, 0x10, 0x1f, 0x11, 0x1f }, // 6
AndyA 0:29155ff9313e 16 { 0x1f, 0x01, 0x01, 0x02, 0x02 }, // 7
AndyA 0:29155ff9313e 17 { 0x1f, 0x11, 0x08, 0x11, 0x1f }, // 8
AndyA 0:29155ff9313e 18 { 0x1f, 0x11, 0x1f, 0x01, 0x1f } // 9
AndyA 0:29155ff9313e 19 };
AndyA 0:29155ff9313e 20
AndyA 0:29155ff9313e 21 const char miniFont::letters[26][5] = {
AndyA 0:29155ff9313e 22 { 0x1f, 0x11, 0x1f, 0x11, 0x11 }, // A
AndyA 0:29155ff9313e 23 { 0x1e, 0x11, 0x1e, 0x11, 0x1e }, // B
AndyA 0:29155ff9313e 24 { 0x1f, 0x10, 0x10, 0x10, 0x1f }, // C
AndyA 0:29155ff9313e 25 { 0x1e, 0x11, 0x11, 0x11, 0x1e }, // D
AndyA 0:29155ff9313e 26 { 0x1f, 0x10, 0x1e, 0x10, 0x1f }, // E
AndyA 0:29155ff9313e 27 { 0x1f, 0x10, 0x1e, 0x10, 0x10 }, // F
AndyA 0:29155ff9313e 28 { 0x1f, 0x10, 0x13, 0x11, 0x1f }, // G
AndyA 0:29155ff9313e 29 { 0x11, 0x11, 0x1f, 0x11, 0x11 }, // H
AndyA 0:29155ff9313e 30 { 0x07, 0x02, 0x02, 0x02, 0x07 }, // I
AndyA 0:29155ff9313e 31 { 0x01, 0x01, 0x01, 0x11, 0x1f }, // J
AndyA 0:29155ff9313e 32 { 0x11, 0x12, 0x1c, 0x12, 0x11 }, // K
AndyA 0:29155ff9313e 33 { 0x10, 0x10, 0x10, 0x10, 0x1f }, // L
AndyA 0:29155ff9313e 34 { 0x11, 0x1b, 0x15, 0x11, 0x11 }, // M
AndyA 0:29155ff9313e 35 { 0x11, 0x19, 0x15, 0x13, 0x11 }, // N
AndyA 0:29155ff9313e 36 { 0x1f, 0x11, 0x11, 0x11, 0x1f }, // O
AndyA 0:29155ff9313e 37 { 0x1f, 0x11, 0x1f, 0x10, 0x10 }, // P
AndyA 0:29155ff9313e 38 { 0x1f, 0x11, 0x15, 0x1f, 0x04 }, // Q
AndyA 0:29155ff9313e 39 { 0x1f, 0x11, 0x1f, 0x12, 0x11 }, // R
AndyA 0:29155ff9313e 40 { 0x1f, 0x10, 0x1f, 0x01, 0x1F }, // S
AndyA 0:29155ff9313e 41 { 0x1f, 0x04, 0x04, 0x04, 0x04 }, // T
AndyA 0:29155ff9313e 42 { 0x11, 0x11, 0x11, 0x11, 0x1F }, // U
AndyA 0:29155ff9313e 43 { 0x11, 0x11, 0x11, 0x0a, 0x04 }, // V
AndyA 0:29155ff9313e 44 { 0x11, 0x11, 0x15, 0x1b, 0x11 }, // W
AndyA 0:29155ff9313e 45 { 0x11, 0x0a, 0x04, 0x0a, 0x11 }, // X
AndyA 0:29155ff9313e 46 { 0x11, 0x11, 0x1f, 0x04, 0x04 }, // Y
AndyA 0:29155ff9313e 47 { 0x1f, 0x02, 0x04, 0x08, 0x1f } // Z
AndyA 0:29155ff9313e 48 };
AndyA 0:29155ff9313e 49
AndyA 0:29155ff9313e 50
AndyA 0:29155ff9313e 51 miniFont::miniFont() {
AndyA 0:29155ff9313e 52
AndyA 0:29155ff9313e 53 rotate90 = false;
AndyA 0:29155ff9313e 54 fixedWidth = false;
AndyA 0:29155ff9313e 55 }
AndyA 0:29155ff9313e 56
AndyA 0:29155ff9313e 57
AndyA 0:29155ff9313e 58 uint8_t miniFont::getMinPixWidth(char letter)
AndyA 0:29155ff9313e 59 {
AndyA 0:29155ff9313e 60 switch(letter) {
AndyA 0:29155ff9313e 61 case '.':
AndyA 0:29155ff9313e 62 return 2;
AndyA 0:29155ff9313e 63 case ' ':
AndyA 0:29155ff9313e 64 case '1':
AndyA 0:29155ff9313e 65 case 'I':
AndyA 0:29155ff9313e 66 case 'i':
AndyA 0:29155ff9313e 67 return 3;
AndyA 0:29155ff9313e 68 case '!':
AndyA 0:29155ff9313e 69 return 1;
AndyA 0:29155ff9313e 70 case '?':
AndyA 0:29155ff9313e 71 return 4;
AndyA 0:29155ff9313e 72 default:
AndyA 0:29155ff9313e 73 return maxWidth;
AndyA 0:29155ff9313e 74 }
AndyA 0:29155ff9313e 75 }
AndyA 0:29155ff9313e 76
AndyA 0:29155ff9313e 77
AndyA 0:29155ff9313e 78 uint8_t miniFont::getPixWidth(char letter)
AndyA 0:29155ff9313e 79 {
AndyA 0:29155ff9313e 80 if (fixedWidth)
AndyA 0:29155ff9313e 81 return maxWidth;
AndyA 0:29155ff9313e 82 else
AndyA 0:29155ff9313e 83 return getMinPixWidth(letter);
AndyA 0:29155ff9313e 84 }
AndyA 0:29155ff9313e 85
AndyA 0:29155ff9313e 86 uint8_t miniFont::getPixHeight(char letter)
AndyA 0:29155ff9313e 87 {
AndyA 0:29155ff9313e 88 return 5;
AndyA 0:29155ff9313e 89 }
AndyA 0:29155ff9313e 90
AndyA 0:29155ff9313e 91 // gets the proportional letter
AndyA 0:29155ff9313e 92 bool miniFont::getRawChar(char letter, const char **rowArray)
AndyA 0:29155ff9313e 93 {
AndyA 0:29155ff9313e 94
AndyA 0:29155ff9313e 95 if ((letter>='A') && (letter<='Z')) { // upper
AndyA 0:29155ff9313e 96 *rowArray = letters[letter-'A'];
AndyA 0:29155ff9313e 97 return true;
AndyA 0:29155ff9313e 98 }
AndyA 0:29155ff9313e 99 if ((letter>='a') && (letter<='z')) { // lower
AndyA 0:29155ff9313e 100 *rowArray = letters[letter-'a'];
AndyA 0:29155ff9313e 101 return true;
AndyA 0:29155ff9313e 102 }
AndyA 0:29155ff9313e 103 if ((letter>='0') && (letter <='9')) {
AndyA 0:29155ff9313e 104 *rowArray = numbers[letter-'0'];
AndyA 0:29155ff9313e 105 return true;
AndyA 0:29155ff9313e 106 }
AndyA 0:29155ff9313e 107 if (letter == '.') {
AndyA 0:29155ff9313e 108 *rowArray = dot;
AndyA 0:29155ff9313e 109 return true;
AndyA 0:29155ff9313e 110 }
AndyA 0:29155ff9313e 111 if (letter == '!') {
AndyA 0:29155ff9313e 112 *rowArray = exclam;
AndyA 0:29155ff9313e 113 return true;
AndyA 0:29155ff9313e 114 }
AndyA 0:29155ff9313e 115 if (letter == '?') {
AndyA 0:29155ff9313e 116 *rowArray = quest;
AndyA 0:29155ff9313e 117 return true;
AndyA 0:29155ff9313e 118 }
AndyA 0:29155ff9313e 119 if (letter == ' ') {
AndyA 0:29155ff9313e 120 *rowArray = space;
AndyA 0:29155ff9313e 121 return true;
AndyA 0:29155ff9313e 122 }
AndyA 0:29155ff9313e 123 return false;
AndyA 0:29155ff9313e 124 }
AndyA 0:29155ff9313e 125
AndyA 0:29155ff9313e 126 // converts to fixed width if needed.
AndyA 0:29155ff9313e 127 bool miniFont::getVerticalChar(char letter, const char **rowArray)
AndyA 0:29155ff9313e 128 {
AndyA 0:29155ff9313e 129 if (!fixedWidth)
AndyA 0:29155ff9313e 130 return getRawChar(letter,rowArray);
AndyA 0:29155ff9313e 131
AndyA 0:29155ff9313e 132 uint8_t shift = (maxWidth - getMinPixWidth(letter)) / 2;
AndyA 0:29155ff9313e 133 if (shift == 0)
AndyA 0:29155ff9313e 134 return getRawChar(letter,rowArray);
AndyA 0:29155ff9313e 135
AndyA 0:29155ff9313e 136 const char *rawletter;
AndyA 0:29155ff9313e 137 if (getRawChar(letter,&rawletter)) {
AndyA 0:29155ff9313e 138 for (int i = 0; i < maxHeight; i++) {
AndyA 0:29155ff9313e 139 letterBuffer[i] = rawletter[i]<<shift;
AndyA 0:29155ff9313e 140 }
AndyA 0:29155ff9313e 141 *rowArray = (const char *)letterBuffer;
AndyA 0:29155ff9313e 142 return true;
AndyA 0:29155ff9313e 143 }
AndyA 0:29155ff9313e 144 return false;
AndyA 0:29155ff9313e 145 }
AndyA 0:29155ff9313e 146
AndyA 0:29155ff9313e 147 // rotates if needed.
AndyA 0:29155ff9313e 148 bool miniFont::getChar(char letter, const char **rowArray)
AndyA 0:29155ff9313e 149 {
AndyA 0:29155ff9313e 150 if (!rotate90) return getVerticalChar(letter,rowArray);
AndyA 0:29155ff9313e 151
AndyA 0:29155ff9313e 152 const char *vertical;
AndyA 0:29155ff9313e 153 if (!getVerticalChar(letter,&vertical))
AndyA 0:29155ff9313e 154 return false;
AndyA 0:29155ff9313e 155
AndyA 0:29155ff9313e 156 for (int i = 0; i < maxWidth; i++) {
AndyA 0:29155ff9313e 157 rotateBuffer[i] = 0;
AndyA 0:29155ff9313e 158 }
AndyA 0:29155ff9313e 159
AndyA 0:29155ff9313e 160 for (int i = 0; i < maxHeight; i++) {
AndyA 0:29155ff9313e 161 for (int j = 0; j < maxWidth; j++) {
AndyA 0:29155ff9313e 162 rotateBuffer[i] = vertical[j] << j;
AndyA 0:29155ff9313e 163 }
AndyA 0:29155ff9313e 164 }
AndyA 0:29155ff9313e 165 *rowArray = vertical;
AndyA 0:29155ff9313e 166 return true;
AndyA 0:29155ff9313e 167 }