帧缓冲电子墨水
根据 GPLv3+ 许可。位于 GitHub 上。
这是为了填补 Kobo 开发人员和修补者在意识到他们没有内置方法在设备屏幕上打印内容时感到的空白!
在习惯了 Kindle 上无处不在的eips
之后,转向 Kobo 时尤其残酷……
简而言之,它在屏幕上打印消息或图像,处理 Linux 帧缓冲区接口和 i.MX EPDC(以及 Kindle 上的 MTK 和 Kobo 上的 sunxi )的低级修补。
它已经在 Kobo、Kindle、BQ Cervantes、reMarkable 和 PocketBook 上进行了测试,但将其移植到其他 Linux、i.MX eInk 设备应该是微不足道的(天啊,即使是 Sipix 支持也不应该太难)。 #64 证明我们甚至可以让 sunxi API 屈服于我们的意愿,如果你不太在意在此过程中失去理智的话;)。
默认情况下,文本渲染依赖于捆绑的固定单元格位图字体(请参阅这篇文章的小样本),但感谢 @shermp 的贡献 (#20),您还可以依赖成熟的 TrueType/OpenType 字体渲染!
图像支持包括最常见的格式(JPEG/PNG/TGA/BMP/GIF/PNM),以及最相关像素格式的原始打包像素(Gray8 和 RGB32;均为 +/- Alpha)。
它也恰好可以在任何类型的 Linux 帧缓冲设备上完美工作,并且支持各种位深度(4bpp、8bpp、16bpp、24bpp 和 32bpp),因此您可以使用它在您的 EFI fb 上绘图,例如;) 。
对于 Kobo 设备,MobileRead 上有一个讨论线程,您可以在其中找到独立的二进制文件。它故意缺乏详细的说明,因为目标受众主要是开发人员和修补匠。将此视为安全预防措施;)。
这里还有一个针对 Kindle 设备的姐妹线程,除了二进制文件之外,您还可以找到人们用它做疯狂事情的示例;)。
实际上,大多数 Kindle 和 Kobo 用户实际上都会免费获得它,因为它与我的大多数软件包捆绑在一起。
作为实际使用的示例,请参阅 KFMon(我使用它来提供视觉反馈)或 kobo-rclone(它也用于屏幕抓取)。我们还在 KOReader 中使用它,以使 OTA 更新过程更加用户友好。
在 GitHub 上快速搜索提到 fbink 的代码也应该会产生有趣的结果,例如 X11 的 DAMAGE 处理垫片、Qt5 QPA 或 InkVT、终端仿真器。
另请参阅其他语言中的各种绑定,其中通常包含一些示例。
CLI 实用程序可用,围绕相同的公共 API 构建,可通过 C 项目的共享或静态库使用,或通过其他语言的 FFI 使用(但要注意,它是根据 GPLv3+ 而不是 LGPL 授权的)。对于 CLI 实用程序,请参阅其文档或运行fbink --help
了解详细信息。对于库,请参阅公共标头。如果事情不清楚,请随时与我联系!
注意:它通常不会尝试处理软件轮换,因为目前看来,对于当前的 Kobo FW 版本和 Kindle 来说,这似乎都是正确的做法。
YMMV 在较旧的固件上,或者如果其他东西与 fb 旋转有关,或者您的应用程序正在软件中实现旋转(即旋转视口)。
就硬件轮换而言,Kobo 设备有一些特定的例外情况:
那些在 16bpp 模式下运行且看起来处于横向模式的:因为这似乎是它们的本机状态,我们尝试对此进行补偿,因为我们可以在 Nickel 本身纠正此问题之前合法使用。
在带有加速计的设备上,例如 Forma 和 Libra,Nickel 本身将处理硬件旋转。
固定单元格文本渲染的一些基本示例......
或者如果我们把图像放在那里......
并具有工作透明度的所有花哨功能,即使是在古老的硬件上:)。
这是一些其他字体,以及进度条......
当使用闪亮的 TrueType 字体时:)。
除非您只是想在本机纯 Linux 系统( make linux
)上尝试一下,否则您将需要一个针对您的目标设备的交叉编译器。
Makefile 是专门为自动检测我自己的交叉编译工具链设置而定制的,我显然衷心建议使用它,而不是依赖于通用交叉编译工具链,因为通用交叉编译工具链可能不完全针对正确的内核/libc 组合;)。
使用 koxtoolchain 前端应该可以使构建其中一个变得相当轻松。
如果您使用自己的工具链,请注意我们需要 C11 支持(GCC >= 4.9、Clang >= 3.0)。
如果您没有使用较旧的编译器,我强烈建议您在启用 LTO 的情况下构建它!
排除这种情况后,默认目标(即make
)将生成静态 Kobo 构建,而make kobo
将生成剥离的共享构建,并另外以 Kobo 方式打包所有内容。 Kobo 线程中找到的包就是这样构建的。
对于常见的构建类型,还有一些方便的目标(对于静态构建为make static
,对于共享构建make shared
,对于剥离的静态构建make strip
,对于剥离的共享构建make release
,对于调试构建make debug
)对于非常具体的用例,通常与 FFI 绑定相关(为 PIC 静态构建make pic
,或传递STATIC_LIBM=1
以尝试静态链接 libm)。
目标平台的选择是通过一个简单的变量来处理的:
KINDLE=1
以进行 Kindle 构建( make kindle
在剥离的静态构建上执行此操作)。KINDLE=1 LEGACY=1
来构建 FW 2.x Kindle( make legacy
在剥离的静态构建上执行此操作)。这基本上只是禁用 CLOEXEC,FW 2.x 可能不支持 CLOEXEC。CERVANTES=1
以进行 BQ/Cervantes 构建( make cervantes
在剥离的静态构建上执行此操作)。REMARKABLE=1
来进行 reMarkable 构建(在剥离的静态构建上make remarkable
)。POCKETBOOK=1
以进行 PocketBook 构建( make pocketbook
在剥离的静态构建上执行此操作)。使用相同的逻辑可以进行一些定制:
MINIMAL=1
来构建功能非常有限的构建(无绘图基元、无固定单元字体渲染、无图像渲染、无额外字体、无 OpenType),这会产生更小的应用程序和库。DEBUG=1
以进行调试构建,并传递DEBUG=1 DEBUGFLAGS=1
以使用强制调试 CFLAGS 进行调试构建。您还可以将功能一一附加到MINIMAL
构建中:
DRAW=1
以添加对绘图基元的支持。BITMAP=1
以添加对固定单元字体渲染的支持。 (表示DRAW
)FONTS=1
以添加对额外捆绑的固定单元字体的支持。 (表示BITMAP
)IMAGE=1
以添加图像支持。 (表示DRAW
)OPENTYPE=1
添加 OTF/TTF 字体渲染支持。 (表示DRAW
)INPUT=1
以添加对输入实用程序的支持。BUTTON_SCAN=1
添加对 Kobo 特定按钮扫描内容的支持。 (表示DRAW
)如果您确实需要在固定单元代码路径中实现极端的Unicode 覆盖,您还可以选择通过传递UNIFONT=1
来嵌入 GNU Unifont。
请注意,这将增加近 2MB 的二进制大小,并且字体实际上被分成两部分(双宽字形被转为特定字体),这可能会削弱它在实践中的实用性......
由于显而易见的原因,默认情况下永远不会启用此功能。
除非您正在做非常具体的事情,否则您通常希望至少在MINIMAL
构建中启用DRAW
和BITMAP
...
在更改目标平台或功能标志时,不要忘记至少运行make cleanlib
,否则将保留最新的匹配库构建,因为它将填充 make 依赖项;)。
在此过程中, utils
文件夹中可能会出现一些辅助工具。 make utils
将对这些进行静态构建(这是推荐的方法,因为它们相当粗暴地依赖于 FBInk 的内部API)。目前,这些包括有关轮换行为的诊断工具和下面提到的厄运压力测试。
其中大部分仅在 Kobo 上进行过测试,除非您知道自己在做什么,否则应该不要管它;)。
还可以使用正确操作电子墨水设备上的位深度的工具,并且可以使用make fbdepth
为电子墨水目标构建。
它的名字很平淡,叫做fbdepth
,Kobo 和 reMarkable 上的 KOReader 使用它来强制执行合理的旋转并切换到更高效的位深度。它还在 Kindle 上进行了测试,旋转处理至少应该表现正常。请注意,在 FW 5.x 上,库存 GUI 在 X 下运行,并且 X不会喜欢您从其脚下旋转 fb ;)。
如果您想要尽可能小的二进制文件,请确保您从原始源代码树单独构建它。
还有一个相当愚蠢的示例,展示了可以通过make dump
构建的转储/恢复 API。
实施了另一个基于 PSX Doom 火焰效果的愚蠢演示,以一种稍微有趣的方式对 EPDC 进行压力测试。
如果您对整个 mxcfb alt_buffer shindig 感到好奇,您可以看一下这个 PoC。
同样,如果您正在研究 Kobo 上的旋转和输入恶作剧, make devcap
将构建一个包含一些二进制文件和 devcap_test.sh 脚本的 tarball,当在目标设备上运行时,将编译相当多的信息。特别是,如果您需要报告fbdepth
的错误,我可能会要求您运行该错误并将结果附加到问题中;)。
关于 Kobo 上的输入和旋转主题, make ftrace
将构建一个简单的指针跟踪实用程序,该实用程序利用 libevdev 和一些更时髦的 API 调用来尝试理解 Kobo 上发生的输入翻译恶作剧。
如果您打算在代码中以任何方式处理触摸输入,这应该是一个值得一看的好地方;)。
它还演示了如何在 Elipsa 上有效处理笔输入和绘图。
至于make input_scan
,它将围绕fbink_input_scan
API 构建一个小型 CLI 工具,这有助于了解哪个输入设备执行什么操作(又名“那个该死的触摸屏在哪里?”;))。
Kindle 支持涵盖从 K2 开始的整个 Kindle 系列。
Kobo 支持涵盖整个 Kobo 系列,从 Kobo Touch A/B/C 开始(注意:某些功能在 sunxi SoC 上不可用,参见 API 文档)。
BQ Cervantes 支持由 @pazos (#17) 提供,并且应该能够处理当前的阵容。
reMarkable 支持由 @tcrs (#41) 贡献,并且在与各种 rm2fb shim 实现之一配对时支持 rM2。
PocketBook 支持由 @ezdiy (#47) 测试,并且应该支持与 KOReader 相同的设备集。请记住,PocketBook 是一个...处理起来很复杂的平台,而且我自己无法访问它。这意味着涉及很多怪癖:
fbink_get_fb_info
而不是自己求助于本机 ioctl。FBINK_NO_INKVIEW
变量来要求 FBInk永远不要触摸 InkView。目前,唯一的缺点是设备识别受损:具体来说,没有设备名称,并且 DPI 不准确(我们默认为 212,除非您通过FBINK_FORCE_DPI
环境变量设置覆盖)。FBINK_NO_SW_ROTA
变量来禁用此行为,在这种情况下,我们将始终在本机 fb 布局中进行绘制。 如果您不想写入帧缓冲区,而是想获取它的 PNG 快照(这会派上用场),我有一个经过大量修改的 FBGrab 版本,它应该能够合理地处理电子墨水帧缓冲区的各种怪癖;)。如果您实际上不需要 PNG 文件而只想使用内存中的 fb 转储,请查看整个fbink_dump
和fbink_restore
API 调用。
这样每个人都能玩得开心,即使你无法忍受 C!
锈:
Go:go-fbink 及其后继者 go-fbink-v2,作者:@shermp
LuaJIT:lua-fbink 作者:@NiLuJe
Python:py-fbink 作者:@NiLuJe
请注意,由于 API 在 master 上可能并不完全稳定,因此这些 API 都绑定到特定标签(通常是最新版本)。你应该遵守这个要求,否则一切都会崩溃;)。
我通常会尝试将损坏保持在最低限度,或者除非出现这种情况,否则,请使升级路径尽可能轻松,但是,你已经知道了,支持新东西通常意味着现有东西的工作方式必须略有不同。
我尝试在每个标签的注释中详细说明 API/ABI 损坏,但可视化的一个好方法当然是区分单个公共标头(或者,为了快速无上下文概述,为 FFI 绑定生成的最小标头);)。