| 325 | } |
| 326 | |
| 327 | void BookMetadataCache::createTocEntry(const std::string& title, const std::string& href, const std::string& anchor, |
| 328 | const uint8_t level) { |
| 329 | if (!buildMode || !tocFile || !spineFile) { |
| 330 | LOG_DBG("BMC", "createTocEntry called but not in build mode"); |
| 331 | return; |
| 332 | } |
| 333 | |
| 334 | int16_t spineIndex = -1; |
| 335 | |
| 336 | if (useSpineHrefIndex) { |
| 337 | uint64_t targetHash = fnvHash64(href); |
| 338 | uint16_t targetLen = static_cast<uint16_t>(href.size()); |
| 339 | |
| 340 | auto it = |
| 341 | std::lower_bound(spineHrefIndex.begin(), spineHrefIndex.end(), SpineHrefIndexEntry{targetHash, targetLen, 0}, |
| 342 | [](const SpineHrefIndexEntry& a, const SpineHrefIndexEntry& b) { |
| 343 | return a.hrefHash < b.hrefHash || (a.hrefHash == b.hrefHash && a.hrefLen < b.hrefLen); |
| 344 | }); |
| 345 | |
| 346 | while (it != spineHrefIndex.end() && it->hrefHash == targetHash && it->hrefLen == targetLen) { |
| 347 | spineIndex = it->spineIndex; |
| 348 | break; |
| 349 | } |
| 350 | |
| 351 | if (spineIndex == -1) { |
| 352 | LOG_DBG("BMC", "createTocEntry: Could not find spine item for TOC href %s", href.c_str()); |
| 353 | } |
| 354 | } else { |
| 355 | spineFile.seek(0); |
| 356 | for (int i = 0; i < spineCount; i++) { |
| 357 | auto spineEntry = readSpineEntry(spineFile); |
| 358 | if (spineEntry.href == href) { |
| 359 | spineIndex = static_cast<int16_t>(i); |
| 360 | break; |
| 361 | } |
| 362 | } |
| 363 | if (spineIndex == -1) { |
| 364 | LOG_DBG("BMC", "createTocEntry: Could not find spine item for TOC href %s", href.c_str()); |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | // Compose the title to NFC at index time so the cache stores precomposed glyphs; |
| 369 | // device fonts have no combining-mark positioning, so NFD titles render broken. |
| 370 | const TocEntry entry(utf8ComposeNfc(title), href, anchor, level, spineIndex); |
| 371 | writeTocEntry(tocFile, entry); |
| 372 | tocCount++; |
| 373 | } |
| 374 | |
| 375 | /* ============= READING / LOADING FUNCTIONS ================ */ |
| 376 |
no test coverage detected