Search in sources :

Example 1 with LeadingMarginSpan

use of android.text.style.LeadingMarginSpan in project android_frameworks_base by ParanoidAndroid.

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 i = firstLine; i <= lastLine; 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 (mSpannedText) {
            Spanned sp = (Spanned) buf;
            int textLength = buf.length();
            boolean isFirstParaLine = (start == 0 || buf.charAt(start - 1) == '\n');
            // our problem.
            if (start >= spanEnd && (i == 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;
            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(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 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 && !mSpannedText && !hasTabOrEmoji) {
            // 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, hasTabOrEmoji, tabStops);
            tl.draw(canvas, x, ltop, lbaseline, lbottom);
        }
    }
    TextLine.recycle(tl);
}
Also used : AlignmentSpan(android.text.style.AlignmentSpan) ParagraphStyle(android.text.style.ParagraphStyle) Paint(android.graphics.Paint) LeadingMarginSpan2(android.text.style.LeadingMarginSpan.LeadingMarginSpan2) LeadingMarginSpan(android.text.style.LeadingMarginSpan)

Example 2 with LeadingMarginSpan

use of android.text.style.LeadingMarginSpan in project android_frameworks_base by ParanoidAndroid.

the class Layout method getParagraphLeadingMargin.

/**
     * Returns the effective leading margin (unsigned) for this line,
     * taking into account LeadingMarginSpan and LeadingMarginSpan2.
     * @param line the line index
     * @return the leading margin of this line
     */
private int getParagraphLeadingMargin(int line) {
    if (!mSpannedText) {
        return 0;
    }
    Spanned spanned = (Spanned) mText;
    int lineStart = getLineStart(line);
    int lineEnd = getLineEnd(line);
    int spanEnd = spanned.nextSpanTransition(lineStart, lineEnd, LeadingMarginSpan.class);
    LeadingMarginSpan[] spans = getParagraphSpans(spanned, lineStart, spanEnd, LeadingMarginSpan.class);
    if (spans.length == 0) {
        // no leading margin span;
        return 0;
    }
    int margin = 0;
    boolean isFirstParaLine = lineStart == 0 || spanned.charAt(lineStart - 1) == '\n';
    for (int i = 0; i < spans.length; i++) {
        LeadingMarginSpan span = spans[i];
        boolean useFirstLineMargin = isFirstParaLine;
        if (span instanceof LeadingMarginSpan2) {
            int spStart = spanned.getSpanStart(span);
            int spanLine = getLineForOffset(spStart);
            int count = ((LeadingMarginSpan2) span).getLeadingMarginLineCount();
            useFirstLineMargin = line < spanLine + count;
        }
        margin += span.getLeadingMargin(useFirstLineMargin);
    }
    return margin;
}
Also used : LeadingMarginSpan2(android.text.style.LeadingMarginSpan.LeadingMarginSpan2) LeadingMarginSpan(android.text.style.LeadingMarginSpan) Paint(android.graphics.Paint)

Example 3 with LeadingMarginSpan

use of android.text.style.LeadingMarginSpan in project platform_frameworks_base by android.

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);
}
Also used : AlignmentSpan(android.text.style.AlignmentSpan) ParagraphStyle(android.text.style.ParagraphStyle) Paint(android.graphics.Paint) LeadingMarginSpan2(android.text.style.LeadingMarginSpan.LeadingMarginSpan2) LeadingMarginSpan(android.text.style.LeadingMarginSpan)

Example 4 with LeadingMarginSpan

use of android.text.style.LeadingMarginSpan in project platform_frameworks_base by android.

the class Layout method measurePara.

