Finetuning 2

This commit is contained in:
jpirnay
2026-04-20 13:15:05 +02:00
parent 5e4f78f7be
commit 3fb9ac9e29
2 changed files with 40 additions and 32 deletions
+8 -10
View File
@@ -584,23 +584,21 @@ std::optional<uint16_t> Section::getPageForParagraphIndex(const uint16_t pIndex)
return std::nullopt; return std::nullopt;
} }
// Find the page that contains the requested paragraph index. // Each LUT entry stores the paragraph index at page-break time — i.e. the last
// Each entry stores the first paragraph index for that page, so the page // <p> whose start tag had been seen while page i was being laid out. Paragraph
// containing pIndex is the last page whose start paragraph is <= pIndex. // P therefore first appears on the smallest i where storedPIdx[i] >= P.
uint16_t resultPage = 0;
for (uint16_t i = 0; i < count; i++) { for (uint16_t i = 0; i < count; i++) {
uint32_t byteOffset; f.seek(paragraphLutOffset + sizeof(uint16_t) + i * ENTRY_SIZE + sizeof(uint32_t));
uint16_t pagePIdx; uint16_t pagePIdx;
serialization::readPod(f, byteOffset);
serialization::readPod(f, pagePIdx); serialization::readPod(f, pagePIdx);
if (pagePIdx > pIndex) { if (pagePIdx >= pIndex) {
break; f.close();
return i;
} }
resultPage = i;
} }
f.close(); f.close();
return resultPage; return static_cast<uint16_t>(count - 1);
} }
std::optional<uint16_t> Section::getParagraphIndexForPage(const uint16_t page) const { std::optional<uint16_t> Section::getParagraphIndexForPage(const uint16_t page) const {
+32 -22
View File
@@ -47,33 +47,43 @@ struct ReverseState : StackState {
const char* bestTierName = nullptr; const char* bestTierName = nullptr;
ReverseState(const int spineIndex, const std::string& xpath) : spineIndex(spineIndex) { ReverseState(const int spineIndex, const std::string& xpath) : spineIndex(spineIndex) {
// Parse optional /text()[N].M suffix before normalizing for element matching. // Parse optional text-node suffix before normalizing for element matching.
// KOReader emits two shapes that both land here:
// /text()[N].M — explicit 1-based text-node index + codepoint offset
// /text().M — implicit first text-node (N=1) + codepoint offset
std::string raw = xpath; std::string raw = xpath;
for (char& c : raw) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c))); for (char& c : raw) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
const std::string tnPat = "/text()["; const std::string tnPat = "/text()";
const size_t tnPos = raw.rfind(tnPat); const size_t tnPos = raw.rfind(tnPat);
if (tnPos != std::string::npos) { if (tnPos != std::string::npos) {
const size_t numStart = tnPos + tnPat.size(); size_t cursor = tnPos + tnPat.size();
size_t numEnd = numStart; int nodeIdx = 1;
while (numEnd < raw.size() && std::isdigit(static_cast<unsigned char>(raw[numEnd]))) { bool valid = true;
numEnd++; if (cursor < raw.size() && raw[cursor] == '[') {
cursor++;
size_t numEnd = cursor;
while (numEnd < raw.size() && std::isdigit(static_cast<unsigned char>(raw[numEnd]))) {
numEnd++;
}
if (numEnd > cursor && numEnd < raw.size() && raw[numEnd] == ']') {
nodeIdx = static_cast<int>(std::strtol(raw.substr(cursor, numEnd - cursor).c_str(), nullptr, 10));
cursor = numEnd + 1;
} else {
valid = false;
}
} }
if (numEnd > numStart && numEnd < raw.size() && raw[numEnd] == ']') { if (valid && nodeIdx >= 1) {
const long nodeIdx = std::strtol(raw.substr(numStart, numEnd - numStart).c_str(), nullptr, 10); targetTextNodeIndex = nodeIdx;
if (nodeIdx >= 1) { if (cursor < raw.size() && raw[cursor] == '.') {
targetTextNodeIndex = static_cast<int>(nodeIdx); cursor++;
size_t after = numEnd + 1; size_t charEnd = cursor;
if (after < raw.size() && raw[after] == '.') { while (charEnd < raw.size() && std::isdigit(static_cast<unsigned char>(raw[charEnd]))) {
after++; charEnd++;
size_t charEnd = after; }
while (charEnd < raw.size() && std::isdigit(static_cast<unsigned char>(raw[charEnd]))) { if (charEnd > cursor) {
charEnd++; const long charOff = std::strtol(raw.substr(cursor, charEnd - cursor).c_str(), nullptr, 10);
} if (charOff >= 0) {
if (charEnd > after) { targetCharOffset = static_cast<int>(charOff);
const long charOff = std::strtol(raw.substr(after, charEnd - after).c_str(), nullptr, 10);
if (charOff >= 0) {
targetCharOffset = static_cast<int>(charOff);
}
} }
} }
} }