Search in sources :

Example 21 with ReplacementSpan

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

the class MeasuredText method setPara.

/**
     * Analyzes text for bidirectional runs.  Allocates working buffers.
     */
void setPara(CharSequence text, int start, int end, TextDirectionHeuristic textDir) {
    mText = text;
    mTextStart = start;
    int len = end - start;
    mLen = len;
    mPos = 0;
    if (mWidths == null || mWidths.length < len) {
        mWidths = new float[ArrayUtils.idealFloatArraySize(len)];
    }
    if (mChars == null || mChars.length < len) {
        mChars = new char[ArrayUtils.idealCharArraySize(len)];
    }
    TextUtils.getChars(text, start, end, mChars, 0);
    if (text instanceof Spanned) {
        Spanned spanned = (Spanned) text;
        ReplacementSpan[] spans = spanned.getSpans(start, end, ReplacementSpan.class);
        for (int i = 0; i < spans.length; i++) {
            int startInPara = spanned.getSpanStart(spans[i]) - start;
            int endInPara = spanned.getSpanEnd(spans[i]) - start;
            // The span interval may be larger and must be restricted to [start, end[
            if (startInPara < 0)
                startInPara = 0;
            if (endInPara > len)
                endInPara = len;
            for (int j = startInPara; j < endInPara; j++) {
                // object replacement character
                mChars[j] = '';
            }
        }
    }
    if ((textDir == TextDirectionHeuristics.LTR || textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR || textDir == TextDirectionHeuristics.ANYRTL_LTR) && TextUtils.doesNotNeedBidi(mChars, 0, len)) {
        mDir = Layout.DIR_LEFT_TO_RIGHT;
        mEasy = true;
    } else {
        if (mLevels == null || mLevels.length < len) {
            mLevels = new byte[ArrayUtils.idealByteArraySize(len)];
        }
        int bidiRequest;
        if (textDir == TextDirectionHeuristics.LTR) {
            bidiRequest = Layout.DIR_REQUEST_LTR;
        } else if (textDir == TextDirectionHeuristics.RTL) {
            bidiRequest = Layout.DIR_REQUEST_RTL;
        } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
            bidiRequest = Layout.DIR_REQUEST_DEFAULT_LTR;
        } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
            bidiRequest = Layout.DIR_REQUEST_DEFAULT_RTL;
        } else {
            boolean isRtl = textDir.isRtl(mChars, 0, len);
            bidiRequest = isRtl ? Layout.DIR_REQUEST_RTL : Layout.DIR_REQUEST_LTR;
        }
        mDir = AndroidBidi.bidi(bidiRequest, mChars, mLevels, len, false);
        mEasy = false;
    }
}
Also used : ReplacementSpan(android.text.style.ReplacementSpan) Paint(android.graphics.Paint)

Example 22 with ReplacementSpan

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

the class MeasuredText method setPara.

/**
     * Analyzes text for bidirectional runs.  Allocates working buffers.
     */
