diff --git a/library/src/main/java/ru/noties/markwon/SpannableConfiguration.java b/library/src/main/java/ru/noties/markwon/SpannableConfiguration.java index aa9b6f15..57b11a55 100644 --- a/library/src/main/java/ru/noties/markwon/SpannableConfiguration.java +++ b/library/src/main/java/ru/noties/markwon/SpannableConfiguration.java @@ -3,6 +3,8 @@ package ru.noties.markwon; import android.content.Context; import android.support.annotation.NonNull; +import ru.noties.markwon.renderer.html.ImageSizeResolver; +import ru.noties.markwon.renderer.html.ImageSizeResolverDef; import ru.noties.markwon.renderer.html.SpannableHtmlParser; import ru.noties.markwon.spans.AsyncDrawable; import ru.noties.markwon.spans.LinkSpan; @@ -12,10 +14,12 @@ import ru.noties.markwon.spans.SpannableTheme; public class SpannableConfiguration { // creates default configuration + @NonNull public static SpannableConfiguration create(@NonNull Context context) { return new Builder(context).build(); } + @NonNull public static Builder builder(@NonNull Context context) { return new Builder(context); } @@ -27,7 +31,7 @@ public class SpannableConfiguration { private final UrlProcessor urlProcessor; private final SpannableHtmlParser htmlParser; - private SpannableConfiguration(Builder builder) { + private SpannableConfiguration(@NonNull Builder builder) { this.theme = builder.theme; this.asyncDrawableLoader = builder.asyncDrawableLoader; this.syntaxHighlight = builder.syntaxHighlight; @@ -36,26 +40,32 @@ public class SpannableConfiguration { this.htmlParser = builder.htmlParser; } + @NonNull public SpannableTheme theme() { return theme; } + @NonNull public AsyncDrawable.Loader asyncDrawableLoader() { return asyncDrawableLoader; } + @NonNull public SyntaxHighlight syntaxHighlight() { return syntaxHighlight; } + @NonNull public LinkSpan.Resolver linkResolver() { return linkResolver; } + @NonNull public UrlProcessor urlProcessor() { return urlProcessor; } + @NonNull public SpannableHtmlParser htmlParser() { return htmlParser; } @@ -69,60 +79,89 @@ public class SpannableConfiguration { private LinkSpan.Resolver linkResolver; private UrlProcessor urlProcessor; private SpannableHtmlParser htmlParser; + private ImageSizeResolver imageSizeResolver; - Builder(Context context) { + Builder(@NonNull Context context) { this.context = context; } - public Builder theme(SpannableTheme theme) { + @NonNull + public Builder theme(@NonNull SpannableTheme theme) { this.theme = theme; return this; } - public Builder asyncDrawableLoader(AsyncDrawable.Loader asyncDrawableLoader) { + @NonNull + public Builder asyncDrawableLoader(@NonNull AsyncDrawable.Loader asyncDrawableLoader) { this.asyncDrawableLoader = asyncDrawableLoader; return this; } - public Builder syntaxHighlight(SyntaxHighlight syntaxHighlight) { + @NonNull + public Builder syntaxHighlight(@NonNull SyntaxHighlight syntaxHighlight) { this.syntaxHighlight = syntaxHighlight; return this; } - public Builder linkResolver(LinkSpan.Resolver linkResolver) { + @NonNull + public Builder linkResolver(@NonNull LinkSpan.Resolver linkResolver) { this.linkResolver = linkResolver; return this; } - public Builder urlProcessor(UrlProcessor urlProcessor) { + @NonNull + public Builder urlProcessor(@NonNull UrlProcessor urlProcessor) { this.urlProcessor = urlProcessor; return this; } - public Builder htmlParser(SpannableHtmlParser htmlParser) { + @NonNull + public Builder htmlParser(@NonNull SpannableHtmlParser htmlParser) { this.htmlParser = htmlParser; return this; } + /** + * @since 1.0.1 + */ + @NonNull + public Builder imageSizeResolver(@NonNull ImageSizeResolver imageSizeResolver) { + this.imageSizeResolver = imageSizeResolver; + return this; + } + + @NonNull public SpannableConfiguration build() { + if (theme == null) { theme = SpannableTheme.create(context); } + if (asyncDrawableLoader == null) { asyncDrawableLoader = new AsyncDrawableLoaderNoOp(); } + if (syntaxHighlight == null) { syntaxHighlight = new SyntaxHighlightNoOp(); } + if (linkResolver == null) { linkResolver = new LinkResolverDef(); } + if (urlProcessor == null) { urlProcessor = new UrlProcessorNoOp(); } + if (htmlParser == null) { - htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver); + + if (imageSizeResolver == null) { + imageSizeResolver = new ImageSizeResolverDef(); + } + + htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver, imageSizeResolver); } + return new SpannableConfiguration(this); } } diff --git a/library/src/main/java/ru/noties/markwon/renderer/html/ImageProviderImpl.java b/library/src/main/java/ru/noties/markwon/renderer/html/ImageProviderImpl.java index d9f589cc..54a5086f 100644 --- a/library/src/main/java/ru/noties/markwon/renderer/html/ImageProviderImpl.java +++ b/library/src/main/java/ru/noties/markwon/renderer/html/ImageProviderImpl.java @@ -6,9 +6,9 @@ import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import ru.noties.markwon.UrlProcessor; import ru.noties.markwon.spans.AsyncDrawable; @@ -17,20 +17,21 @@ import ru.noties.markwon.spans.SpannableTheme; class ImageProviderImpl implements SpannableHtmlParser.ImageProvider { - private static final Pattern STYLE_WIDTH = Pattern.compile(".*width:\\s*(\\d+)(%|em|px)*.*"); - private static final Pattern STYLE_HEIGHT = Pattern.compile(".*height:\\s*(\\d+)(%|em|px)*.*"); - private final SpannableTheme theme; private final AsyncDrawable.Loader loader; private final UrlProcessor urlProcessor; + private final ImageSizeResolver imageSizeResolver; ImageProviderImpl( @NonNull SpannableTheme theme, @NonNull AsyncDrawable.Loader loader, - @NonNull UrlProcessor urlProcessor) { + @NonNull UrlProcessor urlProcessor, + @NonNull ImageSizeResolver imageSizeResolver + ) { this.theme = theme; this.loader = loader; this.urlProcessor = urlProcessor; + this.imageSizeResolver = imageSizeResolver; } @Override @@ -53,7 +54,7 @@ class ImageProviderImpl implements SpannableHtmlParser.ImageProvider { replacement = "\uFFFC"; } - final AsyncDrawable drawable = new AsyncDrawable(destination, loader, parseImageSize(attributes)); + final AsyncDrawable drawable = new AsyncDrawable(destination, loader, imageSizeResolver, parseImageSize(attributes)); final AsyncDrawableSpan span = new AsyncDrawableSpan(theme, drawable); final SpannableString string = new SpannableString(replacement); @@ -70,145 +71,134 @@ class ImageProviderImpl implements SpannableHtmlParser.ImageProvider { @Nullable private static ImageSize parseImageSize(@NonNull Map attributes) { - return null; + final ImageSize imageSize; -// final String width = attributes.get("width"); -// final String height = attributes.get("height"); -// -// final ImageSize imageSize; -// -// final String width = extractWidth(attributes); -// final String height = extractHeight(attributes); -// -// if (TextUtils.isEmpty(width) -// && TextUtils.isEmpty(height)) { -// imageSize = null; -// } else { -// if (isRelative(width)) { -// // check if height is NOT relative, if it is -> ignore -// final int h = isRelative(height) -// ? 0 -// : parseInt(height); -// imageSize = new ImageSize(, parseInt(width), h); -// } else { -// imageSize = new ImageSize(false, parseInt(width), parseInt(height)); -// } -// } -// -// return imageSize; - } + final StyleProvider styleProvider = new StyleProvider(attributes.get("style")); -// @Nullable -// private static ImageSize.Dimension parseWidth(@NonNull Map attributes) { -// -// // so, we can have raw value specified via direct attribute -// -// final ImageSize.Dimension dimension; -// -// final String width = attributes.get("width"); -// if (!TextUtils.isEmpty(width)) { -// final Matcher matcher = -// } -// } + final ImageSize.Dimension width = parseDimension(extractDimension("width", attributes, styleProvider)); + final ImageSize.Dimension height = parseDimension(extractDimension("height", attributes, styleProvider)); - @Nullable - private static String extractWidth(@NonNull Map attributes) { - - // let's check style first - - String width = attributes.get("width"); - - if (width == null) { - final String style = attributes.get("style"); - if (!TextUtils.isEmpty(style)) { - final Matcher matcher = STYLE_WIDTH.matcher(style); - if (matcher.matches()) { - width = matcher.group(1); - } - } + if (width == null + && height == null) { + imageSize = null; + } else { + imageSize = new ImageSize(width, height); } - return width; + return imageSize; } @Nullable - private static String extractHeight(@NonNull Map attributes) { + private static String extractDimension(@NonNull String name, @NonNull Map attributes, @NonNull StyleProvider styleProvider) { - String height = attributes.get("height"); + final String out; - if (height == null) { - final String style = attributes.get("style"); - if (!TextUtils.isEmpty(style)) { - final Matcher matcher = STYLE_HEIGHT.matcher(style); - if (matcher.matches()) { - height = matcher.group(1); - } - } + final String inline = attributes.get(name); + if (!TextUtils.isEmpty(inline)) { + out = inline; + } else { + out = extractDimensionFromStyle(name, styleProvider); } - return height; + return out; } @Nullable - private static ImageSize.Dimension extractFromStyle(@Nullable String style, @NonNull Pattern pattern) { + private static String extractDimensionFromStyle(@NonNull String name, @NonNull StyleProvider styleProvider) { + return styleProvider.attributes().get(name); + } + + @Nullable + private static ImageSize.Dimension parseDimension(@Nullable String raw) { + + // a set of digits, then dimension unit (allow floating) + final ImageSize.Dimension dimension; - if (style == null) { + + final int length = raw != null + ? raw.length() + : 0; + + if (length == 0) { dimension = null; } else { - final Matcher matcher = pattern.matcher(style); - if (matcher.matches()) { - dimension = new ImageSize.Dimension( - parseUnit(matcher.group(2)), - parseInt(matcher.group(1)) - ); - } else { + + // first digit to find -> unit is finished (can be null) + + int index = -1; + + for (int i = length - 1; i >= 0; i--) { + if (Character.isDigit(raw.charAt(i))) { + index = i; + break; + } + } + + // no digits -> no dimension + if (index == -1) { dimension = null; + } else { + + final String value; + final String unit; + + // no unit is specified + if (index == length - 1) { + value = raw; + unit = null; + } else { + value = raw.substring(0, index + 1); + unit = raw.substring(index + 1); + } + + ImageSize.Dimension inner; + try { + final float floatValue = Float.parseFloat(value); + inner = new ImageSize.Dimension(floatValue, unit); + } catch (NumberFormatException e) { + inner = null; + } + + dimension = inner; } } + return dimension; } - @NonNull - private static ImageSize.Unit parseUnit(@Nullable String s) { + private static class StyleProvider { - final ImageSize.Unit unit; + private final String style; + private Map attributes; - if (TextUtils.isEmpty(s)) { + StyleProvider(@Nullable String style) { + this.style = style; + } - unit = ImageSize.Unit.PIXELS; - - } else { - - final int length = s.length(); - - if (length == 1 - && '%' == s.charAt(length - 1)) { - unit = ImageSize.Unit.PERCENT; - } else if (length == 2 - && 'e' == s.charAt(length - 2) - && 'm' == s.charAt(length - 1)) { - unit = ImageSize.Unit.FONT_SIZE; + @NonNull + Map attributes() { + final Map out; + if (attributes != null) { + out = attributes; } else { - unit = ImageSize.Unit.PIXELS; + if (TextUtils.isEmpty(style)) { + out = attributes = Collections.emptyMap(); + } else { + final String[] split = style.split(";"); + final Map map = new HashMap<>(split.length); + String[] parts; + for (String s : split) { + if (!TextUtils.isEmpty(s)) { + parts = s.split(":"); + if (parts.length == 2) { + map.put(parts[0].trim(), parts[1].trim()); + } + } + } + out = attributes = map; + } } + return out; } - - return unit; - } - - private static boolean isRelative(@Nullable String attr) { - return attr != null && attr.charAt(attr.length() - 1) == '%'; - } - - private static int parseInt(@Nullable String s) { - int result = 0; - if (!TextUtils.isEmpty(s)) { - try { - result = Integer.parseInt(s.replaceAll("[^\\d]", "")); - } catch (NumberFormatException e) { - result = 0; - } - } - return result; } } diff --git a/library/src/main/java/ru/noties/markwon/renderer/html/ImageSize.java b/library/src/main/java/ru/noties/markwon/renderer/html/ImageSize.java index 0f916716..f65144ab 100644 --- a/library/src/main/java/ru/noties/markwon/renderer/html/ImageSize.java +++ b/library/src/main/java/ru/noties/markwon/renderer/html/ImageSize.java @@ -1,72 +1,37 @@ package ru.noties.markwon.renderer.html; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; /** * @since 1.0.1 */ +@SuppressWarnings("WeakerAccess") public class ImageSize { - public enum Unit { - PERCENT, FONT_SIZE, PIXELS - } - public static class Dimension { - private final Unit unit; - private final int value; + public final float value; + public final String unit; - public Dimension(@NonNull Unit unit, int value) { - this.unit = unit; + public Dimension(float value, @Nullable String unit) { this.value = value; - } - - @NonNull - public Unit unit() { - return unit; - } - - public int value() { - return value; + this.unit = unit; } @Override public String toString() { return "Dimension{" + - "unit=" + unit + - ", value=" + value + + "value=" + value + + ", unit='" + unit + '\'' + '}'; } } - // width can be relative (in percent) - // height CANNOT be relative (endless loop) - // both can be absolute - - private final Dimension width; - private final Dimension height; + public final Dimension width; + public final Dimension height; public ImageSize(@Nullable Dimension width, @Nullable Dimension height) { this.width = width; this.height = height; } - - @Nullable - public Dimension width() { - return width; - } - - @Nullable - public Dimension height() { - return height; - } - - @Override - public String toString() { - return "ImageSize{" + - "width=" + width + - ", height=" + height + - '}'; - } } diff --git a/library/src/main/java/ru/noties/markwon/renderer/html/ImageSizeResolver.java b/library/src/main/java/ru/noties/markwon/renderer/html/ImageSizeResolver.java new file mode 100644 index 00000000..41574bb7 --- /dev/null +++ b/library/src/main/java/ru/noties/markwon/renderer/html/ImageSizeResolver.java @@ -0,0 +1,29 @@ +package ru.noties.markwon.renderer.html; + +import android.graphics.Rect; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * @since 1.0.1 + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public abstract class ImageSizeResolver { + + /** + * We do not expose canvas height deliberately. As we cannot rely on this value very much + * + * @param imageSize {@link ImageSize} parsed from HTML + * @param imageBounds original image bounds + * @param canvasWidth width of the canvas + * @param textSize current font size + * @return resolved image bounds + */ + @NonNull + public abstract Rect resolveImageSize( + @Nullable ImageSize imageSize, + @NonNull Rect imageBounds, + int canvasWidth, + float textSize + ); +} diff --git a/library/src/main/java/ru/noties/markwon/renderer/html/ImageSizeResolverDef.java b/library/src/main/java/ru/noties/markwon/renderer/html/ImageSizeResolverDef.java new file mode 100644 index 00000000..b7eb1fc9 --- /dev/null +++ b/library/src/main/java/ru/noties/markwon/renderer/html/ImageSizeResolverDef.java @@ -0,0 +1,85 @@ +package ru.noties.markwon.renderer.html; + +import android.graphics.Rect; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * @since 1.0.1 + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public class ImageSizeResolverDef extends ImageSizeResolver { + + // we track these two, others are considered to be pixels + protected static final String UNIT_PERCENT = "%"; + protected static final String UNIT_EM = "em"; + + @NonNull + @Override + public Rect resolveImageSize( + @Nullable ImageSize imageSize, + @NonNull Rect imageBounds, + int canvasWidth, + float textSize + ) { + + if (imageSize == null) { + return imageBounds; + } + + final Rect rect; + + final ImageSize.Dimension width = imageSize.width; + final ImageSize.Dimension height = imageSize.height; + + final int imageWidth = imageBounds.width(); + final int imageHeight = imageBounds.height(); + + final float ratio = (float) imageWidth / imageHeight; + + if (width != null) { + + final int w; + final int h; + + if (UNIT_PERCENT.equals(width.unit)) { + w = (int) (canvasWidth * (width.value / 100.F) + .5F); + } else { + w = resolveAbsolute(width, imageWidth, textSize); + } + + if (height == null + || UNIT_PERCENT.equals(height.unit)) { + h = (int) (w / ratio + .5F); + } else { + h = resolveAbsolute(height, imageHeight, textSize); + } + + rect = new Rect(0, 0, w, h); + + } else if (height != null) { + + if (!UNIT_PERCENT.equals(height.unit)) { + final int h = resolveAbsolute(height, imageHeight, textSize); + final int w = (int) (h * ratio + .5F); + rect = new Rect(0, 0, w, h); + } else { + rect = imageBounds; + } + } else { + rect = imageBounds; + } + + return rect; + } + + protected int resolveAbsolute(@NonNull ImageSize.Dimension dimension, int original, float textSize) { + final int out; + if (UNIT_EM.equals(dimension.unit)) { + out = (int) (dimension.value * textSize + .5F); + } else { + out = original; + } + return out; + } +} diff --git a/library/src/main/java/ru/noties/markwon/renderer/html/SpannableHtmlParser.java b/library/src/main/java/ru/noties/markwon/renderer/html/SpannableHtmlParser.java index af616330..6423e1f9 100644 --- a/library/src/main/java/ru/noties/markwon/renderer/html/SpannableHtmlParser.java +++ b/library/src/main/java/ru/noties/markwon/renderer/html/SpannableHtmlParser.java @@ -21,37 +21,74 @@ import ru.noties.markwon.spans.SpannableTheme; public class SpannableHtmlParser { // creates default parser + @NonNull public static SpannableHtmlParser create( @NonNull SpannableTheme theme, @NonNull AsyncDrawable.Loader loader ) { - return builderWithDefaults(theme, loader, null, null) + return builderWithDefaults(theme, loader, null, null, null) .build(); } + /** + * @since 1.0.1 + */ + @NonNull + public static SpannableHtmlParser create( + @NonNull SpannableTheme theme, + @NonNull AsyncDrawable.Loader loader, + @NonNull ImageSizeResolver imageSizeResolver + ) { + return builderWithDefaults(theme, loader, null, null, imageSizeResolver) + .build(); + } + + @NonNull public static SpannableHtmlParser create( @NonNull SpannableTheme theme, @NonNull AsyncDrawable.Loader loader, @NonNull UrlProcessor urlProcessor, @NonNull LinkSpan.Resolver resolver ) { - return builderWithDefaults(theme, loader, urlProcessor, resolver) + return builderWithDefaults(theme, loader, urlProcessor, resolver, null) .build(); } + /** + * @since 1.0.1 + */ + @NonNull + public static SpannableHtmlParser create( + @NonNull SpannableTheme theme, + @NonNull AsyncDrawable.Loader loader, + @NonNull UrlProcessor urlProcessor, + @NonNull LinkSpan.Resolver resolver, + @NonNull ImageSizeResolver imageSizeResolver + ) { + return builderWithDefaults(theme, loader, urlProcessor, resolver, imageSizeResolver) + .build(); + } + + @NonNull public static Builder builder() { return new Builder(); } + @NonNull public static Builder builderWithDefaults(@NonNull SpannableTheme theme) { - return builderWithDefaults(theme, null, null, null); + return builderWithDefaults(theme, null, null, null, null); } + /** + * Updated in 1.0.1: added imageSizeResolverArgument + */ + @NonNull public static Builder builderWithDefaults( @NonNull SpannableTheme theme, @Nullable AsyncDrawable.Loader asyncDrawableLoader, @Nullable UrlProcessor urlProcessor, - @Nullable LinkSpan.Resolver resolver + @Nullable LinkSpan.Resolver resolver, + @Nullable ImageSizeResolver imageSizeResolver ) { if (urlProcessor == null) { @@ -68,7 +105,12 @@ public class SpannableHtmlParser { final ImageProvider imageProvider; if (asyncDrawableLoader != null) { - imageProvider = new ImageProviderImpl(theme, asyncDrawableLoader, urlProcessor); + + if (imageSizeResolver == null) { + imageSizeResolver = new ImageSizeResolverDef(); + } + + imageProvider = new ImageProviderImpl(theme, asyncDrawableLoader, urlProcessor, imageSizeResolver); } else { imageProvider = null; } @@ -163,21 +205,25 @@ public class SpannableHtmlParser { private ImageProvider imageProvider; private HtmlParser parser; + @NonNull Builder simpleTag(@NonNull String tag, @NonNull SpanProvider provider) { simpleTags.put(tag, provider); return this; } - public Builder imageProvider(ImageProvider imageProvider) { + @NonNull + public Builder imageProvider(@Nullable ImageProvider imageProvider) { this.imageProvider = imageProvider; return this; } + @NonNull public Builder parser(@NonNull HtmlParser parser) { this.parser = parser; return this; } + @NonNull public SpannableHtmlParser build() { if (parser == null) { parser = DefaultHtmlParser.create(); diff --git a/library/src/main/java/ru/noties/markwon/spans/AsyncDrawable.java b/library/src/main/java/ru/noties/markwon/spans/AsyncDrawable.java index 4471e699..2253a5ba 100644 --- a/library/src/main/java/ru/noties/markwon/spans/AsyncDrawable.java +++ b/library/src/main/java/ru/noties/markwon/spans/AsyncDrawable.java @@ -11,6 +11,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import ru.noties.markwon.renderer.html.ImageSize; +import ru.noties.markwon.renderer.html.ImageSizeResolver; public class AsyncDrawable extends Drawable { @@ -24,22 +25,30 @@ public class AsyncDrawable extends Drawable { private final String destination; private final Loader loader; private final ImageSize imageSize; + private final ImageSizeResolver imageSizeResolver; private Drawable result; private Callback callback; private int canvasWidth; + private float textSize; public AsyncDrawable(@NonNull String destination, @NonNull Loader loader) { - this(destination, loader, null); + this(destination, loader, null, null); } /** * @since 1.0.1 */ - public AsyncDrawable(@NonNull String destination, @NonNull Loader loader, @Nullable ImageSize imageSize) { + public AsyncDrawable( + @NonNull String destination, + @NonNull Loader loader, + @Nullable ImageSizeResolver imageSizeResolver, + @Nullable ImageSize imageSize + ) { this.destination = destination; this.loader = loader; + this.imageSizeResolver = imageSizeResolver; this.imageSize = imageSize; } @@ -103,8 +112,9 @@ public class AsyncDrawable extends Drawable { * @since 1.0.1 */ @SuppressWarnings("WeakerAccess") - public void initWithCanvasWidth(int width) { + public void initWithKnownDimensions(int width, float textSize) { this.canvasWidth = width; + this.textSize = textSize; } @Override @@ -162,70 +172,13 @@ public class AsyncDrawable extends Drawable { */ @NonNull private Rect resolveBounds() { - - return result.getBounds(); - -// final Rect rect; -// -// if (canvasWidth == 0 -// || imageSize == null) { -// -// rect = result.getBounds(); -// -// } else { -// -// final Rect bounds = result.getBounds(); -// final float ratio = (float) bounds.width() / bounds.height(); -// -// if (imageSize.widthIsRelative()) { -// -// final int w = (int) (canvasWidth * ((float) imageSize.width() / 100.F) + .5F); -// final int h; -// -// // we still should allow absolute height -// if (imageSize.height() > 0) { -// h = imageSize.height(); -// } else { -// h = (int) (w / ratio); -// } -// -// rect = new Rect(0, 0, w, h); -// -// } else { -// -// // if width is specified, but height not -> calculate by ratio (and vice versa) -// // else -// -// final int w; -// final int h; -// -// final int width = imageSize.width(); -// final int height = imageSize.height(); -// -// if (width > 0 -// && height > 0) { -// w = width; -// h = height; -// } else if (width > 0) { -// w = width; -// h = (int) (w / ratio + .5F); -// } else if (height > 0) { -// h = height; -// w = (int) (h * ratio + .5F); -// } else { -// w = 0; -// h = 0; -// } -// -// if (w == 0 -// || h == 0) { -// rect = bounds; -// } else { -// rect = new Rect(0, 0, w, h); -// } -// } -// } -// -// return rect; + final Rect rect; + if (imageSizeResolver == null + || imageSize == null) { + rect = result.getBounds(); + } else { + rect = imageSizeResolver.resolveImageSize(imageSize, result.getBounds(), canvasWidth, textSize); + } + return rect; } } diff --git a/library/src/main/java/ru/noties/markwon/spans/AsyncDrawableSpan.java b/library/src/main/java/ru/noties/markwon/spans/AsyncDrawableSpan.java index 216203d1..14ddc4b8 100644 --- a/library/src/main/java/ru/noties/markwon/spans/AsyncDrawableSpan.java +++ b/library/src/main/java/ru/noties/markwon/spans/AsyncDrawableSpan.java @@ -112,7 +112,9 @@ public class AsyncDrawableSpan extends ReplacementSpan { int bottom, @NonNull Paint paint) { - drawable.initWithCanvasWidth(canvas.getWidth()); + // we will pass this value, so when image is obtained drawable will have dimensions + // to resolve image size + drawable.initWithKnownDimensions(canvas.getWidth(), paint.getTextSize()); this.lastKnownDrawX = (int) (x + .5F); this.lastKnownDrawY = y;