From 95ef38f464ead085f048139ee4e6f5b2e3fc223c Mon Sep 17 00:00:00 2001 From: M66B Date: Sun, 6 Sep 2020 18:12:17 +0200 Subject: [PATCH] Delegate image scaling to image helper --- .../eu/faircode/email/ActivitySignature.java | 4 +- .../eu/faircode/email/AdapterMessage.java | 38 ++++----------- .../eu/faircode/email/EditTextCompose.java | 2 +- .../eu/faircode/email/FragmentAnswer.java | 4 +- .../eu/faircode/email/FragmentCompose.java | 10 ++-- .../eu/faircode/email/FragmentMessages.java | 16 ------- .../java/eu/faircode/email/ImageHelper.java | 47 ++++++++++++------- 7 files changed, 47 insertions(+), 74 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/ActivitySignature.java b/app/src/main/java/eu/faircode/email/ActivitySignature.java index f8f6a58131..8ef33b5d0c 100644 --- a/app/src/main/java/eu/faircode/email/ActivitySignature.java +++ b/app/src/main/java/eu/faircode/email/ActivitySignature.java @@ -193,7 +193,7 @@ public class ActivitySignature extends ActivityBase { etText.setText(HtmlHelper.fromHtml(html, false, new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { - return ImageHelper.decodeImage(ActivitySignature.this, -1, source, true, 0, etText); + return ImageHelper.decodeImage(ActivitySignature.this, -1, source, true, 0, 1.0f, etText); } }, null, this)); dirty = false; @@ -300,7 +300,7 @@ public class ActivitySignature extends ActivityBase { SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText()); ssb.insert(start, " \uFFFC"); // Object replacement character String source = uri.toString(); - Drawable d = ImageHelper.decodeImage(this, -1, source, true, 0, etText); + Drawable d = ImageHelper.decodeImage(this, -1, source, true, 0, 1.0f, etText); ImageSpan is = new ImageSpan(d, source); ssb.setSpan(is, start + 1, start + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); etText.setText(ssb); diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 34f0dd1dae..e336faaa71 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -475,7 +475,6 @@ public class AdapterMessage extends RecyclerView.Adapter> drawableSize = new HashMap<>(); private SimpleTask taskContactInfo; @@ -775,21 +774,11 @@ public class AdapterMessage extends RecyclerView.Adapter p = drawableSize.get(d); - if (p == null || p.first == 0) - continue; - - float s = Math.min(bw / (float) p.first, scale); - properties.setScale(message.id, s); - - int w = Math.round(p.first * s); - int h = Math.round(p.second * s); - d.setBounds(0, 0, w, h); - } + for (ImageSpan img : spanned.getSpans(0, spanned.length(), ImageSpan.class)) { + Drawable d = img.getDrawable(); + ImageHelper.AnnotatedSource a = new ImageHelper.AnnotatedSource(img.getSource()); + ImageHelper.fitDrawable(d, a, scale, tvBody); + } // Feedback String perc = Math.round(scale * 100) + " %"; @@ -1970,7 +1959,8 @@ public class AdapterMessage extends RecyclerView.Adapter() { @Override @@ -2145,17 +2135,10 @@ public class AdapterMessage extends RecyclerView.Adapter> map = new HashMap<>(); SpannableStringBuilder ssb = HtmlHelper.fromDocument(context, document, true, new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { - Drawable drawable = ImageHelper.decodeImage(context, message.id, source, show_images, zoom, tvBody); - Rect bounds = drawable.getBounds(); - map.put(drawable, new Pair<>(bounds.right, bounds.bottom)); - - bounds.right = Math.round(bounds.right * scale); - bounds.bottom = Math.round(bounds.bottom * scale); - drawable.setBounds(bounds); + Drawable drawable = ImageHelper.decodeImage(context, message.id, source, show_images, zoom, scale, tvBody); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (drawable instanceof AnimatedImageDrawable) @@ -2165,7 +2148,6 @@ public class AdapterMessage extends RecyclerView.Adapter kv = new HashMap<>(); final private Map> values = new HashMap<>(); - final private LongSparseArray scales = new LongSparseArray<>(); final private LongSparseArray sizes = new LongSparseArray<>(); final private LongSparseArray heights = new LongSparseArray<>(); final private LongSparseArray> positions = new LongSparseArray<>(); @@ -1646,19 +1645,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. handleExpand(message.id); } - @Override - public void setScale(long id, Float size) { - if (size == null) - scales.remove(id); - else - scales.put(id, size); - } - - @Override - public float getScale(long id, float defaultSize) { - return scales.get(id, defaultSize); - } - @Override public void setSize(long id, Float size) { if (size == null) @@ -3529,7 +3515,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. Log.i("Hidden id=" + id); for (String key : values.keySet()) values.get(key).remove(id); - scales.remove(id); sizes.remove(id); heights.remove(id); positions.remove(id); @@ -4128,7 +4113,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } private void clearMeasurements() { - scales.clear(); sizes.clear(); heights.clear(); positions.clear(); diff --git a/app/src/main/java/eu/faircode/email/ImageHelper.java b/app/src/main/java/eu/faircode/email/ImageHelper.java index 97d7af79ce..d6169b4f32 100644 --- a/app/src/main/java/eu/faircode/email/ImageHelper.java +++ b/app/src/main/java/eu/faircode/email/ImageHelper.java @@ -72,6 +72,8 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Date; +import java.util.Map; +import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; class ImageHelper { @@ -226,7 +228,7 @@ class ImageHelper { return round; } - static Drawable decodeImage(final Context context, final long id, String source, boolean show, int zoom, final TextView view) { + static Drawable decodeImage(final Context context, final long id, String source, boolean show, int zoom, final float scale, final TextView view) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean inline = prefs.getBoolean("inline_images", false); @@ -270,7 +272,7 @@ class ImageHelper { try { Drawable d = getScaledDrawable(attachment.getFile(context), scaleToPixels); if (view != null) - fitDrawable(d, a, view); + fitDrawable(d, a, scale, view); return d; } catch (IOException ex) { Log.w(ex); @@ -290,7 +292,7 @@ class ImageHelper { DisplayMetrics dm = context.getResources().getDisplayMetrics(); d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density)); if (view != null) - fitDrawable(d, a, view); + fitDrawable(d, a, scale, view); return d; } } @@ -310,7 +312,7 @@ class ImageHelper { d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density)); if (view != null) - fitDrawable(d, a, view); + fitDrawable(d, a, scale, view); return d; } catch (IllegalArgumentException ex) { Log.w(ex); @@ -355,7 +357,7 @@ class ImageHelper { d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density)); if (view != null) - fitDrawable(d, a, view); + fitDrawable(d, a, scale, view); return d; } catch (Throwable ex) { // FileNotFound, Security @@ -384,7 +386,7 @@ class ImageHelper { } else return cached; else - fitDrawable(cached, a, view); + fitDrawable(cached, a, scale, view); return cached; } @@ -425,14 +427,14 @@ class ImageHelper { // Check cache again Drawable cached = getCachedImage(context, id, a.source); if (cached != null) { - fitDrawable(cached, a, view); + fitDrawable(cached, a, scale, view); post(cached, a.source); return; } // Download image Drawable d = downloadImage(context, id, a.source); - fitDrawable(d, a, view); + fitDrawable(d, a, scale, view); post(d, a.source); } catch (Throwable ex) { // Show broken icon @@ -479,10 +481,19 @@ class ImageHelper { } } - private static void fitDrawable(final Drawable d, final AnnotatedSource a, final View view) { + private static Map drawableBounds = new WeakHashMap<>(); + + static void fitDrawable(final Drawable d, final AnnotatedSource a, float scale, final View view) { + synchronized (drawableBounds) { + if (drawableBounds.containsKey(d)) + d.setBounds(drawableBounds.get(d)); + else + drawableBounds.put(d, d.copyBounds()); + } + Rect bounds = d.getBounds(); - int w = bounds.width(); - int h = bounds.height(); + int w = Math.round(bounds.width() * scale); + int h = Math.round(bounds.height() * scale); if (a.width == 0 && a.height != 0) a.width = Math.round(a.height * w / (float) h); @@ -490,9 +501,8 @@ class ImageHelper { a.height = Math.round(a.width * h / (float) w); if (a.width != 0 && a.height != 0) { - w = Helper.dp2pixels(view.getContext(), a.width); - h = Helper.dp2pixels(view.getContext(), a.height); - d.setBounds(0, 0, w, h); + w = Math.round(Helper.dp2pixels(view.getContext(), a.width) * scale); + h = Math.round(Helper.dp2pixels(view.getContext(), a.height) * scale); } float width = view.getContext().getResources().getDisplayMetrics().widthPixels; @@ -509,11 +519,12 @@ class ImageHelper { } if (w > width) { - float scale = width / w; - w = Math.round(w * scale); - h = Math.round(h * scale); - d.setBounds(0, 0, w, h); + float s = width / w; + w = Math.round(w * s); + h = Math.round(h * s); } + + d.setBounds(0, 0, w, h); } static Bitmap getDataBitmap(String source) {