| 1196 | |
| 1197 | template <typename Iter> |
| 1198 | int SdCardFont::buildAdvanceTableRange(Iter begin, Iter end, bool includeSpace, bool includeHyphen, uint8_t styleMask) { |
| 1199 | if (!loaded_) return -1; |
| 1200 | styleMask = resolveStyleMask(styleMask); |
| 1201 | if (styleMask == 0) return 0; |
| 1202 | |
| 1203 | unsigned long startMs = millis(); |
| 1204 | |
| 1205 | // +2 reserved slots for space and hyphen injected after the main scan. |
| 1206 | static constexpr uint32_t MAX_UNIQUE_CODEPOINTS = 4096; |
| 1207 | uint32_t* codepoints = new (std::nothrow) uint32_t[MAX_UNIQUE_CODEPOINTS + 2]; |
| 1208 | if (!codepoints) { |
| 1209 | LOG_ERR("SDCF", "buildAdvanceTable: failed to allocate codepoint buffer (%u bytes)", MAX_UNIQUE_CODEPOINTS * 4); |
| 1210 | return -1; |
| 1211 | } |
| 1212 | uint32_t cpCount = 0; |
| 1213 | bool hitCap = false; |
| 1214 | |
| 1215 | for (auto it = begin; it != end && !hitCap; ++it) { |
| 1216 | hitCap = collectUniqueCodepoints(asCStr(*it), codepoints, cpCount, MAX_UNIQUE_CODEPOINTS); |
| 1217 | } |
| 1218 | |
| 1219 | if (includeSpace && std::none_of(codepoints, codepoints + cpCount, [](uint32_t c) { return c == ' '; })) |
| 1220 | codepoints[cpCount++] = ' '; |
| 1221 | if (includeHyphen && std::none_of(codepoints, codepoints + cpCount, [](uint32_t c) { return c == '-'; })) |
| 1222 | codepoints[cpCount++] = '-'; |
| 1223 | |
| 1224 | if (hitCap) { |
| 1225 | LOG_ERR("SDCF", "buildAdvanceTable: unique codepoint cap (%u) hit, layout may be approximate", |
| 1226 | MAX_UNIQUE_CODEPOINTS); |
| 1227 | } |
| 1228 | std::sort(codepoints, codepoints + cpCount); |
| 1229 | int totalMissed = fetchAdvancesForCodepoints(codepoints, cpCount, styleMask); |
| 1230 | delete[] codepoints; |
| 1231 | stats_.prewarmTotalMs = millis() - startMs; |
| 1232 | return totalMissed; |
| 1233 | } |
| 1234 | |
| 1235 | int SdCardFont::buildAdvanceTable(const char* utf8Text, uint8_t styleMask) { |
| 1236 | return buildAdvanceTableRange(&utf8Text, &utf8Text + 1, false, false, styleMask); |
nothing calls this directly
no test coverage detected