| 27 | } // namespace |
| 28 | |
| 29 | const uint8_t* GfxRenderer::getGlyphBitmap(const EpdFontData* fontData, const EpdGlyph* glyph) const { |
| 30 | if (fontData->groups != nullptr) { |
| 31 | auto* fd = fontCacheManager_ ? fontCacheManager_->getDecompressor() : nullptr; |
| 32 | if (!fd) { |
| 33 | LOG_ERR("GFX", "Compressed font but no FontDecompressor set"); |
| 34 | return nullptr; |
| 35 | } |
| 36 | uint32_t glyphIndex = static_cast<uint32_t>(glyph - fontData->glyph); |
| 37 | // For page-buffer hits the pointer is stable for the page lifetime. |
| 38 | // For hot-group hits it is valid only until the next getBitmap() call — callers |
| 39 | // must consume it (draw the glyph) before requesting another bitmap. |
| 40 | return fd->getBitmap(fontData, glyph, glyphIndex); |
| 41 | } |
| 42 | // For SD card fonts, check if the glyph was loaded on demand into the overflow |
| 43 | // buffer. getOverflowBitmap() returns: |
| 44 | // - bitmap pointer for overflow glyphs with bitmap data |
| 45 | // - nullptr for overflow glyphs without bitmap data (e.g. space: width=0, height=0) |
| 46 | // - nullptr for non-overflow glyphs (normal prewarmed path) |
| 47 | // We distinguish overflow-with-no-bitmap from non-overflow by checking isOverflowGlyph(). |
| 48 | if (fontData->glyphMissCtx) { |
| 49 | auto* sdFont = SdCardFont::fromMissCtx(fontData->glyphMissCtx); |
| 50 | if (sdFont->isOverflowGlyph(glyph)) { |
| 51 | return sdFont->getOverflowBitmap(glyph); // may be nullptr for zero-width glyphs |
| 52 | } |
| 53 | } |
| 54 | return &fontData->bitmap[glyph->dataOffset]; |
| 55 | } |
| 56 | |
| 57 | void GfxRenderer::ensureSdCardFontReady(int fontId, const char* utf8Text, uint8_t styleMask) const { |
| 58 | auto it = sdCardFonts_.find(fontId); |
no test coverage detected