Coder Social home page Coder Social logo

takkao / openfontrender Goto Github PK

View Code? Open in Web Editor NEW
95.0 5.0 17.0 3.25 MB

TTF font render support library for microcomputer.

License: Other

PowerShell 0.36% Shell 0.24% C++ 3.15% C 95.72% Makefile 0.33% Python 0.11% CMake 0.08% Dockerfile 0.01%
arduino-ide freetype2 m5stack wioterminal arduino esp-idf esp32 font platformio rp2040

openfontrender's Introduction

Open Font Render

TTF font render support library for microcomputer using Arduino IDE.
This library can render TTF font files in the SD card or TTF font files embedded in the program.

This program is inspired by M5FontRender.
Any small contribution is welcome.

image

Features

  • Available for a variety of hardware using the Arduino IDE
  • Draws beautiful, anti-aliased fonts
  • Can be loaded from font data embedded in code (no SD card required)
  • Can use any drawing library
  • Can be changed to any version of FreeType.

Installation

Clone this repository into Arduino library folder.

API and Usage

See GitHub Pages for a list of available APIs. Bellow is only a part of the sample code.
More detailed examples can be found in examples.

Load from array (Wio Terminal)

#include "TFT_eSPI.h"
#include "binaryttf.h"
#include "OpenFontRender.h"

TFT_eSPI tft;
OpenFontRender render;

void setup()
{
	// put your setup code here, to run once:
	Serial.begin(115200);
	Serial.flush();
	delay(50);

	tft.begin();
	tft.setRotation(3);
	tft.fillScreen(TFT_BLACK);
	digitalWrite(LCD_BACKLIGHT, HIGH); // turn on the backlight

	render.setSerial(Serial);	  // Need to print render library message
	render.showFreeTypeVersion(); // print FreeType version
	render.showCredit();		  // print FTL credit

	if (render.loadFont(binaryttf, sizeof(binaryttf)))
	{
		Serial.println("Render initialize error");
		return;
	}

	render.setDrawer(tft); // Set drawer object
	/* You can also be written as follows. */
	// render.setDrawPixel(tft.drawPixel);
	// render.setDrawFastHLine(tft.drawFastHLine); // optional
	// render.setStartWrite(tft.startWrite);       // optional
	// render.setEndWrite(tft.endWrite);           // optional

	unsigned long t_start = millis();

	render.setFontColor(TFT_WHITE);
	render.printf("Hello World\n");
	render.seekCursor(0, 10);

	render.setFontSize(30);
	render.setFontColor(TFT_GREEN);
	render.printf("完全なUnicodeサポート\n");
	render.seekCursor(0, 10);

	render.setFontSize(40);
	render.setFontColor(TFT_ORANGE);
	render.printf("こんにちは世界\n");

	unsigned long t_end = millis();
	Serial.printf("Time: %ld ms\n", t_end - t_start);
}

void loop()
{
	// put your main code here, to run repeatedly:
}

Load from SD card (M5Stack)

#include <Arduino.h>
#include <M5Unified.h>
#include <SD.h>

#include "OpenFontRender.h"			 // Include after M5Unified.h
#include "ofrfs/M5Stack_SD_Preset.h" // Use preset

OpenFontRender render;

void setup()
{
	// put your setup code here, to run once:
	auto cfg = M5.config();
	M5.begin(cfg);
	M5.Display.fillScreen(TFT_BLACK);

	SD.begin(GPIO_NUM_4, SPI, 40000000);

	render.setSerial(Serial);	  // Need to print render library message
	render.showFreeTypeVersion(); // print FreeType version
	render.showCredit();		  // print FTL credit

	if (render.loadFont("/JKG-M_3_Tiny.ttf"))
	{
		Serial.println("Render initialize error");
		return;
	}

	render.setDrawer(M5.Display); // Set drawer object
	/* You can also be written as follows. */
	// render.setDrawPixel(M5.Display.drawPixel);
	// render.setDrawFastHLine(M5.Display.drawFastHLine); // optional
	// render.setStartWrite(M5.Display.startWrite);       // optional
	// render.setEndWrite(M5.Display.endWrite);           // optional

	unsigned long t_start = millis();

	render.setFontColor(TFT_WHITE);
	render.printf("Hello World\n");
	render.seekCursor(0, 10);

	render.setFontSize(30);
	render.setFontColor(TFT_GREEN);
	render.printf("完全なUnicodeサポート\n");
	render.seekCursor(0, 10);

	render.setFontSize(40);
	render.setFontColor(TFT_ORANGE);
	render.printf("こんにちは世界\n");

	unsigned long t_end = millis();
	Serial.printf("Time: %ld ms\n", t_end - t_start);
}

void loop()
{
	// put your main code here, to run repeatedly:
}

How to create binary TTF file

We use binary2ttf.py in tools directory to create binary TTF font file.
The binary2ttf.py is provided in the M5EPD library. The same program is included in tools directory in this repo.
You only execute below command.

python3 binary2ttf.py your_font_file.ttf

Switch draw function

In this library, you can change the drawing-related operations to your favorite functions (e.g. LavyonGFX).
To change it, use the following function.

render.setDrawPixel(my_draw_function);         // necessary

render.setDrawFastHLine(my_draw_fast_h_line);  // optional
render.setStartWrite(my_start_write_function); // optional
render.setEndWrite(my_end_write_function);     // optional

If you have an object for drawing and it contains the necessary methods, you can also use setDrawer method instead.

render.setDrawer(my_draw_object);	// Set drawer object

Switch other FreeType version

You can switch to any FreeType version in this library.
We have confirmed that it works with 2.4.12 and 2.12.1.
Default version is 2.4.12 because it was the version that worked most stably.

How to switch

  1. Download the version of FreeType that you like.
  2. Place the downloaded FreeType folder directly under OpenFontRender.
  3. Execute AutoRun script.

Note

If you are using FreeRTOS, some versions may become unstable.
You may have to increase the stack size or enable useRenderTask to get it to work.

How to load font files from SD/TF cards, SPIFFS, and so on

Control of file systems such as SD/TF cards and SPIFFS is strongly hardware-dependent. OpenFontRender supports the following reads as presets.

  • M5Stack
    • SD/TF (ofrfs/M5Stack_SD_Preset.h)
    • SPIFFS (ofrfs/M5Stack_SPIFFS_Preset.h)
  • Wio Terminal
    • SD/TF (ofrfs/WioTerminal_SD_Preset.h)

If you want to load font file from unsupported file system, you will need to overwrite some functions on the user code.

See the documentation for details on how to overwrite them. If you created a new preset, it would be great if you could provide us with the code.

Test

Tested Hardware

This library has been tested on the following hardware.
We would be happy to receive reports on hardware not listed here.

  • Arduino IDE 2.0
    • Seeed SAMD Boards (Board Manager v1.8.3)
      • Wio Terminal
    • M5Stack (Board Manager v2.0.4)
      • M5Stack Basic (Library v0.1.4)
      • M5Stack Core2 (Library v0.4.0)
  • PlatformIO
    • M5Stack Basic (Library v2.0.4)
    • M5Stack Core2 (Library v2.0.4)
  • ESP-IDF (4.4)
    • M5Stack Basic

Rendering speed

The table below shows the time taken to draw the sample program when it was run. Note: the time depends on the hardware settings or font file, so this is for reference only.

Load from SD Load from array Load from array
(Use LavyonGFX)
Wio Terminal 576 ms 491 ms 405 ms
M5Stack Basic 227 ms 230 ms 98 ms
M5Stack Core2 346 ms 281 ms 148 ms

