Replace OpenGD77 fonts with Adafruit GFX fonts

OpenGD77 custom binary font format was replaced with Adafruit GFX
library standard font format, to be able to reuse all the available
fonts, together with the relative tools.
replace/4e1d789a6e146359e0d72783f85aefa9d651786d
Niccolò Izzo 2020-11-17 14:30:20 +01:00
rodzic c0ed3a7466
commit 91d0e05af7
6 zmienionych plików z 195 dodań i 156 usunięć

Wyświetl plik

@ -18,10 +18,10 @@ openrtx_src = ['openrtx/src/main.c',
'openrtx/src/threads.c']
openrtx_inc = ['openrtx/include/interfaces',
'openrtx/include/fonts',
'openrtx/include',
'platform/drivers/ADC',
'platform/drivers/tones']
'platform/drivers/tones',
'openrtx/include/fonts/adafruit']
## RTOS
rtos_src = ['rtos/uC-OS3/Source/__dbg_uCOS-III.c',

Wyświetl plik

@ -23,6 +23,12 @@
#include <stdint.h>
#include <stdbool.h>
#include <display.h>
#include "gfxfont.h"
#include "TomThumb.h"
#include "FreeSans9pt7b.h"
#include "FreeSans12pt7b.h"
#include "FreeSans18pt7b.h"
#include "FreeSans24pt7b.h"
/**
* Standard high-level graphic interface for all display types.
@ -72,20 +78,29 @@ typedef struct color_t
typedef enum
{
FONT_SIZE_1 = 0,
FONT_SIZE_1_BOLD,
FONT_SIZE_2,
FONT_SIZE_3,
FONT_SIZE_4
FONT_SIZE_6PT = 0,
FONT_SIZE_9PT,
FONT_SIZE_12PT,
FONT_SIZE_18PT,
FONT_SIZE_24PT
} fontSize_t;
typedef enum
{
TEXT_ALIGN_LEFT = 0,
TEXT_ALIGN_CENTER,
TEXT_ALIGN_RIGHT
TEXT_ALIGN_LEFT = 0,
TEXT_ALIGN_CENTER,
TEXT_ALIGN_RIGHT
} textAlign_t;
/**
* Selection of the fonts, ordered by the fontSize_t enum.
*/
static GFXfont fonts[] = { TomThumb, // 6pt
FreeSans9pt7b, // 9pt
FreeSans12pt7b, // 12pt
FreeSans18pt7b, // 18pt
FreeSans24pt7b }; // 24pt
/**
* This function calls the correspondent method of the low level interface display.h
* It initializes the display.

Wyświetl plik

@ -27,7 +27,6 @@
#include <stdio.h>
#include "display.h"
#include "graphics.h"
#include "font_OpenGD77.h"
typedef enum
{
@ -158,92 +157,104 @@ void gfx_drawRect(point_t start, uint16_t width, uint16_t height, color_t color,
}
}
void gfx_print(point_t start, const char *text, fontSize_t size, textAlign_t alignment, color_t color)
{
uint8_t *currentCharData;
uint8_t *currentFont;
uint16_t *writePos;
uint8_t *readPos;
bw_t bw = _color2bw(color);
switch(size)
{
case FONT_SIZE_1:
currentFont = (uint8_t *) font_6x8;
break;
case FONT_SIZE_1_BOLD:
currentFont = (uint8_t *) font_6x8_bold;
break;
case FONT_SIZE_2:
currentFont = (uint8_t *) font_8x8;
break;
case FONT_SIZE_3:
currentFont = (uint8_t *) font_8x16;
break;
case FONT_SIZE_4:
currentFont = (uint8_t *) font_16x32;
break;
default:
return;// Invalid font selected
/**
* Compute the pixel size of the first text line
* @param f: font used as the source of glyphs
* @param text: the input text
* @param length: the length of the input text, used for boundary checking
*/
static inline uint16_t get_line_size(GFXfont f,
const char *text,
uint16_t length) {
uint16_t line_size = 0;
for(unsigned i = 0;
i < length && text[i] != '\n' && text[i] != '\r';
i++) {
GFXglyph glyph = f.glyph[text[i] - f.first];
if (line_size + glyph.xAdvance < SCREEN_WIDTH)
line_size += glyph.xAdvance;
else
break;
}
return line_size;
}
int16_t startCode = currentFont[2]; // get first defined character
int16_t endCode = currentFont[3]; // get last defined character
int16_t charWidthPixels = currentFont[4]; // width in pixel of one char
int16_t charHeightPixels = currentFont[5]; // page count per char
int16_t bytesPerChar = currentFont[7]; // bytes per char
int16_t sLen = strlen(text);
// Compute amount of letters that fit till the end of the screen
if ((charWidthPixels*sLen) + start.x > SCREEN_WIDTH)
{
sLen = (SCREEN_WIDTH-start.x)/charWidthPixels;
}
if (sLen < 0) return;
/**
* Compute the start x coordinate of a new line of given pixel size
* @param alinment: enum representing the text alignment
* @param line_size: the size of the current text line in pixels
*/
static inline uint16_t get_reset_x(textAlign_t alignment, uint16_t line_size) {
switch(alignment)
{
case TEXT_ALIGN_LEFT:
// left aligned, do nothing.
break;
return 0;
case TEXT_ALIGN_CENTER:
start.x = (SCREEN_WIDTH - (charWidthPixels * sLen))/2;
break;
return (SCREEN_WIDTH - line_size)/2;
case TEXT_ALIGN_RIGHT:
start.x = SCREEN_WIDTH - (charWidthPixels * sLen);
break;
return SCREEN_WIDTH - line_size;
}
return 0;
}
for (int16_t i=0; i<sLen; i++)
{
uint32_t charOffset = (text[i] - startCode);
void gfx_print(point_t start, const char *text, fontSize_t size, textAlign_t alignment, color_t color) {
// End boundary checking.
if (charOffset > endCode)
{
charOffset = ('?' - startCode); // Substitute unsupported ASCII code by a question mark
bw_t bw = _color2bw(color);
GFXfont f = fonts[size];
size_t len = strlen(text);
// Compute size of the first row in pixels
uint16_t line_size = get_line_size(f, text, len);
uint16_t reset_x = get_reset_x(alignment, line_size);
start.x = reset_x;
/* For each char in the string */
for(unsigned i = 0; i < len; i++) {
char c = text[i];
GFXglyph glyph = f.glyph[c - f.first];
uint8_t *bitmap = f.bitmap;
uint16_t bo = glyph.bitmapOffset;
uint8_t w = glyph.width, h = glyph.height;
int8_t xo = glyph.xOffset,
yo = glyph.yOffset;
uint8_t xx, yy, bits = 0, bit = 0;
// Handle newline and carriage return
if (c == '\n') {
start.x = reset_x;
start.y += f.yAdvance;
continue;
} else if (c == '\r') {
start.x = reset_x;
continue;
}
currentCharData = (uint8_t *)&currentFont[8 + (charOffset * bytesPerChar)];
// Handle wrap around
if (start.x + glyph.xAdvance > SCREEN_WIDTH) {
// Compute size of the first row in pixels
line_size = get_line_size(f, text, len);
start.x = reset_x = get_reset_x(alignment, line_size);
start.y += f.yAdvance;
}
// We print the character from up-left to bottom right
for(int16_t vscan=0; vscan < charHeightPixels; vscan++) {
for(int16_t hscan=0; hscan < charWidthPixels; hscan++) {
int16_t charChunk = vscan / 8;
int16_t bitIndex = (hscan + charChunk * charWidthPixels) * 8 +
vscan % 8;
int16_t byte = bitIndex >> 3;
int16_t bitMask = 1 << (bitIndex & 7);
if (currentCharData[byte] & bitMask)
{
point_t pos = {start.x + hscan + i * charWidthPixels,
start.y + vscan};
_bw_setPixel(pos, bw);
// Draw bitmap
for (yy = 0; yy < h; yy++) {
for (xx = 0; xx < w; xx++) {
if (!(bit++ & 7)) {
bits = bitmap[bo++];
}
if (bits & 0x80) {
if (start.y + yo + yy < SCREEN_HEIGHT && start.x + xo + xx < SCREEN_WIDTH && start.y + yo + yy > 0 && start.x + xo + xx > 0) {
point_t pos = {start.x + xo + xx, start.y + yo + yy};
_bw_setPixel(pos, bw);
}
}
bits <<= 1;
}
}
start.x += glyph.xAdvance;
}
}

Wyświetl plik

@ -27,7 +27,6 @@
#include <hwconfig.h>
#include "display.h"
#include "graphics.h"
#include "font_OpenGD77.h"
/* This graphics driver is meant for an RGB565 little endian pixel format.
* Thus, to accomodate for the endianness, the fields in struct rgb565_t have to
@ -147,89 +146,103 @@ void gfx_drawRect(point_t start, uint16_t width, uint16_t height, color_t color,
}
}
void gfx_print(point_t start, const char *text, fontSize_t size, textAlign_t alignment, color_t color)
{
uint8_t *currentCharData;
uint8_t *currentFont;
uint16_t *writePos;
uint8_t *readPos;
rgb565_t color_565 = _true2highColor(color);
switch(size)
{
case FONT_SIZE_1:
currentFont = (uint8_t *) font_6x8;
break;
case FONT_SIZE_1_BOLD:
currentFont = (uint8_t *) font_6x8_bold;
break;
case FONT_SIZE_2:
currentFont = (uint8_t *) font_8x8;
break;
case FONT_SIZE_3:
currentFont = (uint8_t *) font_8x16;
break;
case FONT_SIZE_4:
currentFont = (uint8_t *) font_16x32;
break;
default:
return;// Invalid font selected
/**
* Compute the pixel size of the first text line
* @param f: font used as the source of glyphs
* @param text: the input text
* @param length: the length of the input text, used for boundary checking
*/
static inline uint16_t get_line_size(GFXfont f,
const char *text,
uint16_t length) {
uint16_t line_size = 0;
for(unsigned i = 0;
i < length && text[i] != '\n' && text[i] != '\r';
i++) {
GFXglyph glyph = f.glyph[text[i] - f.first];
if (line_size + glyph.xAdvance < SCREEN_WIDTH)
line_size += glyph.xAdvance;
else
break;
}
return line_size;
}
int16_t startCode = currentFont[2]; // get first defined character
int16_t endCode = currentFont[3]; // get last defined character
int16_t charWidthPixels = currentFont[4]; // width in pixel of one char
int16_t charHeightPixels = currentFont[5]; // page count per char
int16_t bytesPerChar = currentFont[7]; // bytes per char
int16_t sLen = strlen(text);
// Compute amount of letters that fit till the end of the screen
if ((charWidthPixels*sLen) + start.x > SCREEN_WIDTH)
{
sLen = (SCREEN_WIDTH-start.x)/charWidthPixels;
}
if (sLen < 0) return;
/**
* Compute the start x coordinate of a new line of given pixel size
* @param alinment: enum representing the text alignment
* @param line_size: the size of the current text line in pixels
*/
static inline uint16_t get_reset_x(textAlign_t alignment, uint16_t line_size) {
switch(alignment)
{
case TEXT_ALIGN_LEFT:
// left aligned, do nothing.
break;
return 0;
case TEXT_ALIGN_CENTER:
start.x = (SCREEN_WIDTH - (charWidthPixels * sLen))/2;
break;
return (SCREEN_WIDTH - line_size)/2;
case TEXT_ALIGN_RIGHT:
start.x = SCREEN_WIDTH - (charWidthPixels * sLen);
break;
return SCREEN_WIDTH - line_size;
}
return 0;
}
for (int16_t i=0; i<sLen; i++)
{
uint32_t charOffset = (text[i] - startCode);
void gfx_print(point_t start, const char *text, fontSize_t size, textAlign_t alignment, color_t color) {
// End boundary checking.
if (charOffset > endCode)
{
charOffset = ('?' - startCode); // Substitute unsupported ASCII code by a question mark
rgb565_t color_565 = _true2highColor(color);
GFXfont f = fonts[size];
size_t len = strlen(text);
// Compute size of the first row in pixels
uint16_t line_size = get_line_size(f, text, len);
uint16_t reset_x = get_reset_x(alignment, line_size);
start.x = reset_x;
/* For each char in the string */
for(unsigned i = 0; i < len; i++) {
char c = text[i];
GFXglyph glyph = f.glyph[c - f.first];
uint8_t *bitmap = f.bitmap;
uint16_t bo = glyph.bitmapOffset;
uint8_t w = glyph.width, h = glyph.height;
int8_t xo = glyph.xOffset,
yo = glyph.yOffset;
uint8_t xx, yy, bits = 0, bit = 0;
// Handle newline and carriage return
if (c == '\n') {
start.x = reset_x;
start.y += f.yAdvance;
continue;
} else if (c == '\r') {
start.x = reset_x;
continue;
}
currentCharData = (uint8_t *)&currentFont[8 + (charOffset * bytesPerChar)];
// Handle wrap around
if (start.x + glyph.xAdvance > SCREEN_WIDTH) {
// Compute size of the first row in pixels
line_size = get_line_size(f, text, len);
start.x = reset_x = get_reset_x(alignment, line_size);
start.y += f.yAdvance;
}
// We print the character from up-left to bottom right
for(int16_t vscan=0; vscan < charHeightPixels; vscan++) {
for(int16_t hscan=0; hscan < charWidthPixels; hscan++) {
int16_t charChunk = vscan / 8;
int16_t bitIndex = (hscan + charChunk * charWidthPixels) * 8 +
vscan % 8;
int16_t byte = bitIndex >> 3;
int16_t bitMask = 1 << (bitIndex & 7);
if (currentCharData[byte] & bitMask)
buf[(start.y + vscan) * SCREEN_WIDTH +
start.x + hscan + i * charWidthPixels] = color_565;
// Draw bitmap
for (yy = 0; yy < h; yy++) {
for (xx = 0; xx < w; xx++) {
if (!(bit++ & 7)) {
bits = bitmap[bo++];
}
if (bits & 0x80) {
if (start.y + yo + yy < SCREEN_HEIGHT && start.x + xo + xx < SCREEN_WIDTH && start.y + yo + yy > 0 && start.x + xo + xx > 0)
buf[(start.y + yo + yy) * SCREEN_WIDTH +
start.x + xo + xx] = color_565;
}
bits <<= 1;
}
}
start.x += glyph.xAdvance;
}
}

Wyświetl plik

@ -62,7 +62,7 @@ static void ui_task(void *arg)
color_t yellow_fab413 = {250, 180, 19};
char *splash_buf = "OpenRTX";
gfx_clearScreen();
gfx_print(splash_origin, "OpenRTX", FONT_SIZE_4, TEXT_ALIGN_CENTER,
gfx_print(splash_origin, "OpenRTX", FONT_SIZE_18PT, TEXT_ALIGN_CENTER,
yellow_fab413);
gfx_render();
while(gfx_renderingInProgress());

Wyświetl plik

@ -107,13 +107,13 @@ layout_t _ui_calculateLayout()
const uint16_t bottom_pad = 4;
// Top bar font: 8 pt
const fontSize_t top_font = FONT_SIZE_1;
const fontSize_t top_font = FONT_SIZE_9PT;
// Middle line fonts: 16 pt
const fontSize_t line1_font = FONT_SIZE_3;
const fontSize_t line2_font = FONT_SIZE_3;
const fontSize_t line3_font = FONT_SIZE_3;
const fontSize_t line1_font = FONT_SIZE_12PT;
const fontSize_t line2_font = FONT_SIZE_12PT;
const fontSize_t line3_font = FONT_SIZE_12PT;
// Bottom bar font: 8 pt
const fontSize_t bottom_font = FONT_SIZE_1;
const fontSize_t bottom_font = FONT_SIZE_9PT;
// Radioddity GD-77
#elif SCREEN_HEIGHT > 63