/* package */
static float measurePara(TextPaint paint, CharSequence text, int start, int end) {
    MeasuredText mt = MeasuredText.obtain();
    TextLine tl = TextLine.obtain();
    try {
        mt.setPara(text, start, end, TextDirectionHeuristics.LTR, null);
        Directions directions;
        int dir;
        if (mt.mEasy) {
            directions = DIRS_ALL_LEFT_TO_RIGHT;
            dir = Layout.DIR_LEFT_TO_RIGHT;
        } else {
            directions = AndroidBidi.directions(mt.mDir, mt.mLevels, 0, mt.mChars, 0, mt.mLen);
            dir = mt.mDir;
        }
        char[] chars = mt.mChars;
        int len = mt.mLen;
        boolean hasTabs = false;
        TabStops tabStops = null;
        // leading margins should be taken into account when measuring a paragraph
        int margin = 0;
        if (text instanceof Spanned) {
            Spanned spanned = (Spanned) text;
            LeadingMarginSpan[] spans = getParagraphSpans(spanned, start, end, LeadingMarginSpan.class);
            for (LeadingMarginSpan lms : spans) {
                margin += lms.getLeadingMargin(true);
            }
        }
        for (int i = 0; i < len; ++i) {
            if (chars[i] == '\t') {
                hasTabs = true;
                if (text instanceof Spanned) {
                    Spanned spanned = (Spanned) text;
                    int spanEnd = spanned.nextSpanTransition(start, end, TabStopSpan.class);
                    TabStopSpan[] spans = getParagraphSpans(spanned, start, spanEnd, TabStopSpan.class);
                    if (spans.length > 0) {
                        tabStops = new TabStops(TAB_INCREMENT, spans);
                    }
                }
                break;
            }
        }
        tl.set(paint, text, start, end, dir, directions, hasTabs, tabStops);
        return margin + tl.metrics(null);
    } finally {
        TextLine.recycle(tl);
        MeasuredText.recycle(mt);
    }
}
Also used : TabStopSpan(android.text.style.TabStopSpan) LeadingMarginSpan(android.text.style.LeadingMarginSpan) Paint(android.graphics.Paint)

Example 5 with LeadingMarginSpan

use of android.text.style.LeadingMarginSpan in project TextJustify-Android by bluejamesbond.

the class SpannableDocumentLayout method onMeasure.

