mirror of
https://github.com/usetrmnl/bb_epaper.git
synced 2026-04-29 13:43:26 -07:00
91 lines
4.0 KiB
Arduino
91 lines
4.0 KiB
Arduino
//
|
|
// Compressed font example
|
|
// written by Larry Bank
|
|
//
|
|
// This sketch demonstrates how to work with BBF (BitBank Font) files
|
|
// and render the characters to a color LCD display
|
|
// This should definitely be considered an advanced topic. Some of this functionality will be baked into
|
|
// my display libraries eventually, but the paid vs free divide makes it necessary to demonstrate how to
|
|
// work with the compressed font files created by the Group5 fontconvert tool
|
|
//
|
|
#include <Group5.h>
|
|
#include <bb_spi_lcd.h>
|
|
#include "Roboto_Black_40.h" // BBF (BitBank Font file included as hex data to compile with the sketch)
|
|
|
|
BB_SPI_LCD lcd; // class instance of bb_spi_lcd display library
|
|
G5DECODER g5dec; // class instance of Group5 image decoder
|
|
uint16_t u16Temp[256]; // holds one line of a character being displayed
|
|
|
|
//
|
|
// Draw a string of characters in the given font at the given position and color
|
|
// The y coordinate is relative to the baseline of the character, not the top
|
|
// This means that drawing at coordinate 0,0 on the display will usually get clipped 100%
|
|
// For this example, a 40pt font is about 64 pixels tall, so the baseline should be top+64
|
|
//
|
|
void DrawString(const char *szMsg, const BB_FONT *pFont, int x, int y, uint16_t u16FG, uint16_t u16BG)
|
|
{
|
|
int i, rc, iBitOff, dx, dy, cx, cy, tx, ty;
|
|
char c;
|
|
BB_GLYPH *pGlyph;
|
|
uint8_t *s, u8, u8Mask, *pG5, u8Temp[32]; // 32 bytes can hold 256 1-bit pixels (of each character)
|
|
uint16_t *d;
|
|
|
|
u16FG = __builtin_bswap16(u16FG); // swap for big endian (the SPI LCD data format)
|
|
u16BG = __builtin_bswap16(u16BG);
|
|
i = 0;
|
|
cx = (pFont->last - pFont->first + 1); // Glyph count
|
|
pG5 = (uint8_t *)&pFont->glyphs[cx]; // compressed data starts after the last glyph
|
|
while (szMsg[i] != 0 && x < lcd.width()) {
|
|
c = szMsg[i++];
|
|
if (c < pFont->first || c > pFont->last) // undefined character
|
|
continue; // skip it
|
|
c -= pFont->first; // subtract first char of font defined to start from index 0
|
|
pGlyph = (BB_GLYPH *)&pFont->glyphs[c];
|
|
// set up the destination window (rectangle) on the display
|
|
dx = x + pGlyph->xOffset; // offset from character UL to start drawing
|
|
dy = y + pGlyph->yOffset;
|
|
cx = pGlyph->width;
|
|
cy = pGlyph->height;
|
|
if (dy + cy > lcd.height())
|
|
cy = lcd.height() - dy; // clip bottom edge
|
|
if (dx + cx > lcd.width())
|
|
cx = lcd.width() - dx; // clip right edge
|
|
lcd.setAddrWindow(dx, dy, cx, cy); // tell the LCD the memory window in advance of writing the pixels
|
|
s = pG5 + pGlyph->bitmapOffset; // start of bitmap data
|
|
ty = (pGlyph[1].bitmapOffset - pGlyph[0].bitmapOffset); // compressed size
|
|
if (ty < 0 || ty > 4096) ty = 4096; // DEBUG
|
|
rc = g5dec.init(pGlyph->width, cy, s, ty);
|
|
if (rc != G5_SUCCESS) return;
|
|
for (ty=0; ty<cy && rc == G5_SUCCESS; ty++) { // loop over the lines (all equal width)
|
|
rc = g5dec.decodeLine(u8Temp); // decode the 1-bit image one line at a time
|
|
s = u8Temp;
|
|
d = u16Temp; // point to start of output buffer
|
|
u8Mask = 0x80; // MSB first
|
|
u8 = *s++; // preload first byte
|
|
for (tx=0; tx<cx; tx++) { // loop over the pixels on this line and convert from 1 to 16-bits
|
|
*d++ = (u8 & u8Mask) ? u16FG : u16BG; // 1/0 foreground or background color is written
|
|
u8Mask >>= 1;
|
|
if (u8Mask == 0) { // next source byte
|
|
u8 = *s++;
|
|
u8Mask = 0x80;
|
|
}
|
|
} // for x
|
|
lcd.pushPixels(u16Temp, cx); // write to the memory window one line at a time
|
|
} // for ty
|
|
x += pGlyph->xAdvance;
|
|
} // while characters
|
|
} /* DrawString() */
|
|
|
|
void setup()
|
|
{
|
|
lcd.begin(DISPLAY_CYD_2USB); // easy initialization of a named display type (ESP32 w/ 2.8" 240x320 ST7789)
|
|
lcd.fillScreen(TFT_BLACK);
|
|
DrawString("Hello", (BB_FONT *)Roboto_Black_40, 0, 70, TFT_GREEN, TFT_BLACK);
|
|
DrawString("World!", (BB_FONT *)Roboto_Black_40, 0, 140, TFT_BLUE, TFT_BLACK);
|
|
} /* setup() */
|
|
|
|
void loop()
|
|
{
|
|
} /* loop() */
|
|
|