Final review

This commit is contained in:
jpirnay
2026-04-24 19:42:18 +02:00
parent a73836c594
commit 37395f8e0f
4 changed files with 32 additions and 21 deletions
+9 -8
View File
@@ -112,7 +112,7 @@ void FontDecompressor::compactSingleGlyph(const uint8_t* alignedSrc, uint8_t* pa
if (outBits > 0) packedDst[writeIdx] = outByte << (8 - outBits);
}
// --- getBitmap: page buffer → hot group → decompress ---
// --- getBitmap: page buffer → transient malloc + decompress + compact ---
const uint8_t* FontDecompressor::getBitmap(const EpdFontData* fontData, const EpdGlyph* glyph, uint32_t glyphIndex) {
const uint32_t tStart = micros();
@@ -159,6 +159,12 @@ const uint8_t* FontDecompressor::getBitmap(const EpdFontData* fontData, const Ep
stats.cacheMisses++;
const EpdFontGroup& group = fontData->groups[groupIndex];
if (glyph->dataLength > HOT_GLYPH_BUF_SIZE) {
LOG_ERR("FDC", "Glyph dataLength %u exceeds HOT_GLYPH_BUF_SIZE %u", glyph->dataLength, HOT_GLYPH_BUF_SIZE);
stats.getBitmapTimeUs += micros() - tStart;
return nullptr;
}
if (group.uncompressedSize > stats.peakTempBytes) stats.peakTempBytes = group.uncompressedSize;
uint8_t* groupBuf = static_cast<uint8_t*>(malloc(group.uncompressedSize));
@@ -174,13 +180,6 @@ const uint8_t* FontDecompressor::getBitmap(const EpdFontData* fontData, const Ep
return nullptr;
}
if (glyph->dataLength > HOT_GLYPH_BUF_SIZE) {
LOG_ERR("FDC", "Glyph dataLength %u exceeds HOT_GLYPH_BUF_SIZE %u", glyph->dataLength, HOT_GLYPH_BUF_SIZE);
free(groupBuf);
stats.getBitmapTimeUs += micros() - tStart;
return nullptr;
}
uint32_t alignedOff = getAlignedOffset(fontData, groupIndex, glyphIndex);
compactSingleGlyph(&groupBuf[alignedOff], _hotGlyphBuf, glyph->width, glyph->height);
free(groupBuf);
@@ -348,6 +347,8 @@ int FontDecompressor::prewarmCache(const EpdFontData* fontData, const char* utf8
if (!groupIdToPos) {
LOG_ERR("FDC", "OOM: cannot allocate %u bytes for groupIdToPos map", fontData->groupCount);
// Roll back this slot only (other slots from prior prewarmCache calls stay valid)
stats.pageBufferBytes -= totalBytes;
stats.pageGlyphsBytes -= glyphCount * sizeof(PageGlyphEntry);
free(slot.buffer);
free(slot.glyphs);
slot = {};
+5 -1
View File
@@ -16,7 +16,11 @@ class FontDecompressor {
void deinit();
// Returns pointer to decompressed bitmap data for the given glyph.
// Checks the page buffer (from prewarm) first, then falls back to the hot group slot.
// Checks the page buffer (from prewarm) first and otherwise transiently
// allocates/decompresses the glyph's group into a temporary buffer and
// compacts the requested glyph. The returned pointer is valid only until the
// next getBitmap call or cache eviction; callers must copy bitmap data if a
// longer lifetime is required.
const uint8_t* getBitmap(const EpdFontData* fontData, const EpdGlyph* glyph, uint32_t glyphIndex);
// Free all cached data (page buffers).
+6 -1
View File
@@ -765,9 +765,14 @@ if compress:
group_count = 0
group_uncompressed = 0
for i, (props, packed) in enumerate(all_glyphs):
for i, (props, _) in enumerate(all_glyphs):
sg = get_script_group(props.code_point)
glyph_aligned_size = ((props.width + 3) // 4) * props.height if props.width > 0 and props.height > 0 else 0
if glyph_aligned_size > GROUP_MAX_UNCOMPRESSED_BYTES:
raise ValueError(
f"Glyph {i} (code point U+{props.code_point:04X}) single aligned size "
f"{glyph_aligned_size} exceeds GROUP_MAX_UNCOMPRESSED_BYTES={GROUP_MAX_UNCOMPRESSED_BYTES}"
)
size_overflow = group_uncompressed + glyph_aligned_size > GROUP_MAX_UNCOMPRESSED_BYTES
if sg != current_group_id or size_overflow: