Skip to content

Instantly share code, notes, and snippets.

@fridgerator
Created April 1, 2019 16:20
Show Gist options
  • Save fridgerator/0bc7167a964b021ffe62da40de2af250 to your computer and use it in GitHub Desktop.
Save fridgerator/0bc7167a964b021ffe62da40de2af250 to your computer and use it in GitHub Desktop.
LittlevGL + FreeType
#include "custom_font.h"
int rows = 20;
int load_custom_font(void)
{
printf("load custom font\n");
int error;
error = FT_Init_FreeType(&library);
if (error) {
printf("error init freetype\n");
return EXIT_FAILURE;
}
error = FT_New_Face(library, "./NotoSansCJKtc-Regular.otf", 0, &face);
if (error == FT_Err_Unknown_File_Format) {
printf("unkown file format\n");
return EXIT_FAILURE;
} else if (error) {
printf("error loading font\n");
return EXIT_FAILURE;
}
int height = rows * 64;
error = FT_Set_Char_Size(face, 0, height, 72, 72);
if (error) {
printf("couldnt get char size\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
const uint8_t * get_ttf_bitmap(const lv_font_t * font, uint32_t unicode_letter)
{
return font_buffer;
}
int16_t get_ttf_width(const lv_font_t * font, uint32_t unicode_letter)
{
int error;
error = FT_Load_Char(face, unicode_letter, FT_LOAD_RENDER);
if (error) {
printf("Could not load char in width\n");
return -1;
}
if (face->glyph->bitmap.buffer == NULL) return NULL;
FT_Bitmap bitmap = face->glyph->bitmap;
char * tmp_buffer;
tmp_buffer = malloc(rows * bitmap.width * sizeof(tmp_buffer));
for (int row = 0; row < rows; row++) {
for (int col = 0; col < bitmap.width; col++) {
int idx = (row * bitmap.width) + col;
if (row < (rows - bitmap.rows)) {
tmp_buffer[idx] = 0x00;
} else {
int bufferIdx = idx - (bitmap.width * (rows - bitmap.rows));
tmp_buffer[idx] = bitmap.buffer[bufferIdx];
}
}
}
font_buffer = tmp_buffer;
free(tmp_buffer);
return bitmap.width;
}
#ifndef CUSTOM_FONT
#define CUSTOM_FONT
#include <stdint.h>
#include "./lvgl/lv_misc/lv_font.h"
#include <ft2build.h>
#include FT_FREETYPE_H
static FT_Library library;
static FT_Face face;
static char * font_buffer;
int load_custom_font(void);
const uint8_t * get_ttf_bitmap(const lv_font_t * font, uint32_t unicode_letter);
int16_t get_ttf_width(const lv_font_t * font, uint32_t unicode_letter);
static lv_font_t custom_font =
{
.unicode_first = 0,
.unicode_last = 9999999,
.h_px = 20,
.glyph_bitmap = NULL,
.glyph_dsc = NULL,
.unicode_list = NULL,
.get_bitmap = get_ttf_bitmap,
.get_width = get_ttf_width,
.bpp = 8,
.next_page = NULL
};
#endif // CUSTOM_FONT
#define USE_SDL 1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "lvgl/lvgl.h"
#if USE_SDL
#include <SDL2/SDL.h>
#include "lv_drivers/display/monitor.h"
#else
#include "lv_drivers/display/fbdev.h"
#endif
#include "custom_font.h"
static char * label_text = "The quick brown fox jumps over the lazy";
static void hal_init(void);
void disp_init(void);
void build_container(lv_obj_t * parent);
LV_FONT_DECLARE(custom_font);
int main (int argc, char ** argv)
{
load_custom_font();
lv_init();
hal_init();
disp_init();
while (1) {
lv_tick_inc(5);
lv_task_handler();
usleep(5 * 1000);
}
}
static void hal_init(void)
{
#if USE_SDL
monitor_init();
#else
fbdev_init();
#endif
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
#if USE_SDL
disp_drv.disp_flush = monitor_flush;
disp_drv.disp_fill = monitor_fill;
disp_drv.disp_map = monitor_map;
#else
disp_drv.disp_flush = fbdev_flush;
disp_drv.disp_fill = fbdev_fill;
disp_drv.disp_map = fbdev_map;
#endif
lv_disp_drv_register(&disp_drv);
}
void disp_init(void)
{
lv_obj_t *scr = lv_obj_create(NULL, NULL);
lv_scr_load(scr);
build_container(scr);
}
lv_style_t label_style;
void build_container(lv_obj_t *parent)
{
lv_obj_t *main_container = lv_obj_create(parent, NULL);
lv_obj_set_size(main_container, 800, 480);
lv_obj_t *label = lv_label_create(main_container, NULL);
lv_style_copy(&label_style, &lv_style_plain);
label_style.text.font = &custom_font;
label_style.text.color = LV_COLOR_RED;
lv_obj_set_style(label, &label_style);
lv_label_set_text(label, label_text);
lv_obj_align(label, main_container, LV_ALIGN_CENTER, 0, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment