At least: font code generator, exchange code support for color 128x128

This commit is contained in:
2019-08-04 15:35:44 -07:00
parent e0b49ba109
commit 77f09bca16
47 changed files with 899 additions and 16431 deletions

3
.gitignore vendored
View File

@@ -4,3 +4,6 @@
*.elf
build
*.pyc
*.su
*.map
.gdb_history

View File

@@ -66,8 +66,8 @@ ReturnCode ButtonManager::init()
NextTime ButtonManager::execute()
{
// TODO: is this call too expensive for an interrupt handler?
Common::time_t systime;
Common::time_t endtime = 0;
BSP::SystemTimer::get_time(systime);
@@ -81,12 +81,22 @@ NextTime ButtonManager::execute()
btn.m_callback(btn.m_state);
}
btn.m_prev_call_state = btn.m_state;
continue;
} else {
// It's not time yet. Use this to figure out the next time we should check
if (endtime == 0 || btn.m_state_change_ts + btn.m_debounce_time < endtime) {
endtime = btn.m_state_change_ts + btn.m_debounce_time;
}
}
}
}
// TODO: Call less frequently, and let the buttonmanager re-add itself to the task list on interrupts
return NextTime::asap();
if (endtime == 0) {
return NextTime::never();
} else {
return NextTime::at(endtime);
}
}
void ButtonManager::set_callback(Button btn, ChangeCallback callback)
@@ -110,7 +120,7 @@ void ButtonManager::remove_callback(Button btn)
void ButtonManager::irq()
{
uint32_t idr = GPIOA->IDR;
Common::time_t systime;
static Common::time_t systime;
// TODO: is this call too expensive for an interrupt handler?
BSP::SystemTimer::get_time(systime);
@@ -134,6 +144,10 @@ void ButtonManager::irq()
// Clear the event
SET(EXTI->PR, 1u << btn.m_gpio_idx);
}
if (m_instance != nullptr) {
m_instance->m_scheduler.add_task(*m_instance, NextTime::asap());
}
}

View File

