use of android.text.style.ParagraphStyle in project android_frameworks_base by ParanoidAndroid.
the class TextView method spanChange.
/**
* Not private so it can be called from an inner class without going
* through a thunk.
*/
void spanChange(Spanned buf, Object what, int oldStart, int newStart, int oldEnd, int newEnd) {
// XXX Make the start and end move together if this ends up
// spending too much time invalidating.
boolean selChanged = false;
int newSelStart = -1, newSelEnd = -1;
final Editor.InputMethodState ims = mEditor == null ? null : mEditor.mInputMethodState;
if (what == Selection.SELECTION_END) {
selChanged = true;
newSelEnd = newStart;
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
checkForResize();
registerForPreDraw();
if (mEditor != null)
mEditor.makeBlink();
}
}
if (what == Selection.SELECTION_START) {
selChanged = true;
newSelStart = newStart;
if (oldStart >= 0 || newStart >= 0) {
int end = Selection.getSelectionEnd(buf);
invalidateCursor(end, oldStart, newStart);
}
}
if (selChanged) {
mHighlightPathBogus = true;
if (mEditor != null && !isFocused())
mEditor.mSelectionMoved = true;
if ((buf.getSpanFlags(what) & Spanned.SPAN_INTERMEDIATE) == 0) {
if (newSelStart < 0) {
newSelStart = Selection.getSelectionStart(buf);
}
if (newSelEnd < 0) {
newSelEnd = Selection.getSelectionEnd(buf);
}
onSelectionChanged(newSelStart, newSelEnd);
}
}
if (what instanceof UpdateAppearance || what instanceof ParagraphStyle || what instanceof CharacterStyle) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidate();
mHighlightPathBogus = true;
checkForResize();
} else {
ims.mContentChanged = true;
}
if (mEditor != null) {
if (oldStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, oldStart, oldEnd);
if (newStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, newStart, newEnd);
}
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
mHighlightPathBogus = true;
if (ims != null && MetaKeyKeyListener.isSelectingMetaTracker(buf, what)) {
ims.mSelectionModeChanged = true;
}
if (Selection.getSelectionStart(buf) >= 0) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidateCursor();
} else {
ims.mCursorChanged = true;
}
}
}
if (what instanceof ParcelableSpan) {
// the current extract editor would be interested in it.
if (ims != null && ims.mExtractedTextRequest != null) {
if (ims.mBatchEditNesting != 0) {
if (oldStart >= 0) {
if (ims.mChangedStart > oldStart) {
ims.mChangedStart = oldStart;
}
if (ims.mChangedStart > oldEnd) {
ims.mChangedStart = oldEnd;
}
}
if (newStart >= 0) {
if (ims.mChangedStart > newStart) {
ims.mChangedStart = newStart;
}
if (ims.mChangedStart > newEnd) {
ims.mChangedStart = newEnd;
}
}
} else {
if (DEBUG_EXTRACT)
Log.v(LOG_TAG, "Span change outside of batch: " + oldStart + "-" + oldEnd + "," + newStart + "-" + newEnd + " " + what);
ims.mContentChanged = true;
}
}
}
if (mEditor != null && mEditor.mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
mEditor.mSpellChecker.onSpellCheckSpanRemoved((SpellCheckSpan) what);
}
}
use of android.text.style.ParagraphStyle in project XobotOS by xamarin.
the class Layout method draw.
/**
* Draw this Layout on the specified canvas, with the highlight path drawn
* between the background and the text.
*
* @param c the canvas
* @param highlight the path of the highlight or cursor; can be null
* @param highlightPaint the paint for the highlight
* @param cursorOffsetVertical the amount to temporarily translate the
* canvas while rendering the highlight
*/
public void draw(Canvas c, Path highlight, Paint highlightPaint, int cursorOffsetVertical) {
int dtop, dbottom;
synchronized (sTempRect) {
if (!c.getClipBounds(sTempRect)) {
return;
}
dtop = sTempRect.top;
dbottom = sTempRect.bottom;
}
int top = 0;
int bottom = getLineTop(getLineCount());
if (dtop > top) {
top = dtop;
}
if (dbottom < bottom) {
bottom = dbottom;
}
int first = getLineForVertical(top);
int last = getLineForVertical(bottom);
int previousLineBottom = getLineTop(first);
int previousLineEnd = getLineStart(first);
TextPaint paint = mPaint;
CharSequence buf = mText;
int width = mWidth;
boolean spannedText = mSpannedText;
ParagraphStyle[] spans = NO_PARA_SPANS;
int spanEnd = 0;
int textLength = 0;
// They are evaluated at each line.
if (spannedText) {
Spanned sp = (Spanned) buf;
textLength = buf.length();
for (int i = first; i <= last; i++) {
int start = previousLineEnd;
int end = getLineStart(i + 1);
previousLineEnd = end;
int ltop = previousLineBottom;
int lbottom = getLineTop(i + 1);
previousLineBottom = lbottom;
int lbaseline = lbottom - getLineDescent(i);
if (start >= spanEnd) {
// These should be infrequent, so we'll use this so that
// we don't have to check as often.
spanEnd = sp.nextSpanTransition(start, textLength, LineBackgroundSpan.class);
// All LineBackgroundSpans on a line contribute to its
// background.
spans = getParagraphSpans(sp, start, end, LineBackgroundSpan.class);
}
for (int n = 0; n < spans.length; n++) {
LineBackgroundSpan back = (LineBackgroundSpan) spans[n];
back.drawBackground(c, paint, 0, width, ltop, lbaseline, lbottom, buf, start, end, i);
}
}
// reset to their original values
spanEnd = 0;
previousLineBottom = getLineTop(first);
previousLineEnd = getLineStart(first);
spans = NO_PARA_SPANS;
}
// a non-spanned transformation of a spanned editing buffer.
if (highlight != null) {
if (cursorOffsetVertical != 0) {
c.translate(0, cursorOffsetVertical);
}
c.drawPath(highlight, highlightPaint);
if (cursorOffsetVertical != 0) {
c.translate(0, -cursorOffsetVertical);
}
}
Alignment paraAlign = mAlignment;
TabStops tabStops = null;
boolean tabStopsIsInitialized = false;
TextLine tl = TextLine.obtain();
// line's descent.
for (int i = first; i <= last; i++) {
int start = previousLineEnd;
previousLineEnd = getLineStart(i + 1);
int end = getLineVisibleEnd(i, start, previousLineEnd);
int ltop = previousLineBottom;
int lbottom = getLineTop(i + 1);
previousLineBottom = lbottom;
int lbaseline = lbottom - getLineDescent(i);
int dir = getParagraphDirection(i);
int left = 0;
int right = mWidth;
if (spannedText) {
Spanned sp = (Spanned) buf;
boolean isFirstParaLine = (start == 0 || buf.charAt(start - 1) == '\n');
// our problem.
if (start >= spanEnd && (i == first || isFirstParaLine)) {
spanEnd = sp.nextSpanTransition(start, textLength, ParagraphStyle.class);
spans = getParagraphSpans(sp, start, spanEnd, ParagraphStyle.class);
paraAlign = mAlignment;
for (int n = spans.length - 1; n >= 0; n--) {
if (spans[n] instanceof AlignmentSpan) {
paraAlign = ((AlignmentSpan) spans[n]).getAlignment();
break;
}
}
tabStopsIsInitialized = false;
}
// Draw all leading margin spans. Adjust left or right according
// to the paragraph direction of the line.
final int length = spans.length;
for (int n = 0; n < length; n++) {
if (spans[n] instanceof LeadingMarginSpan) {
LeadingMarginSpan margin = (LeadingMarginSpan) spans[n];
boolean useFirstLineMargin = isFirstParaLine;
if (margin instanceof LeadingMarginSpan2) {
int count = ((LeadingMarginSpan2) margin).getLeadingMarginLineCount();
int startLine = getLineForOffset(sp.getSpanStart(margin));
useFirstLineMargin = i < startLine + count;
}
if (dir == DIR_RIGHT_TO_LEFT) {
margin.drawLeadingMargin(c, paint, right, dir, ltop, lbaseline, lbottom, buf, start, end, isFirstParaLine, this);
right -= margin.getLeadingMargin(useFirstLineMargin);
} else {
margin.drawLeadingMargin(c, paint, left, dir, ltop, lbaseline, lbottom, buf, start, end, isFirstParaLine, this);
left += margin.getLeadingMargin(useFirstLineMargin);
}
}
}
}
boolean hasTabOrEmoji = getLineContainsTab(i);
// Can't tell if we have tabs for sure, currently
if (hasTabOrEmoji && !tabStopsIsInitialized) {
if (tabStops == null) {
tabStops = new TabStops(TAB_INCREMENT, spans);
} else {
tabStops.reset(TAB_INCREMENT, spans);
}
tabStopsIsInitialized = true;
}
// Determine whether the line aligns to normal, opposite, or center.
Alignment align = paraAlign;
if (align == Alignment.ALIGN_LEFT) {
align = (dir == DIR_LEFT_TO_RIGHT) ? Alignment.ALIGN_NORMAL : Alignment.ALIGN_OPPOSITE;
} else if (align == Alignment.ALIGN_RIGHT) {
align = (dir == DIR_LEFT_TO_RIGHT) ? Alignment.ALIGN_OPPOSITE : Alignment.ALIGN_NORMAL;
}
int x;
if (align == Alignment.ALIGN_NORMAL) {
if (dir == DIR_LEFT_TO_RIGHT) {
x = left;
} else {
x = right;
}
} else {
int max = (int) getLineExtent(i, tabStops, false);
if (align == Alignment.ALIGN_OPPOSITE) {
if (dir == DIR_LEFT_TO_RIGHT) {
x = right - max;
} else {
x = left - max;
}
} else {
// Alignment.ALIGN_CENTER
max = max & ~1;
x = (right + left - max) >> 1;
}
}
Directions directions = getLineDirections(i);
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !spannedText && !hasTabOrEmoji) {
// XXX: assumes there's nothing additional to be done
c.drawText(buf, start, end, x, lbaseline, paint);
} else {
tl.set(paint, buf, start, end, dir, directions, hasTabOrEmoji, tabStops);
tl.draw(c, x, ltop, lbaseline, lbottom);
}
}
TextLine.recycle(tl);
}
use of android.text.style.ParagraphStyle in project android_frameworks_base by AOSPA.
the class TextView method spanChange.
/**
* Not private so it can be called from an inner class without going
* through a thunk.
*/
void spanChange(Spanned buf, Object what, int oldStart, int newStart, int oldEnd, int newEnd) {
// XXX Make the start and end move together if this ends up
// spending too much time invalidating.
boolean selChanged = false;
int newSelStart = -1, newSelEnd = -1;
final Editor.InputMethodState ims = mEditor == null ? null : mEditor.mInputMethodState;
if (what == Selection.SELECTION_END) {
selChanged = true;
newSelEnd = newStart;
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
checkForResize();
registerForPreDraw();
if (mEditor != null)
mEditor.makeBlink();
}
}
if (what == Selection.SELECTION_START) {
selChanged = true;
newSelStart = newStart;
if (oldStart >= 0 || newStart >= 0) {
int end = Selection.getSelectionEnd(buf);
invalidateCursor(end, oldStart, newStart);
}
}
if (selChanged) {
mHighlightPathBogus = true;
if (mEditor != null && !isFocused())
mEditor.mSelectionMoved = true;
if ((buf.getSpanFlags(what) & Spanned.SPAN_INTERMEDIATE) == 0) {
if (newSelStart < 0) {
newSelStart = Selection.getSelectionStart(buf);
}
if (newSelEnd < 0) {
newSelEnd = Selection.getSelectionEnd(buf);
}
if (mEditor != null) {
mEditor.refreshTextActionMode();
if (!hasSelection() && mEditor.mTextActionMode == null && hasTransientState()) {
// User generated selection has been removed.
setHasTransientState(false);
}
}
onSelectionChanged(newSelStart, newSelEnd);
}
}
if (what instanceof UpdateAppearance || what instanceof ParagraphStyle || what instanceof CharacterStyle) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidate();
mHighlightPathBogus = true;
checkForResize();
} else {
ims.mContentChanged = true;
}
if (mEditor != null) {
if (oldStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, oldStart, oldEnd);
if (newStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, newStart, newEnd);
mEditor.invalidateHandlesAndActionMode();
}
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
mHighlightPathBogus = true;
if (ims != null && MetaKeyKeyListener.isSelectingMetaTracker(buf, what)) {
ims.mSelectionModeChanged = true;
}
if (Selection.getSelectionStart(buf) >= 0) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidateCursor();
} else {
ims.mCursorChanged = true;
}
}
}
if (what instanceof ParcelableSpan) {
// the current extract editor would be interested in it.
if (ims != null && ims.mExtractedTextRequest != null) {
if (ims.mBatchEditNesting != 0) {
if (oldStart >= 0) {
if (ims.mChangedStart > oldStart) {
ims.mChangedStart = oldStart;
}
if (ims.mChangedStart > oldEnd) {
ims.mChangedStart = oldEnd;
}
}
if (newStart >= 0) {
if (ims.mChangedStart > newStart) {
ims.mChangedStart = newStart;
}
if (ims.mChangedStart > newEnd) {
ims.mChangedStart = newEnd;
}
}
} else {
if (DEBUG_EXTRACT)
Log.v(LOG_TAG, "Span change outside of batch: " + oldStart + "-" + oldEnd + "," + newStart + "-" + newEnd + " " + what);
ims.mContentChanged = true;
}
}
}
if (mEditor != null && mEditor.mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
mEditor.mSpellChecker.onSpellCheckSpanRemoved((SpellCheckSpan) what);
}
}
use of android.text.style.ParagraphStyle in project android_frameworks_base by AOSPA.
the class Layout method drawText.
/**
* @hide
*/
public void drawText(Canvas canvas, int firstLine, int lastLine) {
int previousLineBottom = getLineTop(firstLine);
int previousLineEnd = getLineStart(firstLine);
ParagraphStyle[] spans = NO_PARA_SPANS;
int spanEnd = 0;
TextPaint paint = mPaint;
CharSequence buf = mText;
Alignment paraAlign = mAlignment;
TabStops tabStops = null;
boolean tabStopsIsInitialized = false;
TextLine tl = TextLine.obtain();
// The baseline is the top of the following line minus the current line's descent.
for (int lineNum = firstLine; lineNum <= lastLine; lineNum++) {
int start = previousLineEnd;
previousLineEnd = getLineStart(lineNum + 1);
int end = getLineVisibleEnd(lineNum, start, previousLineEnd);
int ltop = previousLineBottom;
int lbottom = getLineTop(lineNum + 1);
previousLineBottom = lbottom;
int lbaseline = lbottom - getLineDescent(lineNum);
int dir = getParagraphDirection(lineNum);
int left = 0;
int right = mWidth;
if (mSpannedText) {
Spanned sp = (Spanned) buf;
int textLength = buf.length();
boolean isFirstParaLine = (start == 0 || buf.charAt(start - 1) == '\n');
// our problem.
if (start >= spanEnd && (lineNum == firstLine || isFirstParaLine)) {
spanEnd = sp.nextSpanTransition(start, textLength, ParagraphStyle.class);
spans = getParagraphSpans(sp, start, spanEnd, ParagraphStyle.class);
paraAlign = mAlignment;
for (int n = spans.length - 1; n >= 0; n--) {
if (spans[n] instanceof AlignmentSpan) {
paraAlign = ((AlignmentSpan) spans[n]).getAlignment();
break;
}
}
tabStopsIsInitialized = false;
}
// Draw all leading margin spans. Adjust left or right according
// to the paragraph direction of the line.
final int length = spans.length;
boolean useFirstLineMargin = isFirstParaLine;
for (int n = 0; n < length; n++) {
if (spans[n] instanceof LeadingMarginSpan2) {
int count = ((LeadingMarginSpan2) spans[n]).getLeadingMarginLineCount();
int startLine = getLineForOffset(sp.getSpanStart(spans[n]));
// the count that is greatest
if (lineNum < startLine + count) {
useFirstLineMargin = true;
break;
}
}
}
for (int n = 0; n < length; n++) {
if (spans[n] instanceof LeadingMarginSpan) {
LeadingMarginSpan margin = (LeadingMarginSpan) spans[n];
if (dir == DIR_RIGHT_TO_LEFT) {
margin.drawLeadingMargin(canvas, paint, right, dir, ltop, lbaseline, lbottom, buf, start, end, isFirstParaLine, this);
right -= margin.getLeadingMargin(useFirstLineMargin);
} else {
margin.drawLeadingMargin(canvas, paint, left, dir, ltop, lbaseline, lbottom, buf, start, end, isFirstParaLine, this);
left += margin.getLeadingMargin(useFirstLineMargin);
}
}
}
}
boolean hasTab = getLineContainsTab(lineNum);
// Can't tell if we have tabs for sure, currently
if (hasTab && !tabStopsIsInitialized) {
if (tabStops == null) {
tabStops = new TabStops(TAB_INCREMENT, spans);
} else {
tabStops.reset(TAB_INCREMENT, spans);
}
tabStopsIsInitialized = true;
}
// Determine whether the line aligns to normal, opposite, or center.
Alignment align = paraAlign;
if (align == Alignment.ALIGN_LEFT) {
align = (dir == DIR_LEFT_TO_RIGHT) ? Alignment.ALIGN_NORMAL : Alignment.ALIGN_OPPOSITE;
} else if (align == Alignment.ALIGN_RIGHT) {
align = (dir == DIR_LEFT_TO_RIGHT) ? Alignment.ALIGN_OPPOSITE : Alignment.ALIGN_NORMAL;
}
int x;
if (align == Alignment.ALIGN_NORMAL) {
if (dir == DIR_LEFT_TO_RIGHT) {
x = left + getIndentAdjust(lineNum, Alignment.ALIGN_LEFT);
} else {
x = right + getIndentAdjust(lineNum, Alignment.ALIGN_RIGHT);
}
} else {
int max = (int) getLineExtent(lineNum, tabStops, false);
if (align == Alignment.ALIGN_OPPOSITE) {
if (dir == DIR_LEFT_TO_RIGHT) {
x = right - max + getIndentAdjust(lineNum, Alignment.ALIGN_RIGHT);
} else {
x = left - max + getIndentAdjust(lineNum, Alignment.ALIGN_LEFT);
}
} else {
// Alignment.ALIGN_CENTER
max = max & ~1;
x = ((right + left - max) >> 1) + getIndentAdjust(lineNum, Alignment.ALIGN_CENTER);
}
}
paint.setHyphenEdit(getHyphen(lineNum));
Directions directions = getLineDirections(lineNum);
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText && !hasTab) {
// XXX: assumes there's nothing additional to be done
canvas.drawText(buf, start, end, x, lbaseline, paint);
} else {
tl.set(paint, buf, start, end, dir, directions, hasTab, tabStops);
tl.draw(canvas, x, ltop, lbaseline, lbottom);
}
paint.setHyphenEdit(0);
}
TextLine.recycle(tl);
}
use of android.text.style.ParagraphStyle in project android_frameworks_base by ResurrectionRemix.
the class HtmlToSpannedConverter method withinBlockquoteIndividual.
private static void withinBlockquoteIndividual(StringBuilder out, Spanned text, int start, int end) {
boolean isInList = false;
int next;
for (int i = start; i <= end; i = next) {
next = TextUtils.indexOf(text, '\n', i, end);
if (next < 0) {
next = end;
}
if (next == i) {
if (isInList) {
// Current paragraph is no longer a list item; close the previously opened list
isInList = false;
out.append("</ul>\n");
}
out.append("<br>\n");
} else {
boolean isListItem = false;
ParagraphStyle[] paragraphStyles = text.getSpans(i, next, ParagraphStyle.class);
for (ParagraphStyle paragraphStyle : paragraphStyles) {
final int spanFlags = text.getSpanFlags(paragraphStyle);
if ((spanFlags & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH && paragraphStyle instanceof BulletSpan) {
isListItem = true;
break;
}
}
if (isListItem && !isInList) {
// Current paragraph is the first item in a list
isInList = true;
out.append("<ul").append(getTextStyles(text, i, next, true, false)).append(">\n");
}
if (isInList && !isListItem) {
// Current paragraph is no longer a list item; close the previously opened list
isInList = false;
out.append("</ul>\n");
}
String tagType = isListItem ? "li" : "p";
out.append("<").append(tagType).append(getTextDirection(text, i, next)).append(getTextStyles(text, i, next, !isListItem, true)).append(">");
withinParagraph(out, text, i, next);
out.append("</");
out.append(tagType);
out.append(">\n");
if (next == end && isInList) {
isInList = false;
out.append("</ul>\n");
}
}
next++;
}
}
Aggregations