Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Readium version #261

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README-CHANGES.xml
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@
<c:change date="2022-04-29T00:00:00+00:00" summary="Fixed &quot;Unable to initialize audio engine&quot; error playing some audio books."/>
</c:changes>
</c:release>
<c:release date="2023-11-16T10:37:09+00:00" is-open="true" ticket-system="org.lyrasis.jira" version="1.8.0">
<c:release date="2023-11-17T00:00:00+00:00" is-open="false" ticket-system="org.lyrasis.jira" version="1.8.0">
<c:changes>
<c:change date="2023-11-07T00:00:00+00:00" summary="Book sample buttons are no longer displayed for loaned books.">
<c:tickets>
Expand Down Expand Up @@ -400,13 +400,18 @@
</c:tickets>
</c:change>
<c:change date="2023-11-10T00:00:00+00:00" summary="Removed profile idle timer."/>
<c:change date="2023-11-16T10:37:09+00:00" summary="Eliminate duplicate bookmark display.">
<c:change date="2023-11-16T00:00:00+00:00" summary="Eliminate duplicate bookmark display.">
<c:tickets>
<c:ticket id="PP-727"/>
</c:tickets>
</c:change>
</c:changes>
</c:release>
<c:release date="2023-11-17T18:17:09+00:00" is-open="true" ticket-system="org.lyrasis.jira" version="1.9.0">
<c:changes>
<c:change date="2023-11-17T18:17:09+00:00" summary="Updated Readium version."/>
</c:changes>
</c:release>
</c:releases>
<c:ticket-systems>
<c:ticket-system default="true" id="org.lyrasis.jira" url="https://ebce-lyrasis.atlassian.net/browse/"/>
Expand Down
2 changes: 0 additions & 2 deletions simplified-app-palace/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,6 @@ dependencies {
implementation(libs.kotlinx.datetime)
implementation(libs.logback.android)
implementation(libs.moznion.uribuildertiny)
implementation(libs.nano.httpd)
implementation(libs.nano.httpd.nanolets)
implementation(libs.nypl.readium)
implementation(libs.okhttp3)
implementation(libs.okio)
Expand Down
2 changes: 0 additions & 2 deletions simplified-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,6 @@ val dependencyObjects = listOf(
libs.mockito.android,
libs.mockito.core,
libs.mockito.kotlin,
libs.nano.httpd,
libs.nano.httpd.nanolets,
libs.nypl.readium,
libs.objenesis,
libs.okhttp3,
Expand Down
2 changes: 0 additions & 2 deletions simplified-viewer-pdf-pdfjs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ dependencies {
implementation(libs.kotlin.reflect)
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines)
implementation(libs.nano.httpd)
implementation(libs.nano.httpd.nanolets)
implementation(libs.palace.drm.core)
implementation(libs.palace.theme)
implementation(libs.pdfium.android)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.librarysimplified.viewer.pdf.pdfjs
import android.content.Context
import android.net.Uri
import kotlinx.coroutines.runBlocking
import org.librarysimplified.viewer.pdf.pdfjs.factory.PdfDocumentFactory
import org.nanohttpd.protocols.http.IHTTPSession
import org.nanohttpd.protocols.http.response.Response
import org.nanohttpd.protocols.http.response.Status
Expand Down Expand Up @@ -53,6 +54,7 @@ class PdfServer private constructor(
),
PdfParser(
context = context,
pdfFactory = PdfDocumentFactory(context)
)
),
contentProtections = contentProtections,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package org.librarysimplified.viewer.pdf.pdfjs.factory

import android.content.Context
import android.os.ParcelFileDescriptor
import com.shockwave.pdfium.PdfDocument
import com.shockwave.pdfium.PdfiumCore
import org.readium.r2.shared.PdfSupport
import org.readium.r2.shared.extensions.md5
import org.readium.r2.shared.extensions.tryOrNull
import org.readium.r2.shared.fetcher.Resource
import org.readium.r2.shared.util.pdf.PdfDocumentFactory
import org.readium.r2.shared.util.use
import java.io.File
import kotlin.reflect.KClass

@OptIn(PdfSupport::class)
class PdfDocumentFactory(context: Context) : PdfDocumentFactory<PdfReaderDocument> {
override val documentType: KClass<PdfReaderDocument> = PdfReaderDocument::class

private val core by lazy { PdfiumCore(context.applicationContext) }

override suspend fun open(file: File, password: String?): PdfReaderDocument {
return core.fromFile(file, password)
}

override suspend fun open(resource: Resource, password: String?): PdfReaderDocument {
return resource.openAsFile(password) ?: resource.openBytes(password)
}

private suspend fun Resource.openAsFile(password: String?): PdfReaderDocument? {
return file?.let {
tryOrNull { open(it, password) }
}
}

private suspend fun Resource.openBytes(password: String?): PdfReaderDocument {
return use {
core.fromBytes(read().getOrThrow(), password)
}
}

private fun PdfiumCore.fromFile(file: File, password: String?): PdfReaderDocument {
return fromDocument(
newDocument(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY), password),
identifier = file.md5()
)
}

/**
* Creates a [PdfReaderDocument] from raw bytes.
*/
private fun PdfiumCore.fromBytes(bytes: ByteArray, password: String?): PdfReaderDocument {
return fromDocument(
newDocument(bytes, password),
identifier = bytes.md5()
)
}

private fun PdfiumCore.fromDocument(
document: PdfDocument,
identifier: String?
): PdfReaderDocument {
return PdfReaderDocument(
core = this,
document = document,
identifier = identifier,
pageCount = getPageCount(document)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.librarysimplified.viewer.pdf.pdfjs.factory

import android.content.Context
import android.graphics.Bitmap
import com.shockwave.pdfium.PdfiumCore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.readium.r2.shared.PdfSupport
import org.readium.r2.shared.util.pdf.PdfDocument
import org.slf4j.LoggerFactory
import com.shockwave.pdfium.PdfDocument as PdfiumDocument

class PdfReaderDocument(
val core: PdfiumCore,
val document: PdfiumDocument,
override val identifier: String?,
override val pageCount: Int
) : PdfDocument {

override val title: String?
get() = metadata.title

override val author: String?
get() = metadata.author

override val subject: String?
get() = metadata.subject

override val keywords: List<String>
get() = metadata.keywords
.split(",")
.map { it.trim() }
.filter { it.isNotEmpty() }

private val logger = LoggerFactory.getLogger(PdfReaderDocument::class.java)
private val metadata: PdfiumDocument.Meta by lazy { core.getDocumentMeta(document) }

override suspend fun cover(context: Context): Bitmap? {
return withContext(Dispatchers.IO) {
try {
core.openPage(document, 0)
val width = core.getPageWidth(document, 0)
val height = core.getPageHeight(document, 0)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
core.renderPageBitmap(document, bitmap, 0, 0, 0, width, height, false)
bitmap
} catch (e: Exception) {
logger.error("Error rendering page: ", e)
null
} catch (e: OutOfMemoryError) {
logger.error("Error rendering page: ", e)
null
}
}
}

override val outline: List<PdfDocument.OutlineNode> by lazy {
core.getTableOfContents(document).map { it.toOutlineNode() }
}

override suspend fun close() {
// do nothing
}

@OptIn(PdfSupport::class)
private fun PdfiumDocument.Bookmark.toOutlineNode(): PdfDocument.OutlineNode {
return PdfDocument.OutlineNode(
title = title,
pageNumber = pageIdx.toInt() + 1,
children = children.map { it.toOutlineNode() },
)
}
}