@@ -22,6 +22,8 @@
#pragma once
#include <functional>
#include "TaskScheduler.h"
#include "Task.h"
#include "ReturnCode.h"
@@ -29,11 +31,13 @@ namespace BSP {
class ButtonManager : public Common::Schedule::Task {
public:
ButtonManager(uint8_t up_gpio_idx,
ButtonManager(Common::Schedule::TaskScheduler &scheduler,
uint8_t up_gpio_idx,
uint8_t mid_gpio_idx,
uint8_t down_gpio_idx,
Common::time_t debounce_time)
: m_buttons
: m_scheduler(scheduler)
, m_buttons
{
button_state(up_gpio_idx, debounce_time, ButtonManager::nop_callback),
button_state(mid_gpio_idx, debounce_time, ButtonManager::nop_callback),
@@ -83,7 +87,6 @@ private:
, m_state_change_ts(0)
, m_callback(callback)
{}
uint8_t const m_gpio_idx;
Common::time_t const m_debounce_time;
@@ -93,6 +96,7 @@ private:
ChangeCallback m_callback; /*<! The callback to call when the button has changed states (post-debounce) */
};
Common::Schedule::TaskScheduler &m_scheduler;
button_state m_buttons[Button::Count];
static void nop_callback(ButtonState) {};

0
DebugScreen.cpp Normal file
View File

89
DebugScreen.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2019 Max Regan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "macros.h"
#include "SystemFonts.h"
#include "ScreenManager.h"
#include "Screen.h"
class DebugScreen : public Screen {
public:
static constexpr std::size_t MAX_ITEMS = 10;
DebugScreen(BSP::DisplayDriver &display,
ScreenManager &manager)
: m_driver(display)
, m_manager(manager)
{}
Common::ReturnCode init() {
return Common::ReturnCode::OK;
}
void render() {
const struct font &font = default_font;
char buffer[32] = {0};
m_driver.clear();
uint32_t x = 0;
uint32_t y = 0;
// snprintf(buffer, sizeof(buffer), "Wakeups");
m_driver.string_at(&x, y, buffer, &font);
y += font.height;
m_driver.refresh();
}
Common::Schedule::NextTime execute() override {
render();
return Common::Schedule::NextTime::never();
}
void enable() override {
render();
}
void disable() override {
m_driver.clear();
}
void notify_up_button() override {
}
void notify_middle_button() override {
m_manager.pop_screen();
}
void notify_down_button() override {
m_manager.pop_screen();
}
private:
BSP::DisplayDriver &m_driver;
ScreenManager &m_manager;
};

View File

@@ -93,6 +93,12 @@ void DisplayDriver::set_bit(uint32_t x, uint32_t y, uint8_t val)
set_dirty(y);
}
uint8_t DisplayDriver::get_bit(uint32_t x, uint32_t y)
{
struct display_line &line = m_buffer.lines[y];
return (line.data[x >> 3] >> (x & 7)) & 1;
}
void DisplayDriver::set_byte(uint32_t x, uint32_t y, uint8_t val)
{
// if (x >= DISPLAY_WIDTH || y >= DISPLAY_HEIGHT) {
@@ -114,7 +120,7 @@ void DisplayDriver::set_byte(uint32_t x, uint32_t y, uint8_t val)
#define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
#define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
static const unsigned char BitReverseTable256[256] =
static constexpr unsigned char BitReverseTable256[256] =
{
R6(0), R6(2), R6(1), R6(3)
};
@@ -129,11 +135,11 @@ unsigned char ReverseBitsLookupTable(unsigned char v)
* (obviously) requires that everything is aligned correctly.
*/
void DisplayDriver::clear_glyph_aligned(uint32_t x_off, uint32_t y_off, const struct font *, const struct glyph *g)
void DisplayDriver::clear_glyph_aligned(uint32_t x_off, uint32_t y_off, const struct font *f, const struct glyph *g)
{
for (uint32_t y = y_off; y < y_off + g->rows && y < DISPLAY_HEIGHT; y++) {
for (uint32_t y = y_off; y < y_off + f->height + g->top && y < DISPLAY_HEIGHT; y++) {
uint8_t *start = (uint8_t *) &m_buffer.lines[y].data[(x_off) >> 3];
uint8_t *end = (uint8_t *) &m_buffer.lines[y].data[(x_off + g->advance) >> 3];
uint8_t *end = (uint8_t *) &m_buffer.lines[y].data[(x_off + f->width) >> 3];
memset(start, 0xFF, end - start);
}
}
@@ -180,18 +186,18 @@ void DisplayDriver::clear_glyph_unaligned(uint32_t x_off, uint32_t y_off, const
{
int16_t x = 0;
if (x & 7) {
while ((x & 7) && x < g->advance) {
while ((x & 7) && x < font->width) {
// TODO: use a switch on (x & 7) instead?
for (int16_t y = 0; y < g->rows && y < (int16_t) DISPLAY_HEIGHT; y++) {
set_bit(x_off + x, y_off + y + font->size - g->top, 0);
for (int16_t y = 0; y < font->height && y < (int16_t) DISPLAY_HEIGHT; y++) {
set_bit(x_off + x, y_off + y + font->height - g->top, 0);
}
x++;
}
}
while (g->advance - x > 0) {
for (int16_t y = 0; y < g->rows && y < (int16_t) DISPLAY_HEIGHT; y++) {
set_bit(x_off + x, y_off + y + font->size - g->top, 0);
while (font->width - x > 0) {
for (int16_t y = 0; y < font->height && y < (int16_t) DISPLAY_HEIGHT; y++) {
set_bit(x_off + x, y_off + y + font->height - g->top, 0);
}
x++;
}
@@ -199,26 +205,31 @@ void DisplayDriver::clear_glyph_unaligned(uint32_t x_off, uint32_t y_off, const
}
void DisplayDriver::write_glyph_unaligned(uint32_t x_off, uint32_t y_off, const struct font *font, const struct glyph *g)
void DisplayDriver::write_glyph_unaligned(uint32_t x_off, uint32_t y_off, const struct font *f, const struct glyph *g)
{
int byte_cols = g->cols / 8;
if (g->cols & 7) {
byte_cols++;
}
for (size_t x = 0; x < g->cols && x < DISPLAY_WIDTH; x++) {
for (size_t y = 0; y < g->rows && y < DISPLAY_HEIGHT; y++) {
int byte_cols = g->width_bytes;
for (size_t x = 0; x < g->width && x + x_off + g->left < DISPLAY_WIDTH; x++) {
for (size_t y = 0; y < g->height && y_off + y + f->height - g->top < DISPLAY_HEIGHT; y++) {
int byte_x = x / 8;
int byte_y = y;
uint8_t bit = (g->bitmap[byte_y * byte_cols + byte_x] >> (7 - (x & 7))) & 1;
set_bit(g->left + x_off + x,
y_off + y + font->size - g->top,
y_off + y + f->height - g->top,
bit);
}
}
}
void DisplayDriver::draw_hline(uint32_t x, uint32_t y, uint32_t width)
{
for (uint32_t i = 0; i < width; i += 8) {
set_byte(x + i, y, 0);
}
}
// void DisplayDriver::write_glyph_unaligned2(int *x_off, int y_off, const struct font *font, const struct glyph *g)
// {
// int byte_cols = g->cols / 8;
@@ -242,20 +253,17 @@ void DisplayDriver::write_glyph_unaligned(uint32_t x_off, uint32_t y_off, const
* requires that everything is aligned correctly.
*/
void DisplayDriver::write_glyph_aligned(uint32_t x_off, uint32_t y_off,
const struct font *font, const struct glyph *g)
const struct font *, const struct glyph *g)
{
int byte_cols = g->cols / 8;
if (g->cols & 7) {
byte_cols++;
}
int byte_cols = g->width_bytes;
for (size_t x = 0; x < g->cols; x += 8) {
for (size_t y = 0, byte_y = 0; y < g->rows && y < DISPLAY_HEIGHT; y++, byte_y += byte_cols) {
for (size_t x = 0; x < g->width; x += 8) {
for (size_t y = 0, byte_y = 0; y < g->height && y < DISPLAY_HEIGHT; y++, byte_y += byte_cols) {
int byte_x = x / 8;
uint8_t byte = g->bitmap[byte_y + byte_x];
set_byte(g->left + x_off + x,
y_off + y + font->size - g->top,
y_off + y + g->height - g->top,
~ReverseBitsLookupTable(byte));
}
}
@@ -268,28 +276,22 @@ void DisplayDriver::char_at(uint32_t *x_off, uint32_t y_off, char c, const struc
return;
}
if (*x_off + g->left + g->cols >= DISPLAY_WIDTH) {
if (*x_off + font->width >= DISPLAY_WIDTH) {
return;
}
if (!(*x_off & 7) && !((*x_off + g->advance) & 7)) {
if (!(*x_off & 7) && !(font->width & 7)) {
clear_glyph_aligned(*x_off, y_off, font, g);
} else {
clear_glyph_unaligned(*x_off, y_off, font, g);
}
// FIXME: REALLY DO THIS!
// Check the right glyph boundary (g->left + g->cols)
if (!((*x_off + g->left) & 7)) {
write_glyph_aligned(*x_off, y_off, font, g);
} else {
write_glyph_unaligned(*x_off, y_off, font, g);
}
write_glyph_unaligned(*x_off, y_off, font, g);
m_dirty_line_min = MIN(m_dirty_line_min, y_off);
m_dirty_line_max = MAX(m_dirty_line_max, y_off + g->rows);
m_dirty_line_max = MAX(m_dirty_line_max, y_off + g->height);
m_is_dirty = true;
*x_off += g->advance;
*x_off += font->width;
}
void DisplayDriver::string_at(uint32_t *x_off, uint32_t y_off, const char *string, const struct font *font)
@@ -301,12 +303,15 @@ void DisplayDriver::string_at(uint32_t *x_off, uint32_t y_off, const char *strin
}
}
void DisplayDriver::refresh()
{
if (!m_is_dirty) {
return;
}
uint8_t *start = (uint8_t *) &m_buffer.lines[m_dirty_line_min];
// Data size
size_t size = sizeof(m_buffer.lines[0]) * (m_dirty_line_max - m_dirty_line_min + 1);
@@ -330,25 +335,7 @@ void DisplayDriver::clear()
//TODO: put me somewhere fonty
const struct glyph *DisplayDriver::glyph_for_char(const struct font *font, char c)
{
std::size_t low = 0;
std::size_t high = font->count - 1;
while (low <= high) {
std::size_t mid = (high - low) / 2;
mid += low;
const struct glyph *g = font->glyphs[mid];
if (g->glyph == c) {
return g;
}
if (g->glyph > c) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return NULL;
return font->glyphs[(size_t) c];
}
}

View File

@@ -27,12 +27,10 @@
namespace BSP {
class DisplayDriver : public Common::Schedule::Task {
class DisplayDriver final : public Common::Schedule::Task {
public:
DisplayDriver(Common::Schedule::TaskScheduler &scheduler, SpiDriver &spi);
/**
* Common::Schedule::Task
*/
@@ -43,10 +41,12 @@ public:
* DisplayDriver
*/
void set_bit(uint32_t x, uint32_t y, uint8_t val);
uint8_t get_bit(uint32_t x, uint32_t y);
void set_byte(uint32_t x, uint32_t y, uint8_t val);
void char_at(uint32_t *x_off, uint32_t y_off, char c, const struct font *font);
void string_at(uint32_t *x_off, uint32_t y_off,
const char *string, const struct font *font);
void draw_hline(uint32_t x, uint32_t y, uint32_t width);
void refresh();
void clear();
@@ -71,14 +71,15 @@ private:
void write_glyph_unaligned(uint32_t x_off, uint32_t y_off,
const struct font * font, const struct glyph *g);
static constexpr uint32_t DISPLAY_WIDTH = 144;
static constexpr uint32_t DISPLAY_HEIGHT = 168;
static constexpr uint32_t DISPLAY_WIDTH = 128;
static constexpr uint32_t DISPLAY_HEIGHT = 128;
static constexpr uint32_t BITS_PER_PIXEL = 3;
struct display_line
{
uint8_t mode;
uint8_t line;
uint8_t data[DISPLAY_WIDTH / 8];
uint8_t data[DISPLAY_WIDTH * BITS_PER_PIXEL / 8];
};
struct display_buffer

View File

@@ -23,7 +23,7 @@
#include "RtcDriver.h"
#include "SystemTime.h"
#include "SystemFonts.h"
#include "LowPower.h"
using Common::ReturnCode;
using Common::Time;
@@ -34,9 +34,10 @@ DisplayTimeScreen::DisplayTimeScreen(BSP::DisplayDriver &driver,
Screen &menu_screen)
: m_driver(driver)
, m_last_time()
, m_refresh(true)
, m_manager(manager)
, m_menu_screen(menu_screen)
, m_display_seconds(false)
, m_display_seconds(true)
{}
static char get_char_for_digit(uint8_t bcd_digit)
@@ -49,6 +50,8 @@ static char get_char_for_digit(uint8_t bcd_digit)
ReturnCode DisplayTimeScreen::init()
{
SET(RCC->CFGR, RCC_CFGR_SW_HSI);
return ReturnCode::OK;
}
@@ -67,48 +70,57 @@ void DisplayTimeScreen::display_time()
{
Common::WallClockTime time;
BSP::RtcDriver::get_time(time);
const struct font &font = large_font;
const uint32_t font_width = large_font_width;
const uint32_t y_space = (m_driver.get_height() - (2 * font.size)) / 3;
const uint32_t x_space = (m_driver.get_width() - (2 * font_width)) / 2;
const struct font &font = font_large_digits;
const uint32_t y_space = (m_driver.get_height() - (2 * font.height)) / 3;
const uint32_t x_space = (m_driver.get_width() - (2 * font.width)) / 2;
uint32_t x = 0;
if (m_last_time.get_hours_24() != time.get_hours_24()) {
if (m_refresh || m_last_time.get_hours_24() != time.get_hours_24()) {
x = x_space;
display_number(&x, y_space,
time.get_hours_12_tens(), time.get_hours_12_ones(), font);
}
if (m_last_time.get_minutes() != time.get_minutes()) {
if (m_refresh || m_last_time.get_minutes() != time.get_minutes()) {
x = x_space;
display_number(&x, y_space * 2 + font.size,
display_number(&x, y_space * 2 + font.height,
time.get_minutes_tens(), time.get_minutes_ones(), font);
}
if (m_display_seconds) {
if (m_refresh || m_display_seconds) {
// display_number(&x, y,
// time.get_seconds_tens(), time.get_seconds_ones(), font_default);
}
m_last_time = time;
m_refresh = false;
m_driver.refresh();
}
NextTime DisplayTimeScreen::execute()
{
// m_refresh = true;
display_time();
Common::time_t now;
BSP::SystemTimer::get_time(now);
uint32_t next_secs = Time::to_seconds(now) + (m_display_seconds ? 1 : 60);
return NextTime::at(Time::seconds(next_secs));
if (m_display_seconds) {
return NextTime::in(Time::seconds(1));
} else {
Common::WallClockTime wall_time;
BSP::RtcDriver::get_time(wall_time);
return NextTime::in(Time::seconds(61 - wall_time.get_seconds()));
}
}
void DisplayTimeScreen::enable() {
m_refresh = true;
m_driver.clear();
m_last_time = {};
display_time();
}
void DisplayTimeScreen::disable() {

View File

@@ -50,6 +50,7 @@ private:
BSP::DisplayDriver &m_driver;
Common::WallClockTime m_last_time;
bool m_refresh;
ScreenManager &m_manager;
Screen &m_menu_screen;

View File

@@ -25,20 +25,39 @@
#include "stm32l0xx.h"
uint32_t wakeups = 0;
namespace BSP {
using Common::ReturnCode;
ReturnCode LowPower::init()
{
enable_debug();
return ReturnCode::OK;
}
ReturnCode LowPower::enable_debug()
{
/* Enable Clocks */
SET(RCC->APB2ENR, RCC_APB2ENR_DBGEN);
SET(RCC->APB2SMENR, RCC_APB2SMENR_DBGSMEN);
// FIXME: Make these configurable, will mess with power consumption
SET(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
SET(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
SET(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
return ReturnCode::OK;
}
ReturnCode LowPower::disable_debug()
{
CLR(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
CLR(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
CLR(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
CLR(RCC->APB2SMENR, RCC_APB2SMENR_DBGSMEN);
return ReturnCode::OK;
}
@@ -59,8 +78,9 @@ ReturnCode LowPower::stop()
SET(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); // low-power mode = stop mode
__WFI(); // enter low-power mode (Wake from interrupt)
wakeups++;
return ReturnCode::OK;
}
}

View File

@@ -23,6 +23,8 @@
#include "ReturnCode.h"
extern uint32_t wakeups;
namespace BSP {
class LowPower {
@@ -30,9 +32,10 @@ public:
LowPower() = delete;
static Common::ReturnCode init();
static Common::ReturnCode sleep();
static Common::ReturnCode stop();
static Common::ReturnCode enable_debug();
static Common::ReturnCode disable_debug();
};
}

View File

@@ -32,7 +32,7 @@ namespace Common {
namespace Schedule {
template <uint32_t MAX_TASKS>
class LowPowerTaskScheduler : public TaskScheduler {
class LowPowerTaskScheduler final : public TaskScheduler {
public:
LowPowerTaskScheduler() :
m_tasks(),
@@ -44,7 +44,6 @@ public:
{
while (1) {
cycle();
//remove_dead_tasks();
}
}
@@ -128,11 +127,16 @@ private:
remove_dead_tasks();
}
if (!execed && (next_time - time > Time::millis(2))) {
// Common::ReturnCode rc = BSP::RtcDriver::set_wakeup_in(next_time - time);
// if (rc == Common::ReturnCode::OK) {
// BSP::LowPower::stop();
// }
if (m_task_count == 0) {
Common::ReturnCode rc = BSP::RtcDriver::set_wakeup_in(Time::seconds(5));
if (rc == Common::ReturnCode::OK) {
BSP::LowPower::stop();
}
} else if (!execed && (next_time - time > Time::millis(2))) {
Common::ReturnCode rc = BSP::RtcDriver::set_wakeup_in(next_time - time);
if (rc == Common::ReturnCode::OK) {
BSP::LowPower::stop();
}
}
m_cycle_count++;

View File

@@ -40,16 +40,24 @@ DEVICE_TYPE ?= stm32l031k6
DEVICE_FAMILY = stm32l031xx
DEVICE_LINE = stm32l0xx
STACK_SIZE ?= 512
HEAP_SIZE ?= 0
#
# Filenames and paths
#
# Ignores dotfiles and other garbage some tools leave behind
define find_important
$(shell find $(1) -type f -and -name $(2) -and -not -iname "*~" -and -not -iname "*#*" -and -not \( -path "*.cquery_cached_index*" \) )
$(shell find $(1) -type f -and -name $(2) -and -not -iname "*~" -and -not -iname "*#*" -and -not \( -path "*.cquery_cached_index*" \) -and -not \( -path "*build*" \) )
endef
C_SOURCES := $(call find_important, $(SOURCEDIR), '*.c')
FONTS := small large_digits
FONT_GEN_DIR := build/gen/fonts
FONT_C_FILES := $(patsubst %,$(FONT_GEN_DIR)/%.c,$(FONTS))
FONT_H_FILES := $(patsubst %,$(FONT_GEN_DIR)/%.h,$(FONTS))
C_SOURCES := $(call find_important, $(SOURCEDIR), '*.c') $(FONT_C_FILES)
CXX_SOURCES := $(call find_important, $(SOURCEDIR), '*.cpp')
S_SOURCES := $(call find_important, $(SOURCEDIR), '*.s')
SPP_SOURCES := $(DEVICE_TYPE).S
@@ -66,6 +74,7 @@ LINKER_SCRIPT ?= $(DEVICE_TYPE).ld
OUTPUT_NAME ?= watch
OUTPUT_BIN ?= $(OUTPUT_NAME).bin
OUTPUT_ELF ?= $(OUTPUT_NAME).elf
OUTPUT_MAP ?= $(OUTPUT_NAME).map
#
# Flags
@@ -76,32 +85,36 @@ DEVICE_DEFINE = $(subst XX,xx,$(shell echo $(DEVICE_FAMILY) | tr '[:lower:]' '[:
CPU_FLAGS = -mthumb -mcpu=cortex-m0plus -mfloat-abi=soft
# C pedantism
CFLAGS = -Wall -Wextra -Wpedantic -Werror
CFLAGS = -Wall -Wextra -pedantic -Werror -Wcast-align
CXX_FLAGS = -Wsuggest-override -Wsuggest-final-methods -Wsuggest-final-types
# Debug/optimization
CFLAGS += -Os -ggdb -g3
CFLAGS += -Os -ggdb
CFLAGS += -fdata-sections -ffunction-sections
# Architecture
CFLAGS += $(CPU_FLAGS)
CFLAGS += -ffreestanding
CFLAGS += -fstack-usage -Wstack-usage=128
# Defines
CFLAGS += -D$(DEVICE_DEFINE)
# Includes
CFLAGS += -I./lib/stm32/$(DEVICE_LINE)/Include
CFLAGS += -I./lib/CMSIS/Core/Include
CFLAGS += -I./lib/fonts/
CFLAGS += -I./build/gen/
CFLAGS += -I.
CXX_FLAGS += -std=c++14 -fno-exceptions -fno-rtti
CXX_FLAGS += -std=c++14 -fno-exceptions -fno-rtti -fno-use-cxa-atexit
# Startup Definitions
ASFLAGS += $(CPU_FLAGS)
ASFLAGS += -D__STARTUP_CLEAR_BSS
ASFLAGS += -D__HEAP_SIZE=0 # No heap- let the linker decide it all
ASFLAGS += -D__HEAP_SIZE=$(HEAP_SIZE)
ASFLAGS += -D__STACK_SIZE=$(STACK_SIZE)
LDFLAGS += $(CPU_FLAGS)
LDFLAGS += -Wl,--gc-sections -Wl,--build-id=none -static
LDFLAGS += -Wl,--wrap=malloc -Wl,--wrap=free # Fail to link if dynamic allocation is sneaking through
LDFLAGS += -Wl,-print-memory-usage
LDFLAGS += -nostartfiles
#
# Default Target
@@ -113,25 +126,40 @@ build: $(OUTPUT_BIN)
# Build Logic
#
%.o: %.c
%.o: %.c $(FONT_H_FILES)
@echo "CC $@"
@$(CC) $(CFLAGS) -c $< -o $@
%.o: %.S
%.o: %.S $(FONT_H_FILES)
@echo "AS $@"
@$(CC) $(ASFLAGS) -c $< -o $@
%.o: %.cpp
%.o: %.cpp $(FONT_H_FILES)
@echo "CXX $@"
@$(CXX) $(CXX_FLAGS) $(CFLAGS) -c $< -o $@
SMALL_FONT=lib/fonts/roboto_mono/RobotoMono-Medium.ttf
$(FONT_GEN_DIR)/small.h $(FONT_GEN_DIR)/small.c: gen/fixedfont-to-c.py gen/font.py
@echo "GEN $@"
@mkdir -p $(FONT_GEN_DIR)
@gen/fixedfont-to-c.py $(patsubst .%,%,$(suffix $@)) $(SMALL_FONT) "$@" -s 18 --header-dir "" --name font_small
@$(call gen_font,$(FONT),29,small)
LARGE_FONT=lib/fonts/roboto_mono/RobotoMono-Bold.ttf
$(FONT_GEN_DIR)/large_digits.h $(FONT_GEN_DIR)/large_digits.c: gen/fixedfont-to-c.py gen/font.py
@echo "GEN $@"
@mkdir -p $(FONT_GEN_DIR)
@gen/fixedfont-to-c.py $(patsubst .%,%,$(suffix $@)) $(LARGE_FONT) "$@" -s 70 --header-dir "" --name font_large_digits -c "01234567890:"
$(OUTPUT_BIN): $(OUTPUT_ELF)
@echo "OBJCOPY $@"
@$(OBJCOPY) -O binary $(OUTPUT_ELF) $(OUTPUT_BIN)
$(OUTPUT_ELF): $(LINKER_SCRIPT) $(OBJS)
$(OUTPUT_MAP) $(OUTPUT_ELF): $(LINKER_SCRIPT) $(OBJS)
@echo "LD $@"
@$(LD) -T $(LINKER_SCRIPT) $(LDFLAGS) -o $(OUTPUT_ELF) $(OBJS)
@$(LD) -T $(LINKER_SCRIPT) $(LDFLAGS) -o $(OUTPUT_ELF) $(OBJS) -Wl,-Map=$(OUTPUT_MAP)
#
# Utilities
@@ -147,4 +175,4 @@ flash: $(OUTPUT_BIN)
.PHONY: clean
clean:
@echo "RM $(OBJS)"
@rm -f $(OBJS) $(OUTPUT_BIN) $(OUTPUT_ELF)
@rm -f $(OBJS) $(OUTPUT_BIN) $(OUTPUT_ELF) $(FONT_C_FILES) $(OUTPUT_MAP) ./*.su

View File

@@ -31,9 +31,10 @@
struct MenuScreenItem {
enum class Type{
enum class Type {
NONE,
SCREEN,
FUNCTION,
BACK,
};
@@ -49,6 +50,13 @@ struct MenuScreenItem {
, m_type(Type::SCREEN)
{}
MenuScreenItem(const char *item, void (*function)())
: m_text(item)
, m_screen(nullptr)
, m_function(function)
, m_type(Type::FUNCTION)
{}
MenuScreenItem(const char *item)
: m_text(item)
, m_screen(nullptr)
@@ -57,19 +65,22 @@ struct MenuScreenItem {
const char *m_text;
Screen *m_screen;
void (* m_function)();
Type m_type;
};
class MenuScreen : public Screen {
public:
static constexpr std::size_t MAX_ITEMS = 10;
static constexpr std::size_t MAX_ITEMS = 5;
MenuScreen(BSP::DisplayDriver &display,
ScreenManager &manager,
const char *title,
std::initializer_list<MenuScreenItem> items)
: m_driver(display)
, m_manager(manager)
, m_title(title)
, m_items()
, m_num_items{0}
, m_selected{0}
@@ -88,19 +99,27 @@ public:
void render() {
const struct font &font = default_font;
// const uint32_t font_width = default_font_width;
m_driver.clear();
//m_driver.clear();
uint32_t x = 0;
uint32_t y = 0;
m_driver.string_at(&x, y, m_title, &font);
y += font.height + 1;
m_driver.draw_hline(0, y++, m_driver.get_width());
m_driver.draw_hline(0, y++, m_driver.get_width());
for (std::size_t i = 0; i < m_num_items; i++) {
uint32_t x = 0;
uint32_t y = 8 + (font.size + 8) * i;
const char *spacer = " ";
if (i == m_selected) {
spacer = ">";
}
x = 0;
m_driver.string_at(&x, y, spacer, &font);
m_driver.string_at(&x, y, m_items[i].m_text, &font);
y += font.height;
}
m_driver.refresh();
}
@@ -136,6 +155,9 @@ public:
MenuScreenItem &item = m_items[m_selected];
if (item.m_type == MenuScreenItem::Type::SCREEN) {
m_manager.push_screen(*item.m_screen);
} else if (item.m_type == MenuScreenItem::Type::FUNCTION) {
item.m_function();
m_manager.pop_screen();
} else if (item.m_type == MenuScreenItem::Type::BACK) {
m_manager.pop_screen();
}
@@ -155,9 +177,8 @@ private:
BSP::DisplayDriver &m_driver;
ScreenManager &m_manager;
const char *m_title;
MenuScreenItem m_items[MAX_ITEMS];
std::size_t m_num_items;
std::size_t m_selected;
};

View File

@@ -178,7 +178,7 @@ ReturnCode RtcDriver::set_time(const Common::WallClockTime &wall_time)
SET_TO(time, RTC_TR_MNT, wall_time.get_minutes_tens() << RTC_TR_MNT_Pos);
SET_TO(time, RTC_TR_MNU, wall_time.get_minutes_ones() << RTC_TR_MNU_Pos);
SET_TO(time, RTC_TR_ST, wall_time.get_seconds_tens() << RTC_TR_ST_Pos);
SET_TO(time, RTC_TR_SU, wall_time.get_seconds_tens() << RTC_TR_SU_Pos);
SET_TO(time, RTC_TR_SU, wall_time.get_seconds_ones() << RTC_TR_SU_Pos);
RTC->TR = time;
CLR(RTC->ISR, RTC_ISR_INIT);
@@ -269,6 +269,8 @@ void RtcDriver::increment_seconds()
m_sys_timer.increment_seconds();
}
static uint32_t wakeup_alarms = 0;
extern "C" void RTC_IRQHandler()
{
// Clear the wakeup and alarm interrupts in the EXTI
@@ -280,6 +282,7 @@ extern "C" void RTC_IRQHandler()
}
if (RTC->ISR & RTC_ISR_WUTF) {
wakeup_alarms++;
// Clear the interrupt in the RTC
CLR(RTC->ISR, RTC_ISR_WUTF);
// Disable the Wakeup timer (its periodic, but we use it as a

View File

@@ -31,7 +31,7 @@
namespace BSP {
class RtcDriver {
class RtcDriver final {
public:
RtcDriver() = delete;

View File

@@ -69,7 +69,6 @@ ReturnCode ScreenManager::init()
NextTime ScreenManager::execute()
{
// TODO: Handle updating execute times when the screen is swapped out.
return current_screen()->execute();
}

252
SetDateScreen.cpp Normal file
View File

@@ -0,0 +1,252 @@
/*
* Copyright (C) 2019 Max Regan
*
Cr * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <cstring>
#include "SetDateScreen.h"
#include "SystemTime.h"
#include "SystemFonts.h"
#include "RtcDriver.h"
using Common::ReturnCode;
using Common::Time;
using Common::Schedule::NextTime;
SetDateScreen::SetDateScreen(BSP::DisplayDriver &display,
ScreenManager &manager)
: m_display(display)
, m_manager(manager)
, m_state(SetState::HOURS)
, m_is_acked(false)
, m_time()
, m_font(default_font)
, m_row_spacing((m_display.get_height() - m_font.height * 2) / 3)
, m_row_0_y(m_row_spacing)
, m_row_1_y(m_row_0_y + m_font.height + m_row_spacing + m_font.height)
{}
ReturnCode SetDateScreen::init()
{
return ReturnCode::OK;
}
NextTime SetDateScreen::execute()
{
//TODO: Fix this so it doesn't constantly refresh
refresh();
return NextTime::never();
}
static char get_char_for_digit(uint8_t bcd_digit)
{
if (bcd_digit > 9) {
return '0';
}
return bcd_digit + '0';
}
void SetDateScreen::display_number(uint32_t *x, uint32_t y,
uint32_t tens, uint32_t ones)
{
char time_str[3] = { 0 };
time_str[0] = get_char_for_digit(tens);
time_str[1] = get_char_for_digit(ones);
time_str[2] = '\0';
m_display.string_at(x, y, time_str, &m_font);
}
const char *SetDateScreen::get_acknak_string()
{
if (!m_is_acked) {
return "Cancel";
} else {
return "OK";
}
}
uint32_t SetDateScreen::get_acknak_string_len()
{
std::size_t len = strlen(get_acknak_string());
return len * m_font.width - 1;
}
uint32_t SetDateScreen::get_acknak_string_x_pos()
{
std::size_t len = strlen(get_acknak_string());
return m_display.get_width() - len * m_font.width - 1;
}
void SetDateScreen::render_time()
{
uint32_t x = 0;
uint32_t y = m_row_spacing;
display_number(&x, y,
m_time.get_hours_12_tens(), m_time.get_hours_12_ones());
m_display.string_at(&x, y, ":", &m_font);
display_number(&x, y,
m_time.get_minutes_tens(), m_time.get_minutes_ones());
m_display.string_at(&x, y, ":", &m_font);
display_number(&x, y,
m_time.get_seconds_tens(), m_time.get_seconds_ones());
y = m_row_1_y;
x = 0;
m_display.string_at(&x, y, m_time.get_is_pm() ? "PM" : "AM", &m_font);
x = get_acknak_string_x_pos();
m_display.string_at(&x, y, get_acknak_string(), &m_font);
m_display.refresh();
}
void SetDateScreen::draw_line(uint32_t x, uint32_t y, uint32_t width)
{
for (uint32_t i = 0; i < width; i += 8) {
m_display.set_byte(x + i, y, 0);
m_display.set_byte(x + i, y + 1, 0);
}
}
void SetDateScreen::render_selection()
{
switch (m_state) {
case SetState::HOURS:
draw_line(0, m_row_0_y + m_font.height, m_font.width * 2);
break;
case SetState::MINUTES:
draw_line(m_font.width * 3, m_row_0_y + m_font.height, m_font.width * 2);
break;
case SetState::SECONDS:
draw_line(m_font.width * 6, m_row_0_y + m_font.height, m_font.width * 2);
break;
case SetState::AM_PM:
draw_line(0, m_row_1_y + m_font.height, m_font.width * 2);
break;
case SetState::ACK_NACK:
draw_line(get_acknak_string_x_pos(), m_row_1_y + m_font.height, get_acknak_string_len());
break;
}
}
void SetDateScreen::refresh()
{
m_display.clear();
render_time();
render_selection();
m_display.refresh();
}
void SetDateScreen::enable()
{
BSP::RtcDriver::get_time(m_time);
m_state = SetState::HOURS;
m_is_acked = true;
refresh();
}
void SetDateScreen::disable()
{
m_display.clear();
}
void SetDateScreen::notify_up_button()
{
switch (m_state) {
case SetState::HOURS:
m_time.increment_hours();
break;
case SetState::MINUTES:
m_time.increment_minutes();
break;
case SetState::SECONDS:
m_time.increment_seconds();
break;
case SetState::AM_PM:
m_time.toggle_am_pm();
break;
case SetState::ACK_NACK:
m_is_acked = !m_is_acked;
break;
}
refresh();
}
void SetDateScreen::notify_middle_button()
{
switch (m_state) {
case SetState::HOURS:
m_state = SetState::MINUTES;
break;
case SetState::MINUTES:
m_state = SetState::SECONDS;
break;
case SetState::SECONDS:
m_state = SetState::AM_PM;
break;
case SetState::AM_PM:
m_state = SetState::ACK_NACK;
break;
case SetState::ACK_NACK:
if (m_is_acked) {
BSP::RtcDriver::set_time(m_time);
}
m_manager.pop_screen();
return;
}
refresh();
}
void SetDateScreen::notify_down_button()
{
switch(m_state) {
case SetState::HOURS:
m_time.decrement_hours();
break;
case SetState::MINUTES:
m_time.decrement_minutes();
break;
case SetState::SECONDS:
m_time.decrement_seconds();
break;
case SetState::AM_PM:
m_time.toggle_am_pm();
break;
case SetState::ACK_NACK:
m_is_acked = !m_is_acked;
break;
}
refresh();
}

78
SetDateScreen.h Normal file
View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2019 Max Regan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "macros.h"
#include "ScreenManager.h"
#include "DisplayDriver.h"
#include "ReturnCode.h"
#include "Task.h"
#include "Time.h"
#include "font.h"
class SetDateScreen : public Screen {
public:
SetDateScreen(BSP::DisplayDriver &display,
ScreenManager &m_manager);
Common::ReturnCode init();
Common::Schedule::NextTime execute() override;
void enable() override;
void disable() override;
void notify_up_button() override;
void notify_middle_button() override;
void notify_down_button() override;
private:
void refresh();
void render_time();
void render_selection();
void display_number(uint32_t *x, uint32_t y, uint32_t tens, uint32_t ones);
void draw_line(uint32_t x, uint32_t y, uint32_t width);
uint32_t get_acknak_string_x_pos();
uint32_t get_acknak_string_len();
const char *get_acknak_string();
enum class SetState {
HOURS,
MINUTES,
SECONDS,
AM_PM,
ACK_NACK
};
BSP::DisplayDriver &m_display;
ScreenManager &m_manager;
SetState m_state;
bool m_is_acked = false;
Common::WallClockTime m_time;
const struct font &m_font;
const uint32_t m_row_spacing;
const uint32_t m_row_0_y;
const uint32_t m_row_1_y;
};

View File

@@ -19,6 +19,7 @@
* THE SOFTWARE.
*/
#include <cstring>
#include "SetTimeScreen.h"
#include "SystemTime.h"
@@ -36,6 +37,10 @@ SetTimeScreen::SetTimeScreen(BSP::DisplayDriver &display,
, m_state(SetState::HOURS)
, m_is_acked(false)
, m_time()
, m_font(default_font)
, m_row_spacing((m_display.get_height() - m_font.height * 2) / 3)
, m_row_0_y(m_row_spacing)
, m_row_1_y(m_row_0_y + m_font.height + m_row_spacing + m_font.height)
{}
ReturnCode SetTimeScreen::init()
@@ -60,66 +65,92 @@ static char get_char_for_digit(uint8_t bcd_digit)
}
void SetTimeScreen::display_number(uint32_t *x, uint32_t y,
uint32_t tens, uint32_t ones, const struct font &f)
uint32_t tens, uint32_t ones)
{
char time_str[3] = { 0 };
time_str[0] = get_char_for_digit(tens);
time_str[1] = get_char_for_digit(ones);
time_str[2] = '\0';
m_display.string_at(x, y, time_str, &f);
m_display.string_at(x, y, time_str, &m_font);
}
const char *SetTimeScreen::get_acknak_string()
{
if (!m_is_acked) {
return "Cancel";
} else {
return "OK";
}
}
uint32_t SetTimeScreen::get_acknak_string_len()
{
std::size_t len = strlen(get_acknak_string());
return len * m_font.width - 1;
}
uint32_t SetTimeScreen::get_acknak_string_x_pos()
{
std::size_t len = strlen(get_acknak_string());
return m_display.get_width() - len * m_font.width - 1;
}
void SetTimeScreen::render_time()
{
uint32_t x = 0;
uint32_t y = 32;
const struct font &font = default_font;
uint32_t width = m_display.get_width();
uint32_t x = (width - m_font.width * 8) / 2;
uint32_t y = m_row_spacing;
display_number(&x, y,
m_time.get_hours_12_tens(), m_time.get_hours_12_ones(),
font);
m_time.get_hours_12_tens(), m_time.get_hours_12_ones());
m_display.string_at(&x, y, ":", &font);
m_display.string_at(&x, y, ":", &m_font);
display_number(&x, y,
m_time.get_minutes_tens(), m_time.get_minutes_ones(),
font);
m_time.get_minutes_tens(), m_time.get_minutes_ones());
m_display.string_at(&x, y, ":", &font);
m_display.string_at(&x, y, ":", &m_font);
display_number(&x, y,
m_time.get_seconds_tens(), m_time.get_seconds_ones(),
font);
m_time.get_seconds_tens(), m_time.get_seconds_ones());
y = m_row_1_y;
x = 0;
m_display.string_at(&x, y, m_time.get_is_pm() ? "PM" : "AM", &m_font);
x = get_acknak_string_x_pos();
m_display.string_at(&x, y, get_acknak_string(), &m_font);
m_display.refresh();
}
void SetTimeScreen::draw_line(uint32_t x, uint32_t y, uint32_t width)
{
for (uint32_t i = 0; i < width; i += 8) {
m_display.set_byte(x + i, y, 0);
m_display.set_byte(x + i, y + 1, 0);
}
m_display.draw_hline(x, y, width);
m_display.draw_hline(x, y + 1, width);
}
void SetTimeScreen::render_selection()
{
uint32_t font_width = default_font_width;
uint32_t time_offset = (m_display.get_width()- m_font.width * 8) / 2;
switch (m_state) {
case SetState::HOURS:
draw_line(0, 64, font_width * 2);
draw_line(time_offset, m_row_0_y + m_font.height, m_font.width * 2);
break;
case SetState::MINUTES:
draw_line(font_width * 2, 64, font_width * 2);
draw_line(time_offset + m_font.width * 3, m_row_0_y + m_font.height, m_font.width * 2);
break;
case SetState::SECONDS:
draw_line(font_width * 4, 64, font_width * 2);
draw_line(time_offset + m_font.width * 6, m_row_0_y + m_font.height, m_font.width * 2);
break;
case SetState::AM_PM:
draw_line(0, m_row_1_y + m_font.height, m_font.width * 2);
break;
case SetState::ACK_NACK:
draw_line(get_acknak_string_x_pos(), m_row_1_y + m_font.height, get_acknak_string_len());
break;
}
}

View File

@@ -28,7 +28,7 @@
#include "ReturnCode.h"
#include "Task.h"
#include "Time.h"
#include "fontem.h"
#include "font.h"
class SetTimeScreen : public Screen {
public:
@@ -50,8 +50,13 @@ private:
void refresh();
void render_time();
void render_selection();
void display_number(uint32_t *x, uint32_t y, uint32_t tens, uint32_t ones, const struct font &f);
void display_number(uint32_t *x, uint32_t y, uint32_t tens, uint32_t ones);
void draw_line(uint32_t x, uint32_t y, uint32_t width);
uint32_t get_acknak_string_x_pos();
uint32_t get_acknak_string_len();
const char *get_acknak_string();
enum class SetState {
HOURS,
MINUTES,
@@ -66,4 +71,8 @@ private:
SetState m_state;
bool m_is_acked = false;
Common::WallClockTime m_time;
const struct font &m_font;
const uint32_t m_row_spacing;
const uint32_t m_row_0_y;
const uint32_t m_row_1_y;
};

View File

@@ -74,7 +74,7 @@ void SpiDriver::init()
// Enable Master mode and half the baud rate, so it's set to ~1MHz
m_spi->CR1 |= SPI_CR1_MSTR | SPI_CR1_LSBFIRST | SPI_CR1_SSM;
m_spi->CR1 |= 1u << SPI_CR1_BR_Pos;
//m_spi->CR1 |= 1u << SPI_CR1_BR_Pos;
m_spi->CR2 |= SPI_CR2_SSOE;
}

View File

@@ -21,17 +21,7 @@
#pragma once
#include "fontem.h"
#include "font-robotoMono-24.h"
#include "font-robotoMono-68.h"
// All fonts are fixed-width, so we also defined the widths here. It
// lets us know the width without needing a specific glyph to look it
// up.
static const struct font &default_font = font_robotoMono_24;
static constexpr uint32_t default_font_width = 20;
static const struct font &large_font = font_robotoMono_68;
static constexpr uint32_t large_font_width = 54;
#include "fonts/large_digits.h"
#include "fonts/small.h"
static const struct font &default_font = font_small;

2
Task.h
View File

@@ -33,7 +33,7 @@ enum class ScheduleType {
NEVER = 1,
};
class NextTime {
class NextTime final {
public:
NextTime() :
m_type(ScheduleType::NEVER),

2
Time.h
View File

@@ -27,7 +27,7 @@ namespace Common {
using time_t = uint64_t;
class Time {
class Time final {
public:
static constexpr uint64_t MILLIS_PER_SEC = 1e3;
static constexpr uint64_t MICROS_PER_SEC = 1e6;

19
font.h
View File

@@ -19,10 +19,27 @@
* THE SOFTWARE.
*/
#include <stdint.h>
#include <stddef.h>
#ifndef _FONT_H_
#define _FONT_H_
#include "fontem.h"
struct glyph {
const uint8_t *bitmap;
uint8_t width;
uint8_t width_bytes;
uint8_t height;
uint8_t top;
uint8_t left;
};
struct font {
const char *name;
const struct glyph *glyphs[128];
uint8_t width;
uint8_t height;
};
const struct glyph *glyph_for_char(const struct font *font, char c);

78
fontget.py Executable file
View File

@@ -0,0 +1,78 @@
#!/usr/bin/env python3
# Copyright (C) 2019 Max Regan
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import argparse
import io
from PIL import ImageFont, ImageDraw
import logging
logger = logging.getLogger(__name__)
def generate_font_file(ttf, output, size, characters):
font = ImageFont.truetype(ttf, size)
logger.debug("Width of all chars is %d", font.getsize(characters)[0])
characters = list(characters)
characters.sort()
size = None
total = 0
for char in characters:
total += font.getsize(char)[0]
if size is None:
size = font.getsize(str(char))
else:
pass
logger.debug("Width of %c is %d", char, font.getsize(char)[0])
logger.debug("Total width of %d chars is %d", len(characters), total)
logger.debug("Average of %f pixels per char", float(total) / len(characters))
logger.debug("%s", float(total) / len(characters))
def main():
parser = argparse.ArgumentParser("")
parser.add_argument("-o", "--output", help="Output file",
action="store", type=str)
parser.add_argument("-t", "--ttf", help="TrueType font file",
action="store", type=str)
parser.add_argument("-s", "--size", help="Font point size",
action="store", type=int)
parser.add_argument("-c", "--characters", help="Font point size",
default=
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789.,!?<>",
action="store", type=str)
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(levelname)s %(message)s')
generate_font_file(args.ttf, args.output, args.size, args.characters)
if __name__ == "__main__":
main()

View File

@@ -64,15 +64,14 @@ def ceildiv(num, den):
def to_c_name(name):
return name.replace("-","_")
def emit_bmp(output, font_name, char, bmp):
def emit_bmp(output, font_name, char, glyph, bmp):
width_bytes = ceildiv(bmp.width, 8)
height_bytes = ceildiv(bmp.height, 8)
output.write(f"// Bitmap for '{char}'\n")
name = to_c_name(f"{font_name}_{ord(char)}")
output.write(f"static uint8_t {name}_bitmap[] {{\n")
output.write(f"static const uint8_t {name}_bitmap[] = {{\n")
byte = 0
for y in range(bmp.height):
output.write(" ")
@@ -90,50 +89,86 @@ def emit_bmp(output, font_name, char, bmp):
output.write(f"// Glyph data for '{char}'\n")
output.write(f"static struct glyph {name}_glyph {{\n")
output.write(f"static const struct glyph {name}_glyph = {{\n")
output.write(f" .width = {bmp.width},\n")
output.write(f" .width_bytes = {width_bytes},\n")
output.write(f" .height = {bmp.height},\n")
output.write(f" .height_bytes = {height_bytes},\n")
output.write(f" .top = {glyph.top},\n")
output.write(f" .left = {glyph.left},\n")
output.write(f" .bitmap = {name}_bitmap,\n")
output.write("};\n\n")
def emit_font(output, ff, font_name, chars):
def emit_font(output, ff, font_name, charset, height, width):
c_font_name = to_c_name(font_name)
output.write(f"static struct font {c_font_name} {{\n")
output.write(f"const struct font {c_font_name} = {{\n")
output.write(f" .name = \"{font_name}\",\n")
output.write(f" .glypyhs = [\n")
for i in range(127):
if i in
output.write(f" .height = {height},\n")
output.write(f" .width = {width},\n")
output.write(f" .glyphs = {{\n")
for i in range(128):
if chr(i) in charset:
name = to_c_name(f"{font_name}_{i}_glyph")
output.write(f" [{i}] = &{name},\n")
else:
output.write(f" [{i}] = NULL,\n")
output.write(f" }}\n")
output.write("};\n\n")
def gen_c_font_file(ttf, output, charset, width=None, size=None, header_dir=None):
def gen_c_font_file(ttf, output, charset, width=None, size=None, header_dir=None, font_name=None):
ff = font.FixedFont(ttf, width=width, height=size)
if font_name is None:
font_name = ff.face.postscript_name.decode('ASCII')
ff = font.FixedFont(ttf, size)
font_name = ff.face.postscript_name.decode('ASCII')
emit_license(output)
emit_include(output, header_dir)
width = None
max_advance = None
max_height = None
for char in charset:
bmp = ff.render_character(char)
emit_bmp(output, font_name, char, bmp)
if width is None:
width = ceildiv(bmp.width, 8)
emit_font(output, ff, font_name)
glyph = ff.glyph_for_character(char)
emit_bmp(output, font_name, char, glyph, bmp)
advance = glyph.advance_width
if not max_advance or advance > max_advance:
max_advance = advance
height = glyph.top
if not max_height or height > max_height:
max_height = height
emit_font(output, ff, font_name, charset, max_height, max_advance)
def gen_h_font_file(ttf, output, header_dir=None, font_name=None):
if font_name is None:
font_name = ff.face.postscript_name.decode('ASCII')
c_font_name = to_c_name(font_name)
define_name = f"_FONT_{c_font_name.upper()}_H_"
def gen_h_font_file(ttf, output, charset, width=None, size=None):
emit_license(output)
output.write("\n")
output.write(f"#ifndef {define_name}\n")
output.write(f"#define {define_name}\n")
output.write("\n")
emit_include(output, header_dir)
output.write(f"extern const struct font {c_font_name};\n")
output.write("\n")
output.write("#endif")
def main():
parser = argparse.ArgumentParser(description="Fixed-width TrueType C code generator")
parser.add_argument(dest="filetype", help="The filetype to produce", action="store", type=str, choices=["c","h"])
parser.add_argument(dest="ttf", help="TrueType font file", action="store", type=str)
parser.add_argument(dest="output", help="Output C file", action="store", type=argparse.FileType('w'))
parser.add_argument(dest="output", help="Output file", action="store", type=argparse.FileType('w'))
parser.add_argument("--chars", "-c", help="Character set. Defaults to all printable ASCII", action="store", type=str,
default="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=_+{}[]:\";'<>,.?/~!@#$%^&*()|\\")
default="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 -=_+{}[]:\";'<>,.?/~!@#$%^&*()|\\")
parser.add_argument("--header-dir", help="Directory of the font.h header", action="store", type=str)
parser.add_argument("--name", help="Font name to use in the generated code", action="store", type=str)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--size", "-s", help="Font pitch", action="store", type=int)
@@ -143,7 +178,11 @@ def main():
args.chars = list(set(args.chars))
args.chars.sort()
gen_c_font_file(args.ttf, args.output, args.chars, width=args.width, size=args.size, header_dir=args.header_dir)
if args.filetype == "c":
gen_c_font_file(args.ttf, args.output, args.chars, width=args.width,
size=args.size, header_dir=args.header_dir, font_name=args.name)
elif args.filetype == "h":
gen_h_font_file(args.ttf, args.output, header_dir=args.header_dir, font_name=args.name)
if __name__ == "__main__":

View File

@@ -70,12 +70,13 @@ class Bitmap(object):
class Glyph(object):
def __init__(self, pixels, width, height, top, advance_width):
def __init__(self, pixels, width, height, top, left, advance_width):
self.bitmap = Bitmap(width, height, pixels)
# The glyph bitmap's top-side bearing, i.e. the vertical distance from the
# baseline to the bitmap's top-most scanline.
self.top = top
self.left = left
# Ascent and descent determine how many pixels the glyph extends
# above or below the baseline.
@@ -100,13 +101,14 @@ class Glyph(object):
pixels = Glyph.unpack_mono_bitmap(slot.bitmap)
width, height = slot.bitmap.width, slot.bitmap.rows
top = slot.bitmap_top
left = slot.bitmap_left
# The advance width is given in FreeType's 26.6 fixed point format,
# which means that the pixel values are multiples of 64.
assert slot.advance.x % 64 == 0
advance_width = slot.advance.x // 64
return Glyph(pixels, width, height, top, advance_width)
return Glyph(pixels, width, height, top, left, advance_width)
@staticmethod
def unpack_mono_bitmap(bitmap):
@@ -151,12 +153,14 @@ class Glyph(object):
class FixedFont(object):
def __init__(self, filename, size):
def __init__(self, filename, width=0, height=0):
self.face = freetype.Face(filename)
self.face.set_pixel_sizes(0, size)
if not width and not height:
raise ValueError("Width or height must be set non-zero")
self.face.set_pixel_sizes(width, height)
if not self.face.is_fixed_width:
raise ValueError("Font is not fixed width")
# if not self.face.is_fixed_width:
# raise ValueError("Font is not fixed width")
self.face.load_char('A', freetype.FT_LOAD_RENDER | freetype.FT_LOAD_TARGET_MONO)
self.advance = self.face.glyph.advance.x // 64

File diff suppressed because it is too large Load Diff

View File

@@ -1,751 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <stdlib.h>
#include "fontem.h"
#include "font-OpenSansExtraBold-28.h"
/* Character list: 0123456789:APM */
/** Kerning table for character ' '. */
static const struct kerning kerning_OpenSansExtraBold_28_0020[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character ' '. */
static const struct glyph glyph_OpenSansExtraBold_28_0020 = {
.glyph = 32,
.left = 0,
.top = 0,
.advance = 10,
.cols = 0,
.rows = 0,
.bitmap = NULL,
.kerning = kerning_OpenSansExtraBold_28_0020,
};
/** Bitmap definition for character '0'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0030[] = {
0x01, 0xfc, 0x00, 0x00,
0x07, 0xff, 0x00, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x07, 0xff, 0x00, 0x00,
0x01, 0xfc, 0x00, 0x00,
};
/** Kerning table for character '0'. */
static const struct kerning kerning_OpenSansExtraBold_28_0030[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '0'. */
static const struct glyph glyph_OpenSansExtraBold_28_0030 = {
.glyph = 48,
.left = 1,
.top = 28,
.advance = 23,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0030,
.kerning = kerning_OpenSansExtraBold_28_0030,
};
/** Bitmap definition for character '1'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0031[] = {
0x00, 0x7f,
0x01, 0xff,
0x03, 0xff,
0x07, 0xff,
0x0f, 0xff,
0x1f, 0xff,
0x7f, 0xff,
0xff, 0xff,
0xff, 0xff,
0x7e, 0xff,
0x3c, 0xff,
0x18, 0xff,
0x10, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
0x00, 0xff,
};
/** Kerning table for character '1'. */
static const struct kerning kerning_OpenSansExtraBold_28_0031[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '1'. */
static const struct glyph glyph_OpenSansExtraBold_28_0031 = {
.glyph = 49,
.left = 2,
.top = 28,
.advance = 23,
.cols = 16,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0031,
.kerning = kerning_OpenSansExtraBold_28_0031,
};
/** Bitmap definition for character '2'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0032[] = {
0x03, 0xfc, 0x00, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x3f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x3f, 0x0f, 0xf0, 0x00,
0x1c, 0x0f, 0xf0, 0x00,
0x08, 0x0f, 0xf0, 0x00,
0x00, 0x0f, 0xf0, 0x00,
0x00, 0x0f, 0xf0, 0x00,
0x00, 0x1f, 0xe0, 0x00,
0x00, 0x3f, 0xe0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x7f, 0x80, 0x00,
0x00, 0xff, 0x80, 0x00,
0x01, 0xff, 0x00, 0x00,
0x03, 0xfe, 0x00, 0x00,
0x07, 0xf8, 0x00, 0x00,
0x0f, 0xf0, 0x00, 0x00,
0x1f, 0xe0, 0x00, 0x00,
0x3f, 0xc0, 0x00, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
};
/** Kerning table for character '2'. */
static const struct kerning kerning_OpenSansExtraBold_28_0032[] = {
{ /* .left = '7' */ 55, /* .offset = */ -1 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '2'. */
static const struct glyph glyph_OpenSansExtraBold_28_0032 = {
.glyph = 50,
.left = 1,
.top = 28,
.advance = 23,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0032,
.kerning = kerning_OpenSansExtraBold_28_0032,
};
/** Bitmap definition for character '3'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0033[] = {
0x03, 0xfc, 0x00, 0x00,
0x1f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x1c, 0x1f, 0xf0, 0x00,
0x10, 0x0f, 0xf0, 0x00,
0x00, 0x0f, 0xe0, 0x00,
0x00, 0x0f, 0xe0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x07, 0xff, 0x80, 0x00,
0x07, 0xff, 0x00, 0x00,
0x07, 0xfc, 0x00, 0x00,
0x07, 0xff, 0x80, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x07, 0xff, 0xe0, 0x00,
0x00, 0x1f, 0xf0, 0x00,
0x00, 0x0f, 0xf0, 0x00,
0x00, 0x0f, 0xf0, 0x00,
0x80, 0x0f, 0xf0, 0x00,
0xf0, 0x1f, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0x00, 0x00,
0x0f, 0xf8, 0x00, 0x00,
};
/** Kerning table for character '3'. */
static const struct kerning kerning_OpenSansExtraBold_28_0033[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '3'. */
static const struct glyph glyph_OpenSansExtraBold_28_0033 = {
.glyph = 51,
.left = 1,
.top = 28,
.advance = 23,
.cols = 20,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0033,
.kerning = kerning_OpenSansExtraBold_28_0033,
};
/** Bitmap definition for character '4'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0034[] = {
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x7f, 0xc0, 0x00,
0x00, 0xff, 0xc0, 0x00,
0x00, 0xff, 0xc0, 0x00,
0x01, 0xff, 0xc0, 0x00,
0x03, 0xff, 0xc0, 0x00,
0x03, 0xff, 0xc0, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x0f, 0xdf, 0xc0, 0x00,
0x1f, 0xdf, 0xc0, 0x00,
0x1f, 0x9f, 0xc0, 0x00,
0x3f, 0x9f, 0xc0, 0x00,
0x7f, 0x1f, 0xc0, 0x00,
0x7e, 0x1f, 0xc0, 0x00,
0xfe, 0x1f, 0xc0, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x1f, 0xc0, 0x00,
};
/** Kerning table for character '4'. */
static const struct kerning kerning_OpenSansExtraBold_28_0034[] = {
{ /* .left = '7' */ 55, /* .offset = */ -1 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '4'. */
static const struct glyph glyph_OpenSansExtraBold_28_0034 = {
.glyph = 52,
.left = 1,
.top = 28,
.advance = 23,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0034,
.kerning = kerning_OpenSansExtraBold_28_0034,
};
/** Bitmap definition for character '5'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0035[] = {
0x7f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0x80, 0x00,
0x7f, 0xff, 0x80, 0x00,
0x7f, 0x00, 0x00, 0x00,
0x7f, 0x00, 0x00, 0x00,
0x7f, 0x00, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00,
0x7f, 0xfc, 0x00, 0x00,
0x7f, 0xff, 0x00, 0x00,
0xff, 0xff, 0x80, 0x00,
0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0x10, 0x3f, 0xe0, 0x00,
0x00, 0x1f, 0xe0, 0x00,
0x00, 0x0f, 0xe0, 0x00,
0x00, 0x0f, 0xe0, 0x00,
0x00, 0x1f, 0xe0, 0x00,
0xf0, 0x3f, 0xe0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0x80, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xfe, 0x00, 0x00,
0x1f, 0xf0, 0x00, 0x00,
};
/** Kerning table for character '5'. */
static const struct kerning kerning_OpenSansExtraBold_28_0035[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '5'. */
static const struct glyph glyph_OpenSansExtraBold_28_0035 = {
.glyph = 53,
.left = 2,
.top = 28,
.advance = 23,
.cols = 19,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0035,
.kerning = kerning_OpenSansExtraBold_28_0035,
};
/** Bitmap definition for character '6'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0036[] = {
0x00, 0x3f, 0xe0, 0x00,
0x01, 0xff, 0xe0, 0x00,
0x03, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x1f, 0xff, 0xe0, 0x00,
0x1f, 0xff, 0xe0, 0x00,
0x3f, 0xe0, 0x00, 0x00,
0x3f, 0x80, 0x00, 0x00,
0x7f, 0x00, 0x00, 0x00,
0x7f, 0x3f, 0x00, 0x00,
0x7e, 0x7f, 0xc0, 0x00,
0x7e, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0x8f, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0x7f, 0x07, 0xf8, 0x00,
0x7f, 0x07, 0xf8, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x1f, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0xc0, 0x00,
0x07, 0xff, 0x80, 0x00,
0x01, 0xfc, 0x00, 0x00,
};
/** Kerning table for character '6'. */
static const struct kerning kerning_OpenSansExtraBold_28_0036[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '6'. */
static const struct glyph glyph_OpenSansExtraBold_28_0036 = {
.glyph = 54,
.left = 1,
.top = 28,
.advance = 23,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0036,
.kerning = kerning_OpenSansExtraBold_28_0036,
};
/** Bitmap definition for character '7'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0037[] = {
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0x00, 0x1f, 0xe0, 0x00,
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x1f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0x80, 0x00,
0x00, 0x7f, 0x80, 0x00,
0x00, 0x7f, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00,
0x00, 0xfe, 0x00, 0x00,
0x01, 0xfe, 0x00, 0x00,
0x01, 0xfe, 0x00, 0x00,
0x01, 0xfc, 0x00, 0x00,
0x03, 0xfc, 0x00, 0x00,
0x03, 0xf8, 0x00, 0x00,
0x07, 0xf8, 0x00, 0x00,
0x07, 0xf8, 0x00, 0x00,
0x0f, 0xf0, 0x00, 0x00,
0x0f, 0xf0, 0x00, 0x00,
0x0f, 0xe0, 0x00, 0x00,
0x1f, 0xe0, 0x00, 0x00,
0x1f, 0xc0, 0x00, 0x00,
0x3f, 0xc0, 0x00, 0x00,
};
/** Kerning table for character '7'. */
static const struct kerning kerning_OpenSansExtraBold_28_0037[] = {
{ /* .left = '2' */ 50, /* .offset = */ -1 },
{ /* .left = '4' */ 52, /* .offset = */ -1 },
{ /* .left = '7' */ 55, /* .offset = */ 1 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '7'. */
static const struct glyph glyph_OpenSansExtraBold_28_0037 = {
.glyph = 55,
.left = 2,
.top = 28,
.advance = 23,
.cols = 20,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0037,
.kerning = kerning_OpenSansExtraBold_28_0037,
};
/** Bitmap definition for character '8'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0038[] = {
0x03, 0xfe, 0x00, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x3f, 0xdf, 0xe0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x07, 0xfe, 0x00, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x3f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0x7f, 0x8f, 0xf0, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0xfe, 0x03, 0xf8, 0x00,
0xfe, 0x03, 0xf8, 0x00,
0xfe, 0x03, 0xf8, 0x00,
0x7f, 0x07, 0xf0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0x80, 0x00,
0x03, 0xfe, 0x00, 0x00,
};
/** Kerning table for character '8'. */
static const struct kerning kerning_OpenSansExtraBold_28_0038[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '8'. */
static const struct glyph glyph_OpenSansExtraBold_28_0038 = {
.glyph = 56,
.left = 1,
.top = 28,
.advance = 23,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0038,
.kerning = kerning_OpenSansExtraBold_28_0038,
};
/** Bitmap definition for character '9'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0039[] = {
0x03, 0xf8, 0x00, 0x00,
0x0f, 0xff, 0x00, 0x00,
0x1f, 0xff, 0x80, 0x00,
0x3f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0xff, 0x0f, 0xf0, 0x00,
0xff, 0x07, 0xf0, 0x00,
0xfe, 0x07, 0xf0, 0x00,
0xfe, 0x07, 0xf0, 0x00,
0xfe, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x0f, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x3f, 0xfb, 0xf8, 0x00,
0x1f, 0xf3, 0xf0, 0x00,
0x07, 0xe7, 0xf0, 0x00,
0x00, 0x07, 0xf0, 0x00,
0x00, 0x1f, 0xf0, 0x00,
0x00, 0x7f, 0xe0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x3f, 0xff, 0xc0, 0x00,
0x3f, 0xff, 0x80, 0x00,
0x3f, 0xff, 0x00, 0x00,
0x3f, 0xfc, 0x00, 0x00,
0x3f, 0xe0, 0x00, 0x00,
};
/** Kerning table for character '9'. */
static const struct kerning kerning_OpenSansExtraBold_28_0039[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '9'. */
static const struct glyph glyph_OpenSansExtraBold_28_0039 = {
.glyph = 57,
.left = 1,
.top = 28,
.advance = 23,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0039,
.kerning = kerning_OpenSansExtraBold_28_0039,
};
/** Bitmap definition for character ':'. */
static const uint8_t bitmap_OpenSansExtraBold_28_003a[] = {
0x7c, 0x00,
0xfe, 0x00,
0xfe, 0x00,
0xff, 0x00,
0xfe, 0x00,
0xfe, 0x00,
0x7c, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x7c, 0x00,
0xfe, 0x00,
0xfe, 0x00,
0xff, 0x00,
0xfe, 0x00,
0xfe, 0x00,
0x7c, 0x00,
};
/** Kerning table for character ':'. */
static const struct kerning kerning_OpenSansExtraBold_28_003a[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character ':'. */
static const struct glyph glyph_OpenSansExtraBold_28_003a = {
.glyph = 58,
.left = 2,
.top = 22,
.advance = 11,
.cols = 8,
.rows = 22,
.bitmap = bitmap_OpenSansExtraBold_28_003a,
.kerning = kerning_OpenSansExtraBold_28_003a,
};
/** Bitmap definition for character 'A'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0041[] = {
0x00, 0x7f, 0xe0, 0x00,
0x00, 0xff, 0xe0, 0x00,
0x00, 0xff, 0xf0, 0x00,
0x00, 0xff, 0xf0, 0x00,
0x01, 0xff, 0xf0, 0x00,
0x01, 0xff, 0xf8, 0x00,
0x01, 0xff, 0xf8, 0x00,
0x01, 0xf9, 0xf8, 0x00,
0x03, 0xf9, 0xfc, 0x00,
0x03, 0xf9, 0xfc, 0x00,
0x03, 0xf9, 0xfc, 0x00,
0x07, 0xf0, 0xfe, 0x00,
0x07, 0xf0, 0xfe, 0x00,
0x07, 0xf0, 0xfe, 0x00,
0x0f, 0xf0, 0xff, 0x00,
0x0f, 0xf0, 0x7f, 0x00,
0x0f, 0xe0, 0x7f, 0x00,
0x1f, 0xff, 0xff, 0x80,
0x1f, 0xff, 0xff, 0x80,
0x1f, 0xff, 0xff, 0x80,
0x3f, 0xff, 0xff, 0xc0,
0x3f, 0xff, 0xff, 0xc0,
0x3f, 0xff, 0xff, 0xc0,
0x7f, 0xc0, 0x1f, 0xe0,
0x7f, 0x80, 0x1f, 0xe0,
0x7f, 0x80, 0x1f, 0xe0,
0xff, 0x80, 0x1f, 0xf0,
0xff, 0x00, 0x0f, 0xf0,
};
/** Kerning table for character 'A'. */
static const struct kerning kerning_OpenSansExtraBold_28_0041[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character 'A'. */
static const struct glyph glyph_OpenSansExtraBold_28_0041 = {
.glyph = 65,
.left = 0,
.top = 28,
.advance = 28,
.cols = 28,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0041,
.kerning = kerning_OpenSansExtraBold_28_0041,
};
/** Bitmap definition for character 'M'. */
static const uint8_t bitmap_OpenSansExtraBold_28_004d[] = {
0xff, 0xc0, 0x03, 0xff,
0xff, 0xe0, 0x07, 0xff,
0xff, 0xe0, 0x07, 0xff,
0xff, 0xe0, 0x07, 0xff,
0xff, 0xe0, 0x07, 0xff,
0xff, 0xf0, 0x0f, 0xff,
0xff, 0xf0, 0x0f, 0xff,
0xff, 0xf0, 0x0f, 0xff,
0xfd, 0xf8, 0x1f, 0xff,
0xfd, 0xf8, 0x1f, 0xff,
0xfd, 0xf8, 0x1f, 0x7f,
0xfe, 0xf8, 0x1f, 0x7f,
0xfe, 0xfc, 0x3f, 0x7f,
0xfe, 0xfc, 0x3f, 0x7f,
0xfe, 0xfc, 0x3e, 0x7f,
0xfe, 0x7e, 0x7e, 0x7f,
0xfe, 0x7e, 0x7e, 0x7f,
0xfe, 0x7e, 0x7c, 0x7f,
0xfe, 0x3f, 0x7c, 0x7f,
0xfe, 0x3f, 0xfc, 0x7f,
0xfe, 0x3f, 0xfc, 0x7f,
0xfe, 0x3f, 0xf8, 0x7f,
0xfe, 0x1f, 0xf8, 0x7f,
0xfe, 0x1f, 0xf8, 0x7f,
0xfe, 0x1f, 0xf0, 0x7f,
0xfe, 0x0f, 0xf0, 0x7f,
0xfe, 0x0f, 0xf0, 0x7f,
0xfe, 0x0f, 0xf0, 0x7f,
};
/** Kerning table for character 'M'. */
static const struct kerning kerning_OpenSansExtraBold_28_004d[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character 'M'. */
static const struct glyph glyph_OpenSansExtraBold_28_004d = {
.glyph = 77,
.left = 3,
.top = 28,
.advance = 38,
.cols = 32,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_004d,
.kerning = kerning_OpenSansExtraBold_28_004d,
};
/** Bitmap definition for character 'P'. */
static const uint8_t bitmap_OpenSansExtraBold_28_0050[] = {
0xff, 0xfc, 0x00, 0x00,
0xff, 0xff, 0x80, 0x00,
0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0x0f, 0xf0, 0x00,
0xff, 0x07, 0xf0, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xf0, 0x00,
0xff, 0x0f, 0xf0, 0x00,
0xff, 0x1f, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xfc, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00,
};
/** Kerning table for character 'P'. */
static const struct kerning kerning_OpenSansExtraBold_28_0050[] = {
{ /* .left = '7' */ 55, /* .offset = */ -2 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character 'P'. */
static const struct glyph glyph_OpenSansExtraBold_28_0050 = {
.glyph = 80,
.left = 3,
.top = 28,
.advance = 25,
.cols = 21,
.rows = 28,
.bitmap = bitmap_OpenSansExtraBold_28_0050,
.kerning = kerning_OpenSansExtraBold_28_0050,
};
/** Glyphs table for font "Open Sans". */
static const struct glyph *glyphs_OpenSansExtraBold_28[] = {
&glyph_OpenSansExtraBold_28_0020, /* U+0020 ' ' */
&glyph_OpenSansExtraBold_28_0030, /* U+0030 '0' */
&glyph_OpenSansExtraBold_28_0031, /* U+0031 '1' */
&glyph_OpenSansExtraBold_28_0032, /* U+0032 '2' */
&glyph_OpenSansExtraBold_28_0033, /* U+0033 '3' */
&glyph_OpenSansExtraBold_28_0034, /* U+0034 '4' */
&glyph_OpenSansExtraBold_28_0035, /* U+0035 '5' */
&glyph_OpenSansExtraBold_28_0036, /* U+0036 '6' */
&glyph_OpenSansExtraBold_28_0037, /* U+0037 '7' */
&glyph_OpenSansExtraBold_28_0038, /* U+0038 '8' */
&glyph_OpenSansExtraBold_28_0039, /* U+0039 '9' */
&glyph_OpenSansExtraBold_28_003a, /* U+003A ':' */
&glyph_OpenSansExtraBold_28_0041, /* U+0041 'A' */
&glyph_OpenSansExtraBold_28_004d, /* U+004D 'M' */
&glyph_OpenSansExtraBold_28_0050, /* U+0050 'P' */
};
/** Definition for font "Open Sans". */
const struct font font_OpenSansExtraBold_28 = {
.name = "Open Sans",
.style = "ExtraBold",
.size = 28,
.dpi = 100,
.count = 15,
.max = 80,
.ascender = 42,
.descender = -12,
.height = 53,
.glyphs = glyphs_OpenSansExtraBold_28,
.compressed = 0,
};

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_OpenSansExtraBold_28_H
#define _FONTEM_OpenSansExtraBold_28_H
#include "fontem.h"
extern const struct font font_OpenSansExtraBold_28;
#endif /* _FONTEM_OpenSansExtraBold_28_H */

View File

@@ -1,793 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#include <stdio.h>
#include <stdlib.h>
#include "fontem.h"
#include "font-OpenSansExtraBold-32.h"
/* Character list: 0123456789:APM */
/** Kerning table for character ' '. */
static const struct kerning kerning_OpenSansExtraBold_32_0020[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character ' '. */
static const struct glyph glyph_OpenSansExtraBold_32_0020 = {
.glyph = 32,
.left = 0,
.top = 0,
.advance = 11,
.cols = 0,
.rows = 0,
.bitmap = NULL,
.kerning = kerning_OpenSansExtraBold_32_0020,
};
/** Bitmap definition for character '0'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0030[] = {
0x01, 0xfe, 0x00, 0x00,
0x07, 0xff, 0x80, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x1f, 0xff, 0xe0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x7f, 0xcf, 0xf8, 0x00,
0xff, 0x87, 0xfc, 0x00,
0xff, 0x07, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x03, 0xfc, 0x00,
0xff, 0x07, 0xfc, 0x00,
0xff, 0x87, 0xfc, 0x00,
0x7f, 0xcf, 0xf8, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x1f, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x07, 0xff, 0x80, 0x00,
0x01, 0xfe, 0x00, 0x00,
};
/** Kerning table for character '0'. */
static const struct kerning kerning_OpenSansExtraBold_32_0030[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '0'. */
static const struct glyph glyph_OpenSansExtraBold_32_0030 = {
.glyph = 48,
.left = 2,
.top = 31,
.advance = 26,
.cols = 22,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0030,
.kerning = kerning_OpenSansExtraBold_32_0030,
};
/** Bitmap definition for character '1'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0031[] = {
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x7f, 0xc0, 0x00,
0x00, 0xff, 0xc0, 0x00,
0x03, 0xff, 0xc0, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x0f, 0xff, 0xc0, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xc0, 0x00,
0xff, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xc0, 0x00,
0x7f, 0xbf, 0xc0, 0x00,
0x3f, 0x3f, 0xc0, 0x00,
0x1c, 0x3f, 0xc0, 0x00,
0x08, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
};
/** Kerning table for character '1'. */
static const struct kerning kerning_OpenSansExtraBold_32_0031[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '1'. */
static const struct glyph glyph_OpenSansExtraBold_32_0031 = {
.glyph = 49,
.left = 2,
.top = 31,
.advance = 26,
.cols = 18,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0031,
.kerning = kerning_OpenSansExtraBold_32_0031,
};
/** Bitmap definition for character '2'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0032[] = {
0x00, 0xff, 0x00, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x1f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0x7f, 0xff, 0xfc, 0x00,
0x3f, 0x87, 0xfe, 0x00,
0x1e, 0x03, 0xfe, 0x00,
0x0c, 0x03, 0xfe, 0x00,
0x00, 0x03, 0xfe, 0x00,
0x00, 0x03, 0xfc, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x1f, 0xf8, 0x00,
0x00, 0x1f, 0xf0, 0x00,
0x00, 0x3f, 0xe0, 0x00,
0x00, 0x7f, 0xc0, 0x00,
0x00, 0xff, 0x80, 0x00,
0x03, 0xff, 0x00, 0x00,
0x07, 0xfe, 0x00, 0x00,
0x0f, 0xfc, 0x00, 0x00,
0x1f, 0xf8, 0x00, 0x00,
0x3f, 0xf0, 0x00, 0x00,
0x7f, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
};
/** Kerning table for character '2'. */
static const struct kerning kerning_OpenSansExtraBold_32_0032[] = {
{ /* .left = '7' */ 55, /* .offset = */ -1 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '2'. */
static const struct glyph glyph_OpenSansExtraBold_32_0032 = {
.glyph = 50,
.left = 1,
.top = 31,
.advance = 26,
.cols = 23,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0032,
.kerning = kerning_OpenSansExtraBold_32_0032,
};
/** Bitmap definition for character '3'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0033[] = {
0x03, 0xfe, 0x00, 0x00,
0x1f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x3c, 0x0f, 0xf8, 0x00,
0x10, 0x07, 0xf8, 0x00,
0x00, 0x07, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x1f, 0xf0, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0xc0, 0x00,
0x0f, 0xff, 0x00, 0x00,
0x0f, 0xff, 0x00, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0xf0, 0x00,
0x0f, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xfc, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x80, 0x07, 0xfc, 0x00,
0xf0, 0x0f, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0x80, 0x00,
0x0f, 0xfc, 0x00, 0x00,
};
/** Kerning table for character '3'. */
static const struct kerning kerning_OpenSansExtraBold_32_0033[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '3'. */
static const struct glyph glyph_OpenSansExtraBold_32_0033 = {
.glyph = 51,
.left = 2,
.top = 31,
.advance = 26,
.cols = 22,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0033,
.kerning = kerning_OpenSansExtraBold_32_0033,
};
/** Bitmap definition for character '4'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0034[] = {
0x00, 0x07, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x1f, 0xf8, 0x00,
0x00, 0x1f, 0xf8, 0x00,
0x00, 0x3f, 0xf8, 0x00,
0x00, 0x7f, 0xf8, 0x00,
0x00, 0xff, 0xf8, 0x00,
0x00, 0xff, 0xf8, 0x00,
0x01, 0xff, 0xf8, 0x00,
0x03, 0xff, 0xf8, 0x00,
0x03, 0xff, 0xf8, 0x00,
0x07, 0xff, 0xf8, 0x00,
0x0f, 0xef, 0xf8, 0x00,
0x0f, 0xef, 0xf8, 0x00,
0x1f, 0xcf, 0xf8, 0x00,
0x3f, 0xcf, 0xf8, 0x00,
0x3f, 0x8f, 0xf8, 0x00,
0x7f, 0x0f, 0xf8, 0x00,
0xfe, 0x0f, 0xf8, 0x00,
0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0x00,
0xff, 0xff, 0xff, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
};
/** Kerning table for character '4'. */
static const struct kerning kerning_OpenSansExtraBold_32_0034[] = {
{ /* .left = '7' */ 55, /* .offset = */ -1 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '4'. */
static const struct glyph glyph_OpenSansExtraBold_32_0034 = {
.glyph = 52,
.left = 1,
.top = 31,
.advance = 26,
.cols = 24,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0034,
.kerning = kerning_OpenSansExtraBold_32_0034,
};
/** Bitmap definition for character '5'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0035[] = {
0x3f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0x80, 0x00, 0x00,
0x7f, 0x80, 0x00, 0x00,
0x7f, 0x80, 0x00, 0x00,
0x7f, 0x80, 0x00, 0x00,
0x7f, 0xff, 0x00, 0x00,
0x7f, 0xff, 0xc0, 0x00,
0x7f, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0xf0, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xfc, 0x00,
0x18, 0x1f, 0xfc, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x80, 0x07, 0xfc, 0x00,
0xf8, 0x0f, 0xfc, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xe0, 0x00,
0x7f, 0xff, 0x80, 0x00,
0x0f, 0xfc, 0x00, 0x00,
};
/** Kerning table for character '5'. */
static const struct kerning kerning_OpenSansExtraBold_32_0035[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '5'. */
static const struct glyph glyph_OpenSansExtraBold_32_0035 = {
.glyph = 53,
.left = 2,
.top = 31,
.advance = 26,
.cols = 22,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0035,
.kerning = kerning_OpenSansExtraBold_32_0035,
};
/** Bitmap definition for character '6'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0036[] = {
0x00, 0x1f, 0xf8, 0x00,
0x00, 0xff, 0xf8, 0x00,
0x03, 0xff, 0xf8, 0x00,
0x07, 0xff, 0xf8, 0x00,
0x1f, 0xff, 0xf8, 0x00,
0x1f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x7f, 0xf0, 0x00, 0x00,
0x7f, 0xc0, 0x00, 0x00,
0x7f, 0x80, 0x00, 0x00,
0xff, 0x1f, 0x80, 0x00,
0xff, 0x7f, 0xe0, 0x00,
0xfe, 0xff, 0xf0, 0x00,
0xfe, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0x87, 0xfc, 0x00,
0xff, 0x03, 0xfe, 0x00,
0xff, 0x03, 0xfe, 0x00,
0xff, 0x03, 0xfe, 0x00,
0xff, 0x03, 0xfe, 0x00,
0xff, 0x83, 0xfc, 0x00,
0xff, 0xc7, 0xfc, 0x00,
0x7f, 0xff, 0xfc, 0x00,
0x7f, 0xff, 0xfc, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x1f, 0xff, 0xf0, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x00, 0xfe, 0x00, 0x00,
};
/** Kerning table for character '6'. */
static const struct kerning kerning_OpenSansExtraBold_32_0036[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '6'. */
static const struct glyph glyph_OpenSansExtraBold_32_0036 = {
.glyph = 54,
.left = 2,
.top = 31,
.advance = 26,
.cols = 23,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0036,
.kerning = kerning_OpenSansExtraBold_32_0036,
};
/** Bitmap definition for character '7'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0037[] = {
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0x00, 0x07, 0xf8, 0x00,
0x00, 0x07, 0xf8, 0x00,
0x00, 0x0f, 0xf8, 0x00,
0x00, 0x0f, 0xf0, 0x00,
0x00, 0x1f, 0xf0, 0x00,
0x00, 0x1f, 0xe0, 0x00,
0x00, 0x1f, 0xe0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x3f, 0xc0, 0x00,
0x00, 0x7f, 0xc0, 0x00,
0x00, 0x7f, 0x80, 0x00,
0x00, 0xff, 0x80, 0x00,
0x00, 0xff, 0x00, 0x00,
0x01, 0xff, 0x00, 0x00,
0x01, 0xfe, 0x00, 0x00,
0x03, 0xfe, 0x00, 0x00,
0x03, 0xfe, 0x00, 0x00,
0x03, 0xfc, 0x00, 0x00,
0x07, 0xfc, 0x00, 0x00,
0x07, 0xf8, 0x00, 0x00,
0x0f, 0xf8, 0x00, 0x00,
0x0f, 0xf0, 0x00, 0x00,
0x1f, 0xf0, 0x00, 0x00,
0x1f, 0xf0, 0x00, 0x00,
};
/** Kerning table for character '7'. */
static const struct kerning kerning_OpenSansExtraBold_32_0037[] = {
{ /* .left = '2' */ 50, /* .offset = */ -1 },
{ /* .left = '4' */ 52, /* .offset = */ -1 },
{ /* .left = '7' */ 55, /* .offset = */ 1 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '7'. */
static const struct glyph glyph_OpenSansExtraBold_32_0037 = {
.glyph = 55,
.left = 2,
.top = 31,
.advance = 26,
.cols = 23,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0037,
.kerning = kerning_OpenSansExtraBold_32_0037,
};
/** Bitmap definition for character '8'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0038[] = {
0x00, 0xff, 0x80, 0x00,
0x07, 0xff, 0xe0, 0x00,
0x0f, 0xff, 0xf8, 0x00,
0x1f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xfc, 0x00,
0x3f, 0xff, 0xfc, 0x00,
0x7f, 0xc3, 0xfe, 0x00,
0x7f, 0x81, 0xfe, 0x00,
0x7f, 0x81, 0xfe, 0x00,
0x3f, 0xc3, 0xfc, 0x00,
0x3f, 0xe7, 0xfc, 0x00,
0x1f, 0xff, 0xf8, 0x00,
0x1f, 0xff, 0xf8, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x03, 0xff, 0xc0, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x0f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xfc, 0x00,
0x7f, 0xc7, 0xfe, 0x00,
0x7f, 0x81, 0xfe, 0x00,
0x7f, 0x00, 0xfe, 0x00,
0xff, 0x00, 0xff, 0x00,
0xff, 0x80, 0xff, 0x00,
0x7f, 0xc1, 0xfe, 0x00,
0x7f, 0xff, 0xfe, 0x00,
0x7f, 0xff, 0xfe, 0x00,
0x3f, 0xff, 0xfc, 0x00,
0x1f, 0xff, 0xf8, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x01, 0xff, 0x80, 0x00,
};
/** Kerning table for character '8'. */
static const struct kerning kerning_OpenSansExtraBold_32_0038[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '8'. */
static const struct glyph glyph_OpenSansExtraBold_32_0038 = {
.glyph = 56,
.left = 1,
.top = 31,
.advance = 26,
.cols = 24,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0038,
.kerning = kerning_OpenSansExtraBold_32_0038,
};
/** Bitmap definition for character '9'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0039[] = {
0x01, 0xfe, 0x00, 0x00,
0x07, 0xff, 0xc0, 0x00,
0x0f, 0xff, 0xe0, 0x00,
0x1f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0xfc, 0x00,
0x7f, 0xff, 0xfc, 0x00,
0x7f, 0xc7, 0xfe, 0x00,
0xff, 0x83, 0xfe, 0x00,
0xff, 0x01, 0xfe, 0x00,
0xff, 0x01, 0xfe, 0x00,
0xff, 0x01, 0xfe, 0x00,
0xff, 0x81, 0xfe, 0x00,
0xff, 0xc7, 0xff, 0x00,
0x7f, 0xff, 0xff, 0x00,
0x7f, 0xff, 0xff, 0x00,
0x7f, 0xff, 0xfe, 0x00,
0x3f, 0xfe, 0xfe, 0x00,
0x1f, 0xfe, 0xfe, 0x00,
0x0f, 0xfd, 0xfe, 0x00,
0x03, 0xf1, 0xfe, 0x00,
0x00, 0x03, 0xfe, 0x00,
0x00, 0x07, 0xfc, 0x00,
0x00, 0x3f, 0xfc, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xf8, 0x00,
0x3f, 0xff, 0xf0, 0x00,
0x3f, 0xff, 0xe0, 0x00,
0x3f, 0xff, 0xc0, 0x00,
0x3f, 0xff, 0x00, 0x00,
0x3f, 0xf0, 0x00, 0x00,
};
/** Kerning table for character '9'. */
static const struct kerning kerning_OpenSansExtraBold_32_0039[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character '9'. */
static const struct glyph glyph_OpenSansExtraBold_32_0039 = {
.glyph = 57,
.left = 1,
.top = 31,
.advance = 26,
.cols = 24,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0039,
.kerning = kerning_OpenSansExtraBold_32_0039,
};
/** Bitmap definition for character ':'. */
static const uint8_t bitmap_OpenSansExtraBold_32_003a[] = {
0x3e, 0x00,
0x7f, 0x00,
0xff, 0x80,
0xff, 0x80,
0xff, 0x80,
0xff, 0x80,
0x7f, 0x00,
0x3e, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x3e, 0x00,
0x7f, 0x00,
0xff, 0x80,
0xff, 0x80,
0xff, 0x80,
0xff, 0x80,
0x7f, 0x00,
0x3e, 0x00,
};
/** Kerning table for character ':'. */
static const struct kerning kerning_OpenSansExtraBold_32_003a[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character ':'. */
static const struct glyph glyph_OpenSansExtraBold_32_003a = {
.glyph = 58,
.left = 2,
.top = 25,
.advance = 13,
.cols = 9,
.rows = 25,
.bitmap = bitmap_OpenSansExtraBold_32_003a,
.kerning = kerning_OpenSansExtraBold_32_003a,
};
/** Bitmap definition for character 'A'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0041[] = {
0x00, 0x3f, 0xfc, 0x00,
0x00, 0x3f, 0xfc, 0x00,
0x00, 0x7f, 0xfc, 0x00,
0x00, 0x7f, 0xfe, 0x00,
0x00, 0x7f, 0xfe, 0x00,
0x00, 0xff, 0xfe, 0x00,
0x00, 0xff, 0xff, 0x00,
0x00, 0xfe, 0xff, 0x00,
0x01, 0xfe, 0x7f, 0x00,
0x01, 0xfe, 0x7f, 0x80,
0x01, 0xfe, 0x7f, 0x80,
0x03, 0xfc, 0x3f, 0x80,
0x03, 0xfc, 0x3f, 0xc0,
0x03, 0xfc, 0x3f, 0xc0,
0x07, 0xfc, 0x3f, 0xc0,
0x07, 0xf8, 0x1f, 0xe0,
0x07, 0xf8, 0x1f, 0xe0,
0x0f, 0xf8, 0x1f, 0xe0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x1f, 0xff, 0xff, 0xf0,
0x1f, 0xff, 0xff, 0xf8,
0x1f, 0xff, 0xff, 0xf8,
0x3f, 0xff, 0xff, 0xf8,
0x3f, 0xff, 0xff, 0xfc,
0x3f, 0xe0, 0x07, 0xfc,
0x7f, 0xe0, 0x03, 0xfc,
0x7f, 0xc0, 0x03, 0xfe,
0x7f, 0xc0, 0x03, 0xfe,
0xff, 0xc0, 0x03, 0xff,
0xff, 0x80, 0x01, 0xff,
};
/** Kerning table for character 'A'. */
static const struct kerning kerning_OpenSansExtraBold_32_0041[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character 'A'. */
static const struct glyph glyph_OpenSansExtraBold_32_0041 = {
.glyph = 65,
.left = 0,
.top = 31,
.advance = 32,
.cols = 32,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0041,
.kerning = kerning_OpenSansExtraBold_32_0041,
};
/** Bitmap definition for character 'M'. */
static const uint8_t bitmap_OpenSansExtraBold_32_004d[] = {
0xff, 0xf0, 0x00, 0x7f, 0xf8, 0x00,
0xff, 0xf0, 0x00, 0x7f, 0xf8, 0x00,
0xff, 0xf8, 0x00, 0xff, 0xf8, 0x00,
0xff, 0xf8, 0x00, 0xff, 0xf8, 0x00,
0xff, 0xf8, 0x00, 0xff, 0xf8, 0x00,
0xff, 0xf8, 0x00, 0xff, 0xf8, 0x00,
0xff, 0xfc, 0x01, 0xff, 0xf8, 0x00,
0xff, 0xfc, 0x01, 0xff, 0xf8, 0x00,
0xff, 0xfc, 0x01, 0xff, 0xf8, 0x00,
0xff, 0xfe, 0x03, 0xff, 0xf8, 0x00,
0xff, 0xfe, 0x03, 0xf7, 0xf8, 0x00,
0xff, 0x7e, 0x03, 0xf7, 0xf8, 0x00,
0xff, 0x7f, 0x07, 0xf7, 0xf8, 0x00,
0xff, 0x7f, 0x07, 0xf7, 0xf8, 0x00,
0xff, 0x7f, 0x07, 0xe7, 0xf8, 0x00,
0xff, 0x3f, 0x87, 0xe7, 0xf8, 0x00,
0xff, 0x3f, 0x8f, 0xe7, 0xf8, 0x00,
0xff, 0x3f, 0x8f, 0xc7, 0xf8, 0x00,
0xff, 0x1f, 0x8f, 0xc7, 0xf8, 0x00,
0xff, 0x1f, 0xdf, 0xc7, 0xf8, 0x00,
0xff, 0x1f, 0xdf, 0x87, 0xf8, 0x00,
0xff, 0x0f, 0xdf, 0x87, 0xf8, 0x00,
0xff, 0x0f, 0xff, 0x87, 0xf8, 0x00,
0xff, 0x0f, 0xff, 0x87, 0xf8, 0x00,
0xff, 0x0f, 0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xff, 0x07, 0xf8, 0x00,
0xff, 0x07, 0xfe, 0x07, 0xf8, 0x00,
0xff, 0x03, 0xfe, 0x07, 0xf8, 0x00,
0xff, 0x03, 0xfe, 0x07, 0xf8, 0x00,
0xff, 0x03, 0xfe, 0x07, 0xf8, 0x00,
};
/** Kerning table for character 'M'. */
static const struct kerning kerning_OpenSansExtraBold_32_004d[] = {
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character 'M'. */
static const struct glyph glyph_OpenSansExtraBold_32_004d = {
.glyph = 77,
.left = 3,
.top = 31,
.advance = 43,
.cols = 37,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_004d,
.kerning = kerning_OpenSansExtraBold_32_004d,
};
/** Bitmap definition for character 'P'. */
static const uint8_t bitmap_OpenSansExtraBold_32_0050[] = {
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0xe0, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0x87, 0xfe, 0x00,
0xff, 0x83, 0xfe, 0x00,
0xff, 0x81, 0xfe, 0x00,
0xff, 0x81, 0xfe, 0x00,
0xff, 0x81, 0xfe, 0x00,
0xff, 0x83, 0xfe, 0x00,
0xff, 0x87, 0xfe, 0x00,
0xff, 0xff, 0xfe, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xfc, 0x00,
0xff, 0xff, 0xf8, 0x00,
0xff, 0xff, 0xf0, 0x00,
0xff, 0xff, 0xc0, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
0xff, 0x80, 0x00, 0x00,
};
/** Kerning table for character 'P'. */
static const struct kerning kerning_OpenSansExtraBold_32_0050[] = {
{ /* .left = '7' */ 55, /* .offset = */ -2 },
{ /* .left = */ 0, /* .offset = */ 0 },
};
/** Glyph definition for character 'P'. */
static const struct glyph glyph_OpenSansExtraBold_32_0050 = {
.glyph = 80,
.left = 3,
.top = 31,
.advance = 28,
.cols = 23,
.rows = 31,
.bitmap = bitmap_OpenSansExtraBold_32_0050,
.kerning = kerning_OpenSansExtraBold_32_0050,
};
/** Glyphs table for font "Open Sans". */
static const struct glyph *glyphs_OpenSansExtraBold_32[] = {
&glyph_OpenSansExtraBold_32_0020, /* U+0020 ' ' */
&glyph_OpenSansExtraBold_32_0030, /* U+0030 '0' */
&glyph_OpenSansExtraBold_32_0031, /* U+0031 '1' */
&glyph_OpenSansExtraBold_32_0032, /* U+0032 '2' */
&glyph_OpenSansExtraBold_32_0033, /* U+0033 '3' */
&glyph_OpenSansExtraBold_32_0034, /* U+0034 '4' */
&glyph_OpenSansExtraBold_32_0035, /* U+0035 '5' */
&glyph_OpenSansExtraBold_32_0036, /* U+0036 '6' */
&glyph_OpenSansExtraBold_32_0037, /* U+0037 '7' */
&glyph_OpenSansExtraBold_32_0038, /* U+0038 '8' */
&glyph_OpenSansExtraBold_32_0039, /* U+0039 '9' */
&glyph_OpenSansExtraBold_32_003a, /* U+003A ':' */
&glyph_OpenSansExtraBold_32_0041, /* U+0041 'A' */
&glyph_OpenSansExtraBold_32_004d, /* U+004D 'M' */
&glyph_OpenSansExtraBold_32_0050, /* U+0050 'P' */
};
/** Definition for font "Open Sans". */
const struct font font_OpenSansExtraBold_32 = {
.name = "Open Sans",
.style = "ExtraBold",
.size = 32,
.dpi = 100,
.count = 15,
.max = 80,
.ascender = 48,
.descender = -14,
.height = 61,
.glyphs = glyphs_OpenSansExtraBold_32,
.compressed = 0,
};

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_OpenSansExtraBold_32_H
#define _FONTEM_OpenSansExtraBold_32_H
#include "fontem.h"
extern const struct font font_OpenSansExtraBold_32;
#endif /* _FONTEM_OpenSansExtraBold_32_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_OpenSansExtraBold_64_H
#define _FONTEM_OpenSansExtraBold_64_H
#include "fontem.h"
extern const struct font font_OpenSansExtraBold_64;
#endif /* _FONTEM_OpenSansExtraBold_64_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_notomono_24_H
#define _FONTEM_notomono_24_H
#include "fontem.h"
extern const struct font font_notomono_24;
#endif /* _FONTEM_notomono_24_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_notomono_29_H
#define _FONTEM_notomono_29_H
#include "fontem.h"
extern const struct font font_notomono_29;
#endif /* _FONTEM_notomono_29_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_notomono_64_H
#define _FONTEM_notomono_64_H
#include "fontem.h"
extern const struct font font_notomono_64;
#endif /* _FONTEM_notomono_64_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
/* AUTOMATICALLY GENERATED FILE! EDITING NOT RECOMMENDED!
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_notomono_68_H
#define _FONTEM_notomono_68_H
#include "fontem.h"
extern const struct font font_notomono_68;
#endif /* _FONTEM_notomono_68_H */

View File

@@ -1,84 +0,0 @@
/** Font structure definitions.
*
* This file is distributed under the terms of the MIT License.
* See the LICENSE file at the top of this tree, or if it is missing a copy can
* be found at http://opensource.org/licenses/MIT
*/
#ifndef _FONTEM_H
#define _FONTEM_H
#include <stdint.h>
#include <stdio.h>
/** Alpha compositing "A over B" mechanism */
#define alpha_blend(in, in_alpha, out, out_alpha) \
((0x100 * in * in_alpha * (255 - out_alpha) + out * out_alpha * (255 - in_alpha)) >> 16)
#define blend(a, b, alpha) \
(((a) * (255 - (alpha)) + (b) * (alpha)) >> 8)
/** Extract the Alpha channel from a 32-bit RGBA value */
#define rgba32_get_a(rgba) ((rgba >> 24) & 0xff)
/** Extract the Red channel from a 32-bit RGBA value */
#define rgba32_get_r(rgba) ((rgba >> 16) & 0xff)
/** Extract the Green channel from a 32-bit RGBA value */
#define rgba32_get_g(rgba) ((rgba >> 8) & 0xff)
/** Extract the Blue channel from a 32-bit RGBA value */
#define rgba32_get_b(rgba) (rgba & 0xff)
/** Extract the Red channel from a 16-bit RGB value */
#define rgb16_get_r(rgb) ((rgb >> 8) & 0xf8)
/** Extract the Green channel from a 16-bit RGB value */
#define rgb16_get_g(rgb) ((rgb >> 3) & 0xfc)
/** Extract the Blue channel from a 16-bit RGB value */
#define rgb16_get_b(rgb) ((rgb << 3) & 0xf8)
/** Combine Red, Green and Blue channels into a 16-bit RGB value */
#define rgb16_combine(r, g, b) \
((((r) & 0xf8) << 8) | \
(((g) & 0xfc) << 3) | \
(((b) & 0xf8) >> 3))
/** Glyph character value rype */
typedef uint16_t glyph_t;
/** Description of a glyph; a single character in a font. */
struct glyph {
glyph_t glyph; /** The glyph this entry refers to */
int16_t left; /** Offset of the left edge of the glyph */
int16_t top; /** Offset of the top edge of the glyph */
int16_t advance; /** Horizonal offset when advancing to the next glyph */
uint16_t cols; /** Width of the bitmap */
uint16_t rows; /** Height of the bitmap */
const uint8_t *bitmap; /** Bitmap data */
const struct kerning *kerning; /** Font kerning data */
};
/** Kerning table; for a pair of glyphs, provides the horizontal adjustment. */
struct kerning {
glyph_t left; /** The left-glyph */
int16_t offset; /** The kerning offset for this glyph pair */
};
/** Description of a font. */
struct font {
char *name; /** Name of the font */
char *style; /** Style of the font */
uint16_t size; /** Point size of the font */
uint16_t dpi; /** Resolution of the font */
int16_t ascender; /** Ascender height */
int16_t descender; /** Descender height */
int16_t height; /** Baseline-to-baseline height */
uint16_t count; /** Number of glyphs */
uint16_t max; /** Maximum glyph index */
const struct glyph **glyphs; /** Font glyphs */
char compressed; /** TRUE if glyph bitmaps are RLE compressed */
};
#endif /* _FONTEM_H */

View File

@@ -28,8 +28,10 @@
#include "ScreenManager.h"
#include "DisplayTimeScreen.h"
#include "DebugScreen.h"
#include "MenuScreen.h"
#include "SetTimeScreen.h"
#include "SetDateScreen.h"
#include "stm32l0xx.h"
@@ -37,17 +39,38 @@
using Common::Time;
static Common::Schedule::LowPowerTaskScheduler<10> g_sched;
static Common::Schedule::LowPowerTaskScheduler<5> g_sched;
static BSP::SpiDriver g_spi(g_sched);
static BSP::DisplayDriver g_display(g_sched, g_spi);
static BSP::LptimPwm g_lptim_pwm(LPTIM1);
static BSP::ButtonManager g_btn_manager(2, 1, 0, Time::millis(1));
static BSP::ButtonManager g_btn_manager(g_sched, 2, 1, 0, Time::millis(1));
static ScreenManager g_screen_manager(g_sched, g_display, g_btn_manager);
static SetTimeScreen g_set_time_screen(g_display, g_screen_manager);
static MenuScreen g_menu_screen(
g_display, g_screen_manager, std::initializer_list<MenuScreenItem>({MenuScreenItem("Time", g_set_time_screen)}));
static DisplayTimeScreen g_display_time_screen(g_display, g_screen_manager, g_menu_screen);
static SetTimeScreen g_set_date_screen(g_display, g_screen_manager);
static MenuScreen g_enable_debug(g_display,
g_screen_manager,
"SW Update",
std::initializer_list<MenuScreenItem>({MenuScreenItem("Enable", []() { BSP::LowPower::enable_debug(); }),
MenuScreenItem("Disable", []() { BSP::LowPower::disable_debug();
})}));
// static DebugScreen g_debug_screen(g_display, g_screen_manager);
static MenuScreen g_settings_menu_screen(g_display,
g_screen_manager,
"Settings",
std::initializer_list<MenuScreenItem>({MenuScreenItem("Set Time", g_set_time_screen),
MenuScreenItem("Set Date", g_set_date_screen),
MenuScreenItem("Set Face", g_set_date_screen),
MenuScreenItem("SW Update", g_enable_debug)}));
static MenuScreen g_main_menu_screen(g_display,
g_screen_manager,
"Main Menu",
std::initializer_list<MenuScreenItem>({MenuScreenItem("Apps", g_settings_menu_screen),
MenuScreenItem("Settings", g_settings_menu_screen)}));
static DisplayTimeScreen g_display_time_screen(g_display, g_screen_manager, g_main_menu_screen);
extern "C" void __cxa_pure_virtual() { while(1) {} }

View File

@@ -38,11 +38,7 @@
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00000400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
@@ -50,7 +46,6 @@ __StackLimit:
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE