#bitmap-font #font #floating-point #bitmap #noto-sans-mono

no-std noto-sans-mono-bitmap

提供“Noto Sans Mono”字体在不同大小和字体粗细下的预光栅化字符,适用于多个 Unicode 范围。这个包是 no_std,不需要任何分配或浮点运算。在只有“软浮点”可用的情况下,在内核和引导加载程序中使用很有用。严格来说,这个包不仅仅是一个基本的位图字体,因为它将每个像素编码为字节而不是位,这在屏幕上产生了更美观的结果。

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

Download history 4842/week @ 2024-04-22 3633/week @ 2024-04-29 4337/week @ 2024-05-06 5311/week @ 2024-05-13 3407/week @ 2024-05-20 3673/week @ 2024-05-27 3898/week @ 2024-06-03 4738/week @ 2024-06-10 5778/week @ 2024-06-17 4675/week @ 2024-06-24 5141/week @ 2024-07-01 4066/week @ 2024-07-08 3474/week @ 2024-07-15 5543/week @ 2024-07-22 5485/week @ 2024-07-29 6211/week @ 2024-08-05

每月下载量 20,966
用于 11 包(直接使用 8 个)

MIT 许可证

720KB
15K SLoC

noto-sans-mono-bitmap (Rust 库)

提供“Noto Sans Mono”字体在不同大小和字体粗细下的预光栅化字符,适用于多个 Unicode 范围。这个包是 no_std,不需要任何分配或浮点运算。在只有“软浮点”可用的情况下,在内核和引导加载程序中使用很有用。严格来说,这个包不仅仅是一个基本的位图字体,因为它将每个像素编码为字节而不是位,这在屏幕上产生了更美观的结果。

TL;DR

  • no_std,零分配,无浮点运算
  • ✅ 最重要的符号、数字和字母作为预光栅化常量。Unicode 范围可选。
  • ✅ 以 Noto Sans Mono 字体为基础
  • ✅ 不同的尺寸和字体粗细(轻、正常、粗体)
  • ✅ 美观的抗锯齿/平滑处理,比传统的位图字体看起来更好
  • ✅ 每个像素都使用字节(0-255)编码,而不是位,这导致屏幕上的结果更美观。
  • ✅ 相关的字体大小:14、16、24、32 和 64 像素(作为可选的构建时功能)
  • ✅ 无依赖项
  • ✅ 所有字符都对其到它们的框/栅格中。如果它们并排打印,结果看起来很好。

Screenshot of the bitmap font.

开发者指南和贡献

请检查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。

无运行时依赖