Răsfoiți Sursa

Merge branch 'gedoor:master' into master

Xwite 4 ani în urmă
părinte
comite
32faca665a

+ 5 - 4
app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt

@@ -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)
             }

+ 3 - 4
app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt

@@ -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())

+ 78 - 27
app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt

@@ -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)
     }
 
-    fun getImage(
+    private suspend fun cacheImage(
         book: Book,
         src: String,
-        bookSource: BookSource?,
-        onUi: Boolean = false,
-    ): Bitmap? {
+        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 if (!onUi) {
-                runBlocking {
-                    BookHelp.saveImage(bookSource, book, src)
+            } 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?,
+        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)
-                .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
+        }
     }
 
 }