Pages: [1]   Go Down
Author Topic: smaler font than SystemFont5x7  (Read 470 times)
0 Members and 1 Guest are viewing this topic.
Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is there a smaller font for use that is still readable?

/Peter
Logged

Norway
Offline Offline
Sr. Member
****
Karma: 4
Posts: 423
microscopic quantum convulsions of space-time
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 smiley-razz

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.

Code:
// 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).

Code:
// 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:

Code:
:
:
:
// 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);
  }
  :
  :
  :
}
Logged

Germany
Offline Offline
Edison Member
*
Karma: 100
Posts: 1243
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have added the x11 4x6 font for my arduino library:
http://code.google.com/p/dogm128/source/browse/libraries/Dogm/utility/font_4x6.c

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
Logged

Pages: [1]   Go Up
Jump to: