mirror of
https://github.com/nopnop2002/esp-idf-ssd1306.git
synced 2024-10-03 18:18:47 -04:00
added FreeTypeDemo
This commit is contained in:
parent
665c80c22d
commit
87219adcbc
14
FreeTypeDemo/CMakeLists.txt
Normal file
14
FreeTypeDemo/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS ../components/ssd1306)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ssd1306)
|
||||
|
||||
# Create a SPIFFS image from the contents of the 'font' directory
|
||||
# that fits the partition named 'storage'. FLASH_IN_PROJECT indicates that
|
||||
# the generated image should be flashed when the entire project is flashed to
|
||||
# the target with 'idf.py -p PORT flash
|
||||
spiffs_create_partition_image(fonts fonts FLASH_IN_PROJECT)
|
24
FreeTypeDemo/README.md
Normal file
24
FreeTypeDemo/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# FreeTypeDemo for SSD1306
|
||||
|
||||
FreeType components are published in the ESP Component Registry.
|
||||
The github page is [here](https://github.com/espressif/idf-extra-components/tree/master/freetype).
|
||||
This component can convert a True Type Font to a bitmap image.
|
||||
|
||||
___Please note that if you use a proportional font, some fonts may not convert correctly.___
|
||||
Monospaced fonts can be converted correctly.
|
||||
You can find Monospaced fonts [here](https://en.wikipedia.org/wiki/List_of_monospaced_typefaces).
|
||||
|
||||
![FreeTypeDemo](https://github.com/user-attachments/assets/13892a84-8ed8-48b9-8e1e-8e1f7235f8cb)
|
||||
|
||||
# How to use true type font.
|
||||
|
||||
- Download Monospaced fonts from internet.
|
||||
|
||||
- Copy font file to fonts directory.
|
||||
|
||||
- Select font
|
||||
load_font("/fonts/consola.ttf");
|
||||
|
||||
- Specify the display position and threshold
|
||||
render_text(&dev, 0, 16, 128, "FreeType");
|
||||
|
BIN
FreeTypeDemo/fonts/FiraMono-Regular.ttf
Normal file
BIN
FreeTypeDemo/fonts/FiraMono-Regular.ttf
Normal file
Binary file not shown.
BIN
FreeTypeDemo/fonts/consola.ttf
Normal file
BIN
FreeTypeDemo/fonts/consola.ttf
Normal file
Binary file not shown.
BIN
FreeTypeDemo/fonts/monof55.ttf
Normal file
BIN
FreeTypeDemo/fonts/monof55.ttf
Normal file
Binary file not shown.
16
FreeTypeDemo/main/CMakeLists.txt
Normal file
16
FreeTypeDemo/main/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
set(COMPONENT_SRCS "main.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "")
|
||||
|
||||
register_component()
|
||||
#idf_component_register(SRCS "freetype-example.c" INCLUDE_DIRS "." PRIV_REQUIRES spiffs)
|
||||
|
||||
# Download the example font into a directory "spiffs" in the build directory
|
||||
#set(URL "https://github.com/espressif/esp-docs/raw/f036a337d8bee5d1a93b2264ecd29255baec4260/src/esp_docs/fonts/DejaVuSans.ttf")
|
||||
#set(FILE "DejaVuSans.ttf")
|
||||
set(SPIFFS_DIR "../spiffs")
|
||||
#message(SPIFFS_DIR="${SPIFFS_DIR}")
|
||||
#file(MAKE_DIRECTORY ${SPIFFS_DIR})
|
||||
#file(DOWNLOAD ${URL} ${SPIFFS_DIR}/${FILE} SHOW_PROGRESS)
|
||||
|
||||
# Create a partition named "fonts" with the example font
|
||||
#spiffs_create_partition_image(fonts ${SPIFFS_DIR} FLASH_IN_PROJECT)
|
4
FreeTypeDemo/main/idf_component.yml
Normal file
4
FreeTypeDemo/main/idf_component.yml
Normal file
@ -0,0 +1,4 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/freetype:
|
||||
version: "^2.13.0~3"
|
222
FreeTypeDemo/main/main.c
Normal file
222
FreeTypeDemo/main/main.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
//#include "esp_err.h"
|
||||
#include "esp_spiffs.h"
|
||||
#include "ft2build.h"
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "ssd1306.h"
|
||||
|
||||
static const char *tag = "MAIN";
|
||||
|
||||
#define BITMAP_WIDTH 20
|
||||
#define BITMAP_HEIGHT 16
|
||||
|
||||
static FT_Library s_library;
|
||||
static FT_Face s_face;
|
||||
static uint8_t s_bitmap[BITMAP_HEIGHT][BITMAP_WIDTH];
|
||||
|
||||
static void load_font(char *font)
|
||||
{
|
||||
FT_Error error = FT_New_Face( s_library, font, 0, &s_face );
|
||||
if (error) {
|
||||
ESP_LOGE(tag, "Error loading font: %d", error);
|
||||
abort();
|
||||
}
|
||||
ESP_LOGI(tag, "Font [%s] loaded", font);
|
||||
}
|
||||
|
||||
static void render_text(SSD1306_t * dev, int xpos, int ypos, int threshold, char *text)
|
||||
{
|
||||
/* Configure character size. */
|
||||
//const int font_size = 14;
|
||||
const int font_size = 16;
|
||||
const int freetype_scale = 64;
|
||||
FT_Error error = FT_Set_Char_Size(s_face, 0, font_size * freetype_scale, 0, 0 );
|
||||
if (error) {
|
||||
ESP_LOGE(tag, "Error setting font size: %d", error);
|
||||
abort();
|
||||
}
|
||||
|
||||
int num_chars = strlen(text);
|
||||
|
||||
/* current drawing position */
|
||||
int x = 0;
|
||||
int y = 12;
|
||||
|
||||
for (int n = 0; n < num_chars; n++) {
|
||||
memset(s_bitmap, 0, BITMAP_WIDTH*BITMAP_HEIGHT);
|
||||
ESP_LOGI(tag, "Rendering char: '%c'", text[n]);
|
||||
|
||||
/* retrieve glyph index from character code */
|
||||
FT_UInt glyph_index = FT_Get_Char_Index( s_face, text[n] );
|
||||
|
||||
/* load glyph image into the slot (erase previous one) */
|
||||
error = FT_Load_Glyph( s_face, glyph_index, FT_LOAD_DEFAULT );
|
||||
//error = FT_Load_Glyph( s_face, glyph_index, FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO);
|
||||
if (error) {
|
||||
ESP_LOGE(tag, "Error loading glyph: %d", error);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* convert to a bitmap */
|
||||
error = FT_Render_Glyph( s_face->glyph, FT_RENDER_MODE_NORMAL );
|
||||
if (error) {
|
||||
ESP_LOGE(tag, "Error rendering glyph: %d", error);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* copy the glyph bitmap into the overall bitmap */
|
||||
FT_GlyphSlot slot = s_face->glyph;
|
||||
ESP_LOGD(tag, "font_size=%d", font_size);
|
||||
ESP_LOGD(tag, "slot->bitmap.rows=%d", slot->bitmap.rows);
|
||||
ESP_LOGD(tag, "slot->bitmap.width=%d", slot->bitmap.width);
|
||||
ESP_LOGD(tag, "slot->bitmap_top=%d", slot->bitmap_top);
|
||||
ESP_LOGD(tag, "slot->bitmap_left=%d", slot->bitmap_left);
|
||||
ESP_LOGD(tag, "slot->advance.x/64=%"PRIi32, slot->advance.x/64);
|
||||
int width = 0;
|
||||
for (int iy = 0; iy < slot->bitmap.rows; iy++) {
|
||||
for (int ix = 0; ix < slot->bitmap.width; ix++) {
|
||||
/* bounds check */
|
||||
//int res_x = ix + x;
|
||||
int res_x = ix + x + slot->bitmap_left;
|
||||
if (res_x < 0) res_x = 0;
|
||||
int res_y = y + iy - slot->bitmap_top;
|
||||
if (res_y < 0) res_y = 0;
|
||||
ESP_LOGD(tag,"res_x=%d res_y=%d", res_x, res_y);
|
||||
if (res_x >= BITMAP_WIDTH || res_y >= BITMAP_HEIGHT) {
|
||||
ESP_LOGW(tag, "bitmap size too large. res_x=%d res_y=%d", res_x, res_y);
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(tag, "iy=%d ix=%d res_y=%d res_x=%d", iy, ix, res_y, res_x);
|
||||
s_bitmap[res_y][res_x] = slot->bitmap.buffer[ix + iy * slot->bitmap.width];
|
||||
if (res_x > width) width = res_x;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t bitmap[BITMAP_HEIGHT];
|
||||
memset(bitmap, 0, BITMAP_HEIGHT);
|
||||
ESP_LOGD(tag, "width=%d", width);
|
||||
for (int iy = 0; iy < BITMAP_HEIGHT; iy++) {
|
||||
for (int ix = 0; ix < width; ix++) {
|
||||
int val = s_bitmap[iy][ix];
|
||||
if (val > 128) {
|
||||
putchar('#');
|
||||
} else if (val > 64) {
|
||||
putchar('+');
|
||||
} else if (val > 32) {
|
||||
putchar('.');
|
||||
} else {
|
||||
putchar('_');
|
||||
}
|
||||
|
||||
uint8_t wk = 0;
|
||||
if (val > threshold) wk = 1;
|
||||
wk = wk << ix;
|
||||
bitmap[iy] = bitmap[iy] | wk;
|
||||
ESP_LOGD(tag, "val=%d threshold=%d ix=%d iy=%d wk=0x%x bitmap[iy]=0x%x", val, threshold, ix, iy, wk, bitmap[iy]);
|
||||
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
//ESP_LOG_BUFFER_HEXDUMP(tag, bitmap, BITMAP_HEIGHT, ESP_LOG_INFO);
|
||||
for (int i=0;i<BITMAP_HEIGHT;i++) {
|
||||
bitmap[i] = ssd1306_rotate_byte(bitmap[i]);
|
||||
}
|
||||
//ESP_LOG_BUFFER_HEXDUMP(tag, bitmap, BITMAP_HEIGHT, ESP_LOG_INFO);
|
||||
ssd1306_bitmaps(dev, xpos, ypos, bitmap, 8, BITMAP_HEIGHT, false);
|
||||
xpos += slot->advance.x / 64;
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
SSD1306_t dev;
|
||||
//int top, bottom;
|
||||
//char lineChar[20];
|
||||
|
||||
#if CONFIG_I2C_INTERFACE
|
||||
ESP_LOGI(tag, "INTERFACE is i2c");
|
||||
ESP_LOGI(tag, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
|
||||
ESP_LOGI(tag, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
|
||||
ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
|
||||
i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO);
|
||||
#endif // CONFIG_I2C_INTERFACE
|
||||
|
||||
#if CONFIG_SPI_INTERFACE
|
||||
ESP_LOGI(tag, "INTERFACE is SPI");
|
||||
ESP_LOGI(tag, "CONFIG_MOSI_GPIO=%d",CONFIG_MOSI_GPIO);
|
||||
ESP_LOGI(tag, "CONFIG_SCLK_GPIO=%d",CONFIG_SCLK_GPIO);
|
||||
ESP_LOGI(tag, "CONFIG_CS_GPIO=%d",CONFIG_CS_GPIO);
|
||||
ESP_LOGI(tag, "CONFIG_DC_GPIO=%d",CONFIG_DC_GPIO);
|
||||
ESP_LOGI(tag, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
|
||||
spi_master_init(&dev, CONFIG_MOSI_GPIO, CONFIG_SCLK_GPIO, CONFIG_CS_GPIO, CONFIG_DC_GPIO, CONFIG_RESET_GPIO);
|
||||
#endif // CONFIG_SPI_INTERFACE
|
||||
|
||||
#if CONFIG_FLIP
|
||||
dev._flip = true;
|
||||
ESP_LOGW(tag, "Flip upside down");
|
||||
#endif
|
||||
|
||||
#if CONFIG_SSD1306_128x64
|
||||
ESP_LOGI(tag, "Panel is 128x64");
|
||||
ssd1306_init(&dev, 128, 64);
|
||||
#endif // CONFIG_SSD1306_128x64
|
||||
#if CONFIG_SSD1306_128x32
|
||||
ESP_LOGI(tag, "Panel is 128x32");
|
||||
ssd1306_init(&dev, 128, 32);
|
||||
#endif // CONFIG_SSD1306_128x32
|
||||
|
||||
// Initialize SPIFFS
|
||||
esp_vfs_spiffs_conf_t conf = {
|
||||
.base_path = "/fonts",
|
||||
.partition_label = "fonts",
|
||||
.max_files = 1,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&conf));
|
||||
|
||||
// Initialize FreeType
|
||||
FT_Error error = FT_Init_FreeType( &s_library );
|
||||
if (error) {
|
||||
ESP_LOGE(tag, "Error initializing FreeType library: %d", error);
|
||||
abort();
|
||||
}
|
||||
ESP_LOGI(tag, "FreeType library initialized");
|
||||
|
||||
ssd1306_clear_screen(&dev, false);
|
||||
ssd1306_contrast(&dev, 0xff);
|
||||
|
||||
// Bold style
|
||||
load_font("/fonts/consola.ttf");
|
||||
render_text(&dev, 0, 0, 32, "FreeType");
|
||||
FT_Done_Face( s_face );
|
||||
|
||||
// Slim style
|
||||
load_font("/fonts/consola.ttf");
|
||||
render_text(&dev, 0, 16, 128, "FreeType");
|
||||
FT_Done_Face( s_face );
|
||||
|
||||
#if CONFIG_SSD1306_128x64
|
||||
//load_font("/fonts/FiraMono-Regular.ttf");
|
||||
load_font("/fonts/monof55.ttf");
|
||||
render_text(&dev, 0, 32, 32, "FreeType");
|
||||
FT_Done_Face( s_face );
|
||||
|
||||
load_font("/fonts/FiraMono-Regular.ttf");
|
||||
render_text(&dev, 0, 48, 64, "FreeType");
|
||||
FT_Done_Face( s_face );
|
||||
#endif
|
||||
|
||||
FT_Done_FreeType( s_library );
|
||||
}
|
5
FreeTypeDemo/partitions.csv
Normal file
5
FreeTypeDemo/partitions.csv
Normal file
@ -0,0 +1,5 @@
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1M,
|
||||
fonts, data, spiffs, , 0xF0000,
|
||||
#fonts, data, spiffs, , 0x1F0000,
|
|
9
FreeTypeDemo/sdkconfig.defaults
Normal file
9
FreeTypeDemo/sdkconfig.defaults
Normal file
@ -0,0 +1,9 @@
|
||||
#
|
||||
# Partition Table
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
|
||||
#CONFIG_ESP_MAIN_TASK_STACK_SIZE=20000
|
||||
#CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
Loading…
Reference in New Issue
Block a user