From 69c3b1aaf02aa922b2da4849ce8da4d32fbcc261 Mon Sep 17 00:00:00 2001 From: ag2s20150909 Date: Wed, 13 Apr 2022 21:23:42 +0800 Subject: [PATCH 01/11] =?UTF-8?q?Cronet=E5=85=B1=E7=94=A8okhttp=E7=9A=84?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E6=B1=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/help/http/cronet/AbsCallBack.kt | 44 ++++++++++----- .../app/help/http/cronet/CronetHelper.kt | 14 ++--- .../app/help/http/cronet/CronetInterceptor.kt | 1 - .../app/help/http/cronet/CronetLoader.kt | 8 ++- .../app/help/http/cronet/NewCallBack.kt | 53 ++++++------------- .../app/help/http/cronet/OldCallback.kt | 39 +++++--------- .../legado/app/utils/ThrowableExtensions.kt | 4 +- 7 files changed, 77 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/cronet/AbsCallBack.kt b/app/src/main/java/io/legado/app/help/http/cronet/AbsCallBack.kt index 56f5b4bfd..0728b1db3 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/AbsCallBack.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/AbsCallBack.kt @@ -2,7 +2,7 @@ package io.legado.app.help.http.cronet import io.legado.app.help.http.okHttpClient import io.legado.app.utils.DebugLog -import io.legado.app.utils.rethrowAsIOException +import io.legado.app.utils.asIOException import okhttp3.* import okhttp3.EventListener import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -27,12 +27,24 @@ abstract class AbsCallBack( var mResponse: Response - var mException: IOException? = null private var followCount = 0 + @Throws(IOException::class) abstract fun waitForDone(urlRequest: UrlRequest): Response + /** + * 当发生错误时,通知子类终止阻塞抛出错误 + * @param error + */ + abstract fun onError(error: IOException) + + /** + * 请求成功后,通知子类结束阻塞,返回response + * @param response + */ + abstract fun onSuccess(response: Response) + override fun onRedirectReceived( request: UrlRequest, @@ -41,10 +53,13 @@ abstract class AbsCallBack( ) { if (followCount > MAX_FOLLOW_COUNT) { request.cancel() - mException = IOException("Too many redirect") + onError(IOException("Too many redirect")) + return } if (mCall.isCanceled()) { - mException = IOException("Request Canceled") + onError(IOException("Request Canceled")) + request.cancel() + return } followCount += 1 val client = okHttpClient @@ -55,7 +70,7 @@ abstract class AbsCallBack( } else if (okHttpClient.followRedirects) { request.followRedirect() } else { - mException = IOException("Too many redirect") + onError(IOException("Too many redirect")) request.cancel() } } @@ -73,7 +88,7 @@ abstract class AbsCallBack( } - @Throws(Exception::class) + @Throws(IOException::class) override fun onReadCompleted( request: UrlRequest, info: UrlResponseInfo, @@ -83,7 +98,7 @@ abstract class AbsCallBack( if (mCall.isCanceled()) { request.cancel() - mException = IOException("Request Canceled") + onError(IOException("Request Canceled")) } byteBuffer.flip() @@ -91,9 +106,9 @@ abstract class AbsCallBack( try { buffer.write(byteBuffer) } catch (e: IOException) { - DebugLog.i(javaClass.name, "IOException during ByteBuffer read. Details: ", e) - mException = IOException("IOException during ByteBuffer read. Details:", e) - throw e + DebugLog.e(javaClass.name, "IOException during ByteBuffer read. Details: ", e) + onError(IOException("IOException during ByteBuffer read. Details:", e)) + return } byteBuffer.clear() request.read(byteBuffer) @@ -108,7 +123,8 @@ abstract class AbsCallBack( buffer.asResponseBody(contentType) val newRequest = originalRequest.newBuilder().url(info.url).build() this.mResponse = this.mResponse.newBuilder().body(responseBody).request(newRequest).build() - DebugLog.i(javaClass.simpleName, "end[${info.negotiatedProtocol}]${info.url}") + onSuccess(this.mResponse) + //DebugLog.i(javaClass.simpleName, "end[${info.negotiatedProtocol}]${info.url}") eventListener?.callEnd(mCall) if (responseCallback != null) { @@ -123,8 +139,8 @@ abstract class AbsCallBack( //UrlResponseInfo可能为null override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) { - DebugLog.i(javaClass.name, error.message.toString()) - mException = error.rethrowAsIOException() + DebugLog.e(javaClass.name, error.message.toString()) + onError(error.asIOException()) this.eventListener?.callFailed(mCall, error) responseCallback?.onFailure(mCall, error) } @@ -132,7 +148,7 @@ abstract class AbsCallBack( override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) { super.onCanceled(request, info) this.eventListener?.callEnd(mCall) - mException = IOException("Cronet Request Canceled") + onError(IOException("Cronet Request Canceled")) } diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt index c3e2ae992..954d2f62f 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt @@ -2,6 +2,7 @@ package io.legado.app.help.http.cronet import io.legado.app.constant.AppLog import io.legado.app.help.config.AppConfig +import io.legado.app.help.http.okHttpClient import io.legado.app.utils.DebugLog import okhttp3.Headers import okhttp3.MediaType @@ -13,11 +14,8 @@ import org.chromium.net.UploadDataProviders import org.chromium.net.UrlRequest import splitties.init.appCtx -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors - -val executor: ExecutorService by lazy { Executors.newCachedThreadPool() } +//val executor: ExecutorService by lazy { Executors.newCachedThreadPool() } val cronetEngine: ExperimentalCronetEngine? by lazy { if (!AppConfig.isGooglePlay) { @@ -48,7 +46,11 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? { val url = request.url.toString() val headers: Headers = request.headers val requestBody = request.body - return cronetEngine?.newUrlRequestBuilder(url, callback, executor)?.apply { + return cronetEngine?.newUrlRequestBuilder( + url, + callback, + okHttpClient.dispatcher.executorService + )?.apply { setHttpMethod(request.method)//设置 allowDirectExecutor() headers.forEachIndexed { index, _ -> @@ -65,7 +67,7 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? { requestBody.writeTo(buffer) setUploadDataProvider( UploadDataProviders.create(buffer.readByteArray()), - executor + okHttpClient.dispatcher.executorService ) } diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt index 124b6163f..74b685128 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt @@ -49,7 +49,6 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { OldCallback(request, call) } buildRequest(request, callBack)?.let { - it.start() return callBack.waitForDone(it) } return null diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt index b06d0719b..34ad3e5f5 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt @@ -268,7 +268,8 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() { return } download = true - executor.execute { + + Coroutine.async { val result = downloadFileIfNotExist(url, downloadTempFile) DebugLog.d(javaClass.simpleName, "download result:$result") //文件md5再次校验 @@ -279,7 +280,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() { downloadTempFile.deleteOnExit() } download = false - return@execute + return@async } DebugLog.d(javaClass.simpleName, "download success, copy to $destSuccessFile") //下载成功拷贝文件 @@ -289,6 +290,9 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() { @Suppress("SameParameterValue") deleteHistoryFile(parentFile!!, null) } +// executor.execute { +// +// } } /** diff --git a/app/src/main/java/io/legado/app/help/http/cronet/NewCallBack.kt b/app/src/main/java/io/legado/app/help/http/cronet/NewCallBack.kt index 6a0d0eeff..7960f54f8 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/NewCallBack.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/NewCallBack.kt @@ -6,11 +6,8 @@ import androidx.annotation.RequiresApi import okhttp3.Call import okhttp3.Request import okhttp3.Response -import org.chromium.net.CronetException import org.chromium.net.UrlRequest -import org.chromium.net.UrlResponseInfo import java.io.IOException -import java.nio.ByteBuffer import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit @@ -21,45 +18,29 @@ class NewCallBack(originalRequest: Request, mCall: Call) : AbsCallBack(originalR @Throws(IOException::class) override fun waitForDone(urlRequest: UrlRequest): Response { - return responseFuture.get(mCall.timeout().timeoutNanos(), TimeUnit.NANOSECONDS) - } - - override fun onRedirectReceived( - request: UrlRequest, - info: UrlResponseInfo, - newLocationUrl: String - ) { - super.onRedirectReceived(request, info, newLocationUrl) - if (mException != null) { - responseFuture.completeExceptionally(mException) + urlRequest.start() + return if (mCall.timeout().timeoutNanos() > 0) { + responseFuture.get(mCall.timeout().timeoutNanos(), TimeUnit.NANOSECONDS) + } else { + return responseFuture.get() } - } - - - override fun onReadCompleted( - request: UrlRequest, - info: UrlResponseInfo, - byteBuffer: ByteBuffer - ) { - super.onReadCompleted(request, info, byteBuffer) - if (mException != null) { - responseFuture.completeExceptionally(mException) - } - } - override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) { - super.onSucceeded(request, info) - responseFuture.complete(mResponse) } - override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) { - super.onFailed(request, info, error) - responseFuture.completeExceptionally(mException) + /** + * 当发生错误时,通知子类终止阻塞抛出错误 + * @param error + */ + override fun onError(error: IOException) { + responseFuture.completeExceptionally(error) } - override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) { - super.onCanceled(request, info) - responseFuture.completeExceptionally(mException) + /** + * 请求成功后,通知子类结束阻塞,返回response + * @param response + */ + override fun onSuccess(response: Response) { + responseFuture.complete(response) } diff --git a/app/src/main/java/io/legado/app/help/http/cronet/OldCallback.kt b/app/src/main/java/io/legado/app/help/http/cronet/OldCallback.kt index 20ad29c60..3107187df 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/OldCallback.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/OldCallback.kt @@ -4,20 +4,19 @@ import android.os.ConditionVariable import okhttp3.Call import okhttp3.Request import okhttp3.Response -import org.chromium.net.CronetException import org.chromium.net.UrlRequest -import org.chromium.net.UrlResponseInfo import java.io.IOException -import java.nio.ByteBuffer class OldCallback(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) { private val mResponseCondition = ConditionVariable() + private var mException: IOException? = null @Throws(IOException::class) override fun waitForDone(urlRequest: UrlRequest): Response { //获取okhttp call的完整请求的超时时间 val timeOutMs: Long = mCall.timeout().timeoutNanos() / 1000000 + urlRequest.start() if (timeOutMs > 0) { mResponseCondition.block(timeOutMs) } else { @@ -32,35 +31,25 @@ class OldCallback(originalRequest: Request, mCall: Call) : AbsCallBack(originalR if (mException != null) { throw mException as IOException } - return this.mResponse + return mResponse } - - override fun onReadCompleted( - request: UrlRequest, - info: UrlResponseInfo, - byteBuffer: ByteBuffer - ) { - super.onReadCompleted(request, info, byteBuffer) - if (mException != null) { - mResponseCondition.open() - } - } - - override fun onSucceeded(request: UrlRequest, info: UrlResponseInfo) { - super.onSucceeded(request, info) + /** + * 当发生错误时,通知子类终止阻塞抛出错误 + * @param error + */ + override fun onError(error: IOException) { + mException = error mResponseCondition.open() } - override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) { - super.onFailed(request, info, error) + /** + * 请求成功后,通知子类结束阻塞,返回response + * @param response + */ + override fun onSuccess(response: Response) { mResponseCondition.open() } - override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) { - super.onCanceled(request, info) - mResponseCondition.open() - } - } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/ThrowableExtensions.kt b/app/src/main/java/io/legado/app/utils/ThrowableExtensions.kt index a5bfaa8fc..088db9b3b 100644 --- a/app/src/main/java/io/legado/app/utils/ThrowableExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/ThrowableExtensions.kt @@ -12,8 +12,8 @@ val Throwable.msg: String } } -fun Throwable.rethrowAsIOException(): IOException { +fun Throwable.asIOException(): IOException { val newException = IOException(this.message) newException.initCause(this) - throw newException + return newException } \ No newline at end of file From cca075230598f91d2eb4319b57918f0c3871e496 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 08:48:45 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/api/controller/BookController.kt | 9 +-- .../io/legado/app/ui/book/read/PhotoDialog.kt | 5 +- .../app/ui/book/read/page/ContentTextView.kt | 17 +++-- .../book/read/page/provider/ImageProvider.kt | 69 ++++++++++--------- 4 files changed, 52 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/io/legado/app/api/controller/BookController.kt b/app/src/main/java/io/legado/app/api/controller/BookController.kt index 30f887ed3..0abc52b35 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookController.kt @@ -21,8 +21,8 @@ import io.legado.app.model.localBook.EpubFile import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.UmdFile import io.legado.app.model.webBook.WebBook -import io.legado.app.utils.* import io.legado.app.ui.book.read.page.provider.ImageProvider +import io.legado.app.utils.* import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import splitties.init.appCtx @@ -87,9 +87,10 @@ object BookController { this.bookSource = appDb.bookSourceDao.getBookSource(book.origin) } this.bookUrl = bookUrl - return ImageProvider.getImage(book, src, bookSource, width, width)?.let { - returnData.setData(it) - } ?: returnData.setErrorMsg("图片加载失败或不存在") + val bitmap = runBlocking { + ImageProvider.getImage(book, src, bookSource, width, width) + } + return returnData.setData(bitmap) } /** diff --git a/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt index c072debc4..635a24c6e 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt @@ -40,16 +40,13 @@ class PhotoDialog() : BaseDialogFragment(R.layout.dialog_photo_view) { arguments?.let { val path = it.getString("path") if (path.isNullOrEmpty()) { - val chapterIndex = it.getInt("chapterIndex") val src = it.getString("src") ReadBook.book?.let { book -> src?.let { execute { ImageProvider.getImage(book, src, ReadBook.bookSource) }.onSuccess { bitmap -> - if (bitmap != null) { - binding.photoView.setImageBitmap(bitmap) - } + binding.photoView.setImageBitmap(bitmap) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 5ba2d0958..40f02f053 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -10,6 +10,7 @@ import io.legado.app.R import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Bookmark import io.legado.app.help.config.ReadBookConfig +import io.legado.app.help.coroutine.Coroutine import io.legado.app.lib.theme.accentColor import io.legado.app.model.ReadBook import io.legado.app.ui.book.read.PhotoDialog @@ -167,13 +168,15 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at isImageLine: Boolean ) { val book = ReadBook.book ?: return - ImageProvider.getImage( - book, - textChar.charData, - ReadBook.bookSource, - (textChar.end - textChar.start).toInt(), - (lineBottom - lineTop).toInt() - )?.let { bitmap -> + Coroutine.async { + ImageProvider.getImage( + book, + textChar.charData, + ReadBook.bookSource, + (textChar.end - textChar.start).toInt(), + (lineBottom - lineTop).toInt() + ) + }.onSuccess { bitmap -> val rectF = if (isImageLine) { RectF(textChar.start, lineTop, textChar.end, lineBottom) } else { diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index 605fc5eff..a0a1bcc36 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -13,8 +13,9 @@ 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.isXml -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withContext import splitties.init.appCtx import java.io.File import java.io.FileOutputStream @@ -66,53 +67,55 @@ object ImageProvider { } } - fun getImage( + suspend 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} 解码失败\n${e.toString()}", e) - if (FileUtils.readText(vFile.absolutePath).isXml()) { - putDebug("${vFile.absolutePath}为xml,自动删除") - vFile.delete() + ): Bitmap { + return withContext(IO) { + val vFile = cacheImage(book, src, bookSource) + try { + @Suppress("BlockingMethodInNonBlockingContext") + ImageLoader.loadBitmap(appCtx, vFile.absolutePath) + .submit(width, height) + .get() + } catch (e: Exception) { + Coroutine.async { + putDebug("${vFile.absolutePath} 解码失败\n$e", e) + if (FileUtils.readText(vFile.absolutePath).isXml()) { + putDebug("${vFile.absolutePath}为xml,自动删除") + vFile.delete() + } } + errorBitmap } - errorBitmap } } - fun getImage( + suspend 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) - .get() - } catch (e: Exception) { - Coroutine.async { - putDebug("${vFile.absolutePath} 解码失败\n${e.toString()}", e) - if (FileUtils.readText(vFile.absolutePath).isXml()) { - putDebug("${vFile.absolutePath}为xml,自动删除") - vFile.delete() + ): Bitmap { + return withContext(IO) { + val vFile = cacheImage(book, src, bookSource) + try { + @Suppress("BlockingMethodInNonBlockingContext") + ImageLoader.loadBitmap(appCtx, vFile.absolutePath) + .submit(ChapterProvider.visibleWidth, ChapterProvider.visibleHeight) + .get() + } catch (e: Exception) { + Coroutine.async { + putDebug("${vFile.absolutePath} 解码失败\n$e", e) + if (FileUtils.readText(vFile.absolutePath).isXml()) { + putDebug("${vFile.absolutePath}为xml,自动删除") + vFile.delete() + } } + errorBitmap } - errorBitmap } } From 4582ca2a85106fb951d4293c3a3e376d676ef0cd Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 09:23:50 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/page/ContentTextView.kt | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 40f02f053..db7c9f546 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -83,43 +83,36 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at private fun drawPage(canvas: Canvas) { var relativeOffset = relativeOffset(0) textPage.textLines.forEach { textLine -> - draw(canvas, textLine, relativeOffset) + draw(canvas, textPage, textLine, relativeOffset) } if (!callBack.isScroll) return //滚动翻页 if (!pageFactory.hasNext()) return - val nextPage = relativePage(1) + val textPage1 = relativePage(1) relativeOffset = relativeOffset(1) - nextPage.textLines.forEach { textLine -> - draw(canvas, textLine, relativeOffset) + textPage1.textLines.forEach { textLine -> + draw(canvas, textPage1, textLine, relativeOffset) } if (!pageFactory.hasNextPlus()) return relativeOffset = relativeOffset(2) if (relativeOffset < ChapterProvider.visibleHeight) { - relativePage(2).textLines.forEach { textLine -> - draw(canvas, textLine, relativeOffset) + val textPage2 = relativePage(2) + textPage2.textLines.forEach { textLine -> + draw(canvas, textPage2, textLine, relativeOffset) } } } private fun draw( canvas: Canvas, + textPage: TextPage, textLine: TextLine, relativeOffset: Float, ) { val lineTop = textLine.lineTop + relativeOffset val lineBase = textLine.lineBase + relativeOffset val lineBottom = textLine.lineBottom + relativeOffset - drawChars( - canvas, - textLine.textChars, - lineTop, - lineBase, - lineBottom, - textLine.isTitle, - textLine.isReadAloud, - textLine.isImage - ) + drawChars(canvas, textPage, textLine, lineTop, lineBase, lineBottom) } /** @@ -127,23 +120,21 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at */ private fun drawChars( canvas: Canvas, - textChars: List, + textPage: TextPage, + textLine: TextLine, lineTop: Float, lineBase: Float, lineBottom: Float, - isTitle: Boolean, - isReadAloud: Boolean, - isImageLine: Boolean ) { - val textPaint = if (isTitle) { + val textPaint = if (textLine.isTitle) { ChapterProvider.titlePaint } else { ChapterProvider.contentPaint } - val textColor = if (isReadAloud) context.accentColor else ReadBookConfig.textColor - textChars.forEach { + val textColor = if (textLine.isReadAloud) context.accentColor else ReadBookConfig.textColor + textLine.textChars.forEach { if (it.isImage) { - drawImage(canvas, it, lineTop, lineBottom, isImageLine) + drawImage(canvas, textPage, textLine, it, lineTop, lineBottom, textLine.isImage) } else { textPaint.color = textColor if (it.isSearchResult) { @@ -162,6 +153,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at */ private fun drawImage( canvas: Canvas, + textPage: TextPage, + textLine: TextLine, textChar: TextChar, lineTop: Float, lineBottom: Float, @@ -177,18 +170,22 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at (lineBottom - lineTop).toInt() ) }.onSuccess { bitmap -> - val rectF = if (isImageLine) { - RectF(textChar.start, lineTop, textChar.end, lineBottom) - } else { - /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ - 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(bitmap, null, rectF, null) - }.onFailure { e -> - context.toastOnUi(e.localizedMessage) + relativeOffset(textPage)?.let { relativeOffset -> + val lineTopNow = textLine.lineTop + relativeOffset + val lineBottomNow = textLine.lineBottom + relativeOffset + val rectF = if (isImageLine) { + RectF(textChar.start, lineTopNow, textChar.end, lineBottomNow) + } else { + /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ + val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height + val div = (lineBottomNow - lineTopNow - h) / 2 + RectF(textChar.start, lineTopNow + div, textChar.end, lineBottomNow - div) + } + kotlin.runCatching { + canvas.drawBitmap(bitmap, null, rectF, null) + }.onFailure { e -> + context.toastOnUi(e.localizedMessage) + } } } } @@ -531,6 +528,15 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } } + private fun relativeOffset(textPage: TextPage): Float? { + return when (textPage) { + this.textPage -> relativeOffset(0) + pageFactory.nextPage -> relativeOffset(1) + pageFactory.nextPlusPage -> relativeOffset(2) + else -> null + } + } + fun relativePage(relativePos: Int): TextPage { return when (relativePos) { 0 -> textPage From ad86c64ad9969e93cb96e69ee2bbb640e9a70b3a Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 10:08:08 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/constant/AppLog.kt | 2 +- app/src/main/java/io/legado/app/data/entities/Book.kt | 9 ++++++++- app/src/main/java/io/legado/app/help/BookHelp.kt | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/AppLog.kt b/app/src/main/java/io/legado/app/constant/AppLog.kt index 75311752a..e4d6c2911 100644 --- a/app/src/main/java/io/legado/app/constant/AppLog.kt +++ b/app/src/main/java/io/legado/app/constant/AppLog.kt @@ -31,7 +31,7 @@ object AppLog { } fun putDebug(message: String?, throwable: Throwable? = null) { - if (AppConfig.recordLog) { + if (AppConfig.recordLog || BuildConfig.DEBUG) { put(message, throwable) } } diff --git a/app/src/main/java/io/legado/app/data/entities/Book.kt b/app/src/main/java/io/legado/app/data/entities/Book.kt index 568778d14..e042d2525 100644 --- a/app/src/main/java/io/legado/app/data/entities/Book.kt +++ b/app/src/main/java/io/legado/app/data/entities/Book.kt @@ -193,7 +193,14 @@ data class Book( } fun getUseReplaceRule(): Boolean { - return config.useReplaceRule ?: AppConfig.replaceEnableDefault + val useReplaceRule = config.useReplaceRule + if (useReplaceRule != null) { + return useReplaceRule + } + if (type == BookType.image) { + return false + } + return AppConfig.replaceEnableDefault } fun setReSegment(reSegment: Boolean) { diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index dfb7b5193..7e68c778c 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -1,5 +1,6 @@ package io.legado.app.help +import io.legado.app.constant.AppLog import io.legado.app.constant.AppPattern import io.legado.app.constant.EventBus import io.legado.app.data.appDb @@ -126,7 +127,7 @@ object BookHelp { ).writeBytes(it) } } catch (e: Exception) { - e.printOnDebug() + AppLog.putDebug("${src}下载错误", e) } finally { downloadImages.remove(src) } From d57250df32914f32d02429278c694b5c6f2de171 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 10:56:41 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/read/PhotoDialog.kt | 15 ++++++----- .../book/read/page/provider/ImageProvider.kt | 25 ------------------- 2 files changed, 7 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt index 635a24c6e..50eb3a9e5 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/PhotoDialog.kt @@ -5,9 +5,10 @@ import android.view.View import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.databinding.DialogPhotoViewBinding +import io.legado.app.help.BookHelp +import io.legado.app.help.glide.ImageLoader import io.legado.app.model.BookCover import io.legado.app.model.ReadBook -import io.legado.app.ui.book.read.page.provider.ImageProvider import io.legado.app.utils.setLayout import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -40,14 +41,12 @@ class PhotoDialog() : BaseDialogFragment(R.layout.dialog_photo_view) { arguments?.let { val path = it.getString("path") if (path.isNullOrEmpty()) { - val src = it.getString("src") ReadBook.book?.let { book -> - src?.let { - execute { - ImageProvider.getImage(book, src, ReadBook.bookSource) - }.onSuccess { bitmap -> - binding.photoView.setImageBitmap(bitmap) - } + it.getString("src")?.let { src -> + val file = BookHelp.getImage(book, src) + ImageLoader.load(requireContext(), file) + .error(R.drawable.image_loading_error) + .into(binding.photoView) } } } else { diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index a0a1bcc36..f39b883b5 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -94,29 +94,4 @@ object ImageProvider { } } - suspend fun getImage( - book: Book, - src: String, - bookSource: BookSource? - ): Bitmap { - return withContext(IO) { - val vFile = cacheImage(book, src, bookSource) - try { - @Suppress("BlockingMethodInNonBlockingContext") - ImageLoader.loadBitmap(appCtx, vFile.absolutePath) - .submit(ChapterProvider.visibleWidth, ChapterProvider.visibleHeight) - .get() - } catch (e: Exception) { - Coroutine.async { - putDebug("${vFile.absolutePath} 解码失败\n$e", e) - if (FileUtils.readText(vFile.absolutePath).isXml()) { - putDebug("${vFile.absolutePath}为xml,自动删除") - vFile.delete() - } - } - errorBitmap - } - } - } - } From 4647c8ecd2f8ba1d7e3403ea6cfca0cfe6fe19c5 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 11:32:53 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/utils/BitmapUtils.kt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/io/legado/app/utils/BitmapUtils.kt b/app/src/main/java/io/legado/app/utils/BitmapUtils.kt index 92bfff174..9fbba9c02 100644 --- a/app/src/main/java/io/legado/app/utils/BitmapUtils.kt +++ b/app/src/main/java/io/legado/app/utils/BitmapUtils.kt @@ -7,7 +7,6 @@ import android.graphics.* import android.graphics.Bitmap.Config import android.view.View import com.google.android.renderscript.Toolkit -import java.io.FileInputStream import java.io.IOException import kotlin.math.* @@ -27,10 +26,9 @@ object BitmapUtils { @Throws(IOException::class) fun decodeBitmap(path: String, width: Int, height: Int): Bitmap { val op = BitmapFactory.Options() - val ips = FileInputStream(path) // inJustDecodeBounds如果设置为true,仅仅返回图片实际的宽和高,宽和高是赋值给opts.outWidth,opts.outHeight; op.inJustDecodeBounds = true - BitmapFactory.decodeFileDescriptor(ips.fd, null, op) + BitmapFactory.decodeFile(path, op) //获取比例大小 val wRatio = ceil((op.outWidth / width).toDouble()).toInt() val hRatio = ceil((op.outHeight / height).toDouble()).toInt() @@ -43,7 +41,7 @@ object BitmapUtils { } } op.inJustDecodeBounds = false - return BitmapFactory.decodeFileDescriptor(ips.fd, null, op) + return BitmapFactory.decodeFile(path, op) } /** 从path中获取Bitmap图片 @@ -53,12 +51,11 @@ object BitmapUtils { @Throws(IOException::class) fun decodeBitmap(path: String): Bitmap { val opts = BitmapFactory.Options() - val ips = FileInputStream(path) opts.inJustDecodeBounds = true - BitmapFactory.decodeFileDescriptor(ips.fd, null, opts) + BitmapFactory.decodeFile(path, opts) opts.inSampleSize = computeSampleSize(opts, -1, 128 * 128) opts.inJustDecodeBounds = false - return BitmapFactory.decodeFileDescriptor(ips.fd, null, opts) + return BitmapFactory.decodeFile(path, opts) } /** From a6e975ee572404b8e2d46f403c1724d0730606a9 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 12:15:04 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E6=AD=A3=E6=96=87=E7=94=A8glide=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E6=9C=89=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/page/ContentTextView.kt | 53 +++++++++---------- .../book/read/page/provider/ImageProvider.kt | 49 +++++++---------- 2 files changed, 42 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index db7c9f546..e66e8e576 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -10,7 +10,6 @@ import io.legado.app.R import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Bookmark import io.legado.app.help.config.ReadBookConfig -import io.legado.app.help.coroutine.Coroutine import io.legado.app.lib.theme.accentColor import io.legado.app.model.ReadBook import io.legado.app.ui.book.read.PhotoDialog @@ -134,7 +133,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at val textColor = if (textLine.isReadAloud) context.accentColor else ReadBookConfig.textColor textLine.textChars.forEach { if (it.isImage) { - drawImage(canvas, textPage, textLine, it, lineTop, lineBottom, textLine.isImage) + drawImage(canvas, textPage, textLine, it, lineTop, lineBottom) } else { textPaint.color = textColor if (it.isSearchResult) { @@ -157,35 +156,31 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at textLine: TextLine, textChar: TextChar, lineTop: Float, - lineBottom: Float, - isImageLine: Boolean + lineBottom: Float ) { val book = ReadBook.book ?: return - Coroutine.async { - ImageProvider.getImage( - book, - textChar.charData, - ReadBook.bookSource, - (textChar.end - textChar.start).toInt(), - (lineBottom - lineTop).toInt() - ) - }.onSuccess { bitmap -> - relativeOffset(textPage)?.let { relativeOffset -> - val lineTopNow = textLine.lineTop + relativeOffset - val lineBottomNow = textLine.lineBottom + relativeOffset - val rectF = if (isImageLine) { - RectF(textChar.start, lineTopNow, textChar.end, lineBottomNow) - } else { - /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ - val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height - val div = (lineBottomNow - lineTopNow - h) / 2 - RectF(textChar.start, lineTopNow + div, textChar.end, lineBottomNow - div) - } - kotlin.runCatching { - canvas.drawBitmap(bitmap, null, rectF, null) - }.onFailure { e -> - context.toastOnUi(e.localizedMessage) - } + val bitmap = ImageProvider.getImage( + book, + textChar.charData, + ReadBook.bookSource, + (textChar.end - textChar.start).toInt(), + (lineBottom - lineTop).toInt() + ) + relativeOffset(textPage)?.let { relativeOffset -> + val lineTopNow = textLine.lineTop + relativeOffset + val lineBottomNow = textLine.lineBottom + relativeOffset + val rectF = if (textLine.isImage) { + RectF(textChar.start, lineTopNow, textChar.end, lineBottomNow) + } else { + /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ + val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height + val div = (lineBottomNow - lineTopNow - h) / 2 + RectF(textChar.start, lineTopNow + div, textChar.end, lineBottomNow - div) + } + kotlin.runCatching { + canvas.drawBitmap(bitmap, null, rectF, null) + }.onFailure { e -> + context.toastOnUi(e.localizedMessage) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index f39b883b5..ae49d1b0a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -9,17 +9,13 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSource import io.legado.app.help.BookHelp 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.BitmapUtils import io.legado.app.utils.FileUtils import io.legado.app.utils.isXml -import kotlinx.coroutines.Dispatchers.IO -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlinx.coroutines.withContext import splitties.init.appCtx import java.io.File import java.io.FileOutputStream -import kotlin.coroutines.resume object ImageProvider { @@ -55,42 +51,33 @@ object ImageProvider { 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)) - } - } + val op = BitmapFactory.Options() + // inJustDecodeBounds如果设置为true,仅仅返回图片实际的宽和高,宽和高是赋值给opts.outWidth,opts.outHeight; + op.inJustDecodeBounds = true + BitmapFactory.decodeFile(file.absolutePath, op) + return Size(op.outWidth, op.outHeight) } - suspend fun getImage( + fun getImage( book: Book, src: String, bookSource: BookSource?, width: Int, height: Int ): Bitmap { - return withContext(IO) { - val vFile = cacheImage(book, src, bookSource) - try { - @Suppress("BlockingMethodInNonBlockingContext") - ImageLoader.loadBitmap(appCtx, vFile.absolutePath) - .submit(width, height) - .get() - } catch (e: Exception) { - Coroutine.async { - putDebug("${vFile.absolutePath} 解码失败\n$e", e) - if (FileUtils.readText(vFile.absolutePath).isXml()) { - putDebug("${vFile.absolutePath}为xml,自动删除") - vFile.delete() - } + val vFile = BookHelp.getImage(book, src) + @Suppress("BlockingMethodInNonBlockingContext") + return try { + BitmapUtils.decodeBitmap(vFile.absolutePath, width, height) + } catch (e: Exception) { + Coroutine.async { + putDebug("${vFile.absolutePath} 解码失败\n$e", e) + if (FileUtils.readText(vFile.absolutePath).isXml()) { + putDebug("${vFile.absolutePath}为xml,自动删除") + vFile.delete() } - errorBitmap } + errorBitmap } } From a99e0876e727b98a5e5bf81b16edd8564078d502 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 12:16:13 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/ui/book/read/page/ContentTextView.kt | 1 - .../io/legado/app/ui/book/read/page/provider/ImageProvider.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index e66e8e576..5c9766534 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -162,7 +162,6 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at val bitmap = ImageProvider.getImage( book, textChar.charData, - ReadBook.bookSource, (textChar.end - textChar.start).toInt(), (lineBottom - lineTop).toInt() ) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index ae49d1b0a..66ea0c78a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -61,7 +61,6 @@ object ImageProvider { fun getImage( book: Book, src: String, - bookSource: BookSource?, width: Int, height: Int ): Bitmap { From 8101cf7ba8da2eb859aca2ab3f7d6ee400f87640 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 12:17:49 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/api/controller/BookController.kt | 3 ++- .../io/legado/app/ui/book/read/page/provider/ImageProvider.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/api/controller/BookController.kt b/app/src/main/java/io/legado/app/api/controller/BookController.kt index 0abc52b35..8771c8225 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookController.kt @@ -88,7 +88,8 @@ object BookController { } this.bookUrl = bookUrl val bitmap = runBlocking { - ImageProvider.getImage(book, src, bookSource, width, width) + ImageProvider.cacheImage(book, src, bookSource) + ImageProvider.getImage(book, src, width, width) } return returnData.setData(bitmap) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index 66ea0c78a..2de937b44 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -23,7 +23,7 @@ object ImageProvider { BitmapFactory.decodeResource(appCtx.resources, R.drawable.image_loading_error) } - private suspend fun cacheImage( + suspend fun cacheImage( book: Book, src: String, bookSource: BookSource? From 30b785fbb9497697cad2e709657a463af18ab7cc Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 12:24:38 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/page/ContentTextView.kt | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 5c9766534..5fd7e37cd 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -150,6 +150,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at /** * 绘制图片 */ + @Suppress("UNUSED_PARAMETER") private fun drawImage( canvas: Canvas, textPage: TextPage, @@ -165,22 +166,18 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at (textChar.end - textChar.start).toInt(), (lineBottom - lineTop).toInt() ) - relativeOffset(textPage)?.let { relativeOffset -> - val lineTopNow = textLine.lineTop + relativeOffset - val lineBottomNow = textLine.lineBottom + relativeOffset - val rectF = if (textLine.isImage) { - RectF(textChar.start, lineTopNow, textChar.end, lineBottomNow) - } else { - /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ - val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height - val div = (lineBottomNow - lineTopNow - h) / 2 - RectF(textChar.start, lineTopNow + div, textChar.end, lineBottomNow - div) - } - kotlin.runCatching { - canvas.drawBitmap(bitmap, null, rectF, null) - }.onFailure { e -> - context.toastOnUi(e.localizedMessage) - } + val rectF = if (textLine.isImage) { + RectF(textChar.start, lineTop, textChar.end, lineBottom) + } else { + /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ + 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(bitmap, null, rectF, null) + }.onFailure { e -> + context.toastOnUi(e.localizedMessage) } } @@ -522,15 +519,6 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } } - private fun relativeOffset(textPage: TextPage): Float? { - return when (textPage) { - this.textPage -> relativeOffset(0) - pageFactory.nextPage -> relativeOffset(1) - pageFactory.nextPlusPage -> relativeOffset(2) - else -> null - } - } - fun relativePage(relativePos: Int): TextPage { return when (relativePos) { 0 -> textPage From cd5e7633dcb2c70df2397c5161890b4a8100d167 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 14 Apr 2022 12:28:25 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/read/page/provider/ChapterProvider.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index d8c821e6d..4b7fb2168 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -208,22 +208,23 @@ object ChapterProvider { imageStyle: String?, ): Float { var durY = y - ImageProvider.getImageSize(book, src, ReadBook.bookSource).let { + val size = ImageProvider.getImageSize(book, src, ReadBook.bookSource) + if (size.width > 0 && size.height > 0) { if (durY > visibleHeight) { textPages.last().height = durY textPages.add(TextPage()) durY = 0f } - var height = it.height - var width = it.width + var height = size.height + var width = size.width when (imageStyle?.toUpperCase(Locale.ROOT)) { Book.imgStyleFull -> { width = visibleWidth - height = it.height * visibleWidth / it.width + height = size.height * visibleWidth / size.width } else -> { - if (it.width > visibleWidth) { - height = it.height * visibleWidth / it.width + if (size.width > visibleWidth) { + height = size.height * visibleWidth / size.width width = visibleWidth } if (height > visibleHeight) {