Merge branch 'gedoor:master' into master

pull/1778/head
Xwite 3 years ago committed by GitHub
commit cc48698454
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  2. 7
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  3. 105
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt

@ -171,18 +171,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
book, book,
textChar.charData, textChar.charData,
ReadBook.bookSource, ReadBook.bookSource,
true (textChar.end - textChar.start).toInt(),
)?.let { (lineBottom - lineTop).toInt()
)?.let { bitmap ->
val rectF = if (isImageLine) { val rectF = if (isImageLine) {
RectF(textChar.start, lineTop, textChar.end, lineBottom) RectF(textChar.start, lineTop, textChar.end, lineBottom)
} else { } else {
/*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ /*以宽度为基准保持图片的原始比例叠加,当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 val div = (lineBottom - lineTop - h) / 2
RectF(textChar.start, lineTop + div, textChar.end, lineBottom - div) RectF(textChar.start, lineTop + div, textChar.end, lineBottom - div)
} }
kotlin.runCatching { kotlin.runCatching {
canvas.drawBitmap(it, null, rectF, null) canvas.drawBitmap(bitmap, null, rectF, null)
}.onFailure { e -> }.onFailure { e ->
context.toastOnUi(e.localizedMessage) context.toastOnUi(e.localizedMessage)
} }

@ -101,7 +101,7 @@ object ChapterProvider {
/** /**
* 获取拆分完的章节数据 * 获取拆分完的章节数据
*/ */
fun getTextChapter( suspend fun getTextChapter(
book: Book, book: Book,
bookChapter: BookChapter, bookChapter: BookChapter,
displayTitle: String, displayTitle: String,
@ -136,7 +136,6 @@ object ChapterProvider {
while (matcher.find()) { while (matcher.find()) {
matcher.group(1)?.let { src -> matcher.group(1)?.let { src ->
srcList.add(src) srcList.add(src)
ImageProvider.getImage(book, src, ReadBook.bookSource)
matcher.appendReplacement(sb, srcReplaceChar) matcher.appendReplacement(sb, srcReplaceChar)
} }
} }
@ -200,7 +199,7 @@ object ChapterProvider {
) )
} }
private fun setTypeImage( private suspend fun setTypeImage(
book: Book, book: Book,
src: String, src: String,
x: Int, x: Int,
@ -209,7 +208,7 @@ object ChapterProvider {
imageStyle: String?, imageStyle: String?,
): Float { ): Float {
var durY = y var durY = y
ImageProvider.getImage(book, src, ReadBook.bookSource)?.let { ImageProvider.getImageSize(book, src, ReadBook.bookSource).let {
if (durY > visibleHeight) { if (durY > visibleHeight) {
textPages.last().height = durY textPages.last().height = durY
textPages.add(TextPage()) textPages.add(TextPage())

@ -1,6 +1,8 @@
package io.legado.app.ui.book.read.page.provider package io.legado.app.ui.book.read.page.provider
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Size
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.AppLog.putDebug import io.legado.app.constant.AppLog.putDebug
import io.legado.app.data.entities.Book 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.help.glide.ImageLoader
import io.legado.app.model.localBook.EpubFile import io.legado.app.model.localBook.EpubFile
import io.legado.app.utils.FileUtils import io.legado.app.utils.FileUtils
import io.legado.app.utils.BitmapUtils
import io.legado.app.utils.isXml import io.legado.app.utils.isXml
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import kotlin.coroutines.resume
object ImageProvider { object ImageProvider {
private val errorBitmap: Bitmap? by lazy { private val errorBitmap: Bitmap by lazy {
BitmapUtils.decodeBitmap( BitmapFactory.decodeResource(appCtx.resources, R.drawable.image_loading_error)
appCtx,
R.drawable.image_loading_error,
ChapterProvider.visibleWidth,
ChapterProvider.visibleHeight
)
} }
fun getImage( private suspend fun cacheImage(
book: Book, book: Book,
src: String, src: String,
bookSource: BookSource?, bookSource: BookSource?
onUi: Boolean = false, ): File {
): Bitmap? {
val vFile = BookHelp.getImage(book, src) val vFile = BookHelp.getImage(book, src)
if (!vFile.exists()) { if (!vFile.exists()) {
if (book.isEpub()) { if (book.isEpub()) {
EpubFile.getImage(book, src)?.use { input -> EpubFile.getImage(book, src)?.use { input ->
val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath) val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath)
@Suppress("BlockingMethodInNonBlockingContext")
FileOutputStream(newFile).use { output -> FileOutputStream(newFile).use { output ->
input.copyTo(output) input.copyTo(output)
} }
} }
} else if (!onUi) { } else {
runBlocking { BookHelp.saveImage(bookSource, book, src)
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?,
width: Int,
height: Int
): Bitmap? {
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
}
}
fun getImage(
book: Book,
src: String,
bookSource: BookSource?
): Bitmap? {
val vFile = runBlocking {
cacheImage(book, src, bookSource)
} }
return try { return try {
ImageLoader.loadBitmap(appCtx, vFile.absolutePath) ImageLoader.loadBitmap(appCtx, vFile.absolutePath)
.submit(ChapterProvider.visibleWidth,ChapterProvider.visibleHeight) .submit(ChapterProvider.visibleWidth, ChapterProvider.visibleHeight)
.get() .get()
} catch (e: Exception) { } catch (e: Exception) {
Coroutine.async { Coroutine.async {
putDebug("${vFile.absolutePath} 解码失败", e) putDebug("${vFile.absolutePath} 解码失败", e)
if (FileUtils.readText(vFile.absolutePath).isXml()) { if (FileUtils.readText(vFile.absolutePath).isXml()) {
putDebug("${vFile.absolutePath}为xml,自动删除") putDebug("${vFile.absolutePath}为xml,自动删除")
vFile.delete() vFile.delete()
} }
} }
errorBitmap errorBitmap
} }
} }
} }

Loading…
Cancel
Save