Font rendering performance improvements

- FontDecompressor: replace heap-allocated std::vector hot-group and glyph
  scratch buffers with static BSS arrays, eliminating per-page malloc/free
  and the heap fragmentation it causes during rendering
- FontDecompressor: add bounds checks on group/glyph buffer sizes; sort
  prewarm group list by ascending index for sequential flash reads
- ParsedText: upgrade line-break cost function to Knuth-Plass cubic badness
  (strongly penalises very loose lines, lenient on moderate looseness)
- ParsedText: exclude gaps before closing punctuation (. , ) » etc.) from
  justification distribution so they stay at natural space width

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jpirnay
2026-04-22 07:33:39 +02:00
co-authored by Claude Sonnet 4.6
parent 8c72efb3b9
commit e4170e2272
3 changed files with 101 additions and 51 deletions
+12 -6
View File
@@ -2,8 +2,6 @@
#include <InflateReader.h>
#include <vector>
#include "EpdFontData.h"
class FontDecompressor {
@@ -65,15 +63,23 @@ class FontDecompressor {
PageSlot pageSlots[MAX_PAGE_SLOTS] = {};
uint8_t pageSlotCount = 0;
// Measured maxima across all built-in fonts:
// uncompressedSize: 50 KB (notosans_18 / bookerly_18)
// glyph dataLength: 500 B (bookerly_18)
// Static BSS arrays eliminate per-page heap alloc/free and the fragmentation it causes.
static constexpr uint32_t HOT_GROUP_BUF_SIZE = 51200; // 50 KB uncompressed group
static constexpr uint16_t HOT_GLYPH_BUF_SIZE = 512; // largest packed single glyph
// Hot group: last decompressed group (byte-aligned) for non-prewarmed fallback path.
// Kept in byte-aligned format; individual glyphs are compacted on demand into hotGlyphBuf.
// Kept in byte-aligned format; individual glyphs are compacted on demand into _hotGlyphBuf.
const EpdFontData* hotGroupFont = nullptr;
uint16_t hotGroupIndex = UINT16_MAX;
std::vector<uint8_t> hotGroup;
uint32_t _hotGroupBufUsed = 0;
uint8_t _hotGroupBuf[HOT_GROUP_BUF_SIZE];
// Scratch buffer for compacting a single glyph from the hot group.
// Scratch buffer for compacting a single glyph out of the byte-aligned hot group.
// Valid until the next getBitmap() call.
std::vector<uint8_t> hotGlyphBuf;
uint8_t _hotGlyphBuf[HOT_GLYPH_BUF_SIZE];
void freePageBuffer();
void freeHotGroup();