LICENSE

This library is provided under the FTL license.
It is a BSD-style license with a credit clause.
All programs and binaries created using this library must be credited (as shown at the bottom of this README).

However, some files that are not related to FreeType can be used under the MIT license (See each files).

For more information about FTL licenses, see FTL.TXT in this repository or FreeType Licenses.

Sample font

We have used below font file for the sample program.
We would like to thank sozai-font-hako for providing us with an easy-to-use license for these wonderful fonts.

Font Copyright
JK Gothic M Copyright (c) 2014 M+ FONTS PROJECT
Copyright (c) 2015 JK FONTS

Portions of this software are copyright © The FreeTypeProject (www.freetype.org). All rights reserved.

openfontrender's People

Contributors

bodmer avatar rudcode avatar scottchiefbaker avatar takkao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

openfontrender's Issues

ESP32 crash with certain configuration

Hi -- I think this is possibly a TFT_eSPI bug, but I wanted to draw your attention to it: Bodmer/TFT_eSPI#3036

At first I thought this was an OFR problem, but the crash happens when the call to _drawPixel() happens (see that link for details). I don't know which library is actually causing the issue, though, so I wanted to let you know in case you thought it might be an OFR issue.

Text alignment seems shifted down about 50% of glyph height

I'm using setAlignment() to align text to the corners of my TFT and I'm getting odd results. No matter what I do, text always seems to be shifted down about half a glyph worth. I have tried having OFR render to the TFT and to a sprite and both exhibit the same problem. I suspect there is a minor math bug in the alignment code? Am I crazy?

Here is my super simplified use case:

#include "OpenFontRender.h"
OpenFontRender ofr;

#include "NotoSans_Bold.h"
#define TTF_FONT NotoSans_Bold
#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup(void) {
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(TFT_GREEN);

  ofr.setDrawer(tft);
  ofr.loadFont(TTF_FONT, sizeof(TTF_FONT));
  ofr.setBackgroundFillMethod(BgFillMethod::Block);

  ofr.setFontSize(80);
  ofr.setFontColor(TFT_WHITE, TFT_BLACK);

  int width  = tft.width();
  int height = tft.height();

  ofr.setCursor(width, 0)     ; ofr.setAlignment(Align::TopRight)   ; ofr.printf("TR");
  ofr.setCursor(width, height); ofr.setAlignment(Align::BottomRight); ofr.printf("BR");
  ofr.setCursor(0, height)    ; ofr.setAlignment(Align::BottomLeft) ; ofr.printf("BL");
  ofr.setCursor(0, 0)         ; ofr.setAlignment(Align::TopLeft)    ; ofr.printf("TL");
}

void loop() { }

cyd

Getting flickering with large front redraws

I'm attempting to build a count-up timer with a large font (160px+). When I redraw the screen once per second I get a visible flicker when I draw over the previous value. I have tried using BgFillMethod::Block and drawing a large rectangle over the previous text, and both have the same visual flicker. Is this a limitation of using large fonts? Is it even possible to render a large font without flicker on an ESP32?

#include "NotoSans_Bold.h"
#include "OpenFontRender.h"

#define TTF_FONT NotoSans_Bold // The font is referenced with the array name
OpenFontRender ofr;

#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup(void) {
    tft.begin();
    tft.setRotation(1);

    ofr.setDrawer(tft); // Link drawing object to tft instance (so font will be rendered on TFT)
    ofr.loadFont(TTF_FONT, sizeof(TTF_FONT));
}

void loop() {
    tft.fillScreen(TFT_BLACK);

    for (int i = 0; i <= 1000; i++) {
        ofr.setCursor(10, 10);
        ofr.setFontColor(TFT_WHITE, TFT_BLACK);
        ofr.setFontSize(200);

        //ofr.setBackgroundFillMethod(BgFillMethod::Block);
        tft.fillRect(10, 10, 120, 120, TFT_BLACK);

        ofr.printf("%02d", i);

        delay(1000);
    }
}

Cursor x resting place calculated too far right after cprintf (w/ proposed solution)

The solution seems easy. I will give that here, then state the details of the problem. (This came up from the full demo code program I am writing)

When using cprintf, you are adding the entire string length to get the cursor x resting spot. You should only add half of the string length to get to the right end. This has been tested in my code, not by modifying the library. I have not tried this with drawString yet. Not sure if it even applies. But, if so, the same solution is proposed.

Now, the problem as it presents itself...

The first one, using printf, calculates the resting point of the cursor properly. The cursor repositioning then appends the font size where it should be, at the right of the second line ("World").

Cursor starting at 0,0. iota result 34, cursor ending location 192/24.

Helllo
World 34

But the second one, using cprintf, calculates a cursor resting spot way too high for the width (x) value. The Y value is correct. I proved Y is correct by overriding the x cursor value with 400. It then appeared on screen.

iota result 34, cursor ending location 636/106. The text string width is 380. By subtracting 1/2 of that, the proper cursor x resting spot is obtained (446).

// Alignment left
  render.setCursor(0, 0);
  render.printf("Hello\nWorld size ");  // Seems to be required...
  // If you want to chain text together, use the cursor position after printer to add on.
  x = render.getCursorX(); y = render.getCursorY();  // returns 192 for x and 24 for y.  The append is perfect.

  itoa (font_size, str_buf, 10);
  Serial.printf("iota result %s, cursor ending location %i/%i\r\n", str_buf, x, y);
  // Append font size
  render.setCursor(x, y); render.printf(str_buf);

  // Alignment Center
  render.setCursor(tft.width() / 2, tft.height() / 3); render.setFontColor(TFT_GREEN);
  render.cprintf("Comic_Sans_Italic size ");
  // If you want to chain text together, use the returned cursor position after cprintf to add on.
  x = render.getCursorX(); y = render.getCursorY();  // Returns 636 for x (way wrong) and 106 for y (right). The append is off screen.
  itoa (font_size, str_buf, 10);
  Serial.printf("iota result %s, cursor ending location %i/%i\r\n", str_buf, x, y);
  // Append font size
  render.setCursor(x, y); render.printf(str_buf);

Feature request: output to image file

Hello. Can the function of outputting to a image file be implemented, so that even without using actual hardware, the ttf rendering can be checked?

Thanks.

OpenFontRender support for Teensy 4.1

