9 个版本
0.3.0 | 2024 年 4 月 2 日 |
---|---|
0.2.0 | 2022 年 10 月 7 日 |
0.1.6 | 2022 年 9 月 1 日 |
0.1.5 | 2022 年 1 月 20 日 |
在 数据格式 中排名第 4
每月下载量 20,966
用于 11 个 包(直接使用 8 个)
720KB
15K SLoC
noto-sans-mono-bitmap (Rust 库)
提供“Noto Sans Mono”字体在不同大小和字体粗细下的预光栅化字符,适用于多个 Unicode 范围。这个包是 no_std
,不需要任何分配或浮点运算。在只有“软浮点”可用的情况下,在内核和引导加载程序中使用很有用。严格来说,这个包不仅仅是一个基本的位图字体,因为它将每个像素编码为字节而不是位,这在屏幕上产生了更美观的结果。
- 原始字体文件来自:https://fonts.google.com/noto/specimen/Noto+Sans+Mono
- 许可证:SIL 开放字体许可证 (OFL) https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
TL;DR
- ✅
no_std
,零分配,无浮点运算 - ✅ 最重要的符号、数字和字母作为预光栅化常量。Unicode 范围可选。
- ✅ 以 Noto Sans Mono 字体为基础
- ✅ 不同的尺寸和字体粗细(轻、正常、粗体)
- ✅ 美观的抗锯齿/平滑处理,比传统的位图字体看起来更好
- ✅ 每个像素都使用字节(0-255)编码,而不是位,这导致屏幕上的结果更美观。
- ✅ 相关的字体大小:14、16、24、32 和 64 像素(作为可选的构建时功能)
- ✅ 无依赖项
- ✅ 所有字符都对其到它们的框/栅格中。如果它们并排打印,结果看起来很好。
开发者指南和贡献
请检查CONTRIBUTING.md。
术语:位图字体是否是正确的术语?
传统的(8x8)位图字体通常指的是每个符号用8位编码的字体。字节中的这些位(0b00110000
)表示“像素开启”,而零表示“像素关闭”。然而,我的字体实际上将每个像素的强度编码为一个从0到255的字节。因此,这比传统的位图字体小,但看起来要好得多。我仍然使用位图字体的术语,因为当在低级上下文中(如引导过程)谈论预栅格化的字体/字体渲染时,这个术语被使用且为人所知。
何时(或不)使用此软件包
如果您想打印到帧缓冲区,并且如果您正在开发引导加载程序或内核,您通常不需要启用FPU并避免使用浮点指令(即仅使用软浮点)。我的软件包是打印字符到屏幕的好选择。TTF字体的高级实时渲染严重依赖于许多浮点运算,这在低级二进制文件中并不理想。传统的8x8位图字体在屏幕上打印时看起来很丑。《noto_sans_mono_bitmap》可以被视为一个很好的替代品,具有非常好的抗锯齿效果。
如果您拥有标准环境或浮点操作的支持,您可能想使用软件包fontdue
和一些TTF字体来自己栅格化字体,而不是使用我的软件包。
最小代码示例
use noto_sans_mono_bitmap::{get_raster, get_raster_width, FontWeight, RasterHeight};
// Minimal example.
fn main() {
let width = get_raster_width(FontWeight::Regular, RasterHeight::Size16);
println!(
"Each char of the mono-spaced font will be {}px in width if the font \
weight={:?} and the bitmap height={}",
width,
FontWeight::Regular,
RasterHeight::Size16.val()
);
let char_raster =
get_raster('A', FontWeight::Regular, RasterHeight::Size16).expect("unsupported char");
println!("{:?}", char_raster);
for (row_i, row) in char_raster.bitmap().iter().enumerate() {
for (col_i, pixel) in row.iter().enumerate() {
println!("[{:02}][{:02}]: {:03}", row_i, col_i, pixel);
}
}
}
Cargo功能和软件包大小
external/check-size
软件包为您提供了有关将此库静态编译到二进制文件中开销的见解。
默认情况下,仅包含可能功能的一个合理子集。原始软件包大小为几MiB,但在编译后删除不相关的部分(即大小14,常规字体,仅ASCII)后,根据我的测量,开销应小于120 KiB的二进制大小。然而,即使有all
功能,根据您的代码,编译器可以可靠地删除无法访问或未使用的代码路径。不过,建议只包含必要的功能。
将所有功能包含在二进制文件中,并且编译器不进行删除,您可以预期5MiB或更多的内存消耗。然而,这需要相当不可能的情况,即您同时使用不同的尺寸和字体粗细,以及所有Unicode范围。
快速演示
$cargo run --exampleshow_chars_in_window
如果您想在示例中使用特殊字符,例如{ä, ö, ü, �}
,您可以使用
$cargo run --exampleshow_chars_in_window --功能all
限制 & 常见问题解答
- 替换字符
�
被切掉在左边和右边。:
是的,我对此无能为力。似乎这个符号不是来自字体,而是来自栅格化库。然而,我没有花太多时间去调查。更多细节可以在GitHub上找到。 - 行间距太高。
是的,我对此无能为力。我从TTF字体中获取行高,如果不尊重这个值,某些字符将被截断。我不是字体渲染的专家。但是就目前而言,它已经足够好了。然而,如果你将字体渲染到帧缓冲区中,你可以在顶部和底部各截断1-2个像素,这对于常规ASCII应该足够。
趣闻
光栅化是由令人惊叹的 fontdue-Crate 完成的。感谢原始作者们!
许可证
请参阅仓库中的LICENSE文件。
MSRV(针对库消费者)
Rust稳定版1.56.1。