Delegate image scaling to image helper

pull/184/head
M66B 5 years ago
parent ee0c0f9ef1
commit 95ef38f464

@ -193,7 +193,7 @@ public class ActivitySignature extends ActivityBase {
etText.setText(HtmlHelper.fromHtml(html, false, new Html.ImageGetter() { etText.setText(HtmlHelper.fromHtml(html, false, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { 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)); }, null, this));
dirty = false; dirty = false;
@ -300,7 +300,7 @@ public class ActivitySignature extends ActivityBase {
SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText()); SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText());
ssb.insert(start, " \uFFFC"); // Object replacement character ssb.insert(start, " \uFFFC"); // Object replacement character
String source = uri.toString(); 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); ImageSpan is = new ImageSpan(d, source);
ssb.setSpan(is, start + 1, start + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ssb.setSpan(is, start + 1, start + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
etText.setText(ssb); etText.setText(ssb);

@ -475,7 +475,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private TwoStateOwner powner = new TwoStateOwner(owner, "MessagePopup"); private TwoStateOwner powner = new TwoStateOwner(owner, "MessagePopup");
private ScaleGestureDetector gestureDetector; private ScaleGestureDetector gestureDetector;
private Map<Drawable, Pair<Integer, Integer>> drawableSize = new HashMap<>();
private SimpleTask taskContactInfo; private SimpleTask taskContactInfo;
@ -775,20 +774,10 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
// Image size // Image size
Spanned spanned = (Spanned) tvBody.getText(); Spanned spanned = (Spanned) tvBody.getText();
int bw = tvBody.getWidth() - tvBody.getPaddingStart() - tvBody.getPaddingEnd();
if (bw != 0)
for (ImageSpan img : spanned.getSpans(0, spanned.length(), ImageSpan.class)) { for (ImageSpan img : spanned.getSpans(0, spanned.length(), ImageSpan.class)) {
Drawable d = img.getDrawable(); Drawable d = img.getDrawable();
Pair<Integer, Integer> p = drawableSize.get(d); ImageHelper.AnnotatedSource a = new ImageHelper.AnnotatedSource(img.getSource());
if (p == null || p.first == 0) ImageHelper.fitDrawable(d, a, scale, tvBody);
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);
} }
// Feedback // Feedback
@ -1970,7 +1959,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
args.putBoolean("show_quotes", show_quotes); args.putBoolean("show_quotes", show_quotes);
args.putInt("zoom", zoom); args.putInt("zoom", zoom);
args.putFloat("scale", properties.getScale(message.id, 1.0f)); float scale = (size == 0 || textSize == 0 ? 1.0f : size / (textSize * message_zoom / 100f));
args.putFloat("scale", scale);
new SimpleTask<Object>() { new SimpleTask<Object>() {
@Override @Override
@ -2145,17 +2135,10 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
// Draw images // Draw images
Map<Drawable, Pair<Integer, Integer>> map = new HashMap<>();
SpannableStringBuilder ssb = HtmlHelper.fromDocument(context, document, true, new Html.ImageGetter() { SpannableStringBuilder ssb = HtmlHelper.fromDocument(context, document, true, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
Drawable drawable = ImageHelper.decodeImage(context, message.id, source, show_images, zoom, tvBody); Drawable drawable = ImageHelper.decodeImage(context, message.id, source, show_images, zoom, scale, 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);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (drawable instanceof AnimatedImageDrawable) if (drawable instanceof AnimatedImageDrawable)
@ -2165,7 +2148,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
return drawable; return drawable;
} }
}, null); }, null);
drawableSize = map;
if (show_quotes) if (show_quotes)
return ssb; return ssb;
@ -5807,10 +5789,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
void setExpanded(TupleMessageEx message, boolean expanded); void setExpanded(TupleMessageEx message, boolean expanded);
void setScale(long id, Float size);
float getScale(long id, float defaultSize);
void setSize(long id, Float size); void setSize(long id, Float size);
float getSize(long id, float defaultSize); float getSize(long id, float defaultSize);

@ -121,7 +121,7 @@ public class EditTextCompose extends FixedEditText {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(getContext(), return ImageHelper.decodeImage(getContext(),
-1, source, true, 0, EditTextCompose.this); -1, source, true, 0, 1.0f, EditTextCompose.this);
} }
}, null); }, null);

