package jp.juggler.subwaytooter.util import android.graphics.RectF import jp.juggler.subwaytooter.api.entity.TootInstance import jp.juggler.subwaytooter.pref.PrefI import jp.juggler.subwaytooter.table.SavedAccount import jp.juggler.subwaytooter.table.daoImageAspect import jp.juggler.util.log.LogCategory import kotlin.math.min enum class EmojiSizeMode { Square, Wide, } fun SavedAccount?.emojiSizeMode(): EmojiSizeMode = when (PrefI.ipEmojiWideMode.value) { PrefI.EMOJI_WIDE_ENABLE -> EmojiSizeMode.Wide PrefI.EMOJI_WIDE_DISABLE -> EmojiSizeMode.Square else /* PrefI.EMOJI_WIDE_AUTO */ -> { val ti = this?.let { TootInstance.getCached(it) } when { ti == null -> EmojiSizeMode.Square ti.isMisskey || !ti.fedibirdCapabilities.isNullOrEmpty() -> EmojiSizeMode.Wide else -> EmojiSizeMode.Square } } } /** * カスタム絵文字のSpanやビューの描画領域やサイズを計算する */ class EmojiImageRect( private val sizeMode: EmojiSizeMode, val scale: Float = 1f, val scaleRatio: Float = 1f, val descentRatio: Float = 0f, val maxEmojiWidth: Float, // val layout: (Int, Int) -> Unit, ) { companion object { private val log = LogCategory("EmojiImageRect") val imageAspectCache = HashMap() } val rectDst = RectF() var emojiWidth = 0f var emojiHeight = 0f var transY = 0f /** * lastAspect に基づいて rectDst と transY を更新する */ fun updateRect( url: String, aspectArg: Float? = null, textSize: Float, baseline: Float, ) { // テキストサイズをスケーリングした基本高さ val h = textSize * scaleRatio * scale // ベースラインから上下方向にずらすオフセット val cDescent = emojiHeight * descentRatio this.transY = baseline - emojiHeight + cDescent updateRect(url, aspectArg, h) } fun updateRect( url: String, aspectArg: Float? = null, h: Float, ) { this.emojiHeight = h val aspect = when (aspectArg) { null -> { imageAspectCache[url] ?: daoImageAspect.load(url)?.also { imageAspectCache[url] = it } ?: 1f } else -> { if (url.isNotEmpty()) imageAspectCache[url] = aspectArg aspectArg } }.takeIf { it > 0f } ?: 1f when { // 横長画像で、それを許可するモード aspect > 1.36f && sizeMode == EmojiSizeMode.Wide -> { // 絵文字のアスペクト比から描画範囲の幅と高さを決める val dstWidth = min(maxEmojiWidth, aspect * emojiHeight) val dstHeight = dstWidth / aspect val dstX = 0f val dstY = (emojiHeight - dstHeight) / 2f rectDst.set(dstX, dstY, dstX + dstWidth, dstY + dstHeight) emojiWidth = dstWidth } else -> { // 絵文字のアスペクト比から描画範囲の幅と高さを決める val dstWidth: Float val dstHeight: Float if (aspect >= 1f) { dstWidth = emojiHeight dstHeight = emojiHeight / aspect } else { dstHeight = emojiHeight dstWidth = emojiHeight * aspect } val dstX = (emojiHeight - dstWidth) / 2f val dstY = (emojiHeight - dstHeight) / 2f rectDst.set(dstX, dstY, dstX + dstWidth, dstY + dstHeight) emojiWidth = emojiHeight } } } }