V1.0.5 (#39)
* Change LinkSpan to extend URLSpan. Allow default linkColor (if not set explicitly) * Fit an image without dimensions to canvas width (and keep ratio) * Add support for separate color for code blocks (#37)
This commit is contained in:
parent
35c39d0f6d
commit
a02e9bc523
@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```groovy
|
```groovy
|
||||||
compile 'ru.noties:markwon:1.0.4'
|
compile 'ru.noties:markwon:1.0.5'
|
||||||
compile 'ru.noties:markwon-image-loader:1.0.4' // optional
|
compile 'ru.noties:markwon-image-loader:1.0.5' // optional
|
||||||
compile 'ru.noties:markwon-view:1.0.4' // optional
|
compile 'ru.noties:markwon-view:1.0.5' // optional
|
||||||
```
|
```
|
||||||
|
|
||||||
## Supported markdown features:
|
## Supported markdown features:
|
||||||
|
@ -52,6 +52,7 @@ public class AsyncDrawable extends Drawable {
|
|||||||
this.imageSize = imageSize;
|
this.imageSize = imageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public String getDestination() {
|
public String getDestination() {
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
@ -172,13 +173,29 @@ public class AsyncDrawable extends Drawable {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private Rect resolveBounds() {
|
private Rect resolveBounds() {
|
||||||
|
|
||||||
final Rect rect;
|
final Rect rect;
|
||||||
|
|
||||||
if (imageSizeResolver == null
|
if (imageSizeResolver == null
|
||||||
|| imageSize == null) {
|
|| imageSize == null) {
|
||||||
rect = result.getBounds();
|
|
||||||
|
// @since 1.0.5
|
||||||
|
final Rect bounds = result.getBounds();
|
||||||
|
if (bounds.width() > canvasWidth) {
|
||||||
|
|
||||||
|
// let's scale image down, as we do not want to expand beyond canvas width
|
||||||
|
final float ratio = (float) bounds.width() / bounds.height();
|
||||||
|
final int height = (int) (canvasWidth / ratio + .5F);
|
||||||
|
rect = new Rect(0, 0, canvasWidth, height);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rect = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
rect = imageSizeResolver.resolveImageSize(imageSize, result.getBounds(), canvasWidth, textSize);
|
rect = imageSizeResolver.resolveImageSize(imageSize, result.getBounds(), canvasWidth, textSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,12 @@ public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan {
|
|||||||
public void updateDrawState(TextPaint ds) {
|
public void updateDrawState(TextPaint ds) {
|
||||||
apply(ds);
|
apply(ds);
|
||||||
if (!multiline) {
|
if (!multiline) {
|
||||||
ds.bgColor = theme.getCodeBackgroundColor(ds);
|
ds.bgColor = theme.getCodeBackgroundColor(ds, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void apply(TextPaint p) {
|
private void apply(TextPaint p) {
|
||||||
theme.applyCodeTextStyle(p);
|
theme.applyCodeTextStyle(p, multiline);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -50,7 +50,7 @@ public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan {
|
|||||||
if (multiline) {
|
if (multiline) {
|
||||||
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
paint.setStyle(Paint.Style.FILL);
|
||||||
paint.setColor(theme.getCodeBackgroundColor(p));
|
paint.setColor(theme.getCodeBackgroundColor(p, true));
|
||||||
|
|
||||||
final int left;
|
final int left;
|
||||||
final int right;
|
final int right;
|
||||||
|
@ -3,9 +3,10 @@ package ru.noties.markwon.spans;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.text.style.ClickableSpan;
|
import android.text.style.ClickableSpan;
|
||||||
|
import android.text.style.URLSpan;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
public class LinkSpan extends ClickableSpan {
|
public class LinkSpan extends URLSpan {
|
||||||
|
|
||||||
public interface Resolver {
|
public interface Resolver {
|
||||||
void resolve(View view, @NonNull String link);
|
void resolve(View view, @NonNull String link);
|
||||||
@ -16,6 +17,7 @@ public class LinkSpan extends ClickableSpan {
|
|||||||
private final Resolver resolver;
|
private final Resolver resolver;
|
||||||
|
|
||||||
public LinkSpan(@NonNull SpannableTheme theme, @NonNull String link, @NonNull Resolver resolver) {
|
public LinkSpan(@NonNull SpannableTheme theme, @NonNull String link, @NonNull Resolver resolver) {
|
||||||
|
super(link);
|
||||||
this.theme = theme;
|
this.theme = theme;
|
||||||
this.link = link;
|
this.link = link;
|
||||||
this.resolver = resolver;
|
this.resolver = resolver;
|
||||||
|
@ -76,9 +76,11 @@ public class SpannableTheme {
|
|||||||
final int linkColor = resolve(context, android.R.attr.textColorLink);
|
final int linkColor = resolve(context, android.R.attr.textColorLink);
|
||||||
final int backgroundColor = resolve(context, android.R.attr.colorBackground);
|
final int backgroundColor = resolve(context, android.R.attr.colorBackground);
|
||||||
|
|
||||||
|
// before 1.0.5 build had `linkColor` set, but in order for spans to use default link color
|
||||||
|
// set directly in widget (or any caller), we should not pass it here
|
||||||
|
|
||||||
final Dip dip = new Dip(context);
|
final Dip dip = new Dip(context);
|
||||||
return new Builder()
|
return new Builder()
|
||||||
.linkColor(linkColor)
|
|
||||||
.codeMultilineMargin(dip.toPx(8))
|
.codeMultilineMargin(dip.toPx(8))
|
||||||
.blockMargin(dip.toPx(24))
|
.blockMargin(dip.toPx(24))
|
||||||
.blockQuoteWidth(dip.toPx(4))
|
.blockQuoteWidth(dip.toPx(4))
|
||||||
@ -145,9 +147,15 @@ public class SpannableTheme {
|
|||||||
// by default - main text color
|
// by default - main text color
|
||||||
protected final int codeTextColor;
|
protected final int codeTextColor;
|
||||||
|
|
||||||
|
// by default - codeTextColor
|
||||||
|
protected final int codeBlockTextColor;
|
||||||
|
|
||||||
// by default 0.1 alpha of textColor/codeTextColor
|
// by default 0.1 alpha of textColor/codeTextColor
|
||||||
protected final int codeBackgroundColor;
|
protected final int codeBackgroundColor;
|
||||||
|
|
||||||
|
// by default codeBackgroundColor
|
||||||
|
protected final int codeBlockBackgroundColor;
|
||||||
|
|
||||||
// by default `width` of a space char... it's fun and games, but span doesn't have access to paint in `getLeadingMargin`
|
// by default `width` of a space char... it's fun and games, but span doesn't have access to paint in `getLeadingMargin`
|
||||||
// so, we need to set this value explicitly (think of an utility method, that takes TextView/TextPaint and measures space char)
|
// so, we need to set this value explicitly (think of an utility method, that takes TextView/TextPaint and measures space char)
|
||||||
protected final int codeMultilineMargin;
|
protected final int codeMultilineMargin;
|
||||||
@ -198,7 +206,9 @@ public class SpannableTheme {
|
|||||||
this.bulletListItemStrokeWidth = builder.bulletListItemStrokeWidth;
|
this.bulletListItemStrokeWidth = builder.bulletListItemStrokeWidth;
|
||||||
this.bulletWidth = builder.bulletWidth;
|
this.bulletWidth = builder.bulletWidth;
|
||||||
this.codeTextColor = builder.codeTextColor;
|
this.codeTextColor = builder.codeTextColor;
|
||||||
|
this.codeBlockTextColor = builder.codeBlockTextColor;
|
||||||
this.codeBackgroundColor = builder.codeBackgroundColor;
|
this.codeBackgroundColor = builder.codeBackgroundColor;
|
||||||
|
this.codeBlockBackgroundColor = builder.codeBlockBackgroundColor;
|
||||||
this.codeMultilineMargin = builder.codeMultilineMargin;
|
this.codeMultilineMargin = builder.codeMultilineMargin;
|
||||||
this.codeTypeface = builder.codeTypeface;
|
this.codeTypeface = builder.codeTypeface;
|
||||||
this.codeTextSize = builder.codeTextSize;
|
this.codeTextSize = builder.codeTextSize;
|
||||||
@ -214,12 +224,30 @@ public class SpannableTheme {
|
|||||||
this.taskListDrawable = builder.taskListDrawable;
|
this.taskListDrawable = builder.taskListDrawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.5
|
||||||
|
*/
|
||||||
|
public void applyLinkStyle(@NonNull TextPaint paint) {
|
||||||
|
paint.setUnderlineText(true);
|
||||||
|
if (linkColor != 0) {
|
||||||
|
paint.setColor(linkColor);
|
||||||
|
} else {
|
||||||
|
// if linkColor is not specified during configuration -> use default one
|
||||||
|
paint.setColor(paint.linkColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void applyLinkStyle(@NonNull Paint paint) {
|
public void applyLinkStyle(@NonNull Paint paint) {
|
||||||
paint.setUnderlineText(true);
|
paint.setUnderlineText(true);
|
||||||
if (linkColor != 0) {
|
if (linkColor != 0) {
|
||||||
// by default we will be using text color
|
// by default we will be using text color
|
||||||
paint.setColor(linkColor);
|
paint.setColor(linkColor);
|
||||||
|
} else {
|
||||||
|
// @since 1.0.5, if link color is specified during configuration, _try_ to use the
|
||||||
|
// default one (if provided paint is an instance of TextPaint)
|
||||||
|
if (paint instanceof TextPaint) {
|
||||||
|
paint.setColor(((TextPaint) paint).linkColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +306,16 @@ public class SpannableTheme {
|
|||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyCodeTextStyle(@NonNull Paint paint) {
|
/**
|
||||||
|
* Modified in 1.0.5 to accept `multiline` argument
|
||||||
|
*/
|
||||||
|
public void applyCodeTextStyle(@NonNull Paint paint, boolean multiline) {
|
||||||
|
|
||||||
if (codeTextColor != 0) {
|
// @since 1.0.5 added handling of multiline code blocks
|
||||||
|
if (multiline
|
||||||
|
&& codeBlockTextColor != 0) {
|
||||||
|
paint.setColor(codeBlockTextColor);
|
||||||
|
} else if (codeTextColor != 0) {
|
||||||
paint.setColor(codeTextColor);
|
paint.setColor(codeTextColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,13 +347,23 @@ public class SpannableTheme {
|
|||||||
return codeMultilineMargin;
|
return codeMultilineMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCodeBackgroundColor(@NonNull Paint paint) {
|
/**
|
||||||
|
* Modified in 1.0.5 to accept `multiline` argument
|
||||||
|
*/
|
||||||
|
public int getCodeBackgroundColor(@NonNull Paint paint, boolean multiline) {
|
||||||
|
|
||||||
final int color;
|
final int color;
|
||||||
if (codeBackgroundColor != 0) {
|
|
||||||
|
// @since 1.0.5 added handling of multiline code blocks
|
||||||
|
if (multiline
|
||||||
|
&& codeBlockBackgroundColor != 0) {
|
||||||
|
color = codeBlockBackgroundColor;
|
||||||
|
} else if (codeBackgroundColor != 0) {
|
||||||
color = codeBackgroundColor;
|
color = codeBackgroundColor;
|
||||||
} else {
|
} else {
|
||||||
color = ColorUtils.applyAlpha(paint.getColor(), CODE_DEF_BACKGROUND_COLOR_ALPHA);
|
color = ColorUtils.applyAlpha(paint.getColor(), CODE_DEF_BACKGROUND_COLOR_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,6 +472,7 @@ public class SpannableTheme {
|
|||||||
return taskListDrawable;
|
return taskListDrawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private int linkColor;
|
private int linkColor;
|
||||||
@ -437,7 +483,9 @@ public class SpannableTheme {
|
|||||||
private int bulletListItemStrokeWidth;
|
private int bulletListItemStrokeWidth;
|
||||||
private int bulletWidth;
|
private int bulletWidth;
|
||||||
private int codeTextColor;
|
private int codeTextColor;
|
||||||
|
private int codeBlockTextColor; // @since 1.0.5
|
||||||
private int codeBackgroundColor;
|
private int codeBackgroundColor;
|
||||||
|
private int codeBlockBackgroundColor; // @since 1.0.5
|
||||||
private int codeMultilineMargin;
|
private int codeMultilineMargin;
|
||||||
private Typeface codeTypeface;
|
private Typeface codeTypeface;
|
||||||
private int codeTextSize;
|
private int codeTextSize;
|
||||||
@ -464,7 +512,9 @@ public class SpannableTheme {
|
|||||||
this.bulletListItemStrokeWidth = theme.bulletListItemStrokeWidth;
|
this.bulletListItemStrokeWidth = theme.bulletListItemStrokeWidth;
|
||||||
this.bulletWidth = theme.bulletWidth;
|
this.bulletWidth = theme.bulletWidth;
|
||||||
this.codeTextColor = theme.codeTextColor;
|
this.codeTextColor = theme.codeTextColor;
|
||||||
|
this.codeBlockTextColor = theme.codeBlockTextColor;
|
||||||
this.codeBackgroundColor = theme.codeBackgroundColor;
|
this.codeBackgroundColor = theme.codeBackgroundColor;
|
||||||
|
this.codeBlockBackgroundColor = theme.codeBlockBackgroundColor;
|
||||||
this.codeMultilineMargin = theme.codeMultilineMargin;
|
this.codeMultilineMargin = theme.codeMultilineMargin;
|
||||||
this.codeTypeface = theme.codeTypeface;
|
this.codeTypeface = theme.codeTypeface;
|
||||||
this.codeTextSize = theme.codeTextSize;
|
this.codeTextSize = theme.codeTextSize;
|
||||||
@ -498,6 +548,7 @@ public class SpannableTheme {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
@NonNull
|
@NonNull
|
||||||
public Builder blockQuoteColor(@ColorInt int blockQuoteColor) {
|
public Builder blockQuoteColor(@ColorInt int blockQuoteColor) {
|
||||||
this.blockQuoteColor = blockQuoteColor;
|
this.blockQuoteColor = blockQuoteColor;
|
||||||
@ -528,12 +579,31 @@ public class SpannableTheme {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.5
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder codeBlockTextColor(@ColorInt int codeBlockTextColor) {
|
||||||
|
this.codeBlockTextColor = codeBlockTextColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
@NonNull
|
@NonNull
|
||||||
public Builder codeBackgroundColor(@ColorInt int codeBackgroundColor) {
|
public Builder codeBackgroundColor(@ColorInt int codeBackgroundColor) {
|
||||||
this.codeBackgroundColor = codeBackgroundColor;
|
this.codeBackgroundColor = codeBackgroundColor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.0.5
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder codeBlockBackgroundColor(@ColorInt int codeBlockBackgroundColor) {
|
||||||
|
this.codeBlockBackgroundColor = codeBlockBackgroundColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public Builder codeMultilineMargin(@Dimension int codeMultilineMargin) {
|
public Builder codeMultilineMargin(@Dimension int codeMultilineMargin) {
|
||||||
this.codeMultilineMargin = codeMultilineMargin;
|
this.codeMultilineMargin = codeMultilineMargin;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user