@ -185,7 +185,7 @@ public class FragmentAnswer extends FragmentBase {
etText.setText(HtmlHelper.fromHtml(answer.text, false, new Html.ImageGetter() { etText.setText(HtmlHelper.fromHtml(answer.text, false, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(getContext(), -1, source, true, 0, etText); return ImageHelper.decodeImage(getContext(), -1, source, true, 0, 1.0f, etText);
} }
}, null, getContext())); }, null, getContext()));
} }
@ -351,7 +351,7 @@ public class FragmentAnswer extends FragmentBase {
SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText()); SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText());
ssb.insert(start, " \uFFFC"); // Object replacement character ssb.insert(start, " \uFFFC"); // Object replacement character
String source = uri.toString(); String source = uri.toString();
Drawable d = ImageHelper.decodeImage(getContext(), -1, source, true, 0, etText); Drawable d = ImageHelper.decodeImage(getContext(), -1, source, true, 0, 1.0f, etText);
ImageSpan is = new ImageSpan(d, source); ImageSpan is = new ImageSpan(d, source);
ssb.setSpan(is, start + 1, start + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ssb.setSpan(is, start + 1, start + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
etText.setText(ssb); etText.setText(ssb);

@ -2109,7 +2109,7 @@ public class FragmentCompose extends FragmentBase {
return HtmlHelper.fromHtml(HtmlHelper.toHtml(s, context), false, new Html.ImageGetter() { return HtmlHelper.fromHtml(HtmlHelper.toHtml(s, context), false, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(context, id, source, true, zoom, etBody); return ImageHelper.decodeImage(context, id, source, true, zoom, 1.0f, etBody);
} }
}, null, getContext()); }, null, getContext());
} }
@ -2903,7 +2903,7 @@ public class FragmentCompose extends FragmentBase {
Spanned spanned = HtmlHelper.fromHtml(html, false, new Html.ImageGetter() { Spanned spanned = HtmlHelper.fromHtml(html, false, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(getContext(), working, source, true, zoom, etBody); return ImageHelper.decodeImage(getContext(), working, source, true, zoom, 1.0f, etBody);
} }
}, null, getContext()); }, null, getContext());
@ -4817,7 +4817,7 @@ public class FragmentCompose extends FragmentBase {
Spanned spannedBody = HtmlHelper.fromDocument(context, doc, false, new Html.ImageGetter() { Spanned spannedBody = HtmlHelper.fromDocument(context, doc, false, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(context, id, source, true, zoom, etBody); return ImageHelper.decodeImage(context, id, source, true, zoom, 1.0f, etBody);
} }
}, null); }, null);
@ -4846,7 +4846,7 @@ public class FragmentCompose extends FragmentBase {
new Html.ImageGetter() { new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(context, id, source, show_images, zoom, tvReference); return ImageHelper.decodeImage(context, id, source, show_images, zoom, 1.0f, tvReference);
} }
}, },
null); null);
@ -4946,7 +4946,7 @@ public class FragmentCompose extends FragmentBase {
signature = HtmlHelper.fromHtml(identity.signature, false, new Html.ImageGetter() { signature = HtmlHelper.fromHtml(identity.signature, false, new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
return ImageHelper.decodeImage(getContext(), working, source, true, 0, tvSignature); return ImageHelper.decodeImage(getContext(), working, source, true, 0, 1.0f, tvSignature);
} }
}, null, getContext()); }, null, getContext());
tvSignature.setText(signature); tvSignature.setText(signature);

