|
@@ -1,7 +1,6 @@
|
|
|
package com.kdanmobile.reader.screen.view
|
|
|
|
|
|
import android.content.Context
|
|
|
-import android.content.Intent
|
|
|
import android.graphics.RectF
|
|
|
import android.os.Handler
|
|
|
import android.os.Message
|
|
@@ -13,6 +12,7 @@ import android.view.View
|
|
|
import android.view.inputmethod.EditorInfo
|
|
|
import android.view.inputmethod.InputMethodManager
|
|
|
import android.widget.*
|
|
|
+import com.kdanmobile.kmpdfkit.pdfcommon.TextChar
|
|
|
import com.kdanmobile.kmpdfkit.pdfcommon.TextWord
|
|
|
import com.kdanmobile.reader.R
|
|
|
import com.kdanmobile.reader.screen.adapter.SearchAdapter
|
|
@@ -20,15 +20,15 @@ import com.kdanmobile.reader.screen.handler.PdfInfoHandler
|
|
|
import com.kdanmobile.reader.screen.handler.SearchHandler
|
|
|
import com.kdanmobile.reader.screen.model.SearchResultInfo
|
|
|
import com.kdanmobile.reader.screen.model.SimpleTextWatcher
|
|
|
-import com.kdanmobile.reader.thumb.PdfThumbActivity
|
|
|
import com.kdanmobile.reader.utils.DensityUtil
|
|
|
import io.reactivex.Completable
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
|
import io.reactivex.disposables.Disposable
|
|
|
import io.reactivex.schedulers.Schedulers
|
|
|
import kotlinx.android.synthetic.main.view_search.view.*
|
|
|
+import java.lang.StringBuilder
|
|
|
import java.lang.ref.WeakReference
|
|
|
-import java.util.*
|
|
|
+import kotlin.collections.ArrayList
|
|
|
|
|
|
class SearchView: RelativeLayout, View.OnClickListener, LeftToolbarView {
|
|
|
private var pdfInfoHandler: PdfInfoHandler? = null
|
|
@@ -106,7 +106,7 @@ class SearchView: RelativeLayout, View.OnClickListener, LeftToolbarView {
|
|
|
30 -> {
|
|
|
val position = msg.arg1
|
|
|
val info = view.list[position]
|
|
|
- view.searchHandler?.setSearchResult(info.page, info.keyword, arrayOf(info.rect))
|
|
|
+ view.searchHandler?.setSearchResult(info.page, info.keyword, info.rectList)
|
|
|
view.pdfInfoHandler?.setCurrentPage(view.list[position].page)
|
|
|
}
|
|
|
}
|
|
@@ -297,8 +297,8 @@ class SearchView: RelativeLayout, View.OnClickListener, LeftToolbarView {
|
|
|
if (!isDone) {
|
|
|
val results = searchHandler!!.searchPage(i, searchText)
|
|
|
if (results.isNotEmpty()) {
|
|
|
- val texts = pdfInfoHandler!!.textLines(i)
|
|
|
- val list = dealData(texts, results, searchText, i)
|
|
|
+ val chars = pdfInfoHandler!!.getPageChars(i)
|
|
|
+ val list = dealData(chars, results, searchText, i)
|
|
|
msgHandler?.sendMessage(msgHandler?.obtainMessage(10, list))
|
|
|
if (this.list.size + list.size >= MAX_SEARCH_RESULT) {
|
|
|
isDone = true
|
|
@@ -331,32 +331,78 @@ class SearchView: RelativeLayout, View.OnClickListener, LeftToolbarView {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private fun dealData(texts: Array<Array<TextWord>>?, results: Array<RectF>?, search: String, page: Int): List<SearchResultInfo> {
|
|
|
+ private fun dealData(chars: Array<Array<Array<Array<TextChar>>>>?, results: Array<RectF>?, search: String, page: Int): List<SearchResultInfo> {
|
|
|
val list = ArrayList<SearchResultInfo>()
|
|
|
- if (texts == null || results == null) {
|
|
|
+ if (chars == null || results == null) {
|
|
|
return list
|
|
|
}
|
|
|
- for (i in texts.indices) {
|
|
|
- if (!isDone) {
|
|
|
- val tw = texts[i]
|
|
|
- for (j in tw.indices) {
|
|
|
- if (!isDone) {
|
|
|
- for (k in results.indices) {
|
|
|
- if (!isDone) {
|
|
|
- if (tw[j].contains(results[k])) {
|
|
|
- list.add(SearchResultInfo(page, search, results[k], tw))
|
|
|
- if (this.list.size + list.size >= MAX_SEARCH_RESULT) {
|
|
|
- return list
|
|
|
+ var lastResult = results[0]
|
|
|
+ var currentWord = TextWord()
|
|
|
+ var rectList = ArrayList<RectF>()
|
|
|
+ var resultBlockStartIndex = 0
|
|
|
+ var resultLineStartIndex = 0
|
|
|
+
|
|
|
+ for (blockIndex in 0 until chars.size) {
|
|
|
+ val block = chars[blockIndex]
|
|
|
+ if (block.isEmpty()) continue
|
|
|
+ for (lineIndex in 0 until block.size) {
|
|
|
+ val line = block[lineIndex]
|
|
|
+ if (line.isEmpty()) continue
|
|
|
+ for (word in line) {
|
|
|
+ if (word.isEmpty()) continue
|
|
|
+ for (char in word) {
|
|
|
+
|
|
|
+ fun addSearchResult() {
|
|
|
+ val builder = StringBuilder("")
|
|
|
+ for (bIndex in resultBlockStartIndex .. blockIndex) {
|
|
|
+ for (lIndex in 0 until chars[bIndex].size) {
|
|
|
+ if (bIndex == resultBlockStartIndex && lIndex < resultLineStartIndex) continue
|
|
|
+ if (bIndex == blockIndex && lIndex > lineIndex) break
|
|
|
+ if (chars[bIndex][lIndex].isEmpty()) continue
|
|
|
+ for (w in chars[bIndex][lIndex]) {
|
|
|
+ if (w.isEmpty()) continue
|
|
|
+ for (c in w) {
|
|
|
+ builder.append(c.c)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ list.add(SearchResultInfo(page, search, rectList.toTypedArray(), builder.toString()))
|
|
|
+ currentWord = TextWord()
|
|
|
+ rectList = ArrayList()
|
|
|
+ }
|
|
|
|
|
|
+ var targetResult: RectF? = null
|
|
|
+ for (result in results) {
|
|
|
+ if (result.contains(char)) {
|
|
|
+ targetResult = result
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ if (null != targetResult) {
|
|
|
+ if (currentWord.w.contains(search, true) && targetResult != lastResult) {
|
|
|
|
|
|
+ lastResult = targetResult
|
|
|
+ addSearchResult()
|
|
|
+ if (this.list.size + list.size >= MAX_SEARCH_RESULT) {
|
|
|
+ return list
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (currentWord.isEmpty) {
|
|
|
+ resultBlockStartIndex = blockIndex
|
|
|
+ resultLineStartIndex = lineIndex
|
|
|
+ }
|
|
|
+ currentWord.Add(char)
|
|
|
+ rectList.add(char)
|
|
|
+ } else if (currentWord.w.contains(search, true)) {
|
|
|
+ addSearchResult()
|
|
|
+ if (this.list.size + list.size >= MAX_SEARCH_RESULT) {
|
|
|
+ return list
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
return list
|
|
|
}
|