HackRF-Treasure-Chest/Software/portapack-mayhem/hackrf/firmware/common/rad1o/render.c
2022-09-22 09:26:57 -07:00

163 lines
3.7 KiB
C

#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;
}