@ -309,7 +309,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
final private Map<String, String> kv = new HashMap<>(); final private Map<String, String> kv = new HashMap<>();
final private Map<String, List<Long>> values = new HashMap<>(); final private Map<String, List<Long>> values = new HashMap<>();
final private LongSparseArray<Float> scales = new LongSparseArray<>();
final private LongSparseArray<Float> sizes = new LongSparseArray<>(); final private LongSparseArray<Float> sizes = new LongSparseArray<>();
final private LongSparseArray<Integer> heights = new LongSparseArray<>(); final private LongSparseArray<Integer> heights = new LongSparseArray<>();
final private LongSparseArray<Pair<Integer, Integer>> positions = new LongSparseArray<>(); final private LongSparseArray<Pair<Integer, Integer>> positions = new LongSparseArray<>();
@ -1646,19 +1645,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
handleExpand(message.id); 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 @Override
public void setSize(long id, Float size) { public void setSize(long id, Float size) {
if (size == null) if (size == null)
@ -3529,7 +3515,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
Log.i("Hidden id=" + id); Log.i("Hidden id=" + id);
for (String key : values.keySet()) for (String key : values.keySet())
values.get(key).remove(id); values.get(key).remove(id);
scales.remove(id);
sizes.remove(id); sizes.remove(id);
heights.remove(id); heights.remove(id);
positions.remove(id); positions.remove(id);
@ -4128,7 +4113,6 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} }
private void clearMeasurements() { private void clearMeasurements() {
scales.clear();
sizes.clear(); sizes.clear();
heights.clear(); heights.clear();
positions.clear(); positions.clear();

@ -72,6 +72,8 @@ import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Date; import java.util.Date;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
class ImageHelper { class ImageHelper {
@ -226,7 +228,7 @@ class ImageHelper {
return round; 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); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean inline = prefs.getBoolean("inline_images", false); boolean inline = prefs.getBoolean("inline_images", false);
@ -270,7 +272,7 @@ class ImageHelper {
try { try {
Drawable d = getScaledDrawable(attachment.getFile(context), scaleToPixels); Drawable d = getScaledDrawable(attachment.getFile(context), scaleToPixels);
if (view != null) if (view != null)
fitDrawable(d, a, view); fitDrawable(d, a, scale, view);
return d; return d;
} catch (IOException ex) { } catch (IOException ex) {
Log.w(ex); Log.w(ex);
@ -290,7 +292,7 @@ class ImageHelper {
DisplayMetrics dm = context.getResources().getDisplayMetrics(); DisplayMetrics dm = context.getResources().getDisplayMetrics();
d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density)); d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density));
if (view != null) if (view != null)
fitDrawable(d, a, view); fitDrawable(d, a, scale, view);
return d; return d;
} }
} }
@ -310,7 +312,7 @@ class ImageHelper {
d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density)); d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density));
if (view != null) if (view != null)
fitDrawable(d, a, view); fitDrawable(d, a, scale, view);
return d; return d;
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
Log.w(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)); d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density));
if (view != null) if (view != null)
fitDrawable(d, a, view); fitDrawable(d, a, scale, view);
return d; return d;
} catch (Throwable ex) { } catch (Throwable ex) {
// FileNotFound, Security // FileNotFound, Security
@ -384,7 +386,7 @@ class ImageHelper {
} else } else
return cached; return cached;
else else
fitDrawable(cached, a, view); fitDrawable(cached, a, scale, view);
return cached; return cached;
} }
@ -425,14 +427,14 @@ class ImageHelper {
// Check cache again // Check cache again
Drawable cached = getCachedImage(context, id, a.source); Drawable cached = getCachedImage(context, id, a.source);
if (cached != null) { if (cached != null) {
fitDrawable(cached, a, view); fitDrawable(cached, a, scale, view);
post(cached, a.source); post(cached, a.source);
return; return;
} }
// Download image // Download image
Drawable d = downloadImage(context, id, a.source); Drawable d = downloadImage(context, id, a.source);
fitDrawable(d, a, view); fitDrawable(d, a, scale, view);
post(d, a.source); post(d, a.source);
} catch (Throwable ex) { } catch (Throwable ex) {
// Show broken icon // 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<Drawable, Rect> 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(); Rect bounds = d.getBounds();
int w = bounds.width(); int w = Math.round(bounds.width() * scale);
int h = bounds.height(); int h = Math.round(bounds.height() * scale);
if (a.width == 0 && a.height != 0) if (a.width == 0 && a.height != 0)
a.width = Math.round(a.height * w / (float) h); a.width = Math.round(a.height * w / (float) h);
@ -490,9 +501,8 @@ class ImageHelper {
a.height = Math.round(a.width * h / (float) w); a.height = Math.round(a.width * h / (float) w);
if (a.width != 0 && a.height != 0) { if (a.width != 0 && a.height != 0) {
w = Helper.dp2pixels(view.getContext(), a.width); w = Math.round(Helper.dp2pixels(view.getContext(), a.width) * scale);
h = Helper.dp2pixels(view.getContext(), a.height); h = Math.round(Helper.dp2pixels(view.getContext(), a.height) * scale);
d.setBounds(0, 0, w, h);
} }
float width = view.getContext().getResources().getDisplayMetrics().widthPixels; float width = view.getContext().getResources().getDisplayMetrics().widthPixels;
@ -509,11 +519,12 @@ class ImageHelper {
} }
if (w > width) { if (w > width) {
float scale = width / w; float s = width / w;
w = Math.round(w * scale); w = Math.round(w * s);
h = Math.round(h * scale); h = Math.round(h * s);
d.setBounds(0, 0, w, h);
} }
d.setBounds(0, 0, w, h);
} }
static Bitmap getDataBitmap(String source) { static Bitmap getDataBitmap(String source) {

Loading…
Cancel
Save