Skip to content

bdfconv: add characters from utf8 text file #2627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2025
Merged

Conversation

koendv
Copy link
Contributor

@koendv koendv commented Apr 7, 2025

The goal of this PR is to save flash by reducing a font to only those characters that are actually used.

bdfconv converts a bdf font to an u8g2 font.
This PR adds to bdfconv an option -u filename, where filename is a text file in utf8 format.
All characters in the text file are added to the created u8g2 font.
This is useful if a font contains many characters, but only few characters are used.
Examples are programs that have menus in multiple languages, or use Asian languages like Chinese.
One suggested use is generating a font from strings in firmware source files.

To add the characters in file example.txt to the default ascii set:

bdfconv -f 1 -u example.txt -n u8g2_font_unifont -o unifont.h unifont-16.0.02.bdf

Two examples where the font is megabytes in size, but the program only needs a kbyte.

example 1

Print a text in multiple languages in Arduino. Code:

void setup(void) {
  u8g2.begin();
  u8g2.enableUTF8Print();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont);
  u8g2.setCursor(0, 15);
  u8g2.println("Hello 您好");
  u8g2.setCursor(0, 31);
  u8g2.println("Здравствуйте");
  u8g2.setCursor(0, 47);
  u8g2.println("こんにちは");
  u8g2.setCursor(0, 63);
  u8g2.println("안녕");
  u8g2.setCursor(0, 79);
  u8g2.print("font ");
  u8g2.print(sizeof(u8g2_font_unifont));
  u8g2.println(" bytes");
  u8g2.sendBuffer();
}
  • Download gnu unifont in bdf format.

  • Create a font that contains all of ascii, and all characters in the sketch:

bdfconv -f 1  -m '32-127' -u ~/Arduino/bdfconv_test/bdfconv_test.ino -n u8g2_font_unifont -o unifont.h unifont-16.0.02.bdf

where bdfconv_test.ino is the sketch source.

  • Copy the file unifont.h to your source directory
cp unifont.h  ~/Arduino/bdfconv_test/
  • Compile and run. The text appears on the display. The display is also output in PBM format on the serial port:

screenshot

The font uses 1750 bytes of flash. This is 478 bytes more than same font using only the ascii set.

Arduino sketch attached.
sketch.zip

example 2

Simplified Chinese, STM32F103, SSH1306 OLED display. Code:

void setup(void) {
  int h = 16;
  u8g2.begin();
  u8g2.enableUTF8Print();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_puhuiti_t12);
  u8g2.setCursor(0, h - 1);
  u8g2.print("这是一个易于");
  u8g2.setCursor(0, 2 * h - 1);
  u8g2.print("操作的U8G2");
  u8g2.setCursor(0, 3 * h - 1);
  u8g2.print("字体生成工具.");
  u8g2.sendBuffer();
}
  • Download Alibaba PuHuiTi font
  • convert the otf font to a bdf bitmap font
    otf2bdf -p 14 -o AlibabaPuHuiTi-3-35-Thin-14.bdf AlibabaPuHuiTi-3-35-Thin.otf
  • create a u8g2 font that has the Chinese characters used in the sketch
    bdfconv -f 1 -u bdfconv_test_chinese.ino -n u8g2_font_puhuiti_t14 -o u8g2_font_puhuiti_t14.h AlibabaPuHuiTi-3-35-Thin-14.bdf
    where bdfconv__test_chinese.ino is the sketch source.
  • compile and run. Display:

chinese

The font uses 4156 bytes of flash. This is 591 bytes more than same font using only the ascii set.

Arduino sketch attached.
bdfconv_test_chinese.zip

@olikraus
Copy link
Owner

nice idea

@olikraus olikraus merged commit 82efd57 into olikraus:master Apr 11, 2025
@olikraus olikraus added this to the 2.36 milestone Apr 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants