refactor: split reader architecture and chrome handling

This commit is contained in:
shen
2026-05-31 21:47:54 +08:00
parent ea21c6a831
commit 44202357c0
80 changed files with 10635 additions and 8522 deletions
@@ -25,13 +25,6 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
}
/// HTML NSAttributedString fragment
///
///
/// 1. HTML Data
/// 2. DTCoreText 退
/// 3. ${rd-sem-start/end}
/// 4. fragment
/// 5.
public func renderChapter(
request: RDEPUBTextChapterRenderRequest
) throws -> RDEPUBRenderedChapterContent {
@@ -46,8 +39,8 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
}
let attributedString = NSMutableAttributedString(attributedString: rendered)
RDEPUBTextRendererSupport.applyPaginationSemantics(in: attributedString)
let fragmentOffsets = RDEPUBTextRendererSupport.extractFragmentOffsets(from: attributedString)
RDEPUBSemanticMarkerInjector.applyPaginationSemantics(in: attributedString)
let fragmentOffsets = RDEPUBFragmentMarkerInjector.extractFragmentOffsets(from: attributedString)
RDEPUBTextRendererSupport.normalizeReadingAttributes(in: attributedString, style: request.style)
return RDEPUBRenderedChapterContent(
attributedString: attributedString,
@@ -65,22 +58,24 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
baseURL: URL?,
style: RDEPUBTextRenderStyle
) throws -> RDEPUBRenderedChapterContent {
let request = RDEPUBTextRendererSupport.makeChapterRenderRequest(
href: "",
title: "",
rawHTML: html,
baseURL: baseURL,
style: style,
resourceResolver: nil
)
let request = RDEPUBTextTypesetterPipeline().makeRequest(
from: RDEPUBTypesettingInput(
href: "",
title: "",
rawHTML: html,
baseURL: baseURL,
style: style,
resourceResolver: nil
)
).request
return try renderChapter(request: request)
}
/// 退 DTCoreText HTML
private func fallbackRenderedContent(request: RDEPUBTextChapterRenderRequest) -> RDEPUBRenderedChapterContent {
let attributedString = RDEPUBTextRendererSupport.fallbackAttributedString(for: request.context.html, style: request.style)
RDEPUBTextRendererSupport.applyPaginationSemantics(in: attributedString)
let fragmentOffsets = RDEPUBTextRendererSupport.extractFragmentOffsets(from: attributedString)
RDEPUBSemanticMarkerInjector.applyPaginationSemantics(in: attributedString)
let fragmentOffsets = RDEPUBFragmentMarkerInjector.extractFragmentOffsets(from: attributedString)
RDEPUBTextRendererSupport.normalizeReadingAttributes(in: attributedString, style: request.style)
return RDEPUBRenderedChapterContent(
attributedString: attributedString,
@@ -91,9 +86,6 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
#if canImport(DTCoreText)
/// 使 DTCoreText HTML Data
///
/// `willFlushCallback` DOM
/// /
private func makeAttributedString(from data: Data, request: RDEPUBTextChapterRenderRequest) -> NSAttributedString? {
let builder = DTHTMLAttributedStringBuilder(
html: data,
@@ -102,7 +94,7 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
)
builder?.willFlushCallback = { element in
guard let element else { return }
RDEPUBTextRendererSupport.prepareHTMLElementForReaderRendering(
RDEPUBAttachmentNormalizer.prepareHTMLElementForReaderRendering(
element,
style: request.style,
maxImageSize: resolvedMaxImageSize(for: request)
@@ -112,9 +104,6 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
}
/// DTCoreText
///
/// - `( + ) / `
/// style.lineSpacing
private func dtOptions(request: RDEPUBTextChapterRenderRequest) -> [AnyHashable: Any] {
let style = request.style
let maxImageSize = resolvedMaxImageSize(for: request)
@@ -139,16 +128,12 @@ public struct RDEPUBDTCoreTextRenderer: RDEPUBTextRenderer {
}
private func resolvedMaxImageSize(for request: RDEPUBTextChapterRenderRequest) -> CGSize {
if let pageSize = request.pageSize {
let layoutConfig = request.layoutConfig ?? .default
let contentRect = layoutConfig.contentRect(fallback: pageSize)
let maxWidth = max(round(contentRect.width), 1)
let maxHeight = max(round(contentRect.height * layoutConfig.imageMaxHeightRatio), 1)
return CGSize(width: maxWidth, height: maxHeight)
}
let screenBounds = UIScreen.main.bounds.insetBy(dx: 20, dy: 28)
return CGSize(width: max(round(screenBounds.width), 1), height: max(round(screenBounds.height * 0.85), 1))
let layoutConfig = request.layoutConfig ?? .default
let fallbackPageSize = request.pageSize ?? layoutConfig.fallbackViewportSize
let contentRect = layoutConfig.contentRect(fallback: fallbackPageSize)
let maxWidth = max(round(contentRect.width), 1)
let maxHeight = max(round(contentRect.height * layoutConfig.imageMaxHeightRatio), 1)
return CGSize(width: maxWidth, height: maxHeight)
}
#endif
}