114 lines
3.6 KiB
Kotlin
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)
|
|
}
|
|
|
|
}
|