Merge pull request 'perf(text): fold Ensure+Lookup into FontAtlas::EnsureAndGet (#53)' (#84) from claude/issue-53 into master

This commit is contained in:
catbot 2026-06-16 17:44:20 +02:00
commit 0b00d9d680
3 changed files with 13 additions and 6 deletions

View file

@ -74,8 +74,12 @@ bool FontAtlas::ShelfPlace(int w, int h, int& outX, int& outY) {
} }
bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) { bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) {
return EnsureAndGet(font, codepoint) != nullptr;
}
const Glyph* FontAtlas::EnsureAndGet(Font& font, std::uint32_t codepoint) {
Key key{&font, codepoint}; Key key{&font, codepoint};
if (cache_.contains(key)) return true; if (auto it = cache_.find(key); it != cache_.end()) return &it->second;
float fontScale = stbtt_ScaleForPixelHeight(&font.font, kBaseSize); float fontScale = stbtt_ScaleForPixelHeight(&font.font, kBaseSize);
@ -98,7 +102,7 @@ bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) {
int px = 0, py = 0; int px = 0, py = 0;
if (!ShelfPlace(sw, sh, px, py)) { if (!ShelfPlace(sw, sh, px, py)) {
stbtt_FreeSDF(sdf, nullptr); stbtt_FreeSDF(sdf, nullptr);
return false; return nullptr;
} }
std::uint8_t* dst = PixelPtr(); std::uint8_t* dst = PixelPtr();
for (int row = 0; row < sh; ++row) { for (int row = 0; row < sh; ++row) {
@ -119,8 +123,7 @@ bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) {
MarkDirty(px, py, sw, sh); MarkDirty(px, py, sw, sh);
} }
cache_.emplace(key, g); return &cache_.emplace(key, g).first->second;
return true;
} }
const Glyph* FontAtlas::Lookup(Font& font, std::uint32_t codepoint) const { const Glyph* FontAtlas::Lookup(Font& font, std::uint32_t codepoint) const {

View file

@ -75,8 +75,7 @@ std::uint32_t UIRenderer::ShapeText(Font& font, float pxSize,
if (cp == 0) break; if (cp == 0) break;
if (cp == '\n') { continue; } if (cp == '\n') { continue; }
fontAtlas->Ensure(font, cp); const Glyph* g = fontAtlas->EnsureAndGet(font, cp);
const Glyph* g = fontAtlas->Lookup(font, cp);
if (g == nullptr) continue; if (g == nullptr) continue;
if (g->w > 0 && g->h > 0) { if (g->w > 0 && g->h > 0) {

View file

@ -115,6 +115,11 @@ export namespace Crafter {
std::uint8_t* PixelPtr() noexcept; std::uint8_t* PixelPtr() noexcept;
bool Ensure(Font& font, std::uint32_t codepoint); bool Ensure(Font& font, std::uint32_t codepoint);
// Ensure the glyph is in the atlas and return a pointer to it in one
// hash+probe. Returns nullptr only when a brand-new glyph cannot be
// placed (ShelfPlace failure); a glyph with no SDF coverage (e.g.
// space) still returns a valid pointer.
const Glyph* EnsureAndGet(Font& font, std::uint32_t codepoint);
const Glyph* Lookup(Font& font, std::uint32_t codepoint) const; const Glyph* Lookup(Font& font, std::uint32_t codepoint) const;
void Update(GraphicsCommandBuffer cmd); void Update(GraphicsCommandBuffer cmd);