-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(freetype): add freetype example
- Loading branch information
Showing
7 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
cmake_minimum_required(VERSION 3.17) | ||
|
||
set(COMPONENTS main) | ||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(freetype-example) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# FreeType Example | ||
|
||
This is a simple example of initializing FreeType library, loading a font from a filesystem, and rendering a line of text. | ||
|
||
The font file (DejaVu Sans) is downloaded at compile time and is added into a SPIFFS filesystem image. The filesystem is flashed to the board together with the application. The example loads the font file and renders "FreeType" text into the console as ASCII art. | ||
|
||
This example doesn't require any special hardware and can run on any development board. | ||
|
||
## Building and running | ||
|
||
Run the application as usual for an ESP-IDF project. For example, for ESP32: | ||
``` | ||
idf.py set-target esp32 | ||
idf.py -p PORT flash monitor | ||
``` | ||
|
||
## Example output | ||
|
||
The example should output the following: | ||
|
||
``` | ||
I (468) main_task: Calling app_main() | ||
I (538) example: FreeType library initialized | ||
I (1258) example: Font loaded | ||
I (1268) example: Rendering char: 'F' | ||
I (1388) example: Rendering char: 'r' | ||
I (1528) example: Rendering char: 'e' | ||
I (1658) example: Rendering char: 'e' | ||
I (1798) example: Rendering char: 'T' | ||
I (1938) example: Rendering char: 'y' | ||
I (2078) example: Rendering char: 'p' | ||
I (2208) example: Rendering char: 'e' | ||
######. ######### | ||
## +# | ||
## ##### +###+ +###+ +# +# ######## +###+ | ||
## ##+ +#. .#+ +#. .#+ +# #+ #+##+ .#+ +#. .#+ | ||
###### ## #+ +# #+ +# +# ## +# ## +# #+ +# | ||
## ## .####### .####### +# .# ## ## .# .####### | ||
## ## .#. .#. +# #+.#. ## .# .#. | ||
## ## #+ #+ +# +### ## +# #+ | ||
## ## ##+ ++ ##+ ++ +# ##+ ##+ .#+ ##+ ++ | ||
## ## +#### +#### +# ## ###### +#### | ||
## ## | ||
+#. ## | ||
##+ ## | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
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 "${CMAKE_BINARY_DIR}/spiffs") | ||
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) |
150 changes: 150 additions & 0 deletions
150
freetype/examples/freetype-example/main/freetype-example.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: CC0-1.0 | ||
*/ | ||
|
||
|
||
#include <stdlib.h> | ||
#include "esp_log.h" | ||
#include "esp_err.h" | ||
#include "esp_spiffs.h" | ||
#include "ft2build.h" | ||
#include FT_FREETYPE_H | ||
|
||
static const char *TAG = "example"; | ||
|
||
static void init_filesystem(void); | ||
static void init_freetype(void); | ||
static void load_font(void); | ||
static void render_text(void); | ||
|
||
#define BITMAP_WIDTH 80 | ||
#define BITMAP_HEIGHT 18 | ||
|
||
static FT_Library s_library; | ||
static FT_Face s_face; | ||
static uint8_t s_bitmap[BITMAP_HEIGHT][BITMAP_WIDTH]; | ||
|
||
|
||
void app_main(void) | ||
{ | ||
init_filesystem(); | ||
init_freetype(); | ||
load_font(); | ||
render_text(); | ||
} | ||
|
||
static void init_filesystem(void) | ||
{ | ||
esp_vfs_spiffs_conf_t conf = { | ||
.base_path = "/fonts", | ||
.partition_label = "fonts", | ||
.max_files = 1, | ||
}; | ||
|
||
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&conf)); | ||
} | ||
|
||
static void init_freetype(void) | ||
{ | ||
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"); | ||
} | ||
|
||
static void load_font(void) | ||
{ | ||
FT_Error error = FT_New_Face( s_library, | ||
"/fonts/DejaVuSans.ttf", | ||
0, | ||
&s_face ); | ||
if (error) { | ||
ESP_LOGE(TAG, "Error loading font: %d", error); | ||
abort(); | ||
} | ||
|
||
ESP_LOGI(TAG, "Font loaded"); | ||
|
||
} | ||
|
||
static void render_text(void) | ||
{ | ||
/* Configure character size. */ | ||
const int font_size = 14; | ||
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(); | ||
} | ||
|
||
const char *text = "FreeType"; | ||
int num_chars = strlen(text); | ||
|
||
/* current drawing position */ | ||
int x = 0; | ||
int y = 12; | ||
|
||
for (int n = 0; n < num_chars; n++) { | ||
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 ); | ||
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; | ||
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_y = y + iy - slot->bitmap_top; | ||
if (res_x >= BITMAP_WIDTH || res_y >= BITMAP_HEIGHT) { | ||
continue; | ||
} | ||
s_bitmap[res_y][res_x] = slot->bitmap.buffer[ix + iy * slot->bitmap.width]; | ||
} | ||
} | ||
|
||
/* increment horizontal position */ | ||
x += slot->advance.x / 64; | ||
if (x >= BITMAP_WIDTH) { | ||
break; | ||
} | ||
} | ||
|
||
/* output the resulting bitmap to console */ | ||
for (int iy = 0; iy < BITMAP_HEIGHT; iy++) { | ||
for (int ix = 0; ix < x; ix++) { | ||
int val = s_bitmap[iy][ix]; | ||
if (val > 127) { | ||
putchar('#'); | ||
} else if (val > 64) { | ||
putchar('+'); | ||
} else if (val > 32) { | ||
putchar('.'); | ||
} else { | ||
putchar(' '); | ||
} | ||
} | ||
putchar('\n'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dependencies: | ||
espressif/freetype: | ||
version: "*" | ||
override_path: "../../.." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
nvs, data, nvs, 0x9000, 0x6000, | ||
phy_init, data, phy, 0xf000, 0x1000, | ||
factory, app, factory, 0x10000, 1M, | ||
fonts, data, spiffs, , 0xF0000, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
CONFIG_PARTITION_TABLE_CUSTOM=y | ||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" | ||
|
||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=20000 | ||
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y |