Unicode絵文字がたくさん並ぶと改行位置の検出がとても遅くなる問題の対策

This commit is contained in:
tateisu 2020-08-25 08:36:32 +09:00
parent be46e5d517
commit 45b6f4ff12
3 changed files with 34 additions and 15 deletions

View File

@ -1091,12 +1091,10 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
return opener.mimeType.toMediaType()
}
@Throws(IOException::class)
override fun contentLength() : Long {
return size
}
@Throws(IOException::class)
override fun writeTo(sink : BufferedSink) {
opener.open().use { inData ->
val tmp = ByteArray(4096)
@ -1449,7 +1447,6 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
val uri : Uri
@Throws(IOException::class)
fun open() : InputStream
fun deleteTempFile()
@ -1502,7 +1499,6 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
override val uri : Uri
get() = uriArg
@Throws(IOException::class)
override fun open() = FileInputStream(temp_file)
override fun deleteTempFile() {
@ -1530,7 +1526,6 @@ class ActAccountSetting : AsyncActivity(), View.OnClickListener,
override val uri : Uri
get() = uriArg
@Throws(IOException::class)
override fun open() : InputStream {
return contentResolver.openInputStream(uri) ?: error("openInputStream returns null")
}

View File

@ -2,6 +2,8 @@ package jp.juggler.subwaytooter.util
import android.content.Context
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.ReplacementSpan
import jp.juggler.subwaytooter.api.entity.CustomEmoji
import jp.juggler.subwaytooter.api.entity.NicoProfileEmoji
import jp.juggler.subwaytooter.api.entity.TootAttachmentLike
@ -25,7 +27,7 @@ class DecodeOptions(
var enlargeEmoji : Float = 1f,
var forceHtml : Boolean = false, // force use HTML instead of Misskey Markdown
var mentionFullAcct : Boolean = false,
var mentions: ArrayList<TootMention>? = null
var mentions : ArrayList<TootMention>? = null
) {
internal fun isMediaAttachment(url : String?) : Boolean {
@ -38,23 +40,46 @@ class DecodeOptions(
}
// OUTPUT
var highlightSound: HighlightWord? = null
var highlightSpeech: HighlightWord? = null
var highlightAny: HighlightWord? = null
var highlightSound : HighlightWord? = null
var highlightSpeech : HighlightWord? = null
var highlightAny : HighlightWord? = null
////////////////////////
// decoder
// AndroidのStaticLayoutはパラグラフ中に絵文字が沢山あると異常に遅いので、絵文字が連続して登場したら改行文字を挿入する
private fun SpannableStringBuilder.workaroundForEmojiLineBreak() : SpannableStringBuilder {
val spans = getSpans(0, length, ReplacementSpan::class.java)
if(spans != null) {
val insertList = ArrayList<Int>()
spans.sortBy { getSpanStart(it) }
var repeatCount = 0
var preEnd : Int? = null
for(span in spans) {
val start = getSpanStart(span)
if(start != preEnd) {
repeatCount = 0
} else if(++ repeatCount >= 12) {
repeatCount = 0
insertList.add(start)
}
preEnd = getSpanEnd(span)
}
// 後ろから順に挿入する
insertList.reversed().forEach { insert(it, "\n") }
}
return this
}
fun decodeHTML(html : String?) =
HTMLDecoder.decodeHTML(this, html)
HTMLDecoder.decodeHTML(this, html).workaroundForEmojiLineBreak()
fun decodeEmoji(s : String?) : Spannable =
EmojiDecoder.decodeEmoji(this, s ?: "")
EmojiDecoder.decodeEmoji(this, s ?: "").workaroundForEmojiLineBreak()
fun decodeEmojiNullable(s : String?) = when(s) {
null -> null
else -> EmojiDecoder.decodeEmoji(this, s)
}
}

View File

@ -2,7 +2,6 @@ package jp.juggler.subwaytooter.util
import android.content.Context
import android.content.SharedPreferences
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.util.SparseBooleanArray
@ -348,7 +347,7 @@ object EmojiDecoder {
private val reNicoru = """\Anicoru\d*\z""".asciiPattern( Pattern.CASE_INSENSITIVE)
private val reHohoemi = """\Ahohoemi\d*\z""".asciiPattern( Pattern.CASE_INSENSITIVE)
fun decodeEmoji(options : DecodeOptions, s : String) : Spannable {
fun decodeEmoji(options : DecodeOptions, s : String) : SpannableStringBuilder {
val builder = EmojiStringBuilder(options)