由于嵌入式场景的资源有限,通常默认的显示库只支持英文和数字以及少量的字符显示,并不支持中文字符。比如 embedded-graphics 内置的所有字符集里就不支持中文字符的显示。
因此我们需要自己生成中文字符的显示库。这个库可以生成embedded-graphics 支持的中文字符集。
生成之前,需要把open-type 格式的中文字符集文件转换为 bdf 格式。可以使用 otf2bdf 工具来完成这个转换。
sudo apt install otf2bdf
#or
brew install otf2bdf
生成的 api 类似下面这样:
fn main() {
let font = FontConverter::new("Regular.bdf", "REGULAR_FONT")
//.glyphs('a'..='z')
.glyphs('\u{0000}'..='\u{007F}') // ASCII
.glyphs('\u{4E00}'..='\u{9FFF}') // 常用中文字体范围
.glyphs('\u{2E80}'..='\u{2EF3}') // 常见繁体字范围
.missing_glyph_substitute('?') // 替代字符
.convert_eg_bdf()
.unwrap();
let font: MonoFontOutput = converter.convert_mono_font()?;
font.save_png(png)?;
}
如果显示的字符非常的固定并且有限,我们完全可以手动指定要包含的中文字符。比如我生成用于显示温湿度计的字库时,我只需要这些字符:
温,湿,度,0,1,2,3,4,5,6,7,8,9,C,°,:,%
直接指定就好:
converter.glyphs(&['温','湿','度','0','1','2','3','4', '5', '6', '7', '8', '9','C','°',':',',' ,'%',' '][..]);
类似命令:
cargo run -r --bin eg-font-converter ./vivosans.bdf REGULAR_FONT --rust font.rs --data regular_font.data
复制上面生成的这两个文件到项目中就可以使用了。
不过上面这种方式生成的中文和英文的字符间距非常的大,不好看。

bdf 项目还提供了eg-bdf 格式,这个格式显示中文是正常的。因此我修改了原有的生成命令,添加了 --convert-type 参数:
match args.convert_type {
ConvertType::EgBdf => {
let font: EgBdfOutput = converter.convert_eg_bdf()?;
if let Some(rust) = &args.rust {
std::fs::write(rust, font.rust())
.with_context(|| format!("Failed to write Rust file {}", rust.to_string_lossy()))?;
}
if let Some(data) = &args.data {
std::fs::write(data, font.data())
.with_context(|| format!("Failed to write data file {}", data.to_string_lossy()))?;
}
// eg-bdf 使用 save 方法
font.save("./output")?;
}
ConvertType::MonoFont => {
let font: MonoFontOutput = converter.convert_mono_font()?;
if let Some(rust) = &args.rust {
std::fs::write(rust, font.rust())
.with_context(|| format!("Failed to write Rust file {}", rust.to_string_lossy()))?;
}
if let Some(data) = &args.data {
std::fs::write(data, font.data())
.with_context(|| format!("Failed to write data file {}", data.to_string_lossy()))?;
}
if let Some(png) = &args.png {
font.save_png(png)?;
}
}
}
cargo run -r --bin eg-font-converter \
./vivosans.bdf REGULAR_FONT \
--glyph-list 温,湿,度,0,1,2,3,4,5,6,7,8,9,C,°,:,% \
--convert-type eg-bdf
同样地生成的文件丢回项目中,并把bdf 项目里的eg-bdf crate(此crate 并未发布到crates.io)添加到项目的Cargo.toml 中。
直接使用如下:
let temp_str = alloc::format!("温度:{}°C", temp);
let hum_str = alloc::format!("湿度:{}%", hum);
let temp_character_style = BdfTextStyle::new(®ULAR_FONT, Rgb565::new(31, 41, 0)); // White
let hum_character_style = BdfTextStyle::new(®ULAR_FONT, Rgb565::new(0, 63, 31)); // White
效果显示如下:
