opt: draw only visible chars for a line

This commit is contained in:
hyb1996 2018-02-21 23:22:21 +08:00
parent ea5f80b437
commit 6ca73623a2
4 changed files with 72 additions and 47 deletions

View File

@ -8,8 +8,8 @@ android {
applicationId "com.stardust.scriptdroid"
minSdkVersion 17
targetSdkVersion 23
versionCode 250
versionName "3.0.0 Alpha50"
versionCode 251
versionName "3.1.0 Alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {

View File

@ -23,11 +23,10 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.Layout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import com.stardust.scriptdroid.ui.edit.theme.Theme;
@ -128,7 +127,9 @@ public class CodeEditText extends AppCompatEditText {
int fontCount = 0;
int previousColor = mHighlightTokens.getCharColor(lineStart);
int previousColorPos = lineStart;
for (int i = lineStart; i < lineEnd; i++) {
int visibleCharStart = getVisibleCharIndex(paint, getScrollX(), lineStart, lineEnd);
int visibleCharEnd = getVisibleCharIndex(paint, getScrollX() + getWidth(), lineStart, lineEnd) + 1;
for (int i = visibleCharStart; i < visibleCharEnd && i < lineEnd; i++) {
fontCount++;
int color = mHighlightTokens.getCharColor(i);
if (previousColor != color) {
@ -137,13 +138,30 @@ public class CodeEditText extends AppCompatEditText {
previousColorPos = i;
fontCount = 1;
}
if (i == lineEnd - 1) {
if (i == visibleCharEnd - 1) {
drawText(canvas, paint, paddingLeft, lineBaseline, lineStart, previousColorPos, previousColorPos + fontCount, previousColor);
}
}
}
private int getVisibleCharIndex(Paint paint, int x, int lineStart, int lineEnd) {
if (x == 0)
return lineStart;
int low = lineStart;
int high = lineEnd - 1;
while (low < high) {
int mid = (high + low) >>> 1;
float midX = paint.measureText(getText(), lineStart, mid + 1);
if (x < midX) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
private void drawText(Canvas canvas, Paint paint, int paddingLeft, int lineBaseline, int lineStart, int start, int end, int color) {
if (start >= end) {
return;
@ -162,16 +180,23 @@ public class CodeEditText extends AppCompatEditText {
private long getLineRangeForDraw(Layout layout, Canvas canvas) {
canvas.save();
float clipTop = (mScrollView.getScrollY() == 0) ? 0
: getExtendedPaddingTop() + mScrollView.getScrollY()
int scrollY = getRealScrollY();
float clipTop = (scrollY == 0) ? 0
: getExtendedPaddingTop() + scrollY
- mScrollView.getPaddingTop();
canvas.clipRect(0, clipTop, getWidth(), mScrollView.getScrollY()
canvas.clipRect(0, clipTop, getWidth(), scrollY
+ mScrollView.getHeight());
long lineRangeForDraw = LayoutHelper.getLineRangeForDraw(layout, canvas);
canvas.restore();
return lineRangeForDraw;
}
private int getRealScrollY() {
int scrollY = mScrollView.getScrollY();
View parent = (View) mScrollView.getParent();
return scrollY + parent.getScrollY();
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd);
@ -206,7 +231,6 @@ public class CodeEditText extends AppCompatEditText {
public void updateHighlightTokens(JavaScriptHighlighter.HighlightTokens highlightTokens) {
mHighlightTokens = highlightTokens;
Log.d(LOG_TAG, "tokens = " + highlightTokens);
invalidate();
postInvalidate();
}
}

View File

@ -35,10 +35,41 @@ import io.reactivex.Observable;
*/
public class CodeEditor extends HVScrollView {
public interface CursorChangeCallback {
void onCursorChange(String line, int ch);
}
private CharSequence mReplacement = "";
private String mKeywords;
private int mFoundIndex = -1;
private CodeEditText mCodeEditText;
private PreformEdit mPreformEdit;
private JavaScriptHighlighter mJavaScriptHighlighter;
private Theme mTheme;
public CodeEditor(Context context) {
super(context);
init();
}
public CodeEditor(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setFillViewport(true);
inflate(getContext(), R.layout.code_editor, this);
mCodeEditText = (CodeEditText) findViewById(R.id.code_edit_text);
mPreformEdit = new PreformEdit(mCodeEditText);
mJavaScriptHighlighter = new JavaScriptHighlighter(mTheme, mCodeEditText);
setTheme(Theme.getDefault(getContext()));
}
public Observable<Integer> getLineCount() {
return Observable.just(mCodeEditText.getLayout().getLineCount());
@ -100,39 +131,6 @@ public class CodeEditor extends HVScrollView {
}
public interface CursorChangeCallback {
void onCursorChange(String line, int ch);
}
private CodeEditText mCodeEditText;
private PreformEdit mPreformEdit;
private JavaScriptHighlighter mJavaScriptHighlighter;
private Theme mTheme;
public CodeEditor(Context context) {
super(context);
init();
}
public CodeEditor(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setFillViewport(true);
inflate(getContext(), R.layout.code_editor, this);
mCodeEditText = (CodeEditText) findViewById(R.id.code_edit_text);
mPreformEdit = new PreformEdit(mCodeEditText);
mJavaScriptHighlighter = new JavaScriptHighlighter(mTheme, mCodeEditText);
setTheme(Theme.getDefault(getContext()));
}
public void setTheme(Theme theme) {
mTheme = theme;
mJavaScriptHighlighter.setTheme(theme);

View File

@ -24,6 +24,7 @@ public class JavaScriptHighlighter implements SimpleTextWatcher.AfterTextChanged
private int[] mColors;
private String mText;
private int mCount;
public HighlightTokens(String text) {
mColors = new int[text.length()];
@ -40,6 +41,7 @@ public class JavaScriptHighlighter implements SimpleTextWatcher.AfterTextChanged
for (int i = tokenStart; i < tokenEnd; i++) {
mColors[i] = color;
}
mCount = tokenEnd;
}
@Override
@ -50,7 +52,7 @@ public class JavaScriptHighlighter implements SimpleTextWatcher.AfterTextChanged
}
public int getCharCount() {
return mColors.length;
return mCount;
}
public String getText() {
@ -101,9 +103,10 @@ public class JavaScriptHighlighter implements SimpleTextWatcher.AfterTextChanged
int color = mTheme.getColorForToken(token);
highlightTokens.addToken(ts.getTokenBeg(), ts.getTokenEnd(), color);
}
if (highlightTokens.getCharCount() < sourceString.length()) {
highlightTokens.addToken(highlightTokens.getCharCount(), sourceString.length(), mTheme.getColorForToken(Token.NAME));
}
mCodeEditText.updateHighlightTokens(highlightTokens);
Log.d("Highlighter", "code = " + sourceString);
Log.d("Highlighter", "tokens = " + highlightTokens);
}