diff --git a/app/build.gradle b/app/build.gradle index 8c46ef88..f04ce1ad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,6 +66,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation "androidx.recyclerview:recyclerview:1.1.0" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' + implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.github.bumptech.glide:glide:4.11.0' implementation 'com.github.bumptech.glide:okhttp3-integration:4.11.0' implementation 'com.google.android.material:material:1.3.0' diff --git a/app/src/main/java/io/github/lsposed/manager/util/AppModule.java b/app/src/main/java/io/github/lsposed/manager/util/AppModule.java index 0a30b886..f8fb7baa 100644 --- a/app/src/main/java/io/github/lsposed/manager/util/AppModule.java +++ b/app/src/main/java/io/github/lsposed/manager/util/AppModule.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.graphics.Bitmap; import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.PictureDrawable; import androidx.annotation.NonNull; @@ -13,12 +14,14 @@ import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.module.AppGlideModule; +import com.caverock.androidsvg.SVG; import java.io.InputStream; import io.github.lsposed.manager.App; import io.github.lsposed.manager.R; - +import io.github.lsposed.manager.util.svg.SvgDecoder; +import io.github.lsposed.manager.util.svg.SvgDrawableTranscoder; import me.zhanghai.android.appiconloader.glide.AppIconModelLoader; @GlideModule @@ -29,7 +32,9 @@ public class AppModule extends AppGlideModule { registry.prepend(PackageInfo.class, Bitmap.class, new AppIconModelLoader.Factory(iconSize, context.getApplicationInfo().loadIcon(context.getPackageManager()) instanceof AdaptiveIconDrawable, context)); OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(App.getOkHttpClient()); - registry.prepend(GlideUrl.class, InputStream.class, factory); + registry.replace(GlideUrl.class, InputStream.class, factory); + registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder()) + .append(InputStream.class, SVG.class, new SvgDecoder()); } } diff --git a/app/src/main/java/io/github/lsposed/manager/util/svg/SvgDecoder.java b/app/src/main/java/io/github/lsposed/manager/util/svg/SvgDecoder.java new file mode 100644 index 00000000..5979f6eb --- /dev/null +++ b/app/src/main/java/io/github/lsposed/manager/util/svg/SvgDecoder.java @@ -0,0 +1,44 @@ +package io.github.lsposed.manager.util.svg; + +import androidx.annotation.NonNull; + +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.caverock.androidsvg.SVG; +import com.caverock.androidsvg.SVGParseException; + +import java.io.IOException; +import java.io.InputStream; + +import static com.bumptech.glide.request.target.Target.SIZE_ORIGINAL; + +/** + * Decodes an SVG internal representation from an {@link InputStream}. + */ +public class SvgDecoder implements ResourceDecoder { + + @Override + public boolean handles(@NonNull InputStream source, @NonNull Options options) { + // TODO: Can we tell? + return true; + } + + public Resource decode( + @NonNull InputStream source, int width, int height, @NonNull Options options) + throws IOException { + try { + SVG svg = SVG.getFromInputStream(source); + if (width != SIZE_ORIGINAL) { + svg.setDocumentWidth(width); + } + if (height != SIZE_ORIGINAL) { + svg.setDocumentHeight(height); + } + return new SimpleResource<>(svg); + } catch (SVGParseException ex) { + throw new IOException("Cannot load SVG from stream", ex); + } + } +} diff --git a/app/src/main/java/io/github/lsposed/manager/util/svg/SvgDrawableTranscoder.java b/app/src/main/java/io/github/lsposed/manager/util/svg/SvgDrawableTranscoder.java new file mode 100644 index 00000000..0d007507 --- /dev/null +++ b/app/src/main/java/io/github/lsposed/manager/util/svg/SvgDrawableTranscoder.java @@ -0,0 +1,28 @@ +package io.github.lsposed.manager.util.svg; + +import android.graphics.Picture; +import android.graphics.drawable.PictureDrawable; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.load.Options; +import com.bumptech.glide.load.engine.Resource; +import com.bumptech.glide.load.resource.SimpleResource; +import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; +import com.caverock.androidsvg.SVG; + +/** + * Convert the {@link SVG}'s internal representation to an Android-compatible one ({@link Picture}). + */ +public class SvgDrawableTranscoder implements ResourceTranscoder { + @Nullable + @Override + public Resource transcode( + @NonNull Resource toTranscode, @NonNull Options options) { + SVG svg = toTranscode.get(); + Picture picture = svg.renderToPicture(); + PictureDrawable drawable = new PictureDrawable(picture); + return new SimpleResource<>(drawable); + } +}