@SuppressWarnings("ConstantConditions")
@Override
public boolean onMeasure(IProgress<Float> progress, ICancel<Boolean> cancelled) {
    boolean done = true;
    float parentWidth = params.getParentWidth();
    float boundWidth = params.getParentWidth() - params.getInsetPaddingLeft() - params.getInsetPaddingRight();
    mLeadMarginSpanDrawEvents = new LinkedList<>();
    StaticLayout staticLayout = new StaticLayout(getText(), (TextPaint) getPaint(), (int) boundWidth, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
    int[] newTokens = new int[TOKEN_LENGTH * 1000];
    LeadingMarginSpan[] activeLeadSpans = new LeadingMarginSpan[0];
    HashMap<LeadingMarginSpan, Integer> leadSpans = new HashMap<>();
    TextAlignment defAlign = params.textAlignment;
    Spannable textCpy = (Spannable) this.text;
    Paint.FontMetricsInt fmi = paint.getFontMetricsInt();
    int maxTextIndex = textCpy.length() - 1;
    int lines = staticLayout.getLineCount();
    int enableLineBreak = 0;
    int index = 0;
    int lineNumber;
    float x;
    float y = params.insetPaddingTop;
    float left = params.insetPaddingLeft;
    float right = params.insetPaddingRight;
    float lineHeightAdd = params.lineHeightMultiplier;
    float lastAscent;
    float lastDescent;
    boolean isParaStart = true;
    boolean isReverse = params.reverse;
    for (lineNumber = 0; lineNumber < lines; lineNumber++) {
        if (cancelled.isCancelled()) {
            done = false;
            break;
        }
        progress.onUpdate((float) lineNumber / (float) lines);
        newTokens = ammortizeArray(newTokens, index);
        int start = staticLayout.getLineStart(lineNumber);
        int end = staticLayout.getLineEnd(lineNumber);
        float realWidth = boundWidth;
        if (params.debugging) {
            Console.log(start + " => " + end + " :: " + " " + -staticLayout.getLineAscent(lineNumber) + " " + staticLayout.getLineDescent(lineNumber) + " " + textCpy.subSequence(start, end).toString());
        }
        // start == end => end of textCpy
        if (start == end || lineNumber >= params.maxLines) {
            break;
        }
        // Get textCpy alignment for the line
        TextAlignmentSpan[] textAlignmentSpans = textCpy.getSpans(start, end, TextAlignmentSpan.class);
        TextAlignment lineTextAlignment = textAlignmentSpans.length == 0 ? defAlign : textAlignmentSpans[0].getTextAlignment();
        // Calculate components of line height
        lastAscent = -staticLayout.getLineAscent(lineNumber);
        lastDescent = staticLayout.getLineDescent(lineNumber) + lineHeightAdd;
        // Handle reverse
        DirectionSpan[] directionSpans = textCpy.getSpans(start, end, DirectionSpan.class);
        isReverse = directionSpans.length > 0 ? directionSpans[0].isReverse() : params.reverse;
        // Line is ONLY a <br/> or \n
        if (start + 1 == end && (Character.getNumericValue(textCpy.charAt(start)) == -1 || textCpy.charAt(start) == '\n')) {
            // Line break indicates a new paragraph
            // is next
            isParaStart = true;
            // Use the line-height of the next line
            if (lineNumber + 1 < lines) {
                y += enableLineBreak * (-staticLayout.getLineAscent(lineNumber + 1) + staticLayout.getLineDescent(lineNumber + 1));
            }
            // Don't ignore the next line breaks
            enableLineBreak = 1;
            continue;
        } else {
            // Ignore the next line break
            enableLineBreak = 0;
        }
        x = lineTextAlignment == TextAlignment.RIGHT ? right : left;
        y += lastAscent;
        // Line CONTAINS a \n
        boolean isParaEnd = end == maxTextIndex || textCpy.charAt(Math.min(end, maxTextIndex)) == '\n' || textCpy.charAt(end - 1) == '\n';
        if (isParaEnd) {
            enableLineBreak = 1;
        }
        // LeadingMarginSpan block
        if (isParaStart) {
            // Process LeadingMarginSpan
            activeLeadSpans = textCpy.getSpans(start, end, LeadingMarginSpan.class);
            // Set up all the spans
            if (activeLeadSpans.length > 0) {
                for (LeadingMarginSpan leadSpan : activeLeadSpans) {
                    if (!leadSpans.containsKey(leadSpan)) {
                        // Default margin is everything
                        int marginLineCount = -1;
                        if (leadSpan instanceof LeadingMarginSpan.LeadingMarginSpan2) {
                            LeadingMarginSpan.LeadingMarginSpan2 leadSpan2 = ((LeadingMarginSpan.LeadingMarginSpan2) leadSpan);
                            marginLineCount = leadSpan2.getLeadingMarginLineCount();
                        }
                        leadSpans.put(leadSpan, marginLineCount);
                    }
                }
            }
        }
        float totalMargin = 0.0f;
        int top = (int) (y - lastAscent);
        int baseline = (int) (y);
        int bottom = (int) (y + lastDescent);
        for (LeadingMarginSpan leadSpan : activeLeadSpans) {
            // TOKEN_X based on alignment
            float calcX = x;
            // LineAlignment
            int lineAlignmentVal = 1;
            if (lineTextAlignment == TextAlignment.RIGHT) {
                lineAlignmentVal = -1;
                calcX = parentWidth - x;
            }
            // Get current line count
            int spanLines = leadSpans.get(leadSpan);
            // Update only if the valid next valid
            if (spanLines > 0 || spanLines == -1) {
                leadSpans.put(leadSpan, spanLines == -1 ? -1 : spanLines - 1);
                mLeadMarginSpanDrawEvents.add(new LeadingMarginSpanDrawParameters(leadSpan, (int) calcX, lineAlignmentVal, top, baseline, bottom, start, end, isParaStart));
                // Is margin required?
                totalMargin += leadSpan.getLeadingMargin(isParaStart);
            }
        }
        x += totalMargin;
        realWidth -= totalMargin;
        // Disable/enable new paragraph
        isParaStart = isParaEnd;
        // TextAlignmentSpan block
        if (isParaEnd && lineTextAlignment == TextAlignment.JUSTIFIED) {
            lineTextAlignment = isReverse ? TextAlignment.RIGHT : TextAlignment.LEFT;
        }
        if (params.debugging) {
            Console.log(String.format("Align: %s, X: %fpx, Y: %fpx, PWidth: %fpx", lineTextAlignment, x, y, parentWidth));
        }
        switch(lineTextAlignment) {
            case RIGHT:
                {
                    float lineWidth = Styled.measureText(paint, workPaint, textCpy, start, end, fmi);
                    index = pushToken(newTokens, index, start, end, parentWidth - x - lineWidth, y, lastAscent, lastDescent, lineNumber);
                    y += lastDescent;
                    continue;
                }
            case CENTER:
                {
                    float lineWidth = Styled.measureText(paint, workPaint, textCpy, start, end, fmi);
                    index = pushToken(newTokens, index, start, end, x + (realWidth - lineWidth) / 2, y, lastAscent, lastDescent, lineNumber);
                    y += lastDescent;
                    continue;
                }
            case LEFT:
                {
                    index = pushToken(newTokens, index, start, end, x, y, lastAscent, lastDescent, lineNumber);
                    y += lastDescent;
                    continue;
                }
        }
        // FIXME: Space at the end of each line, possibly due to scrollbar offset
        //            LinkedList<Integer> tokenized = tokenize(textCpy, start, end - 1);
        // FIXME: 2016/4/16 Issue #105 bug
        LinkedList<Integer> tokenized = tokenize(textCpy, start, end);
        // If one long word without any spaces
        if (tokenized.size() == 1) {
            int stop = tokenized.get(0);
            // characters individually
            if (getTrimmedLength(textCpy, start, stop) != 0) {
                float[] textWidths = new float[stop - start];
                float sum = 0.0f, textsOffset = 0.0f, offset;
                int m = 0;
                Styled.getTextWidths(paint, workPaint, textCpy, start, stop, textWidths, fmi);
                for (float tw : textWidths) {
                    sum += tw;
                }
                offset = (realWidth - sum) / (textWidths.length - 1);
                for (int k = start; k < stop; k++) {
                    index = pushToken(newTokens, index, k, k + 1, x + textsOffset + (offset * m), y, lastAscent, lastDescent, lineNumber);
                    newTokens = ammortizeArray(newTokens, index);
                    textsOffset += textWidths[m++];
                }
            }
        } else //  Handle multiple words
        {
            int m = 1;
            int indexOffset = 0;
            int startIndex = index;
            int reqSpaces = (tokenized.size() - 1) * TOKEN_LENGTH;
            int rtlZero = 0;
            float rtlRight = 0;
            float rtlMul = 1;
            float lineWidth = 0;
            float offset;
            if (isReverse) {
                indexOffset = -2 * TOKEN_LENGTH;
                rtlRight = parentWidth;
                rtlMul = -1;
                rtlZero = 1;
                // reverse index
                index += reqSpaces;
            }
            // more space
            newTokens = ammortizeArray(newTokens, index + reqSpaces);
            for (int stop : tokenized) {
                float wordWidth = Styled.measureText(paint, workPaint, textCpy, start, stop, fmi);
                // add word
                index = pushToken(newTokens, index, start, stop, rtlRight + rtlMul * (x + lineWidth + rtlZero * wordWidth), y, lastAscent, lastDescent, lineNumber);
                lineWidth += wordWidth;
                start = stop + 1;
                // based on if rtl
                index += indexOffset;
            }
            if (isReverse) {
                index = startIndex + reqSpaces + TOKEN_LENGTH;
            }
            offset = (realWidth - lineWidth) / (float) (tokenized.size() - 1);
            if (isReverse) {
                for (int pos = index - TOKEN_LENGTH * 2; pos >= startIndex; pos -= TOKEN_LENGTH) {
                    newTokens[pos + TOKEN_X] = (int) (((float) newTokens[pos + TOKEN_X]) - (offset * (float) m++));
                }
            } else {
                for (int pos = startIndex + TOKEN_LENGTH; pos < index; pos += TOKEN_LENGTH) {
                    newTokens[pos + TOKEN_X] = (int) (((float) newTokens[pos + TOKEN_X]) + (offset * (float) m++));
                }
            }
        }
        y += lastDescent;
    }
    lineCount = lineNumber;
    tokens = newTokens;
    params.changed = false;
    textChange = !done;
    measuredHeight = (int) (y - lineHeightAdd + params.insetPaddingBottom);
    return done;
}
Also used : DirectionSpan(com.bluejamesbond.text.style.DirectionSpan) HashMap(java.util.HashMap) StaticLayout(android.text.StaticLayout) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) TextAlignmentSpan(com.bluejamesbond.text.style.TextAlignmentSpan) TextAlignment(com.bluejamesbond.text.style.TextAlignment) LeadingMarginSpan(android.text.style.LeadingMarginSpan) Spannable(android.text.Spannable)

