MCPcopy Create free account
hub / github.com/crosspoint-reader/crosspoint-reader / prewarm

Method prewarm

lib/EpdFont/SdCardFont.cpp:660–762  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

658// --- Prewarm ---
659
660int SdCardFont::prewarm(const char* utf8Text, uint8_t styleMask, bool metadataOnly) {
661 if (!loaded_) return -1;
662 styleMask = resolveStyleMask(styleMask);
663 if (styleMask == 0) return 0;
664
665 unsigned long startMs = millis();
666
667 // Step 1: Extract unique codepoints from UTF-8 text (shared across all styles).
668 // Dedup uses O(n^2) linear scan — worst case is MAX_PAGE_GLYPHS (512) unique codepoints
669 // = ~131K comparisons, but in practice pages contain far fewer unique codepoints so the
670 // actual cost is much lower. This is dwarfed by SD I/O that follows. Alternatives (hash
671 // set, bitmap) exceed the 256-byte stack limit or add template bloat.
672 // Heap-allocated: MAX_PAGE_GLYPHS * 4 = 2048 bytes, too large for stack (limit < 256 bytes)
673 std::unique_ptr<uint32_t[]> codepoints(new (std::nothrow) uint32_t[MAX_PAGE_GLYPHS]);
674 if (!codepoints) {
675 LOG_ERR("SDCF", "Failed to allocate codepoint buffer (%u bytes)", MAX_PAGE_GLYPHS * 4);
676 return -1;
677 }
678 uint32_t cpCount = 0;
679
680 const unsigned char* p = reinterpret_cast<const unsigned char*>(utf8Text);
681 while (*p && cpCount < MAX_PAGE_GLYPHS) {
682 uint32_t cp = utf8NextCodepoint(&p);
683 if (cp == 0) break;
684
685 bool found = false;
686 for (uint32_t i = 0; i < cpCount; i++) {
687 if (codepoints[i] == cp) {
688 found = true;
689 break;
690 }
691 }
692 if (!found) {
693 codepoints[cpCount++] = cp;
694 }
695 }
696
697 // Always include the replacement character
698 {
699 bool hasReplacement = false;
700 for (uint32_t i = 0; i < cpCount; i++) {
701 if (codepoints[i] == REPLACEMENT_GLYPH) {
702 hasReplacement = true;
703 break;
704 }
705 }
706 if (!hasReplacement && cpCount < MAX_PAGE_GLYPHS) {
707 codepoints[cpCount++] = REPLACEMENT_GLYPH;
708 }
709 }
710
711 // Add ligature output codepoints from all styles being prewarmed.
712 // Skip during metadata-only prewarm (layout measurement) to avoid loading
713 // kern/lig data for all styles upfront (~22KB per style). Kern/lig is
714 // loaded per-style in prewarmStyle() during the full render prewarm instead.
715 if (!metadataOnly) {
716 for (uint8_t si = 0; si < MAX_STYLES; si++) {
717 if (!(styleMask & (1 << si)) || !styles_[si].present) continue;

Callers 1

prewarmCacheMethod · 0.80

Calls 2

utf8NextCodepointFunction · 0.85
getMethod · 0.80

Tested by

no test coverage detected