Clean up the underline investigations

This commit is contained in:
Dimitry Ivanov 2020-04-28 18:22:37 +03:00
parent a135e07f16
commit 5451a2722e
5 changed files with 0 additions and 209 deletions

View File

@ -1,20 +0,0 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion config['compile-sdk']
buildToolsVersion config['build-tools']
defaultConfig {
minSdkVersion config['min-sdk']
targetSdkVersion config['target-sdk']
versionCode 1
versionName version
}
}
dependencies {
api project(':markwon-core')
}
registerArtifact(this)

View File

@ -1,4 +0,0 @@
POM_NAME=Spans Better
POM_ARTIFACT_ID=spans-better
POM_DESCRIPTION=Better spans
POM_PACKAGING=aar

View File

@ -1 +0,0 @@
<manifest package="io.noties.markwon.spans.better" />

View File

@ -1,183 +0,0 @@
package io.noties.markwon.spans.better;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.text.Layout;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.LineBackgroundSpan;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import io.noties.markwon.core.spans.TextViewSpan;
import static java.lang.Math.max;
import static java.lang.Math.min;
/**
* Credit goes to [Romain Guy](https://github.com/romainguy/elegant-underline)
*
* @since $nap;
*/
public class BetterUnderlineSpan implements LineBackgroundSpan {
public enum Type {
@RequiresApi(Build.VERSION_CODES.KITKAT)
PATH,
REGION
}
private static final float UNDERLINE_CLEAR_GAP = 5.5F;
private final Path underline = new Path();
private final Path outline = new Path();
private final Paint stroke = new Paint();
private final Path strokedOutline = new Path();
private char[] chars;
BetterUnderlineSpan() {
stroke.setStyle(Paint.Style.FILL_AND_STROKE);
stroke.setStrokeCap(Paint.Cap.BUTT);
}
@Override
public void drawBackground(
Canvas c,
Paint p,
int left,
int right,
int top,
int baseline,
int bottom,
CharSequence text,
int start,
int end,
int lnum
) {
final Spanned spanned = (Spanned) text;
final TextView textView = TextViewSpan.textViewOf(spanned);
if (textView == null) {
// no, cannot do it, the whole text will be changed
// p.setUnderlineText(true);
return;
}
final Layout layout = textView.getLayout();
final int selfStart = spanned.getSpanStart(this);
final int selfEnd = spanned.getSpanEnd(this);
// TODO: also doesn't mean that it is last line, imagine text after span is ended
final boolean isLastLine = end == selfEnd || (selfEnd == (end - 1));
final int s = max(selfStart, start);
// e - 1, but only if not last?
// oh... layout line count != span lines..
final int e = min(selfEnd, end) - (isLastLine ? 0 : 1);
final int l = (int) (layout.getPrimaryHorizontal(s) + .5F);
final int r = (int) (layout.getPrimaryHorizontal(e) + .5F);
final int b = getLineBottom(layout, lnum, isLastLine);
final float density = textView.getResources().getDisplayMetrics().density;
underline.rewind();
// TODO: proper baseline
// underline.addRect(
// l, b - (1.8F * density),
// r, b,
// Path.Direction.CW
//
// );
// TODO: this must be configured somehow...
final int diff = (int) (p.descent() / 2F + .5F);
underline.addRect(
l, baseline + diff,
r, baseline + diff + (density * 0.8F),
Path.Direction.CW
);
outline.rewind();
// reallocate only if less, otherwise re-use and then send actual indexes
// TODO: would this return proper array for the last line?!
chars = new char[e - s];
TextUtils.getChars(spanned, s, e, chars, 0);
p.getTextPath(
chars,
0, (e - s),
l, baseline,
outline
);
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
c.drawPath(outline, paint);
outline.op(underline, Path.Op.INTERSECT);
strokedOutline.rewind();
stroke.setStrokeWidth(UNDERLINE_CLEAR_GAP * density);
stroke.getFillPath(outline, strokedOutline);
underline.op(strokedOutline, Path.Op.DIFFERENCE);
c.drawPath(underline, p);
}
private static final float DEFAULT_EXTRA = 0F;
private static final float DEFAULT_MULTIPLIER = 1F;
private static int getLineBottom(@NonNull Layout layout, int line, boolean isLastLine) {
final int bottom = layout.getLineBottom(line);
final boolean lastLineSpacingNotAdded = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// TODO: layout line count != span occupied lines
// final boolean isLastLine = line == layout.getLineCount() - 1;
final int lineBottom;
final float lineSpacingExtra = layout.getSpacingAdd();
final float lineSpacingMultiplier = layout.getSpacingMultiplier();
// simplified check
final boolean hasLineSpacing = lineSpacingExtra != DEFAULT_EXTRA
|| lineSpacingMultiplier != DEFAULT_MULTIPLIER;
if (!hasLineSpacing
|| (isLastLine && lastLineSpacingNotAdded)) {
lineBottom = bottom;
} else {
final float extra;
if (Float.compare(DEFAULT_MULTIPLIER, lineSpacingMultiplier) != 0) {
final int lineHeight = getLineHeight(layout, line);
extra = lineHeight -
((lineHeight - lineSpacingExtra) / lineSpacingMultiplier);
} else {
extra = lineSpacingExtra;
}
lineBottom = (int) (bottom - extra + .5F);
}
if (isLastLine) {
return lineBottom - layout.getBottomPadding();
}
return lineBottom;
}
private static int getLineHeight(@NonNull Layout layout, int line) {
return layout.getLineTop(line + 1) - layout.getLineTop(line);
}
}

View File

@ -16,6 +16,5 @@ include ':app', ':sample',
':markwon-recycler', ':markwon-recycler',
':markwon-recycler-table', ':markwon-recycler-table',
':markwon-simple-ext', ':markwon-simple-ext',
':markwon-spans-better',
':markwon-syntax-highlight', ':markwon-syntax-highlight',
':markwon-test-span' ':markwon-test-span'