SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/MyAppGlideModule.kt

114 lines
3.6 KiB
Kotlin

package jp.juggler.subwaytooter
import android.content.Context
import android.graphics.drawable.PictureDrawable
import androidx.annotation.Nullable
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.ResourceDecoder
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.resource.SimpleResource
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
import com.bumptech.glide.module.AppGlideModule
import com.caverock.androidsvg.SVG
import com.caverock.androidsvg.SVGParseException
import java.io.IOException
import java.io.InputStream
import kotlin.math.min
@GlideModule
class MyAppGlideModule : AppGlideModule() {
companion object{
private val svgSig = "<svg".toByteArray(Charsets.UTF_8)
private fun findBytes(data:ByteArray,dataSize:Int = data.size,key:ByteArray):Int{
fun check(start:Int):Boolean{
for(j in key.indices){
if( data[start+j] != key[j] ) return false
}
return true
}
for(i in 0 .. dataSize - key.size){
if(check(i)) return i
}
return -1
}
}
// Decodes an SVG internal representation from an [InputStream].
inner class SvgDecoder : ResourceDecoder<InputStream, SVG> {
@Throws(IOException::class)
override fun handles(source : InputStream, options : Options) : Boolean {
val size = min(source.available(),1024)
if(size<=0) return false
val buf = ByteArray(size)
val nRead = source.read(buf,0,size)
return -1 != findBytes(buf,nRead, svgSig)
}
@Throws(IOException::class)
override fun decode(
source : InputStream, width : Int, height : Int, options : Options
) : Resource<SVG>? {
try {
val svg = SVG.getFromInputStream(source)
return SimpleResource(svg)
} catch(ex : SVGParseException) {
throw IOException("Cannot load SVG from stream", ex)
}
}
}
// Convert the [SVG]'s internal representation to an Android-compatible one ([Picture]).
class SvgDrawableTranscoder : ResourceTranscoder<SVG, PictureDrawable> {
@Nullable
override fun transcode(
toTranscode : Resource<SVG>, options : Options
) : Resource<PictureDrawable> {
val svg = toTranscode.get()
val picture = svg.renderToPicture()
val drawable = PictureDrawable(picture)
return SimpleResource(drawable)
}
}
// v3との互換性のためにAndroidManifestを読むかどうか(デフォルトtrue)
override fun isManifestParsingEnabled() : Boolean {
return false
}
override fun registerComponents(context : Context, glide : Glide, registry : Registry) {
// デフォルト実装は何もしないらしい
super.registerComponents(context, glide, registry)
// App1を初期化してからOkHttp3Factoryと連動させる
App1.prepare(context.applicationContext,"MyAppGlideModule.registerComponents()")
App1.registerGlideComponents(context, glide, registry)
//SVGデコーダーの追加
registry
.register(SVG::class.java, PictureDrawable::class.java, SvgDrawableTranscoder())
.append(InputStream::class.java, SVG::class.java, SvgDecoder())
}
override fun applyOptions(context : Context, builder : GlideBuilder) {
// デフォルト実装は何もしないらしい
super.applyOptions(context, builder)
// App1を初期化してから色々する
App1.prepare(context.applicationContext,"MyAppGlideModule.applyOptions()")
App1.applyGlideOptions(context, builder)
}
}