1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
#include "render.h"
#include "decoder.h"
#include "display.h"
#include "fonts.h"
#include "smallfonts.h"
#include <string.h>
/* 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;
}
|