Aggregations

LeadingMarginSpan (android.text.style.LeadingMarginSpan)28 Paint (android.graphics.Paint)27 LeadingMarginSpan2 (android.text.style.LeadingMarginSpan.LeadingMarginSpan2)21 TabStopSpan (android.text.style.TabStopSpan)12 AlignmentSpan (android.text.style.AlignmentSpan)8 LineHeightSpan (android.text.style.LineHeightSpan)7 MetricAffectingSpan (android.text.style.MetricAffectingSpan)7 ParagraphStyle (android.text.style.ParagraphStyle)7 Bitmap (android.graphics.Bitmap)2 TextPaint (android.text.TextPaint)2 Spannable (android.text.Spannable)1 StaticLayout (android.text.StaticLayout)1 BulletSpan (android.text.style.BulletSpan)1 LineBackgroundSpan (android.text.style.LineBackgroundSpan)1 StrikethroughSpan (android.text.style.StrikethroughSpan)1 TypefaceSpan (android.text.style.TypefaceSpan)1 DirectionSpan (com.bluejamesbond.text.style.DirectionSpan)1 TextAlignment (com.bluejamesbond.text.style.TextAlignment)1 TextAlignmentSpan (com.bluejamesbond.text.style.TextAlignmentSpan)1 HashMap (java.util.HashMap)1