fixed font rendering
This commit is contained in:
@@ -88,35 +88,55 @@ class BookStore(private val context: Context) {
|
|||||||
|
|
||||||
private fun extractEpub(book: EpubBook, baseDirectory: File) {
|
private fun extractEpub(book: EpubBook, baseDirectory: File) {
|
||||||
try {
|
try {
|
||||||
// First extract CSS files
|
// First extract fonts and CSS files
|
||||||
book.resources.all
|
book.resources.all
|
||||||
.filter { resource ->
|
.filter { resource ->
|
||||||
resource.mediaType?.toString()?.contains("css") ?: false
|
val mediaType = resource.mediaType?.toString() ?: ""
|
||||||
|
mediaType.contains("css") ||
|
||||||
|
mediaType.contains("font") ||
|
||||||
|
resource.href.endsWith(".otf") ||
|
||||||
|
resource.href.endsWith(".ttf") ||
|
||||||
|
resource.href.endsWith(".woff") ||
|
||||||
|
resource.href.endsWith(".woff2")
|
||||||
}
|
}
|
||||||
.forEach { resource ->
|
.forEach { resource ->
|
||||||
val cssPath = resource.href
|
// Extract to both original location and root fonts directory
|
||||||
.replace("../", "")
|
val paths = listOf(
|
||||||
.replace("./", "")
|
resource.href.replace("../", "").replace("./", ""),
|
||||||
|
"Fonts/${resource.href.substringAfterLast("/")}",
|
||||||
|
"Text/Fonts/${resource.href.substringAfterLast("/")}"
|
||||||
|
).distinct()
|
||||||
|
|
||||||
val resourceFile = File(baseDirectory, cssPath)
|
paths.forEach { path ->
|
||||||
|
val resourceFile = File(baseDirectory, path)
|
||||||
resourceFile.parentFile?.mkdirs()
|
resourceFile.parentFile?.mkdirs()
|
||||||
resourceFile.writeBytes(resource.data)
|
resourceFile.writeBytes(resource.data)
|
||||||
|
|
||||||
|
// Log font file extraction
|
||||||
|
if (resource.href.matches(Regex(".+\\.(otf|ttf|woff|woff2)$"))) {
|
||||||
Timber.d("""
|
Timber.d("""
|
||||||
CSS File Extracted:
|
Font File Extracted:
|
||||||
- Original href: ${resource.href}
|
- Original href: ${resource.href}
|
||||||
- Final path: $cssPath
|
- Path: $path
|
||||||
- Full path: ${resourceFile.absolutePath}
|
- Full path: ${resourceFile.absolutePath}
|
||||||
- Size: ${resourceFile.length()}
|
- Size: ${resourceFile.length()}
|
||||||
- Exists: ${resourceFile.exists()}
|
- Exists: ${resourceFile.exists()}
|
||||||
- Content sample: ${String(resource.data.take(100).toByteArray())}
|
- Media Type: ${resource.mediaType}
|
||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Then extract HTML files
|
// Then extract remaining files
|
||||||
book.resources.all
|
book.resources.all
|
||||||
.filter { resource ->
|
.filter { resource ->
|
||||||
!(resource.mediaType?.toString()?.contains("css") ?: false)
|
val mediaType = resource.mediaType?.toString() ?: ""
|
||||||
|
!(mediaType.contains("css") ||
|
||||||
|
mediaType.contains("font") ||
|
||||||
|
resource.href.endsWith(".otf") ||
|
||||||
|
resource.href.endsWith(".ttf") ||
|
||||||
|
resource.href.endsWith(".woff") ||
|
||||||
|
resource.href.endsWith(".woff2"))
|
||||||
}
|
}
|
||||||
.forEach { resource ->
|
.forEach { resource ->
|
||||||
val resourcePath = resource.href.replace("../", "").replace("./", "")
|
val resourcePath = resource.href.replace("../", "").replace("./", "")
|
||||||
@@ -133,26 +153,34 @@ class BookStore(private val context: Context) {
|
|||||||
.escapeMode(org.jsoup.nodes.Entities.EscapeMode.xhtml)
|
.escapeMode(org.jsoup.nodes.Entities.EscapeMode.xhtml)
|
||||||
.prettyPrint(false)
|
.prettyPrint(false)
|
||||||
|
|
||||||
// Ensure head section exists
|
|
||||||
var head = doc.head()
|
|
||||||
if (head == null) {
|
|
||||||
head = doc.createElement("head")
|
|
||||||
doc.prependChild(head)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process CSS links
|
// Process CSS links
|
||||||
doc.select("link[rel=stylesheet]").forEach { link ->
|
doc.select("link[rel=stylesheet]").forEach { link ->
|
||||||
val cssHref = link.attr("href")
|
val cssHref = link.attr("href")
|
||||||
.replace("../", "")
|
.replace("../", "")
|
||||||
.replace("./", "")
|
.replace("./", "")
|
||||||
|
|
||||||
// Create a properly formatted self-closing link tag
|
|
||||||
link.tagName("link")
|
link.tagName("link")
|
||||||
.attr("rel", "stylesheet")
|
.attr("rel", "stylesheet")
|
||||||
.attr("type", "text/css")
|
.attr("type", "text/css")
|
||||||
.attr("href", cssHref)
|
.attr("href", cssHref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update font references in CSS and style tags
|
||||||
|
doc.select("style").forEach { style ->
|
||||||
|
val cssContent = style.html()
|
||||||
|
val updatedCss = cssContent.replace(
|
||||||
|
Regex("url\\(['\"]?(.*?)['\"]?\\)"),
|
||||||
|
{ matchResult ->
|
||||||
|
val fontPath = matchResult.groupValues[1]
|
||||||
|
.replace("../", "")
|
||||||
|
.replace("./", "")
|
||||||
|
.substringAfterLast("/")
|
||||||
|
"url('Fonts/$fontPath')"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
style.html(updatedCss)
|
||||||
|
}
|
||||||
|
|
||||||
// Write properly formatted XHTML
|
// Write properly formatted XHTML
|
||||||
val xhtml = """<?xml version="1.0" encoding="UTF-8"?>
|
val xhtml = """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
@@ -170,6 +198,9 @@ class BookStore(private val context: Context) {
|
|||||||
// Set permissions
|
// Set permissions
|
||||||
baseDirectory.walk().forEach { file ->
|
baseDirectory.walk().forEach { file ->
|
||||||
file.setReadable(true, false)
|
file.setReadable(true, false)
|
||||||
|
if (file.isDirectory) {
|
||||||
|
file.setExecutable(true, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "Error extracting EPUB: ${e.message}")
|
Timber.e(e, "Error extracting EPUB: ${e.message}")
|
||||||
|
|||||||
Reference in New Issue
Block a user