Update markdown core plugin

This commit is contained in:
chengjunzhang61 2021-12-08 10:02:22 -05:00
parent b67253994c
commit 3ce50f90b4
7 changed files with 111 additions and 70 deletions

View File

@ -3,6 +3,8 @@ package io.noties.markwon.core;
import android.text.Spannable; import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -55,6 +57,7 @@ import io.noties.markwon.core.factory.StrongEmphasisSpanFactory;
import io.noties.markwon.core.factory.ThematicBreakSpanFactory; import io.noties.markwon.core.factory.ThematicBreakSpanFactory;
import io.noties.markwon.core.spans.OrderedListItemSpan; import io.noties.markwon.core.spans.OrderedListItemSpan;
import io.noties.markwon.core.spans.TextViewSpan; import io.noties.markwon.core.spans.TextViewSpan;
import io.noties.markwon.image.ImageClickResolver;
import io.noties.markwon.image.ImageProps; import io.noties.markwon.image.ImageProps;
/** /**
@ -114,13 +117,19 @@ public class CorePlugin extends AbstractMarkwonPlugin {
// @since 4.0.0 // @since 4.0.0
private final List<OnTextAddedListener> onTextAddedListeners = new ArrayList<>(0); private final List<OnTextAddedListener> onTextAddedListeners = new ArrayList<>(0);
private static ImageClickResolver imageClickResolver = null;
// @since 4.5.0 // @since 4.5.0
private boolean hasExplicitMovementMethod; private boolean hasExplicitMovementMethod;
protected CorePlugin() { protected CorePlugin() {
} }
@NonNull
public CorePlugin addImageClickResolver(@NonNull ImageClickResolver clickResolver){
imageClickResolver = clickResolver;
return this;
}
/** /**
* @since 4.5.0 * @since 4.5.0
*/ */
@ -323,6 +332,7 @@ public class CorePlugin extends AbstractMarkwonPlugin {
visitor.visitChildren(image); visitor.visitChildren(image);
// we must check if anything _was_ added, as we need at least one char to render // we must check if anything _was_ added, as we need at least one char to render
if (length == visitor.length()) { if (length == visitor.length()) {
visitor.builder().append('\uFFFC'); visitor.builder().append('\uFFFC');
@ -345,8 +355,13 @@ public class CorePlugin extends AbstractMarkwonPlugin {
ImageProps.DESTINATION.set(props, destination); ImageProps.DESTINATION.set(props, destination);
ImageProps.REPLACEMENT_TEXT_IS_LINK.set(props, link); ImageProps.REPLACEMENT_TEXT_IS_LINK.set(props, link);
ImageProps.IMAGE_SIZE.set(props, null); ImageProps.IMAGE_SIZE.set(props, null);
visitor.setSpans(length, spanFactory.getSpans(configuration, props)); visitor.setSpans(length, spanFactory.getSpans(configuration, props));
visitor.setSpans(length, new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
imageClickResolver.clickResolve(widget, destination);
}
});
} }
}); });
} }

View File

@ -110,7 +110,7 @@ public class MarkwonTheme {
// taken from html spec (most browsers render headings like that) // taken from html spec (most browsers render headings like that)
// is not exposed via protected modifier in order to disallow modification // is not exposed via protected modifier in order to disallow modification
private static final float[] HEADING_SIZES = { private static final float[] HEADING_SIZES = {
2.F, 1.5F, 1.17F, 1.F, .83F, .67F, 2.F, 1.75F, 1.514F, 1.388F, 1.135F, 0.946F,
}; };
protected static final int THEMATIC_BREAK_DEF_ALPHA = 25; protected static final int THEMATIC_BREAK_DEF_ALPHA = 25;
@ -393,6 +393,10 @@ public class MarkwonTheme {
return color; return color;
} }
public int getLinkColor() {
return linkColor;
}
/** /**
* @since 3.0.0 * @since 3.0.0
*/ */

View File

@ -1,5 +1,6 @@
package io.noties.markwon.core.spans; package io.noties.markwon.core.spans;
import android.graphics.Paint;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.style.MetricAffectingSpan; import android.text.style.MetricAffectingSpan;
@ -26,10 +27,14 @@ public class CodeSpan extends MetricAffectingSpan {
@Override @Override
public void updateDrawState(TextPaint ds) { public void updateDrawState(TextPaint ds) {
apply(ds); apply(ds);
ds.bgColor = theme.getCodeBackgroundColor(ds); // ds.bgColor = theme.getCodeBackgroundColor(ds);
} }
private void apply(TextPaint p) { private void apply(TextPaint p) {
theme.applyCodeTextStyle(p); theme.applyCodeTextStyle(p);
} }
private int getTagWidth(CharSequence text, int start, int end, Paint paint) {
return Math.round(paint.measureText(text.subSequence(start, end).toString()));
}
} }

View File

