fix: Flatten TextBlock word storage into single allocation (#2547)

This commit is contained in:
Justin Mitchell
2026-07-06 23:41:00 +03:00
committed by GitHub
parent f2b00f6b93
commit 6f5c5a0900
6 changed files with 314 additions and 120 deletions
+20 -10
View File
@@ -90,13 +90,13 @@ if (parsedSize != fileSize) {
## `section.bin`
### Version 28
### Version 29
Each file in `sections/*.bin` stores one laid-out spine section. The header is
also the cache-busting key: if any layout-affecting setting differs from the
current reader settings, the section is discarded and rebuilt.
Version 28 includes:
Version 29 includes:
- cache-busting fields for paragraph alignment, hyphenation, embedded CSS,
image rendering mode, and Focus Reading
@@ -107,6 +107,10 @@ Version 28 includes:
- per-page footnote entries
- serialized word style bits for underline, strikethrough, superscript, and
subscript
- flat TextBlock word storage (v29): per-word arrays plus one shared
NUL-terminated text blob, replacing v28's length-prefixed word strings. The
on-disk order mirrors the in-RAM arena so the firmware reads a whole block
payload with a single allocation and a single SD read
ImHex pattern:
@@ -115,7 +119,7 @@ import std.mem;
import std.string;
import std.core;
#define EXPECTED_VERSION 28
#define EXPECTED_VERSION 29
#define MAX_STRING_LENGTH 65535
#define FOOTNOTE_NUMBER_LEN 32
#define FOOTNOTE_HREF_LEN 96
@@ -176,14 +180,20 @@ struct BlockStyle {
struct TextBlock {
u16 wordCount;
String words[wordCount];
s16 wordXPos[wordCount];
WordStyle wordStyle[wordCount];
u8 hasFocus;
if (hasFocus != 0) {
u8 wordFocusBoundary[wordCount] [[comment("UTF-8 byte boundary between bold prefix and suffix")]];
u16 wordFocusSuffixX[wordCount] [[comment("Suffix x offset from word start")]];
u16 textBytes [[comment("Total size of text[], including one NUL per word")]];
if (wordCount > 0) {
u16 textOff[wordCount] [[comment("Byte offset of word i's text within text[]")]];
s16 wordXPos[wordCount];
if (hasFocus != 0) {
u16 wordFocusSuffixX[wordCount] [[comment("Suffix x offset from word start")]];
}
WordStyle wordStyle[wordCount];
if (hasFocus != 0) {
u8 wordFocusBoundary[wordCount] [[comment("UTF-8 byte boundary between bold prefix and suffix")]];
}
char text[textBytes] [[comment("All words back to back, each NUL-terminated")]];
}
BlockStyle blockStyle;