Is there a smaller font for use that is still readable?
/Peter
Is there a smaller font for use that is still readable?
/Peter
Is there a smaller font for use that is still readable?
Kinda.
I made one for my 4^3 cube about a year ago, where most letters are 4 by 4, and a few are 4 by 5 ("lending" a row of pixels at the top of the cube). Later I extended it to also include lower case letters. Most are readable-ish(?)... with some (or a lot of) goodwill
Depending on the size of your display, it might not be too readable up close.
Heres the code section for the font table. I call it a nibblefont, as each letter is 4 bits wide (but 5 rows high). So I'm storing rows for 2 characters in one byte.
It ought to be optimized by putting it in progmem really, but (as usual) I havent gotten around to do that yet. For now I just have it as a global variable array.
// nibble font, 4 bits wide * 5 rows high
const int fontWidth = 4; // Pretty much must be 4!
const int fontHeight = 5;
const int dispWidth = 8; // width of display unit/vram array in pixels
// Nibble font table
unsigned char nibblefont_table[][fontHeight] = {
{ 0x06, 0x06, 0x06, 0x00, 0x04 }, // ! - ASCII 0x20 (space) + "!"
{ 0xA5, 0xAF, 0x06, 0x0F, 0x0A }, // "# (sort of)
{ 0x20, 0x79, 0xA2, 0x74, 0x29 }, // $% (well...)
{ 0x64, 0xA4, 0x50, 0xA0, 0xD0 }, // &'-ish
{ 0x24, 0x42, 0x42, 0x42, 0x24 }, // ()
{ 0x00, 0x94, 0x6E, 0x64, 0x90 }, // *+
{ 0x00, 0x00, 0x0E, 0x20, 0x40 }, // ,-
{ 0x00, 0x01, 0x02, 0x44, 0x08 }, // ./
{ 0xE2, 0xA6, 0xA2, 0xA2, 0xE2 }, // 01
{ 0xEE, 0x22, 0xE6, 0x82, 0xEE }, // 23
{ 0xAE, 0xA8, 0xEE, 0x22, 0x2E }, // 45
{ 0x8E, 0x82, 0xE2, 0xA2, 0xE2 }, // 67
{ 0xEE, 0xAA, 0xEE, 0xA2, 0xE2 }, // 89
{ 0x00, 0x22, 0x00, 0x22, 0x04 }, // :;
{ 0x20, 0x4E, 0x80, 0x4E, 0x20 }, // <=
{ 0x8E, 0x42, 0x26, 0x40, 0x84 }, // >?
{ 0x64, 0x9A, 0xBE, 0x8A, 0x7A }, // @A
{ 0xC6, 0xA8, 0xC8, 0xA8, 0xC6 }, // BC
{ 0xCE, 0xA8, 0xAC, 0xA8, 0xCE }, // DE
{ 0xE6, 0x88, 0xCE, 0x8A, 0x86 }, // FG
{ 0xA4, 0xA4, 0xE4, 0xA4, 0xA4 }, // HI
{ 0x69, 0x2A, 0x2C, 0x2A, 0x49 }, // JK
{ 0x8A, 0x8E, 0x8E, 0x8A, 0xEA }, // LM
{ 0x04, 0x9A, 0xDA, 0xBA, 0x94 }, // NO
{ 0xC4, 0xAA, 0xCA, 0x8E, 0x86 }, // PQ
{ 0xC6, 0xA8, 0xC4, 0xA2, 0xAC }, // RS
{ 0xE0, 0x4A, 0x4A, 0x4A, 0x44 }, // TU
{ 0x09, 0xA9, 0xA9, 0x6F, 0x26 }, // vW (sort of..)
{ 0x0A, 0xAA, 0x46, 0xA2, 0x04 }, // XY
{ 0xE6, 0x24, 0x44, 0x84, 0xE6 }, // Z[
{ 0x06, 0x82, 0x42, 0x22, 0x16 }, // \]
{ 0x40, 0xA0, 0x00, 0x00, 0x0F }, // ^_
{ 0x40, 0x20, 0x0E, 0x0A, 0x0F }, // `a (sort of)
{ 0x80, 0x80, 0xEC, 0xA8, 0xEC }, // bc
{ 0x20, 0x24, 0xEA, 0xAC, 0xE6 }, // de
{ 0x60, 0x4E, 0xEE, 0x42, 0x4E }, // fg-ish
{ 0x84, 0x80, 0xE4, 0xA4, 0xA4 }, // hi
{ 0x48, 0x08, 0x4A, 0x4C, 0x8A }, // jk
{ 0x40, 0x40, 0x4F, 0x49, 0x49 }, // lm-ish
{ 0x00, 0x00, 0xEE, 0xAA, 0xAE }, // no
{ 0x00, 0xEE, 0xAA, 0xEE, 0x82 }, // pq
{ 0x06, 0xA8, 0xC4, 0x82, 0x8C }, // rs-ish
{ 0x40, 0x40, 0xEA, 0x4A, 0x6E }, // tu
{ 0x00, 0x00, 0xA9, 0x6F, 0x2F }, // vw-ish
{ 0x00, 0x00, 0xAA, 0x44, 0xA8 }, // xy
{ 0x06, 0xE4, 0x2C, 0x44, 0xE6 }, // z{
{ 0x46, 0x42, 0x43, 0x42, 0x46 }};// |}
I don't know how useful this is, but here is my scrolltext function (from another program, since it was somewhat simpler, but using the same font and method).
It writes the characters to (possibly) two display arrays, one for red and one for green colors (I used it with one RG 8x8 led matrix).
// Scrolltext function
// Draws (part of) a text message to a global 8 by 8 2D array (for use in a matrix display)
// of width dispWidth and height at least 5 (or what the font height is).
// Note: msgProgress is kind of a backwards X (horizontal) coordinate, because the intended use
// of this function is to scroll a message across a display from the right-most side towards left.
// Pad text with spaces if it needs to scroll off-screen.
// It can display static messages too, but the msgProgress will be from the rightmost end
// of the display instead of the normal left end.
// 2010.04.18 raron
void scrollText(char* textString, int textLength, int msgProgress, int rowAdd, byte red, byte green, boolean wave, boolean translucent)
{
// some initial values
int msgPixelLength = textLength * fontWidth;
//int msgProgress = (millis()/textSpeed) % msgPixelLength;
//int msgProgress = int( (msgPixelLength/2.0) + ((msgPixelLength/2.0) * sin(millis()/textSpeed/100.0)));
int msgDispStartPosX = dispWidth - msgProgress; // start position on display
if (msgDispStartPosX < 0) msgDispStartPosX = 0;
int msgDispEndPosX = dispWidth - (msgProgress - msgPixelLength);
if (msgDispEndPosX < 0) msgDispEndPosX = 0;
if (msgDispEndPosX > dispWidth) msgDispEndPosX = dispWidth;
int msgDispWidth = msgDispEndPosX - msgDispStartPosX;
int msgStartPos = msgProgress - dispWidth;
if (msgStartPos < 0) msgStartPos = 0;
int msgStartChar = msgStartPos / fontWidth; // first character of text string to (partially?) display
int msgEndPos = msgProgress;
if (msgEndPos > msgPixelLength) msgEndPos = msgPixelLength;
int msgEndChar = msgEndPos / fontWidth; // last character of text string to (partially?) display
for (int msgPos=0; msgPos<msgDispWidth; msgPos++)
{
// get a character
int outputChar = (msgPos + msgStartPos) / fontWidth;
if (outputChar > textLength) outputChar = textLength;
int nibbleIndex = (int)textString[outputChar] - 0x20;
//if (nibbleIndex > 0x01) nibbleIndex -= 0x0E; // It is not space nor "!"..
//if (nibbleIndex > 0x11) nibbleIndex -= 0x01; // its a letter, skip "@",
//if (nibbleIndex > 0x2B) nibbleIndex -= 0x20; // no small letters
boolean highNibble;
if (nibbleIndex % 2 == 0) highNibble = true; else highNibble=false; // which nibble in nibblefont_table
nibbleIndex /= 2; // correct for half nibble address
// Some Wave text fun
if (wave) rowAdd = int(2 + 2 * sin(2*PI*millis()/1000 + (2*PI*msgPos/32)));
// clean up pixels above and below character column
if (!translucent)
{
int bottomRow = 8 - fontHeight + rowAdd;
if (bottomRow > 8) bottomRow = 8;
if (rowAdd > 0)
{
for(int rowClean=0; rowClean<rowAdd; rowClean++)
{
redBitmap[msgDispStartPosX+msgPos][rowClean] = 0;
greenBitmap[msgDispStartPosX+msgPos][rowClean] = 0;
}
}
if (bottomRow < 8)
{
for(int rowClean=bottomRow; rowClean<8; rowClean++)
{
redBitmap[msgDispStartPosX+msgPos][rowClean] = 0;
greenBitmap[msgDispStartPosX+msgPos][rowClean] = 0;
}
}
}
// transfer characters to vram
byte fontRow;
byte fontCol;
for (int row=0; row<fontHeight; row++)
{
fontRow = nibblefont_table[nibbleIndex][row];
if (highNibble) fontRow >>= 4; // transfer to low nibble if odd (high) nibble
fontCol = (msgStartPos + msgPos) % fontWidth;
fontRow >>= (3-fontCol); // get one font bit..
fontRow &= 0x01; // keep only the bit from the font
if(translucent)
{
redBitmap[msgDispStartPosX+msgPos][row+rowAdd] |= red * fontRow;
greenBitmap[msgDispStartPosX+msgPos][row+rowAdd] |= green * fontRow;
} else {
redBitmap[msgDispStartPosX+msgPos][row+rowAdd] = red * fontRow;
greenBitmap[msgDispStartPosX+msgPos][row+rowAdd] = green * fontRow;
}
}
}
}
And finally, a test implementation:
:
:
:
// Text stuff
char textString[] = " Arduino scrolltext test! ";
int textLength = sizeof(textString)-1;
const int textSpeed = 90;
:
:
:
void loop()
{
:
:
:
// Scrolltext test
if (mode == 10)
{
int msgPixelLength = textLength * fontWidth;
int msgProgress = (millis()/textSpeed) % msgPixelLength;
scrollText(textString, textLength, msgProgress, 2, 255, 64, true, false);
}
:
:
:
}
I have added the x11 4x6 font for my arduino library:
font can be seen here:
http://rasher.dk/rockbox/fonts/misc/
I also like this font very much:
http://www.miniml.com/fonts/font/uni_05_53/index.htm
It can be converted and used by the dogm128 lib. However, I have not included this font because of license issues.
Oliver