void setPara(CharSequence text, int start, int end, TextDirectionHeuristic textDir, StaticLayout.Builder builder) {
    mBuilder = builder;
    mText = text;
    mTextStart = start;
    int len = end - start;
    mLen = len;
    mPos = 0;
    if (mWidths == null || mWidths.length < len) {
        mWidths = ArrayUtils.newUnpaddedFloatArray(len);
    }
    if (mChars == null || mChars.length < len) {
        mChars = ArrayUtils.newUnpaddedCharArray(len);
    }
    TextUtils.getChars(text, start, end, mChars, 0);
    if (text instanceof Spanned) {
        Spanned spanned = (Spanned) text;
        ReplacementSpan[] spans = spanned.getSpans(start, end, ReplacementSpan.class);
        for (int i = 0; i < spans.length; i++) {
            int startInPara = spanned.getSpanStart(spans[i]) - start;
            int endInPara = spanned.getSpanEnd(spans[i]) - start;
            // The span interval may be larger and must be restricted to [start, end[
            if (startInPara < 0)
                startInPara = 0;
            if (endInPara > len)
                endInPara = len;
            for (int j = startInPara; j < endInPara; j++) {
                // object replacement character
                mChars[j] = '';
            }
        }
    }
    if ((textDir == TextDirectionHeuristics.LTR || textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR || textDir == TextDirectionHeuristics.ANYRTL_LTR) && TextUtils.doesNotNeedBidi(mChars, 0, len)) {
        mDir = Layout.DIR_LEFT_TO_RIGHT;
        mEasy = true;
    } else {
        if (mLevels == null || mLevels.length < len) {
            mLevels = ArrayUtils.newUnpaddedByteArray(len);
        }
        int bidiRequest;
        if (textDir == TextDirectionHeuristics.LTR) {
            bidiRequest = Layout.DIR_REQUEST_LTR;
        } else if (textDir == TextDirectionHeuristics.RTL) {
            bidiRequest = Layout.DIR_REQUEST_RTL;
        } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
            bidiRequest = Layout.DIR_REQUEST_DEFAULT_LTR;
        } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
            bidiRequest = Layout.DIR_REQUEST_DEFAULT_RTL;
        } else {
            boolean isRtl = textDir.isRtl(mChars, 0, len);
            bidiRequest = isRtl ? Layout.DIR_REQUEST_RTL : Layout.DIR_REQUEST_LTR;
        }
        mDir = AndroidBidi.bidi(bidiRequest, mChars, mLevels, len, false);
        mEasy = false;
    }
}
Also used : ReplacementSpan(android.text.style.ReplacementSpan) Paint(android.graphics.Paint)

Example 23 with ReplacementSpan

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

the class Layout method getOffsetAtStartOf.

private int getOffsetAtStartOf(int offset) {
    // zero-width characters, look at callers
    if (offset == 0)
        return 0;
    CharSequence text = mText;
    char c = text.charAt(offset);
    if (c >= '�' && c <= '�') {
        char c1 = text.charAt(offset - 1);
        if (c1 >= '�' && c1 <= '�')
            offset -= 1;
    }
    if (mSpannedText) {
        ReplacementSpan[] spans = ((Spanned) text).getSpans(offset, offset, ReplacementSpan.class);
        for (int i = 0; i < spans.length; i++) {
            int start = ((Spanned) text).getSpanStart(spans[i]);
            int end = ((Spanned) text).getSpanEnd(spans[i]);
            if (start < offset && end > offset)
                offset = start;
        }
    }
    return offset;
}
Also used : ReplacementSpan(android.text.style.ReplacementSpan) Paint(android.graphics.Paint)

Example 24 with ReplacementSpan

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

the class BaseKeyListener method adjustReplacementSpan.

// Returns the offset of the replacement span edge if the offset is inside of the replacement
// span.  Otherwise, does nothing and returns the input offset value.
private static int adjustReplacementSpan(CharSequence text, int offset, boolean moveToStart) {
    if (!(text instanceof Spanned)) {
        return offset;
    }
    ReplacementSpan[] spans = ((Spanned) text).getSpans(offset, offset, ReplacementSpan.class);
    for (int i = 0; i < spans.length; i++) {
        final int start = ((Spanned) text).getSpanStart(spans[i]);
        final int end = ((Spanned) text).getSpanEnd(spans[i]);
        if (start < offset && end > offset) {
            offset = moveToStart ? start : end;
        }
    }
    return offset;
}
Also used : ReplacementSpan(android.text.style.ReplacementSpan) Paint(android.graphics.Paint)

Example 25 with ReplacementSpan

use of android.text.style.ReplacementSpan in project XobotOS by xamarin.

the class TextLine method handleRun.

/**
     * Utility function for handling a unidirectional run.  The run must not
     * contain tabs or emoji but can contain styles.
     *
     *
     * @param start the line-relative start of the run
     * @param measureLimit the offset to measure to, between start and limit inclusive
     * @param limit the limit of the run
     * @param runIsRtl true if the run is right-to-left
     * @param c the canvas, can be null
     * @param x the end of the run closest to the leading margin
     * @param top the top of the line
     * @param y the baseline
     * @param bottom the bottom of the line
     * @param fmi receives metrics information, can be null
     * @param needWidth true if the width is required
     * @return the signed width of the run based on the run direction; only
     * valid if needWidth is true
     */
