import UIKit extension RDReaderController { func currentEPUBTextPageSize() -> CGSize { let pageWidth: CGFloat if readerView.pagesPerScreen > 1 { pageWidth = view.frame.width / CGFloat(readerView.pagesPerScreen) - 16 * 2 } else { pageWidth = view.frame.width - 16 * 2 } return CGSize(width: max(pageWidth, 1), height: max(view.frame.height - 40 * 2, 1)) } func loadEPUBTextBook( parser: RDEPUBParser, publication: RDEPUBPublication, restoreLocation: RDEPUBLocation? ) { let pageSize = currentEPUBTextPageSize() let font = UIFont.systemFont(ofSize: RDReaderManager.shared.fontValue.currentType) let lineSpacing = RDReaderManager.shared.lineSpaceType.currentType.mulitiple * 15 DispatchQueue.global(qos: .userInitiated).async { [weak self] in let textBook = LegacyRDEPUBTextBookBuilder.build( parser: parser, publication: publication, pageSize: pageSize, font: font, lineSpacing: lineSpacing ) DispatchQueue.main.async { self?.applyEPUBTextBook(textBook, publication: publication, restoreLocation: restoreLocation) } } } func applyEPUBTextBook( _ textBook: LegacyRDEPUBTextBook, publication: RDEPUBPublication, restoreLocation: RDEPUBLocation? ) { epubTextBook = textBook epubTOCItems = flattenedTOCItems(from: publication.tableOfContents, textBook: textBook) print("[EPUB] Text book ready chapters=\(textBook.chapters.count) pages=\(textBook.pages.count) toc=\(epubTOCItems.count)") let resolvedRestorePage = restoreLocation.flatMap { textBook.pageNumber( for: $0, resolver: epubResolver ?? publicationFallbackResolver(), bookIdentifier: currentEPUBBookIdentifier ) } storeEPUBPaginationValidation( mode: "textReflowable", stage: "final", pageCount: textBook.pages.count, chapterCount: textBook.chapters.count, tocCount: epubTOCItems.count, restoreLocation: restoreLocation, resolvedRestorePage: resolvedRestorePage ) isReaderContentReady = true hideLoading() readerView.reloadData() restoreEPUBLocation(restoreLocation) if restoreLocation == nil { epubSession?.transition(to: .idle) } } func flattenedTOCItems( from items: [EPUBTableOfContentsItem], depth: Int = 0, textBook: LegacyRDEPUBTextBook? = nil ) -> [EPUBTOCDisplayItem] { var result: [EPUBTOCDisplayItem] = [] for item in items { let pageNumber = textBook.flatMap { book in book.pageNumber( for: RDEPUBLocation(bookIdentifier: currentEPUBBookIdentifier, href: item.href, progression: 0), resolver: epubResolver ?? publicationFallbackResolver(), bookIdentifier: currentEPUBBookIdentifier ) } result.append(EPUBTOCDisplayItem(title: item.title, href: item.href, depth: depth, pageNumber: pageNumber)) result.append(contentsOf: flattenedTOCItems(from: item.children, depth: depth + 1, textBook: textBook)) } return result } func publicationFallbackResolver() -> RDEPUBResourceResolver { epubPublication?.resourceResolver ?? RDEPUBResourceResolver(parser: epubParser ?? RDEPUBParser()) } }