Forked para SNOCC

Dependencies:   GPS

Dependents:   SNOCC_V1 SNOCC_V2

Fork of RA8875 by SNOCC

Revision:
98:ecebed9b80b2
Parent:
95:ef538bd687c0
Child:
100:0b084475d5a9
diff -r 40b74dd3695b -r ecebed9b80b2 GraphicsDisplay.cpp
--- a/GraphicsDisplay.cpp	Sat Nov 28 15:39:44 2015 +0000
+++ b/GraphicsDisplay.cpp	Thu Dec 17 12:16:40 2015 +0000
@@ -17,7 +17,7 @@
 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
 #define ERR(x, ...)  std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
-static void HexDump(char * title, uint8_t * p, int count)
+static void HexDump(const char * title, const uint8_t * p, int count)
 {
     int i;
     char buf[100] = "0000: ";
@@ -44,107 +44,6 @@
 #define HexDump(a, b, c)
 #endif
 
-#ifdef LOCALFONT
-const unsigned char FONT8x8[97][8] = {
-    0x08, 0x08, 0x08, 0X00, 0X00, 0X00, 0X00, 0X00, // columns, rows, num_bytes_per_char
-    0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // space 0x20
-    0x30, 0x78, 0x78, 0x30, 0x30, 0X00, 0x30, 0X00, // !
-    0x6C, 0x6C, 0x6C, 0X00, 0X00, 0X00, 0X00, 0X00, // "
-    0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0X00, // #
-    0x18, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x18, 0X00, // $
-    0X00, 0x63, 0x66, 0x0C, 0x18, 0x33, 0x63, 0X00, // %
-    0x1C, 0x36, 0x1C, 0x3B, 0x6E, 0x66, 0x3B, 0X00, // &
-    0x30, 0x30, 0x60, 0X00, 0X00, 0X00, 0X00, 0X00, // '
-    0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0X00, // (
-    0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0X00, // )
-    0X00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0X00, 0X00, // *
-    0X00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0X00, 0X00, // +
-    0X00, 0X00, 0X00, 0X00, 0X00, 0x18, 0x18, 0x30, // ,
-    0X00, 0X00, 0X00, 0x7E, 0X00, 0X00, 0X00, 0X00, // -
-    0X00, 0X00, 0X00, 0X00, 0X00, 0x18, 0x18, 0X00, // .
-    0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0X00, // / (forward slash)
-    0x3E, 0x63, 0x63, 0x6B, 0x63, 0x63, 0x3E, 0X00, // 0 0x30
-    0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x7E, 0X00, // 1
-    0x3C, 0x66, 0x06, 0x1C, 0x30, 0x66, 0x7E, 0X00, // 2
-    0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0X00, // 3
-    0x0E, 0x1E, 0x36, 0x66, 0x7F, 0x06, 0x0F, 0X00, // 4
-    0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0X00, // 5
-    0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0X00, // 6
-    0x7E, 0x66, 0x06, 0x0C, 0x18, 0x18, 0x18, 0X00, // 7
-    0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0X00, // 8
-    0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0X00, // 9
-    0X00, 0x18, 0x18, 0X00, 0X00, 0x18, 0x18, 0X00, // :
-    0X00, 0x18, 0x18, 0X00, 0X00, 0x18, 0x18, 0x30, // ;
-    0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0X00, // <
-    0X00, 0X00, 0x7E, 0X00, 0X00, 0x7E, 0X00, 0X00, // =
-    0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0X00, // >
-    0x3C, 0x66, 0x06, 0x0C, 0x18, 0X00, 0x18, 0X00, // ?
-    0x3E, 0x63, 0x6F, 0x69, 0x6F, 0x60, 0x3E, 0X00, // @ 0x40
-    0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0X00, // A
-    0x7E, 0x33, 0x33, 0x3E, 0x33, 0x33, 0x7E, 0X00, // B
-    0x1E, 0x33, 0x60, 0x60, 0x60, 0x33, 0x1E, 0X00, // C
-    0x7C, 0x36, 0x33, 0x33, 0x33, 0x36, 0x7C, 0X00, // D
-    0x7F, 0x31, 0x34, 0x3C, 0x34, 0x31, 0x7F, 0X00, // E
-    0x7F, 0x31, 0x34, 0x3C, 0x34, 0x30, 0x78, 0X00, // F
-    0x1E, 0x33, 0x60, 0x60, 0x67, 0x33, 0x1F, 0X00, // G
-    0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0X00, // H
-    0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // I
-    0x0F, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0X00, // J
-    0x73, 0x33, 0x36, 0x3C, 0x36, 0x33, 0x73, 0X00, // K
-    0x78, 0x30, 0x30, 0x30, 0x31, 0x33, 0x7F, 0X00, // L
-    0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0X00, // M
-    0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63, 0x63, 0X00, // N
-    0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0X00, // O
-    0x7E, 0x33, 0x33, 0x3E, 0x30, 0x30, 0x78, 0X00, // P 0x50
-    0x3C, 0x66, 0x66, 0x66, 0x6E, 0x3C, 0x0E, 0X00, // Q
-    0x7E, 0x33, 0x33, 0x3E, 0x36, 0x33, 0x73, 0X00, // R
-    0x3C, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x3C, 0X00, // S
-    0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // T
-    0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7E, 0X00, // U
-    0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0X00, // V
-    0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0X00, // W
-    0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0X00, // X
-    0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0X00, // Y
-    0x7F, 0x63, 0x46, 0x0C, 0x19, 0x33, 0x7F, 0X00, // Z
-    0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0X00, // [
-    0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0X00, // \ (back slash)
-    0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0X00, // ]
-    0x08, 0x1C, 0x36, 0x63, 0X00, 0X00, 0X00, 0X00, // ^
-    0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0xFF, // _
-    0x18, 0x18, 0x0C, 0X00, 0X00, 0X00, 0X00, 0X00, // ` 0x60
-    0X00, 0X00, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0X00, // a
-    0x70, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x6E, 0X00, // b
-    0X00, 0X00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0X00, // c
-    0x0E, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3B, 0X00, // d
-    0X00, 0X00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0X00, // e
-    0x1C, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0X00, // f
-    0X00, 0X00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x7C, // g
-    0x70, 0x30, 0x36, 0x3B, 0x33, 0x33, 0x73, 0X00, // h
-    0x18, 0X00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0X00, // i
-    0x06, 0X00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, // j
-    0x70, 0x30, 0x33, 0x36, 0x3C, 0x36, 0x73, 0X00, // k
-    0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0X00, // l
-    0X00, 0X00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0X00, // m
-    0X00, 0X00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0X00, // n
-    0X00, 0X00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0X00, // o
-    0X00, 0X00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78, // p
-    0X00, 0X00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F, // q
-    0X00, 0X00, 0x6E, 0x3B, 0x33, 0x30, 0x78, 0X00, // r
-    0X00, 0X00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0X00, // s
-    0x08, 0x18, 0x3E, 0x18, 0x18, 0x1A, 0x0C, 0X00, // t
-    0X00, 0X00, 0x66, 0x66, 0x66, 0x66, 0x3B, 0X00, // u
-    0X00, 0X00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0X00, // v
-    0X00, 0X00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0X00, // w
-    0X00, 0X00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0X00, // x
-    0X00, 0X00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x7C, // y
-    0X00, 0X00, 0x7E, 0x4C, 0x18, 0x32, 0x7E, 0X00, // z
-    0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0E, 0X00, // {
-    0x0C, 0x0C, 0x0C, 0X00, 0x0C, 0x0C, 0x0C, 0X00, // |
-    0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x70, 0X00, // }
-    0x3B, 0x6E, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // ~
-    0x1C, 0x36, 0x36, 0x1C, 0X00, 0X00, 0X00, 0X00  // DEL
-}; 
-#endif // LOCALFONT
 
 char mytolower(char a) {
     if (a >= 'A' && a <= 'Z')
@@ -192,28 +91,16 @@
     return noerror;
 }
 
-#ifdef LOCALFONT
-int GraphicsDisplay::character(int x, int y, int value)
+RetCode_t GraphicsDisplay::SelectUserFont(const unsigned char * _font)
 {
-    if (value <= 0x1F && value >= 7F)
-        return 0;
-    
-    return blitbit(x, y, FONT8X8[0][0], FONT8X8[0][1], 
-        (char *)&(FONT8x8[value - 0x1F][0]));
+    font = _font;     // trusting them, but it might be good to put some checks in here...
+    return noerror;
 }
-#else
+
 int GraphicsDisplay::character(int x, int y, int c)
 {
-    unsigned int offset;
-    const unsigned char * charRecord;
- 
-    if (c <= 0x1F || c >= 0x7F)
-        return 0;
-    offset = font[0];                    // bytes / char
-    charRecord = &font[((c - ' ') * offset) + 4];      // start of char bitmap
-    return fontblit(x, y, font, charRecord);
+    return fontblit(x, y, font, c);
 }
-#endif
 
 RetCode_t GraphicsDisplay::window(loc_t x, loc_t y, dim_t w, dim_t h)
 {
@@ -269,58 +156,63 @@
     return WindowMax();
 }
 
-#ifdef LOCALFONT
-int GraphicsDisplay::blitbit(int x, int y, int w, int h, const char * color)
+// 8 byte "info" section
+//0x00,                // unknown    ????????
+//0x00,                // unknown    ????????
+//0x20,0x00,           // First char 32
+//0x7F,0x00,           // Last char  127
+//0x25,                // Font Height 37
+//0x00,                // Unknown      0  ????????
+//
+//0x01,0x88,0x01,0x00  // ' ' is  1 pixel  wide, data is at offset 0x0188
+//0x0B,0xAD,0x01,0x00  // '!' is 11 pixels wide, data is at offset 0x01AD
+//0x0D,0xF7,0x01,0x00  // '"' is 13 pixels wide, data is at offset 0x01F7
+//...
+//0x00,...             // ' ' data stream.
+//0x00,0x06,0x00,0x07,0x80,0x07,0xC0,0x07,0xC0,0x07,0xC0 // '!'
+//...
+int GraphicsDisplay::fontblit(int x, int y, const unsigned char * fontTable, const unsigned char c)
 {
-    _foreground = 0xFFFF;
-    INFO("blitbit(%d,%d, %d,%d, %02X) [%04X,%04X]", x,y, w,h, *color, _foreground, _background);
-    INFO("%lu  %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
-        color,
-        color[0], color[1], color[2], color[3], color[4], color[5], color[6], color[7], 
-        color[8], color[9], color[10], color[11], color[12], color[13], color[14], color[15]);
-    window(x, y, w, h);
-    _StartGraphicsStream();
-    for (int i = 0; i < w*h; i++) {
-        char byte = color[i >> 3];
-        int offset = i & 0x7;
-        if (offset == 0)
-            INFO(" %2d = %02X", i>>3, byte);
-        int c = ((byte << offset) & 0x80) ? _foreground : _background;
-        _putp(c);
-    }
-    _EndGraphicsStream();
-    WindowMax();
-    return w;
-}
-#endif
-
+    uint16_t offsetToCharLookup;
+    uint16_t firstChar = font[3] * 256 + font[2];
+    uint16_t lastChar  = font[5] * 256 + font[4];
+    uint8_t charHeight = font[6];
+    const unsigned char * charRecord;   // width, data, data, data, ...
+    
+    INFO("first:%d, last:%d, c:%d", firstChar, lastChar, c);
+    if (c < firstChar || c > lastChar)
+        return 0;       // advance zero pixels since it was unprintable...
+    
+    // 8 bytes of preamble to the first level lookup table
+    offsetToCharLookup = 8 + 4 * (c - firstChar);    // 4-bytes: width(pixels), 16-bit offset from table start, 0
+    uint8_t charWidth = font[offsetToCharLookup];
+    charRecord = font + font[offsetToCharLookup + 2] * 256 + font[offsetToCharLookup + 1];
 
-int GraphicsDisplay::fontblit(int x, int y, const unsigned char * fontTable, const unsigned char * fontChar)
-{
-    //int fontWidth = font[1];                       // get hor size of font
-    int fontHeight = font[2];                      // get vert size of font
-    int bytesPerLine = font[3];                       // bytes per line
-    int charWidth = fontChar[0];        // width of this character
-    int px, py;
-    
-    //INFO("(%d,%d) %lu, %lu %X/%X", x,y, fontTable, fontChar, _foreground, _background);
-    //INFO("char size (%d,%d)", charWidth, fontHeight);
-    //HexDump("char", (uint8_t *)fontChar, 32);
-    //INFO("(f,b) = (%04X,%04X)", _foreground, _background)
-    window(x, y, charWidth, fontHeight);
+    INFO("hgt:%d, wdt:%d", charHeight, charWidth);
+    // clip to the edge of the screen
+    //if (x + charWidth >= width())
+    //    charWidth = width() - x;
+    //if (y + charHeight >= height())
+    //    charHeight = height() - y;
+    window(x, y, charWidth, charHeight);
     _StartGraphicsStream();
-    //INFO("(f,b) = (%04X,%04X)", _foreground, _background)
-    for (py = 0; py < fontHeight; py++) {
-        int bitmask = 1 << (py & 7);
+    while (charHeight--) {
+        uint8_t pixels = charWidth;
+        uint8_t bitmask = 0x01;
         
-        for (px = 0; px < charWidth; px++) {
-            int offset = (py / 8) + px * bytesPerLine;
-            unsigned char byte = fontChar[offset + 1];  // skip the char's # bits wide value
+        while (pixels) {
+            uint8_t byte = *charRecord;
+            INFO("byte, mask: %02X, %02X", byte, bitmask);
             color_t c = (byte & bitmask) ? _foreground : _background;
-            //INFO("(%2d,%2d) %02X & %02X => %04X [%04X,%04X]", px, py, byte, bitmask, c, _foreground, _background);
-            //pixel(x+px, y+py, c);
             _putp(c);
+            bitmask <<= 1;
+            if (pixels > 1 && bitmask == 0) {
+                bitmask = 0x01;
+                charRecord++;
+            }
+            pixels--;
         }
+        charRecord++;
     }
     _EndGraphicsStream();
     WindowMax();