private float handleRun(int start, int measureLimit, int limit, boolean runIsRtl, Canvas c, float x, int top, int y, int bottom, FontMetricsInt fmi, boolean needWidth) {
    // Case of an empty line, make sure we update fmi according to mPaint
    if (start == measureLimit) {
        TextPaint wp = mWorkPaint;
        wp.set(mPaint);
        if (fmi != null) {
            expandMetricsFromPaint(fmi, wp);
        }
        return 0f;
    }
    if (mSpanned == null) {
        TextPaint wp = mWorkPaint;
        wp.set(mPaint);
        final int mlimit = measureLimit;
        return handleText(wp, start, mlimit, start, limit, runIsRtl, c, x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
    }
    final SpanSet<MetricAffectingSpan> metricAffectingSpans = new SpanSet<MetricAffectingSpan>(mSpanned, mStart + start, mStart + limit, MetricAffectingSpan.class);
    final SpanSet<CharacterStyle> characterStyleSpans = new SpanSet<CharacterStyle>(mSpanned, mStart + start, mStart + limit, CharacterStyle.class);
    // Shaping needs to take into account context up to metric boundaries,
    // but rendering needs to take into account character style boundaries.
    // So we iterate through metric runs to get metric bounds,
    // then within each metric run iterate through character style runs
    // for the run bounds.
    final float originalX = x;
    for (int i = start, inext; i < measureLimit; i = inext) {
        TextPaint wp = mWorkPaint;
        wp.set(mPaint);
        inext = metricAffectingSpans.getNextTransition(mStart + i, mStart + limit) - mStart;
        int mlimit = Math.min(inext, measureLimit);
        ReplacementSpan replacement = null;
        for (int j = 0; j < metricAffectingSpans.numberOfSpans; j++) {
            // empty by construction. This special case in getSpans() explains the >= & <= tests
            if ((metricAffectingSpans.spanStarts[j] >= mStart + mlimit) || (metricAffectingSpans.spanEnds[j] <= mStart + i))
                continue;
            MetricAffectingSpan span = metricAffectingSpans.spans[j];
            if (span instanceof ReplacementSpan) {
                replacement = (ReplacementSpan) span;
            } else {
                // We might have a replacement that uses the draw
                // state, otherwise measure state would suffice.
                span.updateDrawState(wp);
            }
        }
        if (replacement != null) {
            x += handleReplacement(replacement, wp, i, mlimit, runIsRtl, c, x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
            continue;
        }
        if (c == null) {
            x += handleText(wp, i, mlimit, i, inext, runIsRtl, c, x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
        } else {
            for (int j = i, jnext; j < mlimit; j = jnext) {
                jnext = characterStyleSpans.getNextTransition(mStart + j, mStart + mlimit) - mStart;
                wp.set(mPaint);
                for (int k = 0; k < characterStyleSpans.numberOfSpans; k++) {
                    // Intentionally using >= and <= as explained above
                    if ((characterStyleSpans.spanStarts[k] >= mStart + jnext) || (characterStyleSpans.spanEnds[k] <= mStart + j))
                        continue;
                    CharacterStyle span = characterStyleSpans.spans[k];
                    span.updateDrawState(wp);
                }
                x += handleText(wp, j, jnext, i, inext, runIsRtl, c, x, top, y, bottom, fmi, needWidth || jnext < measureLimit);
            }
        }
    }
    return x - originalX;
}
Also used : ReplacementSpan(android.text.style.ReplacementSpan) Paint(android.graphics.Paint) MetricAffectingSpan(android.text.style.MetricAffectingSpan) CharacterStyle(android.text.style.CharacterStyle)

Aggregations

Paint (android.graphics.Paint)43 ReplacementSpan (android.text.style.ReplacementSpan)43 MetricAffectingSpan (android.text.style.MetricAffectingSpan)22 CharacterStyle (android.text.style.CharacterStyle)8 TextPaint (android.text.TextPaint)2