#include "render.h" #include "decoder.h" #include "display.h" #include "fonts.h" #include "smallfonts.h" #include /* Global Variables */ static const struct FONT_DEF *font = NULL; static struct EXTFONT efont; static uint8_t color_bg = 0xff; /* background color */ static uint8_t color_fg = 0x00; /* foreground color */ /* Exported Functions */ void rad1o_setTextColor(uint8_t bg, uint8_t fg) { color_bg = bg; color_fg = fg; } void rad1o_setIntFont(const struct FONT_DEF *newfont) { memcpy(&efont.def, newfont, sizeof(struct FONT_DEF)); efont.type = FONT_INTERNAL; font = &efont.def; } int rad1o_getFontHeight(void) { if (font) return font->u8Height; return 8; // XXX: Should be done right. } static int _getIndex(int c) { #define ERRCHR (font->u8FirstChar + 1) /* Does this font provide this character? */ if (c < font->u8FirstChar) c = ERRCHR; if (c > font->u8LastChar && efont.type != FONT_EXTERNAL && font->charExtra == NULL) c = ERRCHR; if (c > font->u8LastChar && (efont.type == FONT_EXTERNAL || font->charExtra != NULL)) { int cc = 0; while (font->charExtra[cc] < c) cc++; if (font->charExtra[cc] > c) c = ERRCHR; else c = font->u8LastChar + cc + 1; }; c -= font->u8FirstChar; return c; } int rad1o_DoChar(int sx, int sy, int c) { if (font == NULL) { font = &Font_7x8; }; /* how many bytes is it high? */ char height = (font->u8Height - 1) / 8 + 1; char hoff = (8 - (font->u8Height % 8)) % 8; const uint8_t *data; int width, preblank = 0, postblank = 0; do { /* Get Character data */ /* Get intex into character list */ c = _getIndex(c); /* starting offset into character source data */ int toff = 0; if (font->u8Width == 0) { for (int y = 0; y < c; y++) toff += font->charInfo[y].widthBits; width = font->charInfo[c].widthBits; toff *= height; data = &font->au8FontTable[toff]; postblank = 1; } else if (font->u8Width == 1) { // NEW CODE // Find offset and length for our character for (int y = 0; y < c; y++) toff += font->charInfo[y].widthBits; width = font->charInfo[c].widthBits; if (font->au8FontTable[toff] >> 4 == 15) { // It's a raw character! preblank = font->au8FontTable[toff + 1]; postblank = font->au8FontTable[toff + 2]; data = &font->au8FontTable[toff + 3]; width = (width - 3 / height); } else { data = rad1o_pk_decode( &font->au8FontTable[toff], &width); } } else { toff = (c)*font->u8Width * 1; width = font->u8Width; data = &font->au8FontTable[toff]; }; } while (0); #define xy_(x, y) \ ((x < 0 || y < 0 || x >= RESX || y >= RESY) ? 0 : (y)*RESX + (x)) #define gPx(x, y) (data[x * height + (height - y / 8 - 1)] & (1 << (y % 8))) int x = 0; /* Fonts may not be byte-aligned, shift up so the top matches */ sy -= hoff; sx += preblank; uint8_t *lcdBuffer = rad1o_lcdGetBuffer(); /* per line */ for (int y = hoff; y < height * 8; y++) { if (sy + y >= RESY) continue; /* Optional: empty space to the left */ for (int b = 1; b <= preblank; b++) { if (sx >= RESX) continue; lcdBuffer[xy_(sx - b, sy + y)] = color_bg; }; /* Render character */ for (x = 0; x < width; x++) { if (sx + x >= RESX) continue; if (gPx(x, y)) { lcdBuffer[xy_(sx + x, sy + y)] = color_fg; } else { lcdBuffer[xy_(sx + x, sy + y)] = color_bg; }; }; /* Optional: empty space to the right */ for (int m = 0; m < postblank; m++) { if (sx + x + m >= RESX) continue; lcdBuffer[xy_(sx + x + m, sy + y)] = color_bg; }; }; return sx + (width + postblank); } int rad1o_DoString(int sx, int sy, const char *s) { const char *c; for (c = s; *c != 0; c++) { sx = rad1o_DoChar(sx, sy, *c); }; return sx; }