@ -49,33 +49,33 @@ public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpa
@Override @Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) { public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
if ((level == 1 || level == 2) // if ((level == 1 || level == 2)
&& LeadingMarginUtils.selfEnd(end, text, this)) { // && LeadingMarginUtils.selfEnd(end, text, this)) {
paint.set(p); // paint.set(p);
theme.applyHeadingBreakStyle(paint); // theme.applyHeadingBreakStyle(paint);
final float height = paint.getStrokeWidth(); // final float height = paint.getStrokeWidth();
if (height > .0F) { // if (height > .0F) {
final int b = (int) (bottom - height + .5F); // final int b = (int) (bottom - height + .5F);
final int left; // final int left;
final int right; // final int right;
if (dir > 0) { // if (dir > 0) {
left = x; // left = x;
right = c.getWidth(); // right = c.getWidth();
} else { // } else {
left = x - c.getWidth(); // left = x - c.getWidth();
right = x; // right = x;
} // }
rect.set(left, b, right, bottom); // rect.set(left, b, right, bottom);
c.drawRect(rect, paint); // c.drawRect(rect, paint);
} // }
} // }
} }
/** /**

View File

@ -4,6 +4,7 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.text.style.ReplacementSpan; import android.text.style.ReplacementSpan;
import android.util.Log;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
@ -65,11 +66,20 @@ public class AsyncDrawableSpan extends ReplacementSpan {
final Rect rect = drawable.getBounds(); final Rect rect = drawable.getBounds();
if (fm != null) { if (fm != null) {
fm.ascent = -rect.bottom; // fm.ascent = -rect.bottom;
fm.descent = 0; // fm.descent = 0;
//
// fm.top = fm.ascent;
// fm.bottom = 0;
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.descent - fmPaint.ascent;
int drHeight = rect.bottom - rect.top;
int centerY = fmPaint.ascent + fontHeight / 2;
fm.ascent = centerY - drHeight / 2;
fm.top = fm.ascent; fm.top = fm.ascent;
fm.bottom = 0; fm.bottom = centerY + drHeight / 2;
fm.descent = fm.bottom;
} }
size = rect.right; size = rect.right;
@ -124,6 +134,8 @@ public class AsyncDrawableSpan extends ReplacementSpan {
} }
canvas.translate(x, translationY); canvas.translate(x, translationY);
drawable.draw(canvas); drawable.draw(canvas);
} catch (Exception e){
Log.e("UseRecycleBitmap", e.toString());
} finally { } finally {
canvas.restoreToCount(save); canvas.restoreToCount(save);
} }

View File

@ -0,0 +1,9 @@
package io.noties.markwon.image;
import android.view.View;
import androidx.annotation.NonNull;
public interface ImageClickResolver {
void clickResolve(@NonNull View view, @NonNull String link);
}

View File

@ -38,17 +38,13 @@ public class ImageSizeResolverDef extends ImageSizeResolver {
// must be applied only if imageSize is null // must be applied only if imageSize is null
final Rect rect; final Rect rect;
final int w = imageBounds.width(); final int w = imageBounds.width();
if (w > canvasWidth) { final float reduceRatio = (float) canvasWidth / w;
final float reduceRatio = (float) w / canvasWidth; rect = new Rect(
rect = new Rect( 0,
0, 0,
0, canvasWidth,
canvasWidth, (int) (imageBounds.height() * reduceRatio + .5F)
(int) (imageBounds.height() / reduceRatio + .5F) );
);
} else {
rect = imageBounds;
}
return rect; return rect;
} }
@ -60,40 +56,40 @@ public class ImageSizeResolverDef extends ImageSizeResolver {
final int imageWidth = imageBounds.width(); final int imageWidth = imageBounds.width();
final int imageHeight = imageBounds.height(); final int imageHeight = imageBounds.height();
final float ratio = (float) imageWidth / imageHeight; final float ratio = (float) imageHeight / imageWidth;
final int w = canvasWidth;
final int h = canvasWidth * (int)ratio;
if (width != null) { rect = new Rect(0, 0, w, h);
final int w; // if (width != null) {
final int h; //
////
if (UNIT_PERCENT.equals(width.unit)) { //// if (UNIT_PERCENT.equals(width.unit)) {
w = (int) (canvasWidth * (width.value / 100.F) + .5F); //// w = (int) (canvasWidth * (width.value / 100.F) + .5F);
} else { //// } else {
w = resolveAbsolute(width, imageWidth, textSize); //// w = resolveAbsolute(width, imageWidth, textSize);
} //// }
//
if (height == null //// if (height == null
|| UNIT_PERCENT.equals(height.unit)) { //// || UNIT_PERCENT.equals(height.unit)) {
h = (int) (w / ratio + .5F); //// h = (int) (w / ratio + .5F);
} else { //// } else {
h = resolveAbsolute(height, imageHeight, textSize); //// h = resolveAbsolute(height, imageHeight, textSize);
} //// }
//
rect = new Rect(0, 0, w, h); // } else if (height != null) {
//
} else if (height != null) { // if (!UNIT_PERCENT.equals(height.unit)) {
// final int h = resolveAbsolute(height, imageHeight, textSize);
if (!UNIT_PERCENT.equals(height.unit)) { // final int w = (int) (h * ratio + .5F);
final int h = resolveAbsolute(height, imageHeight, textSize); // rect = new Rect(0, 0, w, h);
final int w = (int) (h * ratio + .5F); // } else {
rect = new Rect(0, 0, w, h); // rect = imageBounds;
} else { // }
rect = imageBounds; // } else {
} // rect = imageBounds;
} else { // }
rect = imageBounds;
}
return rect; return rect;
} }