Merge branch 'gedoor:master' into master
This commit is contained in:
@@ -171,18 +171,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
book,
|
||||
textChar.charData,
|
||||
ReadBook.bookSource,
|
||||
true
|
||||
)?.let {
|
||||
(textChar.end - textChar.start).toInt(),
|
||||
(lineBottom - lineTop).toInt()
|
||||
)?.let { bitmap ->
|
||||
val rectF = if (isImageLine) {
|
||||
RectF(textChar.start, lineTop, textChar.end, lineBottom)
|
||||
} else {
|
||||
/*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/
|
||||
val h = (textChar.end - textChar.start) / it.width * it.height
|
||||
val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height
|
||||
val div = (lineBottom - lineTop - h) / 2
|
||||
RectF(textChar.start, lineTop + div, textChar.end, lineBottom - div)
|
||||
}
|
||||
kotlin.runCatching {
|
||||
canvas.drawBitmap(it, null, rectF, null)
|
||||
canvas.drawBitmap(bitmap, null, rectF, null)
|
||||
}.onFailure { e ->
|
||||
context.toastOnUi(e.localizedMessage)
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ object ChapterProvider {
|
||||
/**
|
||||
* 获取拆分完的章节数据
|
||||
*/
|
||||
fun getTextChapter(
|
||||
suspend fun getTextChapter(
|
||||
book: Book,
|
||||
bookChapter: BookChapter,
|
||||
displayTitle: String,
|
||||
@@ -136,7 +136,6 @@ object ChapterProvider {
|
||||
while (matcher.find()) {
|
||||
matcher.group(1)?.let { src ->
|
||||
srcList.add(src)
|
||||
ImageProvider.getImage(book, src, ReadBook.bookSource)
|
||||
matcher.appendReplacement(sb, srcReplaceChar)
|
||||
}
|
||||
}
|
||||
@@ -200,7 +199,7 @@ object ChapterProvider {
|
||||
)
|
||||
}
|
||||
|
||||
private fun setTypeImage(
|
||||
private suspend fun setTypeImage(
|
||||
book: Book,
|
||||
src: String,
|
||||
x: Int,
|
||||
@@ -209,7 +208,7 @@ object ChapterProvider {
|
||||
imageStyle: String?,
|
||||
): Float {
|
||||
var durY = y
|
||||
ImageProvider.getImage(book, src, ReadBook.bookSource)?.let {
|
||||
ImageProvider.getImageSize(book, src, ReadBook.bookSource).let {
|
||||
if (durY > visibleHeight) {
|
||||
textPages.last().height = durY
|
||||
textPages.add(TextPage())
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.legado.app.ui.book.read.page.provider
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Size
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.AppLog.putDebug
|
||||
import io.legado.app.data.entities.Book
|
||||
@@ -10,59 +12,108 @@ import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.help.glide.ImageLoader
|
||||
import io.legado.app.model.localBook.EpubFile
|
||||
import io.legado.app.utils.FileUtils
|
||||
import io.legado.app.utils.BitmapUtils
|
||||
import io.legado.app.utils.isXml
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
object ImageProvider {
|
||||
|
||||
private val errorBitmap: Bitmap? by lazy {
|
||||
BitmapUtils.decodeBitmap(
|
||||
appCtx,
|
||||
R.drawable.image_loading_error,
|
||||
ChapterProvider.visibleWidth,
|
||||
ChapterProvider.visibleHeight
|
||||
)
|
||||
private val errorBitmap: Bitmap by lazy {
|
||||
BitmapFactory.decodeResource(appCtx.resources, R.drawable.image_loading_error)
|
||||
}
|
||||
|
||||
private suspend fun cacheImage(
|
||||
book: Book,
|
||||
src: String,
|
||||
bookSource: BookSource?
|
||||
): File {
|
||||
val vFile = BookHelp.getImage(book, src)
|
||||
if (!vFile.exists()) {
|
||||
if (book.isEpub()) {
|
||||
EpubFile.getImage(book, src)?.use { input ->
|
||||
val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath)
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
FileOutputStream(newFile).use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BookHelp.saveImage(bookSource, book, src)
|
||||
}
|
||||
}
|
||||
return vFile
|
||||
}
|
||||
|
||||
suspend fun getImageSize(
|
||||
book: Book,
|
||||
src: String,
|
||||
bookSource: BookSource?
|
||||
): Size {
|
||||
val file = cacheImage(book, src, bookSource)
|
||||
return suspendCancellableCoroutine { block ->
|
||||
kotlin.runCatching {
|
||||
ImageLoader.loadBitmap(appCtx, file.absolutePath).submit()
|
||||
.getSize { width, height ->
|
||||
block.resume(Size(width, height))
|
||||
}
|
||||
}.onFailure {
|
||||
block.resume(Size(errorBitmap.width, errorBitmap.height))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getImage(
|
||||
book: Book,
|
||||
src: String,
|
||||
bookSource: BookSource?,
|
||||
onUi: Boolean = false,
|
||||
width: Int,
|
||||
height: Int
|
||||
): Bitmap? {
|
||||
val vFile = BookHelp.getImage(book, src)
|
||||
if (!vFile.exists()) {
|
||||
if (book.isEpub()) {
|
||||
EpubFile.getImage(book, src)?.use { input ->
|
||||
val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath)
|
||||
FileOutputStream(newFile).use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
} else if (!onUi) {
|
||||
runBlocking {
|
||||
BookHelp.saveImage(bookSource, book, src)
|
||||
val vFile = runBlocking {
|
||||
cacheImage(book, src, bookSource)
|
||||
}
|
||||
return try {
|
||||
ImageLoader.loadBitmap(appCtx, vFile.absolutePath)
|
||||
.submit(width, height)
|
||||
.get()
|
||||
} catch (e: Exception) {
|
||||
Coroutine.async {
|
||||
putDebug("${vFile.absolutePath} 解码失败", e)
|
||||
if (FileUtils.readText(vFile.absolutePath).isXml()) {
|
||||
putDebug("${vFile.absolutePath}为xml,自动删除")
|
||||
vFile.delete()
|
||||
}
|
||||
}
|
||||
errorBitmap
|
||||
}
|
||||
return try {
|
||||
}
|
||||
|
||||
fun getImage(
|
||||
book: Book,
|
||||
src: String,
|
||||
bookSource: BookSource?
|
||||
): Bitmap? {
|
||||
val vFile = runBlocking {
|
||||
cacheImage(book, src, bookSource)
|
||||
}
|
||||
return try {
|
||||
ImageLoader.loadBitmap(appCtx, vFile.absolutePath)
|
||||
.submit(ChapterProvider.visibleWidth,ChapterProvider.visibleHeight)
|
||||
.submit(ChapterProvider.visibleWidth, ChapterProvider.visibleHeight)
|
||||
.get()
|
||||
} catch (e: Exception) {
|
||||
Coroutine.async {
|
||||
putDebug("${vFile.absolutePath} 解码失败", e)
|
||||
if (FileUtils.readText(vFile.absolutePath).isXml()) {
|
||||
putDebug("${vFile.absolutePath}为xml,自动删除")
|
||||
vFile.delete()
|
||||
}
|
||||
}
|
||||
errorBitmap
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Coroutine.async {
|
||||
putDebug("${vFile.absolutePath} 解码失败", e)
|
||||
if (FileUtils.readText(vFile.absolutePath).isXml()) {
|
||||
putDebug("${vFile.absolutePath}为xml,自动删除")
|
||||
vFile.delete()
|
||||
}
|
||||
}
|
||||
errorBitmap
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user