Search in sources :

Example 1 with LineHeightSpan

use of jp.sblo.pandora.jota.text.style.LineHeightSpan in project Jota-Text-Editor-old by jiro-aqua.

the class StaticLayout method generate.

/* package */
void generate(CharSequence source, int bufstart, int bufend, TextPaint paint, int outerwidth, Alignment align, float spacingmult, float spacingadd, boolean includepad, boolean trackpad, boolean breakOnlyAtSpaces, float ellipsizedWidth, TextUtils.TruncateAt where, boolean showTab) {
    // Jota Text Editor
    mLineCount = 0;
    int v = 0;
    boolean needMultiply = (spacingmult != 1 || spacingadd != 0);
    Paint.FontMetricsInt fm = mFontMetricsInt;
    int[] choosehtv = null;
    int end = TextUtils.indexOf(source, '\n', bufstart, bufend);
    int bufsiz = end >= 0 ? end - bufstart : bufend - bufstart;
    boolean first = true;
    if (mChdirs == null) {
        mChdirs = new byte[ArrayUtils.idealByteArraySize(bufsiz + 1)];
        mChs = new char[ArrayUtils.idealCharArraySize(bufsiz + 1)];
        mWidths = new float[ArrayUtils.idealIntArraySize((bufsiz + 1) * 2)];
    }
    byte[] chdirs = mChdirs;
    char[] chs = mChs;
    float[] widths = mWidths;
    AlteredCharSequence alter = null;
    // Jota Text Editor
    //        Spanned spanned = null;
    //        if (source instanceof Spanned)
    //            spanned = (Spanned) source;
    // XXX
    int DEFAULT_DIR = DIR_LEFT_TO_RIGHT;
    for (int start = bufstart; start <= bufend; start = end) {
        if (first)
            first = false;
        else
            end = TextUtils.indexOf(source, '\n', start, bufend);
        if (end < 0)
            end = bufend;
        else
            end++;
        int firstWidthLineCount = 1;
        int firstwidth = outerwidth;
        int restwidth = outerwidth;
        LineHeightSpan[] chooseht = null;
        if (end - start > chdirs.length) {
            chdirs = new byte[ArrayUtils.idealByteArraySize(end - start)];
            mChdirs = chdirs;
        }
        if (end - start > chs.length) {
            chs = new char[ArrayUtils.idealCharArraySize(end - start)];
            mChs = chs;
        }
        if ((end - start) * 2 > widths.length) {
            widths = new float[ArrayUtils.idealIntArraySize((end - start) * 2)];
            mWidths = widths;
        }
        TextUtils.getChars(source, start, end, chs, 0);
        final int n = end - start;
        boolean easy = true;
        boolean altered = false;
        // XXX
        int dir = DEFAULT_DIR;
        for (int i = 0; i < n; i++) {
            if (chs[i] >= FIRST_RIGHT_TO_LEFT) {
                easy = false;
                break;
            }
        }
        if (!easy) {
            // XXX put override flags, etc. into chdirs
            dir = bidi(dir, chs, chdirs, n, false);
            for (int i = 0; i < n; i++) {
                if (chdirs[i] == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
                    int j;
                    for (j = i; j < n; j++) {
                        if (chdirs[j] != Character.DIRECTIONALITY_RIGHT_TO_LEFT)
                            break;
                    }
                    if (AndroidCharacter.mirror(chs, i, j - i))
                        altered = true;
                    i = j - 1;
                }
            }
        }
        CharSequence sub;
        if (altered) {
            if (alter == null)
                alter = AlteredCharSequence.make(source, chs, start, end);
            else
                alter.update(chs, start, end);
            sub = alter;
        } else {
            sub = source;
        }
        int width = firstwidth;
        float w = 0;
        int here = start;
        int ok = start;
        float okwidth = w;
        int okascent = 0, okdescent = 0, oktop = 0, okbottom = 0;
        int fit = start;
        float fitwidth = w;
        int fitascent = 0, fitdescent = 0, fittop = 0, fitbottom = 0;
        boolean tab = false;
        int next;
        for (int i = start; i < end; i = next) {
            // Jota Text Editor
            //                if (spanned == null)
            next = end;
            //                else
            //                    next = spanned.nextSpanTransition(i, end,
            //                                                      MetricAffectingSpan.
            //                                                      class);
            //                if (spanned == null) {
            paint.getTextWidths(sub, i, next, widths);
            System.arraycopy(widths, 0, widths, end - start + (i - start), next - i);
            paint.getFontMetricsInt(fm);
            // Jota Text Editor
            //                } else {
            //                    mWorkPaint.baselineShift = 0;
            //
            //                    Styled.getTextWidths(paint, mWorkPaint,
            //                                         spanned, i, next,
            //                                         widths, fm);
            //                    System.arraycopy(widths, 0, widths,
            //                                     end - start + (i - start), next - i);
            //
            //                    if (mWorkPaint.baselineShift < 0) {
            //                        fm.ascent += mWorkPaint.baselineShift;
            //                        fm.top += mWorkPaint.baselineShift;
            //                    } else {
            //                        fm.descent += mWorkPaint.baselineShift;
            //                        fm.bottom += mWorkPaint.baselineShift;
            //                    }
            //                }
            int fmtop = fm.top;
            int fmbottom = fm.bottom;
            int fmascent = fm.ascent;
            int fmdescent = fm.descent;
            for (int j = i; j < next; j++) {
                char c = chs[j - start];
                if (c == '\n') {
                    // Jota Text Editor
                    if (!tab)
                        tab = showTab;
                } else if (c == '\t') {
                    w = Layout.nextTab(sub, start, end, w, null);
                    tab = true;
                } else if (c >= 0xD800 && c <= 0xDFFF && j + 1 < next) {
                    int emoji = Character.codePointAt(chs, j - start);
                    if (emoji >= MIN_EMOJI && emoji <= MAX_EMOJI) {
                        Bitmap bm = EMOJI_FACTORY.getBitmapFromAndroidPua(emoji);
                        if (bm != null) {
                            Paint whichPaint;
                            // Jota Text Editor
                            //                                if (spanned == null) {
                            whichPaint = paint;
                            //                                } else {
                            //                                    whichPaint = mWorkPaint;
                            //                                }
                            float wid = (float) bm.getWidth() * -whichPaint.ascent() / bm.getHeight();
                            w += wid;
                            tab = true;
                            j++;
                        } else {
                            w += widths[j - start + (end - start)];
                        }
                    } else {
                        w += widths[j - start + (end - start)];
                    }
                } else {
                    // Jota Text Editor
                    if (c == 0x3000) {
                        // ideographic space ( for Japanese )
                        if (!tab)
                            tab = showTab;
                    }
                    w += widths[j - start + (end - start)];
                }
                if (w <= width) {
                    fitwidth = w;
                    fit = j + 1;
                    if (fmtop < fittop)
                        fittop = fmtop;
                    if (fmascent < fitascent)
                        fitascent = fmascent;
                    if (fmdescent > fitdescent)
                        fitdescent = fmdescent;
                    if (fmbottom > fitbottom)
                        fitbottom = fmbottom;
                    if (c == ' ' || c == '\t' || ((c == '.' || c == ',' || c == ':' || c == ';') && (j - 1 < here || !Character.isDigit(chs[j - 1 - start])) && (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) || ((c == '/' || c == '-') && (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) || (c >= FIRST_CJK && isIdeographic(c, true) && j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
                        okwidth = w;
                        ok = j + 1;
                        if (fittop < oktop)
                            oktop = fittop;
                        if (fitascent < okascent)
                            okascent = fitascent;
                        if (fitdescent > okdescent)
                            okdescent = fitdescent;
                        if (fitbottom > okbottom)
                            okbottom = fitbottom;
                    }
                } else if (breakOnlyAtSpaces) {
                    if (ok != here) {
                        while (ok < next && chs[ok - start] == ' ') {
                            ok++;
                        }
                        v = out(source, here, ok, okascent, okdescent, oktop, okbottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, needMultiply, start, chdirs, dir, easy, ok == bufend, includepad, trackpad, widths, start, end - start, where, ellipsizedWidth, okwidth, paint);
                        here = ok;
                    } else {
                        // Act like it fit even though it didn't.
                        fitwidth = w;
                        fit = j + 1;
                        if (fmtop < fittop)
                            fittop = fmtop;
                        if (fmascent < fitascent)
                            fitascent = fmascent;
                        if (fmdescent > fitdescent)
                            fitdescent = fmdescent;
                        if (fmbottom > fitbottom)
                            fitbottom = fmbottom;
                    }
                } else {
                    if (ok != here) {
                        while (ok < next && chs[ok - start] == ' ') {
                            ok++;
                        }
                        v = out(source, here, ok, okascent, okdescent, oktop, okbottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, needMultiply, start, chdirs, dir, easy, ok == bufend, includepad, trackpad, widths, start, end - start, where, ellipsizedWidth, okwidth, paint);
                        here = ok;
                    } else if (fit != here) {
                        // Log.e("text", "output fit " + here + " to " +fit);
                        v = out(source, here, fit, fitascent, fitdescent, fittop, fitbottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, needMultiply, start, chdirs, dir, easy, fit == bufend, includepad, trackpad, widths, start, end - start, where, ellipsizedWidth, fitwidth, paint);
                        here = fit;
                    } else {
                        // Log.e("text", "output one " + here + " to " +(here + 1));
                        measureText(paint, mWorkPaint, source, here, here + 1, fm, tab, null);
                        v = out(source, here, here + 1, fm.ascent, fm.descent, fm.top, fm.bottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, needMultiply, start, chdirs, dir, easy, here + 1 == bufend, includepad, trackpad, widths, start, end - start, where, ellipsizedWidth, widths[here - start], paint);
                        here = here + 1;
                    }
                    if (here < i) {
                        // must remeasure
                        j = next = here;
                    } else {
                        // continue looping
                        j = here - 1;
                    }
                    ok = fit = here;
                    w = 0;
                    fitascent = fitdescent = fittop = fitbottom = 0;
                    okascent = okdescent = oktop = okbottom = 0;
                    if (--firstWidthLineCount <= 0) {
                        width = restwidth;
                    }
                }
            }
        }
        if (end != here) {
            if ((fittop | fitbottom | fitdescent | fitascent) == 0) {
                paint.getFontMetricsInt(fm);
                fittop = fm.top;
                fitbottom = fm.bottom;
                fitascent = fm.ascent;
                fitdescent = fm.descent;
            }
            // Log.e("text", "output rest " + here + " to " + end);
            v = out(source, here, end, fitascent, fitdescent, fittop, fitbottom, v, spacingmult, spacingadd, chooseht, choosehtv, fm, tab, needMultiply, start, chdirs, dir, easy, end == bufend, includepad, trackpad, widths, start, end - start, where, ellipsizedWidth, w, paint);
        }
        start = end;
        if (end == bufend)
            break;
    }
    if (bufend == bufstart || source.charAt(bufend - 1) == '\n') {
        // Log.e("text", "output last " + bufend);
        paint.getFontMetricsInt(fm);
        v = out(source, bufend, bufend, fm.ascent, fm.descent, fm.top, fm.bottom, v, spacingmult, spacingadd, null, null, fm, false, needMultiply, bufend, chdirs, DEFAULT_DIR, true, true, includepad, trackpad, widths, bufstart, 0, where, ellipsizedWidth, 0, paint);
    }
}
Also used : LineHeightSpan(jp.sblo.pandora.jota.text.style.LineHeightSpan) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) Bitmap(android.graphics.Bitmap)

Aggregations

Bitmap (android.graphics.Bitmap)1 Paint (android.graphics.Paint)1 TextPaint (android.text.TextPaint)1 LineHeightSpan (jp.sblo.pandora.jota.text.style.LineHeightSpan)1