Hello, OpenFontRender is great, compliments for that!
I am using OpenFontRender together with TFT_eSPI library (2.5.43).
Using Arduino IDE 2.3.2, I can build the Noto_Font_Demo (https://github.com/takkaO/OpenFontRender/tree/master/examples/TFT_eSPI/Noto_Font_Demo) and run it on ESP32 board using a TFT with an ILI9341 controller.
Unfortunately, I cannot compile the same for a Teensy board (tried versions 3.1, 3.6, 4.1).

I get a linker error, please see below (a few warnings first and the error is at the bottom).
I could not figure out what the problem is. Help fixing this is highly appreciated because I would like to use OpenFontRender in a project with a Teensy board.
Note: Without OpenFontRender, I can successfully build and run projects with Teensy 4.1 (1.59.0), TFT_eSPI (2.5.43), and the same TFT display.

Output from Arduino IDE 2.3.2
\arduino\libraries\OpenFontRender\src\sfnt\ttcmap.c:55:3: warning: 'tt_cmap_init' defined but not used [-Wunused-function]
55 | tt_cmap_init( TT_CMap cmap,

\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'uint16_t OpenFontRender::drawHString(const char*, int32_t, int32_t, uint16_t, uint16_t, Align, Drawing, FT_BBox&, FT_Error&)':
\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp:774:75: warning: comparison of integer expressions of different signedness: 'int32_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
774 | if (_saved_state.drawn_bg_point.x < (pos.x + (uint32_t)bit->bitmap.width)) {

\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'void OpenFontRender::draw2screen(FT_BitmapGlyph, uint32_t, uint32_t, uint16_t, uint16_t)':
\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp:1431:83: warning: comparison of integer expressions of different signedness: 'int32_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
1431 | if (_saved_state.drawn_bg_point.x <= (x + _x)) {

\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp:1462:75: warning: comparison of integer expressions of different signedness: 'int32_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
1462 | if (_saved_state.drawn_bg_point.x <= (x + _x)) {

\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'FT_Error OpenFontRender::loadFont(const char*, uint8_t)':
\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp:446:16: warning: 'char* strncpy(char*, const char*, size_t)' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
446 | strncpy(_face_id.filepath, fpath, len);

\arduino\libraries\OpenFontRender\src\OpenFontRender.cpp:443:28: note: length computed here
443 | size_t len = strlen(fpath);

/arduino15/packages/teensy/tools/teensy-compile/11.3.1/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld.exe: /arduino15/packages/teensy/tools/teensy-compile/11.3.1/arm/bin/../lib/gcc/arm-none-eabi/11.3.1/thumb/v7e-m+dp/hard\libc.a(libc_a-openr.o): in function `_open_r':

(.text._open_r+0x14): undefined reference to `_open'
collect2.exe: error: ld returned 1 exit status

exit status 1
Compilation error: exit status 1

Work in PlatformIO

PlatformIO環境では動作させるために修正が必要らしい。
本ライブラリ側で修正対応可能かどうか調査する。

It seems that modifications are necessary to make it work in the PlatformIO environment.
We will investigate whether the modification can be handled on the library side.

unloadFont crashes ESP32 S3 when font file is in FLASH

The ESP32 and RP2040 processors run fine, but the new ESP32 S3 processor crashes after using a font file in FLASH and then calling unloadFont().

This line is causing the crash. Since the sketch has provided the pointer in this case it seems inappropriate for the library to try to delete the memory allocation.

Possible to add a font range? ESP-IDF build in develop

Hi @takkaO
Very interesting project I'm thinking to use it in combination with Lovyan GFX to use chinese fonts in a demo Firmware.

One question: Is possible to add size / range to ttf2bin.py?

When I try to generate a binary for this chinese font:

3.9M Jun 27 2021 yrd_b.ttf
24M Oct 10 13:12 binaryttf.h

I'm getting a 24 megabytes header file. There is no way that I can use that in a microcontroller.
What's the way to generate smaller fonts?

Feature request: loading fonts from SPIFFS/LittleFS

Maybe I didn't quite get it yet but from what I understand OpenFontRender can only load fonts from SD card or binary (i.e. embedded in code).

Working with ESP32 it would be most helpful to be able to load fonts from the internal LittleFS file system.

Align::*Right doesn't work quite right?

I was using URW Gothic Book. This font, as far as I know, has fixed-width numerals.

When I use Align::TopRight or Align::BottomRight for the numerals, however, the alignment changes when a "1" is the last digit drawn to the screen.

E.g. drawing the string "90" and "91" will cause the 9 to be in a slightly different place. The other combinations (92, 93, 94, etc) all align as expected.

If I use that font in LibreOffice and align right, it works as expected.

Here is the original TTF.

Here is the stripped-down version (out of fontforge) that I'm actually using.

Any ideas? Is this a confusion on my part about what to expect from AlignRight? Maybe it goes by the actual glyph contents, rather than the specified character width?

FreeType Cache just keeps growing

I have an application with a lot of strings at different font sizes. All the text is rendered using the same font.

As I walk through my menu system I see memory being allocated as more glyphs are cached by FreeType's cache manager. Eventually all the available heap is allocated and the device resets.

I can work around this by unloading/loading the font every time I update text on the screen but it's not a great solution. Rendering speed is not noticeably worse which makes me wonder if the cache is required at all?

Is there a better way to flush free type's caches or reduce/control its memory usage??

Compile fails in Arduino environment with master branch - develop branch crashes RP2040

--Update-- These warnings are treated as errors with ESP32 board package for the case where "Compile warnings:" is set to "All" in the Arduino IDE "Preferences" dialogue box. If set to "None", "Default" or "More" these warnings will NOT be traeated as errors.

Compile fails for the ESP32, warnings and errors are reported below. This is with the ESP32 board package 2.0.5 which seems to be very picky with type conversions:

D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'FT_Error OpenFontRender::loadFont(const unsigned char*, size_t)':
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:201:59: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  error = FTC_Manager_LookupFace(_ftc_manager, (FTC_FaceID)_face_id, &face);
                                                           ^~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'FT_Error OpenFontRender::loadFont(const char*)':
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:244:59: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  error = FTC_Manager_LookupFace(_ftc_manager, (FTC_FaceID)_face_id, &face);
                                                           ^~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'FT_Error OpenFontRender::drawChar(uint16_t, uint32_t, uint32_t, uint16_t, uint16_t)':
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:279:59: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
  error = FTC_Manager_LookupFace(_ftc_manager, (FTC_FaceID)_face_id, &face);
                                                           ^~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:286:57: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
                                             (FTC_FaceID)_face_id,
                                                         ^~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:331:36: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   image_type.face_id = (FTC_FaceID)_face_id;
                                    ^~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp: In member function 'uint16_t OpenFontRender::drawString(const char*, uint32_t, uint32_t, uint16_t, uint16_t, FT_Error*)':
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:382:61: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   *error = FTC_Manager_LookupFace(_ftc_manager, (FTC_FaceID)_face_id, &face);
                                                             ^~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp: In function 'void RenderTask(void*)':
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:638:79: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
                                                   (FTC_FaceID)g_TaskParameter.face_id,
                                                                               ^~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:646:52: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
    ft_scaler.face_id = (FTC_FaceID)g_TaskParameter.face_id;
                                                    ^~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:676:28: error: narrowing conversion of 'face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::bitmap.FT_Bitmap_::width' from 'int' to 'FT_Byte' {aka 'unsigned char'} inside { } [-Werror=narrowing]
        face->glyph->bitmap.width,      // width
        ~~~~~~~~~~~~~~~~~~~~^~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:677:28: error: narrowing conversion of 'face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::bitmap.FT_Bitmap_::rows' from 'int' to 'FT_Byte' {aka 'unsigned char'} inside { } [-Werror=narrowing]
        face->glyph->bitmap.rows,       // height
        ~~~~~~~~~~~~~~~~~~~~^~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:678:21: error: narrowing conversion of 'face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::bitmap_left' from 'FT_Int' {aka 'int'} to 'FT_Char' {aka 'signed char'} inside { } [-Werror=narrowing]
        face->glyph->bitmap_left,       // left
        ~~~~~~~~~~~~~^~~~~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:679:21: error: narrowing conversion of 'face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::bitmap_top' from 'FT_Int' {aka 'int'} to 'FT_Char' {aka 'signed char'} inside { } [-Werror=narrowing]
        face->glyph->bitmap_top,        // top
        ~~~~~~~~~~~~~^~~~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:681:28: error: narrowing conversion of 'face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::bitmap.FT_Bitmap_::num_grays' from 'short int' to 'FT_Byte' {aka 'unsigned char'} inside { } [-Werror=narrowing]
        face->glyph->bitmap.num_grays,  // max_gray
        ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:682:28: error: narrowing conversion of 'face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::bitmap.FT_Bitmap_::pitch' from 'int' to 'FT_Short' {aka 'short int'} inside { } [-Werror=narrowing]
        face->glyph->bitmap.pitch,      // pitch
        ~~~~~~~~~~~~~~~~~~~~^~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:683:31: error: narrowing conversion of '(face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::advance.FT_Vector_::x >> 6)' from 'FT_Pos' {aka 'long int'} to 'FT_Char' {aka 'signed char'} inside { } [-Werror=narrowing]
        face->glyph->advance.x >> 6,    // xadvance
        ~~~~~~~~~~~~~~~~~~~~~~~^~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:684:31: error: narrowing conversion of '(face->FT_FaceRec_::glyph->FT_GlyphSlotRec_::advance.FT_Vector_::y >> 6)' from 'FT_Pos' {aka 'long int'} to 'FT_Char' {aka 'signed char'} inside { } [-Werror=narrowing]
        face->glyph->advance.y >> 6,    // yadvance
        ~~~~~~~~~~~~~~~~~~~~~~~^~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:695:53: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
    image_type.face_id = (FTC_FaceID)g_TaskParameter.face_id;
                                                     ^~~~~~~
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp: In function 'FT_Error ftc_face_requester(FTC_FaceID, FT_Library, FT_Pointer, FT_FaceRec_**)':
D:\XXXX\Arduino\Sketches\libraries\OpenFontRender\src\OpenFontRender.cpp:566:9: error: 'error' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  return error;
         ^~~~~
cc1plus.exe: some warnings being treated as errors

Nucleo64 : undefined reference to `_open'

c:/users/xxx/appdata/local/arduino15/packages/stmicroelectronics/tools/xpack-arm-none-eabi-gcc/10.3.1-2.3/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe:

c:/users/xxx/appdata/local/arduino15/packages/stmicroelectronics/tools/xpack-arm-none-eabi-gcc/10.3.1-2.3/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-openr.o): in function _open_r': (.text._open_r+0x10): undefined reference to _open'
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

Memory issue

Hello, I am using a OpenFontRender on ESP32 together with TFT_eSPI and I am using multiple fonts. I noticed that after loadFont() and then unloadFont(), approximately 50 bytes of memory remain allocated. So after each loadFont() - unloadFont() of another font, the memory usage increases until the system crashes.

Please support ARM cortex arch?

Im attempting to build this for Adafruit M4 Grand Central, and it's failing.

Build Log
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:120:26: error: macro "swap" requires 2 arguments, but only 1 given    
  120 |       swap(array& __other)
      |                          ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:294:56: error: macro "swap" passed 4 arguments, but takes just 2      
  294 |     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
      |                                                        ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:295:39: error: macro "swap" requires 2 arguments, but only 1 given    
  295 |     noexcept(noexcept(__one.swap(__two)))
      |                                       ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:296:23: error: macro "swap" requires 2 arguments, but only 1 given
  296 |     { __one.swap(__two); }
      |                       ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:302:44: error: macro "swap" passed 4 arguments, but takes just 2      
  302 |     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
      |                                            ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:856:23: error: macro "swap" requires 2 arguments, but only 1 given    
  856 |       swap(tuple& __in)
      |                       ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:879:23: error: macro "swap" requires 2 arguments, but only 1 given    
  879 |       void swap(tuple&) noexcept { /* no-op */ }
      |                       ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1263:23: error: macro "swap" requires 2 arguments, but only 1 given
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\WInterrupts.c.o
 1263 |       swap(tuple& __in)
      |                       ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      | 
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\WMath.cpp.o
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\WString.cpp.o
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1625:35: error: macro "swap" requires 2 arguments, but only 1 given   
 1625 |     noexcept(noexcept(__x.swap(__y)))
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\abi.cpp.o
      |                                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\avr\dtostrf.c.o
      | 
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\cortex_handlers.c.o
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1626:19: error: macro "swap" requires 2 arguments, but only 1 given   
 1626 |     { __x.swap(__y); }
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\delay.c.o
      |                   ^
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\hooks.c.o
In file included from src\main.cpp:14:
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\itoa.c.o
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\main.cpp.o
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:425:16: error: macro "swap" requires 2 arguments, but only 1 given
  425 |  __x.swap(*this);
      |                ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\math_helper.c.o
   35 | #define swap(a, b)      \
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\new.cpp.o
      | 
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\pulse.c.o
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:464:26: error: macro "swap" requires 2 arguments, but only 1 given
  464 |  function(__x).swap(*this);
      |                          ^
In file included from src\main.cpp:14:
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\pulse_asm.S.o
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\startup.c.o
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:482:37: error: macro "swap" requires 2 arguments, but only 1 given
  482 |  function(std::move(__x)).swap(*this);
      |                                     ^
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\wiring.c.o
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:525:52: error: macro "swap" requires 2 arguments, but only 1 given
  525 |    function(std::forward<_Functor>(__f)).swap(*this);
      |                                                    ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:534:28: error: macro "swap" requires 2 arguments, but only 1 given
  534 |    function(__f).swap(*this);
      |                            ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\wiring_analog.c.o
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:547:30: error: macro "swap" requires 2 arguments, but only 1 given
  547 |       void swap(function& __x) noexcept
      |                              ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:786:19: error: macro "swap" requires 2 arguments, but only 1 given
  786 |     { __x.swap(__y); }
      |                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\wiring_digital.c.o
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\deque:67,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:60,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:1849:22: error: macro "swap" requires 2 arguments, but only 1 given
 1849 |       swap(deque& __x) _GLIBCXX_NOEXCEPT
      |                      ^
In file included from src\main.cpp:14:
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\wiring_private.c.o
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\deque:67,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:60,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:2366:56: error: macro "swap" passed 4 arguments, but takes just 2
Compiling .pio\build\adafruit_grandcentral_m4\FrameworkArduino\wiring_shift.c.o
 2366 |     swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
      |                                                        ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\deque:67,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:60,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:2367:49: error: macro "swap" requires 2 arguments, but only 1 given
 2367 |     _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
      |                                                 ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\deque:67,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:60,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:2368:19: error: macro "swap" requires 2 arguments, but only 1 given
 2368 |     { __x.swap(__y); }
      |                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:300:22: error: macro "swap" requires 2 arguments, but only 1 given
  300 |       swap(queue& __q)
      |                      ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:392:54: error: macro "swap" passed 4 arguments, but takes just 2
  392 |     swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
      |                                                      ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:393:35: error: macro "swap" requires 2 arguments, but only 1 given
  393 |     noexcept(noexcept(__x.swap(__y)))
      |                                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      | 
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:394:19: error: macro "swap" requires 2 arguments, but only 1 given
  394 |     { __x.swap(__y); }
      |                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:671:32: error: macro "swap" requires 2 arguments, but only 1 given
  671 |       swap(priority_queue& __pq)
      |                                ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:727:48: error: macro "swap" passed 6 arguments, but takes just 2
  727 |   priority_queue<_Tp, _Sequence, _Compare>& __y)
      |                                                ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:728:35: error: macro "swap" requires 2 arguments, but only 1 given
  728 |     noexcept(noexcept(__x.swap(__y)))
      |                                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:729:19: error: macro "swap" requires 2 arguments, but only 1 given
  729 |     { __x.swap(__y); }
      |                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:63,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:1474:21: error: macro "swap" requires 2 arguments, but only 1 given
 1474 |       swap(list& __x) _GLIBCXX_NOEXCEPT
      |                     ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:63,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:2056:56: error: macro "swap" passed 4 arguments, but takes just 2
 2056 |     swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
      |                                                        ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:63,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:2057:49: error: macro "swap" requires 2 arguments, but only 1 given
 2057 |     _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
      |                                                 ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:63,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:2058:19: error: macro "swap" requires 2 arguments, but only 1 given
 2058 |     { __x.swap(__y); }
      |                   ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:508:30: error: macro "swap" requires 2 arguments, but only 1 given
  508 |       __carry.swap(*__counter);
      |                              ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:510:26: error: macro "swap" requires 2 arguments, but only 1 given
  510 |   __carry.swap(*__counter);
      |                          ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:518:26: error: macro "swap" requires 2 arguments, but only 1 given
  518 |      swap( *(__fill - 1) );
      |                          ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:606:27: error: macro "swap" requires 2 arguments, but only 1 given
  606 |    __carry.swap(*__counter);
      |                           ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:608:30: error: macro "swap" requires 2 arguments, but only 1 given
  608 |       __carry.swap(*__counter);
      |                              ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:616:21: error: macro "swap" requires 2 arguments, but only 1 given
  616 |   swap(*(__fill - 1));
      |                     ^
In file included from src\main.cpp:14:
src\er_oled.h:35: note: macro "swap" defined here
   35 | #define swap(a, b)      \
      |
Archiving .pio\build\adafruit_grandcentral_m4\libFrameworkArduino.a
src\er_oled.cpp: In function 'void OLED_ShowPicture_gray(uint16_t, uint16_t, uint16_t, uint16_t, const uint8_t*)':
src\er_oled.cpp:230:19: warning: unused variable 'timer' [-Wunused-variable]
  230 |     unsigned long timer[8];
      |                   ^~~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:120:7: error: variable or field 'swap' declared void
  120 |       swap(array& __other)
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:120:7: error: expected ';' at end of member declaration
  120 |       swap(array& __other)
      |       ^~~~
      |           ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:121:7: error: expected unqualified-id before 'noexcept'
  121 |       noexcept(_AT_Type::_Is_nothrow_swappable::value)
      |       ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:295:5: error: expected initializer before 'noexcept'
  295 |     noexcept(noexcept(__one.swap(__two)))
      |     ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:302:5: error: 'template<class _Tp, unsigned int _Nm> typename std::enable_if<(! typename std::__array_traits<_Tp, _Nm>::_Is_swappable::value)>::type std::swap' redeclared as different kind of entity
  302 |     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
      |     ^~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\vector:68,
                 from src\main.cpp:5:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_bvector.h:134:3: note: previous declaration 'void std::swap(bool&, std::_Bit_reference)'
  134 |   swap(bool& __x, _Bit_reference __y) noexcept
      |   ^~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:39,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\array:302:54: error: expected primary-expression before ';' token
  302 |     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
      |                                                      ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:856:7: error: variable or field 'swap' declared void
  856 |       swap(tuple& __in)
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:856:7: error: expected ';' at end of member declaration
  856 |       swap(tuple& __in)
      |       ^~~~
      |           ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:857:7: error: expected unqualified-id before 'noexcept'
  857 |       noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
      |       ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:879:12: error: variable or field 'swap' declared void
  879 |       void swap(tuple&) noexcept { /* no-op */ }
      |            ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:879:12: error: expected ';' at end of member declaration
  879 |       void swap(tuple&) noexcept { /* no-op */ }
      |            ^~~~
      |                ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:879:25: error: expected unqualified-id before 'noexcept'
  879 |       void swap(tuple&) noexcept { /* no-op */ }
      |                         ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1263:7: error: variable or field 'swap' declared void
 1263 |       swap(tuple& __in)
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1263:7: error: expected ';' at end of member declaration
 1263 |       swap(tuple& __in)
      |       ^~~~
      |           ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1264:7: error: expected unqualified-id before 'noexcept'
 1264 |       noexcept(__and_<__is_nothrow_swappable<_T1>,
      |       ^~~~~~~~
In file included from src\main.cpp:14:
src\er_oled.h:36:5: error: expected unqualified-id before '{' token
   36 |     {                   \
      |     ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1625:5: error: expected unqualified-id before 'noexcept'
 1625 |     noexcept(noexcept(__x.swap(__y)))
      |     ^~~~~~~~
In file included from src\main.cpp:14:
src\er_oled.h:36:5: error: expected unqualified-id before '{' token
   36 |     {                   \
      |     ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:54,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\tuple:1631:54: error: expected unqualified-id before '=' token
 1631 |     swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
      |                                                      ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:547:12: error: variable or field 'swap' declared void   
  547 |       void swap(function& __x) noexcept
      |            ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:547:12: error: expected ';' at end of member declaration
  547 |       void swap(function& __x) noexcept
      |            ^~~~
      |                ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:547:32: error: expected unqualified-id before 'noexcept'
  547 |       void swap(function& __x) noexcept
      |                                ^~~~~~~~
In file included from src\main.cpp:14:
src\er_oled.h:36:5: error: expected unqualified-id before '{' token
   36 |     {                   \
      |     ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:785:72: error: expected unqualified-id before 'noexcept'
  785 |     swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept
      |                                                                        ^~~~~~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\deque:67,
                 from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:60,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:1849:7: error: variable or field 'swap' declared void      
 1849 |       swap(deque& __x) _GLIBCXX_NOEXCEPT
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:1849:7: error: expected ';' at end of member declaration   
 1849 |       swap(deque& __x) _GLIBCXX_NOEXCEPT
      |       ^~~~
      |           ;
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\string:38,
                 from src\main.cpp:4:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:1849:24: error: expected unqualified-id before 'noexcept'  
 1849 |       swap(deque& __x) _GLIBCXX_NOEXCEPT
      |                        ^~~~~~~~~~~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_deque.h:2367:5: error: expected initializer before 'noexcept'      
 2367 |     _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
      |     ^~~~~~~~~~~~~~~~~~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\queue:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:28,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:300:7: error: variable or field 'swap' declared void       
  300 |       swap(queue& __q)
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:300:7: error: expected ';' at end of member declaration
  300 |       swap(queue& __q)
      |       ^~~~
      |           ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:302:7: error: expected unqualified-id before 'noexcept'    
  302 |       noexcept(__is_nothrow_swappable<_Sequence>::value)
      |       ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:393:5: error: expected initializer before 'noexcept'       
  393 |     noexcept(noexcept(__x.swap(__y)))
      |     ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:671:7: error: variable or field 'swap' declared void       
  671 |       swap(priority_queue& __pq)
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:671:7: error: expected ';' at end of member declaration    
  671 |       swap(priority_queue& __pq)
      |       ^~~~
      |           ;
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:672:7: error: expected unqualified-id before 'noexcept'    
  672 |       noexcept(__and_<
      |       ^~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_queue.h:728:5: error: expected initializer before 'noexcept'       
  728 |     noexcept(noexcept(__x.swap(__y)))
      |     ^~~~~~~~
In file included from src\main.cpp:14:
src\er_oled.h:36:5: error: expected unqualified-id before '{' token
   36 |     {                   \
      |     ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\string:38,
                 from src\main.cpp:4:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:86:56: error: expected unqualified-id before 'noexcept'     
   86 |       swap(_List_node_base& __x, _List_node_base& __y) _GLIBCXX_USE_NOEXCEPT;
      |                                                        ^~~~~~~~~~~~~~~~~~~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:63,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:1474:7: error: variable or field 'swap' declared void       
 1474 |       swap(list& __x) _GLIBCXX_NOEXCEPT
      |       ^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:1474:7: error: expected ';' at end of member declaration    
 1474 |       swap(list& __x) _GLIBCXX_NOEXCEPT
      |       ^~~~
      |           ;
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\string:38,
                 from src\main.cpp:4:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:1474:23: error: expected unqualified-id before 'noexcept'   
 1474 |       swap(list& __x) _GLIBCXX_NOEXCEPT
      |                       ^~~~~~~~~~~~~~~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\stl_list.h:2057:5: error: expected initializer before 'noexcept'       
 2057 |     _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
      |     ^~~~~~~~~~~~~~~~~~~~
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\list:64,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/FileSupport.h:14,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:33,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc: In member function 'void std::__cxx11::list<_Tp, _Alloc>::sort()':
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:518:27: error: statement cannot resolve address of overloaded function
  518 |      swap( *(__fill - 1) );
      |                           ^
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc: In member function 'void std::__cxx11::list<_Tp, _Alloc>::sort(_StrictWeakOrdering)':
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\list.tcc:616:22: error: statement cannot resolve address of overloaded function
  616 |   swap(*(__fill - 1));
      |                      ^
In file included from c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\functional:59,
                 from .pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:27,
                 from src\main.cpp:18:
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h: In instantiation of 'std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {long int, long int, short unsigned int}]':
src\main.cpp:318:9:   required from here
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:425:6: error: 'class std::function<void(long int, long int, short unsigned int)>' has no member named 'swap'
  425 |  __x.swap(*this);
      |  ~~~~^~~~
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h: In instantiation of 'std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {const char*}]':
.pio\libdeps\adafruit_grandcentral_m4\OpenFontRender\src/OpenFontRender.h:320:16:   required from 'static void OpenFontRender::setSerial(T&) [with T = Adafruit_USBD_CDC]'
src\main.cpp:311:25:   required from here
c:\users\biatu\.platformio\packages\toolchain-gccarmnoneeabi\arm-none-eabi\include\c++\9.3.1\bits\std_function.h:425:6: error: 'class std::function<void(const char*)>' has no member named 'swap'
*** [.pio\build\adafruit_grandcentral_m4\src\main.cpp.o] Error 1`

Vertical centering with a line break

I have a function which draws simple large text on the screen, e.g.

`

    ofr.setCursor(tft.width() / 2, tft.height() / 2);

ofr.setFontColor(GLT_COLOR_GOLD, TFT_BLACK);

ofr.setFontSize(46);

ofr.setAlignment(Align::BottomCenter);

ofr.printf(label);

`

This works great for a single line of text:
image

But if my "label" has a line break, e.g. \n, the vertical alignment is not correct:

image

Am I doing this wrong or does the library not support this kind of thing?

Font height is not computed correctly -- too short

I found that the font height was being calculated to a lower value than it should so I created a test string with the largest caps and two descenders and, still, it is coming up with too low of a number.

The font is being loaded with

  if (ofr.loadFont(BritanicBoldTTF, sizeof(BritanicBoldTTF))) {
    Serial.println("Render loadFont error for BritanicBoldTTF.");
    while (1);
  }
  ofr.setFontSize(50);

The display is being updated with

ofr.setCursor(dispWidth / 2, yPos); ofr.cprintf(myBuildString.c_str());

I calculate the size with one of these two (both return too small of a size)

myBuildString = "ABCabcjyWM";  // Include caps and descenders to get the full height
ofrFontHeight = ofr.getTextHeight(myBuildString.c_str());

char sizingChars[] = "ABCabcjyWM";
ofrFontHeight = ofr.getTextHeight(sizingChars);

They both return 42. Adding 8 makes it match the setFontSize parm. Maybe I should just use this. I don't know if it tracks to the larger sizes I am using... But the rest are numbers so it does not matter for now.

Then I do a fill rect with this

tft.fillRect(0, yPos, dispWidth, ofrFontHeight, SkyBlue); // dispWidth is the full 480 pixels.

Either way, it does not blank out the descenders with the initially returned value since it is calculating the height to a lower number than it should. It makes WiFi look like WjFi because there was a descender right under where the first i is in the previous status message.

When I added 5 to the height, it almost cleaned it all with fillRect. When I added 8, it was totally clean. I am using it on numbers, too, but, since there are no descenders, it does not show the problem.

Thanks for the library. I am enjoying using it. Sorry to report so much but there are some minor problems around the edges. It's expected with a new contribution.

Mike

複数のフォントを表示できるようにしたい

下記のように複数のOpenFontRenderクラスから別のインスタンスを生成し、それぞれフォントファイルをloadFont()で指定して、それぞれを表示しようとしましたが、最後にloadFont()した物しか表示されません。
テストした、ArduinoIDEのコードを載せます。

#include "M5Core2.h"
#include "OpenFontRender.h"

void setup()
{
M5.begin();
OpenFontRender ofr1;
OpenFontRender ofr2;
M5.Lcd.fillScreen(BLACK);
ofr1.loadFont("/font/OpenSans-Light-webfont.ttf");
ofr2.loadFont("/font/OpenSans-Bold.ttf");
ofr1.setDrawer(M5.Lcd);
ofr1.setFontSize(30);
ofr1.setCursor(0, 0);
ofr1.printf("ABCDEFG");
//ofr2.loadFont("/font/OpenSans-Bold.ttf");
ofr2.setDrawer(M5.Lcd);
ofr2.setFontSize(30);
ofr2.setCursor(0, 50);
ofr2.printf("12345678");
}

void loop() {
// put your main code here, to run repeatedly:
}

fonttest.zip

Using SPIFFS instead of SD

How can I use SPIFFS to directly access files flashed onto the ESP32 instead of SD? The library works when using a header created from ttf2bin.py. But doesn't work using uploaded file to SPIFFS, due to no SD card. I tried going in FileSupport.cpp and changing fs::FS &fontFS = SPIFFS; from fs::FS &fontFS = SD;. But still there is an error:
FT_Stream_Open: opened '/font.ttf' but zero-sized
font.ttf is not zero-sized and I can confirm by using file.read() which works.

[OFR ERROR] FTC_Manager_LookupFace error: 0x40

Hello, I have some problems. Can you help me.
esp32-woorm-32D.
The error code is resolved as memory overflow, but there is 159136B of available memory left before running. I don't understand why so much memory is needed.

This is part of the code snippet:

Serial.print("FreeHeap:");Serial.println(ESP.getFreeHeap());
if (render.loadFont("/字体/等线细.ttf"))
{
  Serial.println("Render initialize error");
  esp_sleep(0);
  return;
}
render.setDrawer(display); // 设置工程对象
display_ttfLine(0, "渲染测试,16", 16);
display_ttfLine(1, "渲染测试,32", 32);
display_ttfLine(2, "渲染测试,48", 48);

This is the debug output:

FreeHeap:159136
[OFR INFO] Font load required. FaceId: 0x0x3ffc5244
[OFR INFO] Load from file.
[OFR ERROR] Font load Failed1: 0x40
[OFR ERROR] FTC_Manager_LookupFace error: 0x40
Render initialize error

tft_eSPI printf not using bg colour

Hello there,

I am trying to update text in a sprite. The numbers are displayed in the right position and using the same setCursor position. The numbers are not clearing despite setting the background colour to match the background. Here is a code snippet of the updating of the text. I cant see what I could be doing wrong?

    ofr.setDrawer(DATA3gauge);
    ofr.setFontColor(TFT_ORANGE, TFT_BLACK);
    ofr.setFontSize(35);
    ofr.setCursor(79,55);
    ofr.cprintf("ERR");
    DATA3gauge.pushSprite(320,0);

Recommendations for code changes

Some global variables in the code many affect having multiple instances of the fontrender.
in my copy I moved
FT_Library g_FtLibrary;
bool g_NeedInitialize
from OpenFontRenderer.cpp into the the private section of the class OpenFontRender in the .h file.

I did not check if any of the underlying code has globals.

Text rendered below the cursor?

Perhaps this is a feature rather than a bug, but I am running in to an issue that text is being rendered below the cursor (i.e. under the Y coordinates), rather than above.

I am using an ILI9341 240x320 display

Here are my text coordinates, and calls to the printf() function:

`//Measurements display - numbered 1 2 / 3 4
const unsigned char * MEAS_TEXT_FONT = NotoSans_Bold;
const uint8_t MEAS_TEXT_FONT_SIZE = 24;
const unsigned char * MEAS_VAL_FONT = NotoSans_Regular;
const uint8_t MEAS_VAL_FONT_SIZE = 24;

const uint8_t MEAS1_TEXT_X = 20;
const uint8_t MEAS1_TEXT_Y = 75;
const char * MEAS1_TEXT = "Boost";

const uint8_t MEAS1_VAL_X = 46;
const uint8_t MEAS1_VAL_Y = 123;
const char * MEAS1_VAL_UNIT = " PSI";
double boost = 0;

const uint8_t MEAS2_TEXT_X = 193;
const uint8_t MEAS2_TEXT_Y = 75;
const char * MEAS2_TEXT = "EGT";

const uint8_t MEAS2_VAL_X = 219;
const uint8_t MEAS2_VAL_Y = 123;
const char * MEAS2_VAL_UNIT = " F";
double egt_temp_f = 0;

const uint8_t MEAS3_TEXT_X = 20;
const uint8_t MEAS3_TEXT_Y = 171;
const char * MEAS3_TEXT = "Coolant";

const uint8_t MEAS3_VAL_X = 46;
const uint8_t MEAS3_VAL_Y = 219;
const char * MEAS3_VAL_UNIT = " F";
double coolant_temp_f = 0;

const uint8_t MEAS4_TEXT_X = 193;
const uint8_t MEAS4_TEXT_Y = 171;
const char * MEAS4_TEXT = "Trans";

const uint8_t MEAS4_VAL_X = 219;
const uint8_t MEAS4_VAL_Y = 219;
const char * MEAS4_VAL_UNIT = " F";
double trans_temp_f = 0;
`

`void drawStaticSensorScreen () {

// draw banner double line
display.drawFastHLine(1, LINE1_Y, 320, COLOR_WHITE); // draw banner line
display.drawFastHLine(1, LINE1_Y+2, 320, COLOR_WHITE); // draw banner line

// set up four measurement labels

// Load the font and check it can be read OK
if (render.loadFont(NotoSans_Bold, sizeof(NotoSans_Bold))) {
Serial.println("Error Loading MEAS_TEXT_FONT ");
return;
}
render.setFontColor(COLOR_WHITE);
render.setFontSize(MEAS_TEXT_FONT_SIZE);

render.setCursor(MEAS1_TEXT_X, MEAS1_TEXT_Y);
render.printf(MEAS1_TEXT);

render.setCursor(MEAS2_TEXT_X, MEAS2_TEXT_Y);
render.printf(MEAS2_TEXT);

render.setCursor(MEAS3_TEXT_X, MEAS3_TEXT_Y);
render.printf(MEAS3_TEXT);

render.setCursor(MEAS4_TEXT_X, MEAS4_TEXT_Y);
render.printf(MEAS4_TEXT);

render.unloadFont();

// for test purposes, fill in some sample measurements
// banner measurements
if (render.loadFont(NotoSans_Regular, sizeof(NotoSans_Regular))) {
Serial.println("Error Loading MEAS_VAL_FONT ");
return;
}

render.setFontSize(MEAS_VAL_FONT_SIZE);

render.setCursor(MEAS1_VAL_X, MEAS1_VAL_Y);
boost = 15;
render.printf("%.0lf", banner_val1);
render.printf(MEAS1_VAL_UNIT);

render.setCursor(MEAS2_VAL_X, MEAS2_VAL_Y);
egt_temp_f = 700;
render.printf("%.0lf", egt_temp_f);
render.printf(MEAS2_VAL_UNIT);

render.setCursor(MEAS3_VAL_X, MEAS3_VAL_Y);
coolant_temp_f = 180;
render.printf("%.0lf", coolant_temp_f);
render.printf(MEAS3_VAL_UNIT);

render.setCursor(MEAS4_VAL_X, MEAS4_VAL_Y);
trans_temp_f = 170;
render.printf("%.0lf", trans_temp_f);
render.printf(MEAS4_VAL_UNIT);

render.unloadFont();
}`

Here is the result I am getting.
image

And here is is what I should be getting with the same coordinates (displayed using u8g2 library)
image

Compilation error using "setBackgroundFillMethod"

Hello Guys,
I like this Library and got it to render Font pretty well so far.
Now I am trying to use the setBackgroundFillMethod() function to set the background fill method of an OpenFontRender instance, but I am encountering compilation errors.

Here's the code snippet I tried:
render.setBackgroundFillMethod(BgFillMethod::Block);

And I also attempted:
render.setBackgroundFillMethod(OpenFontRender::BgFillMethod::Block);

For the first example using "BgFillMethod::Block," the error message is:

c:/users/XXXXX/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32s3-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: C:\Users\XXXXX\AppData\Local\Temp\arduino\sketches\85F2AE1913F559FC9EDFB4035A9B5E91\sketch\objs.a(GFX_LilygoTest.ino.cpp.o):(.literal._Z4loopv+0x48): undefined reference to OpenFontRender::setBackgroundFillMethod(BgFillMethod)'

For the second example using "OpenFontRender::BgFillMethod::Block," the error message is:

C:\Users\XXXXX\Documents\Arduino\GFX_LilygoTest\GFX_LilygoTest.ino: In function 'void loop()':
C:\Users\XXXXX\Documents\Arduino\GFX_LilygoTest\GFX_LilygoTest.ino:324:54: error: 'OpenFontRender::BgFillMethod' has not been declared
       render.setBackgroundFillMethod(OpenFontRender::BgFillMethod::Block);

I am unsure how to proceed and set the background fill method correctly. Can you please help me understand what might be causing the issue and how to resolve it?

Thank you!

STM32H750

not really an issue, but I have a STM32H750 board running at 480MHz, SDRAM at 120MHz with STM32duino (code needed some modification to compile for file system). I thought I'd pass along the render speed of your demo code. Using only drawpixel, 65ms. This is with a modified version of Adafruit_GFX, to a 640x480 LCD running in 32 bit pixels (ARGB). The fonts look fantastic. thanks so much for developing this library.

How can an integer be printed without sprintf

I have tried 6 different ways. I am trying to avoid sprintf, if possible and have some kind of conversion in the single line of code.

Here's my last attempt of the 6 ways I tried:

ofr.printf(char*(timeinfo->tm_mday)); // timeinfo->tm_mday points to an integer.

gives this error:

C:\Arduino@ESP32 Sketches\TTGO T4 v1.3\Triple_Time_on_T4_v1.3_Ver_12_MultiAC\Analog_Clock.ino: In function 'void showCorners(time_t)':
Analog_Clock:183:14: error: expected primary-expression before 'char'
ofr.printf(char*(timeinfo->tm_mday));

also tried:

ofr.printf(char(timeinfo->tm_mday));

and several others.

what does work:

strftime(charWork, sizeof(charWork), "%d", localtime(&now)); // Numeric day of month
ofr.setCursor(0, tft.height() - 26); ofr.printf(charWork);

But that takes strftime or sprintf. Was trying for some kind of inline conversion like can be used practically everywhere else in ESP land.

Mike

Feature request: text wrap

I want you to increase the function of wrap operation

for LovyanGFX
setTextWrap(true, true)
If the first argument is true, move to the left edge after reaching the right edge.
If the second argument is true, it will move to the top after reaching the bottom. (If omitted: false)

Thanks.

Seems unable to render fonts with too large font size

Hello, I came across your project and I ported it to my own device, excitingly it works for the most part, but I found a frustrating problem. When I set the font too big (about bigger than 170) it doesn't draw the font I want, have you encountered a similar problem?
This is my code,I did not find any errors.

if (render->loadFont(_TimeFontPath))
	{
		Serial.println("Render initialize error");
		return;
	}
render->setDrawPixel(EPD->DrawPixel);
render->setFontSize(180);
render->setCursor(50, 70);
render->printf("A");
render->drawChar('1', 100, 100);

Recommendations for memory use?

Hello!

I noticed that my SRAM drops by about 4k after a single myofr.printf() call (drawing a time to the screen). However, if I repeat that call many times, the SRAM only drops once.

So I assume that it is just a cache in OpenOFR that is caching something the first time? (Edit: I see setCacheSize() which looks useful for this).

Are there any recommendations you can give to protect SRAM? E.g.:

  • is it smart to use the same sized font to avoid needing to render it at different sizes?
  • does it cache per glyph, so that using more varied glyphs will use more memory?
  • do larger font sizes mean more memory use?
  • can the cache be cleared periodically to save SRAM? (Edit: I see setCacheSize() exists to limit cache size)
  • alternately, can the cache be forced to grow to maximum size to guarantee a bound on memory usage? (Edit: I see setCacheSize() exists to limit cache size)

Thanks!

Unable to use OpenFrontRender to use with TFT-eSPI

I use the example load_from_binary.ino with a little adjustments.

#include "TFT_eSPI.h" // tryed <TFT_eSPI.h> too
#include "binaryttf.h" 
#include "OpenFontRender.h" // tryed <OpenFontRender.h> too

#define BACKLIGHT_PIN 13

TFT_eSPI tft;
OpenFontRender render;

void setup() {
  Serial.begin(19200);
  analogWrite(BACKLIGHT_PIN, 200);
  analogWriteFreq(250);

  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLUE);
  tft.setCursor(10,100);
  tft.println("Test");
  delay(2000);  // until here it works perfect

  if (render.loadFont(binaryttf, sizeof(binaryttf))) {
    Serial.println("Render initialize error");
    return;
  }
  render.setDrawer(tft); // Set drawer object
  tft.fillScreen(TFT_WHITE);
  render.setFontColor(TFT_WHITE, TFT_BLUE);
  render.printf("Hello World\n");
  render.seekCursor(0, 10);
  delay(1000);

  render.setFontSize(30);
  render.setFontColor(TFT_GREEN, TFT_RED);
  render.printf("完全なUnicodeサポート\n");
  render.seekCursor(0, 10);
  delay(1000);

  render.setFontSize(40);
  render.setFontColor(TFT_ORANGE, TFT_BLACK);
  render.printf("こんにちは世界\n");
}

void loop() {
}

binaryttf.h is in the same map as the program. All works fine until the font is loaded.

I use these this as display settings

//                            USER DEFINED SETTINGS
//   Set driver type, fonts to be loaded, pins used and SPI control method etc
//
//   See the User_Setup_Select.h file if you wish to be able to define multiple
//   setups and then easily select which setup file is used by the compiler.
//
//   If this file is edited correctly then all the library example sketches should
//   run without the need to make any more changes for a particular hardware setup!
//   Note that some sketches are designed for a particular TFT pixel width/height

// User defined information reported by "Read_User_Setup" test & diagnostics example
#define USER_SETUP_ID 500

// Define to disable all #warnings in library (can be put in User_Setup_Select.h)
//#define DISABLE_ALL_LIBRARY_WARNINGS

// ##################################################################################
//
// Section 1. Call up the right driver file and any options for it
//
// ##################################################################################

#define ILI9486_DRIVER

#define TFT_INVERSION_OFF
//#define TFT_INVERSION_ON


// ##################################################################################
//
// Section 2. Define the pins that are used to interface with the display here
//
// ##################################################################################

// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ######

// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS   PIN_D1  // Chip select control pin D8
#define TFT_DC   PIN_D2  // Data Command control pin
#define TFT_RST  PIN_D3  // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST  -1    // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V

//#define TFT_BL PIN_D1  // LED back-light (only for ST7789 with backlight control pin)

//#define TOUCH_CS PIN_D2     // Chip select pin (T_CS) of touch screen
#define TOUCH_CS -1

// ##################################################################################
//
// Section 3. Define the fonts that are to be used here
//
// ##################################################################################

// Comment out the #defines below with // to stop that font being loaded
// The ESP8366 and ESP32 have plenty of memory so commenting out fonts is not
// normally necessary. If all fonts are loaded the extra FLASH space required is
// about 17Kbytes. To save FLASH space only enable the fonts you need!

//#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
//#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
//#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
//#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
//#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
//#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
// this will save ~20kbytes of FLASH
#define SMOOTH_FONT


// ##################################################################################
//
// Section 4. Other options
//
// ##################################################################################
//#define SPI_FREQUENCY  27000000
 #define SPI_FREQUENCY  40000000
// #define SPI_FREQUENCY  55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY  80000000

// Optional reduced SPI frequency for reading TFT
//#define SPI_READ_FREQUENCY  20000000

// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
//#define SPI_TOUCH_FREQUENCY  2500000

Adding a getTextWidth(char* text_buffer) function

To design stuff sometimes is great to know how much is the text width (Using font size) that you will draw. Lovyan has a function like this:

uint16_t getTextWidth(char* text_buffer);

@takkaO if you give me some pointers on how to do it I can add it myself.
On another question: Is possible to speed up just a little bit the drawing?
Tried with ESP32 at 80Mhz and also at 160Mhz, the difference is not noticeable, but still I like a lot to see how it draws the font from the binary TTF. Amazing work!

Need some way to center text on screen

You don't honor or allow setTextDatum so I am left without any way to center my string on the display. Can you tell what calls to make to enable that? When I am using bit coded text, I choose the centered Datum and it does it for me. I cannot figure out how to make cdrawString work. I can't figure out how to code the Layout item to get past the compiler. I am not even sure that will work for me since there is no specification of the size to center in. Maybe it uses the display width. Surely would like a valid example. Your samples are very basic and leave out a lot.

I am sure I am missing the obvious. Thanks for coding the library. I like having the ability to specify font size by number rather than building a whole new bitcoded font file.

Meaning of error code

Hi
When I use loadFont, it returns FTC_ Manager_ LookupFace error: 0x02, but I can't find the document to explain the meaning of the error code. Can you help me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.